links / beat.html
minispace's picture
Optimize and sanitize public codebase: remove all comments, explanatory notes, backend training data, and verify security isolation
9b14626
Raw History Blame Contribute Delete
50 kB
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="BEAT Cajas Acústicas - Carpintería Profesional de Gabinetes para Audio en Fenólico en Crudo y Texturados.">
<title>BEAT | Cajas Acústicas & Carpintería de Audio</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@600;700;800;900&family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--primary: #38bdf8;
--primary-hover: #0284c7;
--bg-body: #111625;
--bg-card: #181e2e;
--text-dark: #f8fafc;
--text-muted: #94a3b8;
--border-color: rgba(255, 255, 255, 0.08);
--radius-lg: 20px;
--shadow-sm: 0 4px 12px rgba(0,0,0,0.3);
--shadow-md: 0 12px 30px rgba(0,0,0,0.5);
--shadow-lg: 0 20px 50px rgba(0,0,0,0.7);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Plus Jakarta Sans', sans-serif;
background-color: var(--bg-body);
color: var(--text-dark);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
background-image: radial-gradient(circle at 50% 0%, rgba(56, 189, 248, 0.08) 0%, transparent 75%);
}
.top-bar {
background: #0f172a;
color: #38bdf8;
font-size: 0.8rem;
font-weight: 800;
text-align: center;
padding: 8px 16px;
letter-spacing: 0.8px;
text-transform: uppercase;
border-bottom: 1px solid rgba(56, 189, 248, 0.2);
}
.store-header {
background: rgba(17, 22, 37, 0.85);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border-color);
position: sticky;
top: 0;
z-index: 50;
box-shadow: var(--shadow-sm);
}
.header-inner {
max-width: 1200px;
margin: 0 auto;
padding: 14px 24px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.nav-left {
display: flex;
align-items: center;
gap: 16px;
}
.back-link {
display: inline-flex;
align-items: center;
gap: 6px;
text-decoration: none;
color: var(--text-muted);
font-weight: 700;
font-size: 0.85rem;
padding: 6px 14px;
border-radius: 20px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.2s ease;
}
.back-link:hover {
background: var(--primary);
color: #0f172a;
border-color: var(--primary);
}
.brand-logo-text {
font-family: 'Outfit', sans-serif;
font-size: 1.6rem;
font-weight: 900;
letter-spacing: 1px;
color: #ffffff;
display: flex;
align-items: center;
gap: 6px;
}
.brand-logo-text span {
color: var(--primary);
}
.search-bar {
flex-grow: 1;
max-width: 380px;
position: relative;
}
.search-input {
width: 100%;
padding: 10px 16px 10px 42px;
border-radius: 25px;
border: 1.5px solid rgba(255, 255, 255, 0.12);
background: rgba(15, 23, 42, 0.6);
color: #ffffff;
font-size: 0.88rem;
outline: none;
transition: border-color 0.2s ease;
}
.search-input:focus {
border-color: var(--primary);
}
.search-icon {
position: absolute;
left: 14px;
top: 50%;
transform: translateY(-50%);
width: 18px;
height: 18px;
stroke: #64748b;
}
.controls-right {
display: flex;
align-items: center;
gap: 10px;
}
.lang-vertical-toggle {
position: relative;
display: flex;
flex-direction: column;
background: rgba(15, 23, 42, 0.8);
border: 1.5px solid rgba(56, 189, 248, 0.3);
border-radius: 12px;
padding: 2px;
cursor: pointer;
user-select: none;
width: 78px;
height: 48px;
overflow: hidden;
}
.lang-slider {
position: absolute;
left: 2px;
width: calc(100% - 4px);
height: 21px;
background: var(--primary);
border-radius: 8px;
transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
z-index: 1;
box-shadow: 0 2px 8px rgba(56, 189, 248, 0.4);
}
.lang-slider.es-active { transform: translateY(22px); }
.lang-slider.en-active { transform: translateY(0px); }
.lang-opt {
position: relative;
z-index: 2;
height: 21px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.7rem;
font-weight: 800;
color: #64748b;
transition: color 0.25s ease;
}
.lang-opt.active-text { color: #0f172a !important; }
.categories-nav {
background: rgba(15, 23, 42, 0.5);
border-bottom: 1px solid var(--border-color);
}
.cat-inner {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px;
display: flex;
gap: 24px;
overflow-x: auto;
}
.cat-link {
padding: 12px 0;
text-decoration: none;
color: var(--text-muted);
font-size: 0.88rem;
font-weight: 700;
white-space: nowrap;
border-bottom: 2px solid transparent;
transition: all 0.2s ease;
cursor: pointer;
}
.cat-link:hover, .cat-link.active {
color: var(--primary);
border-bottom-color: var(--primary);
}
.store-container {
max-width: 1200px;
margin: 0 auto;
padding: 24px;
}
.hero-banner {
background: linear-gradient(135deg, rgba(30, 41, 59, 0.7) 0%, rgba(15, 23, 42, 0.9) 100%);
border-radius: 20px;
padding: 18px 24px;
margin-bottom: 28px;
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid rgba(56, 189, 248, 0.2);
backdrop-filter: blur(10px);
}
.hero-text h1 {
font-family: 'Outfit', sans-serif;
font-size: 1.55rem;
font-weight: 900;
color: #ffffff;
line-height: 1.25;
margin-bottom: 4px;
}
.hero-text p {
color: #94a3b8;
font-size: 0.88rem;
font-weight: 500;
}
.hero-badge {
display: inline-block;
background: rgba(56, 189, 248, 0.15);
border: 1px solid rgba(56, 189, 248, 0.3);
color: #38bdf8;
font-size: 0.72rem;
font-weight: 800;
padding: 3px 10px;
border-radius: 20px;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
}
.section-heading {
font-family: 'Outfit', sans-serif;
font-size: 1.5rem;
font-weight: 800;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.product-count {
font-size: 0.85rem;
font-weight: 600;
color: var(--text-muted);
font-family: 'Plus Jakarta Sans', sans-serif;
}
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 22px;
}
.product-card {
background: var(--bg-card);
border-radius: var(--radius-lg);
border: 1px solid var(--border-color);
overflow: hidden;
box-shadow: var(--shadow-sm);
transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
cursor: pointer;
position: relative;
display: flex;
flex-direction: column;
}
.product-card:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-md);
border-color: rgba(56, 189, 248, 0.4);
}
.card-img-wrapper {
width: 100%;
aspect-ratio: 1 / 1;
overflow: hidden;
background: #0f1422;
position: relative;
}
.product-img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.4s ease;
}
.product-card:hover .product-img {
transform: scale(1.05);
}
.off-badge {
position: absolute;
top: 12px;
left: 12px;
background: var(--primary);
color: #0f172a;
font-size: 0.72rem;
font-weight: 800;
padding: 4px 8px;
border-radius: 6px;
z-index: 2;
}
.card-body {
padding: 18px;
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: space-between;
}
.card-category {
font-size: 0.75rem;
font-weight: 800;
color: var(--primary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 4px;
}
.card-title {
font-size: 0.98rem;
font-weight: 700;
color: #ffffff;
margin-bottom: 10px;
line-height: 1.35;
}
.card-price-row {
display: flex;
align-items: baseline;
gap: 8px;
}
.current-price {
font-family: 'Outfit', sans-serif;
font-size: 1.25rem;
font-weight: 800;
color: #ffffff;
}
.old-price {
font-size: 0.85rem;
color: #64748b;
text-decoration: line-through;
}
.quick-view-hint {
margin-top: 10px;
font-size: 0.78rem;
font-weight: 700;
color: var(--primary);
display: flex;
align-items: center;
gap: 4px;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(9, 13, 22, 0.82);
backdrop-filter: blur(10px);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.modal-overlay.active {
opacity: 1;
pointer-events: auto;
}
.modal-content {
background: #181e2e;
border: 1px solid rgba(255, 255, 255, 0.12);
width: 100%;
max-width: 840px;
border-radius: 24px;
box-shadow: var(--shadow-lg);
position: relative;
overflow: hidden;
transform: scale(0.92);
transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
display: grid;
grid-template-columns: 1.1fr 1fr;
}
.modal-overlay.active .modal-content {
transform: scale(1);
}
.modal-close-btn {
position: absolute;
top: 16px;
right: 16px;
width: 38px;
height: 38px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
border: none;
color: #94a3b8;
font-size: 1.2rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 20;
transition: all 0.2s ease;
}
.modal-close-btn:hover {
background: var(--primary);
color: #0f172a;
transform: rotate(90deg);
}
.modal-gallery-wrapper {
background: #0f1422;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
position: relative;
}
.main-gallery-view {
width: 100%;
height: 320px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.modal-img {
max-width: 100%;
max-height: 310px;
object-fit: contain;
border-radius: 12px;
}
.dots-indicator-row {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-top: 12px;
}
.dot-indicator {
width: 9px;
height: 9px;
border-radius: 50%;
background: #334155;
cursor: pointer;
transition: all 0.25s ease;
}
.dot-indicator.active {
background: var(--primary);
transform: scale(1.3);
}
.modal-details {
padding: 32px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.modal-cat {
font-size: 0.78rem;
font-weight: 800;
color: var(--primary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
}
.modal-title {
font-family: 'Outfit', sans-serif;
font-size: 1.5rem;
font-weight: 800;
color: #ffffff;
margin-bottom: 12px;
line-height: 1.25;
}
.modal-price-row {
display: flex;
align-items: baseline;
gap: 10px;
margin-bottom: 8px;
}
.modal-price {
font-family: 'Outfit', sans-serif;
font-size: 1.8rem;
font-weight: 800;
color: var(--primary);
}
.modal-old-price {
font-size: 1rem;
color: #64748b;
text-decoration: line-through;
}
.modal-shipping-note {
font-size: 0.75rem;
color: #94a3b8;
font-weight: 600;
margin-bottom: 14px;
}
.modal-desc {
font-size: 0.88rem;
color: #cbd5e1;
line-height: 1.6;
margin-bottom: 24px;
}
.buy-btn {
background: #25d366;
color: #ffffff;
text-decoration: none;
border: none;
padding: 14px 24px;
border-radius: 12px;
font-size: 0.95rem;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: background 0.2s ease, transform 0.2s ease;
box-shadow: 0 4px 14px rgba(37, 211, 102, 0.3);
}
.buy-btn:hover {
background: #1eb954;
transform: translateY(-2px);
}
.wholesale-section {
margin-top: 50px;
background: linear-gradient(135deg, rgba(30, 41, 59, 0.8) 0%, rgba(15, 23, 42, 0.95) 100%);
border-radius: 24px;
padding: 36px;
color: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
gap: 30px;
border: 1px solid rgba(56, 189, 248, 0.25);
box-shadow: var(--shadow-md);
}
.wholesale-info h2 {
font-family: 'Outfit', sans-serif;
font-size: 1.7rem;
font-weight: 800;
color: #ffffff;
margin-bottom: 8px;
}
.wholesale-info p {
color: #94a3b8;
font-size: 0.95rem;
max-width: 600px;
}
.wholesale-badge {
display: inline-block;
background: rgba(56, 189, 248, 0.15);
color: #38bdf8;
font-size: 0.78rem;
font-weight: 800;
padding: 4px 12px;
border-radius: 20px;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 12px;
}
.wholesale-btn {
background: var(--primary);
color: #0f172a;
border: none;
padding: 16px 28px;
border-radius: 14px;
font-size: 0.95rem;
font-weight: 800;
cursor: pointer;
white-space: nowrap;
display: flex;
align-items: center;
gap: 10px;
transition: all 0.25s ease;
box-shadow: 0 4px 16px rgba(56, 189, 248, 0.35);
}
.wholesale-btn:hover {
background: var(--primary-hover);
color: #ffffff;
transform: translateY(-3px);
}
.form-modal-content {
background: #181e2e;
border: 1px solid rgba(255, 255, 255, 0.12);
width: 100%;
max-width: 480px;
border-radius: 24px;
padding: 32px;
position: relative;
box-shadow: var(--shadow-lg);
}
.form-title {
font-family: 'Outfit', sans-serif;
font-size: 1.5rem;
font-weight: 800;
margin-bottom: 6px;
color: #ffffff;
}
.form-desc {
font-size: 0.88rem;
color: #94a3b8;
margin-bottom: 20px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 14px;
}
.form-label {
font-size: 0.82rem;
font-weight: 700;
color: #cbd5e1;
}
.form-input {
width: 100%;
padding: 12px 16px;
border-radius: 12px;
border: 1.5px solid rgba(255, 255, 255, 0.12);
background: rgba(15, 23, 42, 0.8);
color: #ffffff;
font-size: 0.9rem;
outline: none;
transition: border-color 0.2s ease;
}
.form-input:focus {
border-color: var(--primary);
}
.submit-wholesale-btn {
width: 100%;
background: #25d366;
color: #ffffff;
border: none;
padding: 14px;
border-radius: 12px;
font-size: 0.95rem;
font-weight: 800;
cursor: pointer;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: background 0.2s ease;
}
.submit-wholesale-btn:hover {
background: #1eb954;
}
.store-footer {
background: #0f1422;
border-top: 1px solid var(--border-color);
padding: 40px 24px 20px;
margin-top: 60px;
}
.footer-inner {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
text-align: center;
}
.copyright-text {
font-size: 0.88rem;
color: var(--text-muted);
font-weight: 600;
}
img, svg, .product-img, .modal-img {
-webkit-user-drag: none !important;
user-drag: none !important;
user-select: none !important;
}
.page-loader {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #111625;
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), visibility 0.35s ease;
opacity: 1;
visibility: visible;
}
.page-loader.loaded {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.loader-spinner {
width: 42px;
height: 42px;
border: 3.5px solid rgba(255, 255, 255, 0.12);
border-top-color: #38bdf8;
border-radius: 50%;
animation: loaderSpin 0.75s infinite linear;
}
@keyframes loaderSpin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.under-construction-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(17, 22, 37, 0.90);
backdrop-filter: blur(7px);
-webkit-backdrop-filter: blur(7px);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.under-construction-frameless {
background: none !important;
border: none !important;
box-shadow: none !important;
padding: 0 !important;
max-width: 520px;
width: 100%;
text-align: center;
}
.construction-badge-clean {
display: inline-block;
color: #38bdf8;
font-size: 0.8rem;
font-weight: 800;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 10px;
}
.construction-title-clean {
font-family: 'Outfit', sans-serif;
font-size: 2.2rem;
font-weight: 900;
color: #ffffff;
margin-bottom: 10px;
line-height: 1.15;
}
.construction-desc-clean {
font-size: 0.85rem !important;
color: #94a3b8;
line-height: 1.6;
max-width: 440px;
margin: 0 auto 24px;
}
.construction-link-clean {
display: inline-flex;
align-items: center;
gap: 6px;
color: #38bdf8;
font-size: 0.88rem;
font-weight: 700;
text-decoration: none;
transition: color 0.2s ease;
}
.construction-link-clean:hover {
color: #ffffff;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="under-construction-overlay">
<div class="under-construction-frameless">
<span class="construction-badge-clean">PRÓXIMAMENTE</span>
<h2 class="construction-title-clean">Sitio en construcción</h2>
<p class="construction-desc-clean">Estamos realizando los últimos ajustes en la plataforma de carpintería y gabinetes acústicos profesionales.</p>
<div class="construction-actions-clean">
<a href="index.html" class="construction-link-clean">← Volver al inicio</a>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader" class="page-loader">
<div class="loader-spinner"></div>
</div>
<div class="top-bar">
<span id="announcementText">🔊 CARPINTERÍA PROFESIONAL DE CAJAS ACÚSTICAS | ENVIOS A TODO EL PAÍS</span>
</div>
<header class="store-header">
<div class="header-inner">
<div class="nav-left">
<a href="index.html" class="back-link">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M19 12H5M12 19l-7-7 7-7"/>
</svg>
<span id="backText">Volver</span>
</a>
<div class="brand-logo-text">BEAT <span>AUDIO</span></div>
</div>
<div class="search-bar">
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8"/>
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
<input type="text" id="searchInput" class="search-input" placeholder="Buscar gabinetes acústicos..." oninput="filterProducts(this.value)">
</div>
<div class="controls-right">
<div class="lang-vertical-toggle" onclick="toggleLanguage()" title="Cambiar idioma / Switch language">
<div class="lang-slider es-active" id="langSlider"></div>
<span class="lang-opt" id="optEn">Inglés</span>
<span class="lang-opt active-text" id="optEs">Español</span>
</div>
</div>
</div>
</header>
<nav class="categories-nav">
<div class="cat-inner" id="catNav"></div>
</nav>
<div class="store-container">
<div class="hero-banner">
<div class="hero-text">
<span class="hero-badge" id="heroBadge">Carpintería de Audio Profesional</span>
<h1 id="heroTitle">BEAT Cajas Acústicas & Gabinetes</h1>
<p id="heroDesc">Fabricación artesanal en terciado fenólico de abedul en crudo y acabados texturados de alta resistencia. (Carpintería sola sin componentes).</p>
</div>
</div>
<div class="section-heading">
<h2 id="catalogTitle">Catálogo de Gabinetes</h2>
<span class="product-count" id="productCount">6 modelos</span>
</div>
<div class="products-grid" id="productsGrid"></div>
<div class="wholesale-section">
<div class="wholesale-info">
<span class="wholesale-badge">Fabricación a Medida & Lotes</span>
<h2 id="wsTitle">Presupuesto & Diseños Especiales</h2>
<p id="wsDesc">Enviamos cajas caladas y listas para armar a todo el país para fabricantes de audio, DJs y empresas de sonido.</p>
</div>
<button class="wholesale-btn" onclick="openWholesaleModal()">
📦 <span id="wsBtnText">Solicitar presupuesto a medida</span>
</button>
</div>
</div>
<div class="modal-overlay" id="productModal" onclick="closeModal(event)">
<div class="modal-content" onclick="event.stopPropagation()">
<button class="modal-close-btn" onclick="closeModalDirect()" title="Cerrar (Esc)">✕</button>
<div class="modal-gallery-wrapper">
<div class="main-gallery-view">
<img id="modalImg" src="" alt="" class="modal-img" draggable="false">
</div>
<div class="dots-indicator-row" id="dotsContainer"></div>
</div>
<div class="modal-details">
<div>
<span id="modalCat" class="modal-cat">SUBWOOFERS</span>
<h2 id="modalTitle" class="modal-title">Nombre del Modelo</h2>
<div class="modal-price-row">
<span id="modalPrice" class="modal-price">$0,00</span>
<span id="modalOldPrice" class="modal-old-price"></span>
</div>
<div class="modal-shipping-note" id="shippingNote">*(Precios de carpintería vacía sin parlantes)*</div>
<p id="modalDesc" class="modal-desc">Descripción del producto...</p>
</div>
<button class="buy-btn" onclick="openPurchaseModal()">
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M.057 24l1.687-6.163c-1.041-1.804-1.588-3.849-1.587-5.946.003-6.556 5.338-11.891 11.893-11.891 3.181.001 6.167 1.24 8.413 3.488 2.245 2.248 3.481 5.236 3.48 8.414-.003 6.557-5.338 11.892-11.893 11.892-1.99-.001-3.951-.5-5.688-1.448l-6.305 1.654zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884-.001 2.225.651 3.891 1.746 5.634l-.999 3.648 3.742-.981zm11.387-5.464c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.768.967-.941 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.095 3.2 5.076 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414z"/>
</svg>
<span id="buyBtnText">Consultar por WhatsApp</span>
</button>
</div>
</div>
</div>
<div class="modal-overlay" id="purchaseModal" onclick="closePurchaseModal(event)">
<div class="form-modal-content" onclick="event.stopPropagation()">
<button class="modal-close-btn" onclick="closePurchaseModalDirect()">✕</button>
<h3 class="form-title" id="purchaseFormTitle">Consulta / Pedido por WhatsApp</h3>
<p class="form-desc" id="purchaseFormDesc">Completa tus datos para enviar la consulta directa por este modelo.</p>
<form onsubmit="handlePurchaseSubmit(event)">
<div class="form-group">
<label class="form-label">Nombre completo</label>
<input type="text" id="pNombre" class="form-input" placeholder="Ej: Carlos Rossi" required>
</div>
<div class="form-group">
<label class="form-label">Ciudad / Provincia</label>
<input type="text" id="pCiudad" class="form-input" placeholder="Ej: Rosario, Santa Fe" required>
</div>
<div class="form-group">
<label class="form-label">Comentario o Consulta</label>
<textarea id="pComentario" class="form-input" style="height: 80px; resize: none;" placeholder="Ej: Quisiera consultar envío o terminación..." required></textarea>
</div>
<button type="submit" class="submit-wholesale-btn">
<span>Enviar Consulta a WhatsApp</span>
</button>
</form>
</div>
</div>
<div class="modal-overlay" id="wholesaleModal" onclick="closeWholesaleModal(event)">
<div class="form-modal-content" onclick="event.stopPropagation()">
<button class="modal-close-btn" onclick="closeWholesaleModalDirect()">✕</button>
<h3 class="form-title" id="formTitle">Presupuesto de Cajas Acústicas</h3>
<p class="form-desc" id="formDesc">Ingresa tus datos para recibir asesoramiento o presupuesto a medida.</p>
<form onsubmit="handleWholesaleSubmit(event)">
<div class="form-group">
<label class="form-label">Nombre completo</label>
<input type="text" id="wsNombre" class="form-input" placeholder="Ej: Carlos Rossi" required>
</div>
<div class="form-group">
<label class="form-label">Teléfono / WhatsApp</label>
<input type="tel" id="wsTelefono" class="form-input" placeholder="Ej: 2364320482" required>
</div>
<div class="form-group">
<label class="form-label">Ciudad / Provincia</label>
<input type="text" id="wsCiudad" class="form-input" placeholder="Ej: Rosario, Santa Fe" required>
</div>
<button type="submit" class="submit-wholesale-btn">
<span>Enviar Consulta por WhatsApp</span>
</button>
</form>
</div>
</div>
<footer class="store-footer">
<div class="footer-inner">
<div class="brand-logo-text" style="font-size: 1.3rem;">BEAT <span>AUDIO</span></div>
<p class="copyright-text">Sitio creado con Neo Studio</p>
</div>
</footer>
<script>
(function() {
function hideLoaderNow() {
var loader = document.getElementById('pageLoader');
if (loader) {
loader.style.opacity = '0';
loader.style.visibility = 'hidden';
loader.style.pointerEvents = 'none';
if (loader.parentNode) loader.parentNode.removeChild(loader);
}
}
if (document.readyState === 'interactive' || document.readyState === 'complete') {
hideLoaderNow();
} else {
document.addEventListener('DOMContentLoaded', hideLoaderNow);
window.addEventListener('load', hideLoaderNow);
}
setTimeout(hideLoaderNow, 250);
})();
</script>
<script>
(function() {
setTimeout(function() {
try {
const pageName = document.title || window.location.pathname;
const startTime = Date.now();
const dateStr = new Date().toLocaleDateString('es-AR', { day: '2-digit', month: 'long', year: 'numeric' });
const timeStr = new Date().toLocaleTimeString('es-AR', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
const userAgent = navigator.userAgent;
let deviceStr = 'Desktop';
if (/Mobi|Android|iPhone|iPad/i.test(userAgent)) deviceStr = 'Móvil / Celular';
let currentRecordIndex = -1;
function saveVisit(ip, city, country, flag) {
let logs = JSON.parse(localStorage.getItem('site_visitor_history') || '[]');
const visitRecord = {
id: Date.now(),
date: dateStr,
time: timeStr,
page: pageName,
ip: ip || 'Desconocida',
city: city || 'Desconocida',
country: country || 'Desconocido',
flag: flag || '🌐',
device: deviceStr,
durationSec: 1
};
logs.push(visitRecord);
if (logs.length > 500) logs = logs.slice(-500);
localStorage.setItem('site_visitor_history', JSON.stringify(logs));
currentRecordIndex = logs.length - 1;
}
fetch('https://ipapi.co/json/', { signal: AbortSignal.timeout(2000) })
.then(res => res.json())
.then(data => {
saveVisit(data.ip, data.city, data.country_name, data.country_code ? String.fromCodePoint(...[...data.country_code.toUpperCase()].map(c => 127397 + c.charCodeAt())) : '🌐');
})
.catch(() => {
saveVisit('Oculta', 'Local', 'Argentina', '🇦🇷');
});
setInterval(() => {
if (currentRecordIndex < 0) return;
const elapsed = Math.round((Date.now() - startTime) / 1000);
let logs = JSON.parse(localStorage.getItem('site_visitor_history') || '[]');
if (logs[currentRecordIndex]) {
logs[currentRecordIndex].durationSec = elapsed;
localStorage.setItem('site_visitor_history', JSON.stringify(logs));
}
}, 3000);
} catch(e) {}
}, 100);
})();
</script>
<script>
document.addEventListener('contextmenu', function(e) { e.preventDefault(); });
document.addEventListener('keydown', function(e) {
if (e.keyCode === 123 ||
(e.ctrlKey && e.shiftKey && (e.keyCode === 73 || e.keyCode === 74 || e.keyCode === 67)) ||
(e.ctrlKey && (e.keyCode === 85 || e.keyCode === 83)) ||
(e.metaKey && e.altKey && (e.keyCode === 73 || e.keyCode === 74)) ||
(e.metaKey && (e.keyCode === 85 || e.keyCode === 83))) {
e.preventDefault();
return false;
}
});
document.addEventListener('dragstart', function(e) { e.preventDefault(); });
</script>
<div id="beatModal" style="display:none; position:fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.85); backdrop-filter:blur(10px); z-index:10000; align-items:center; justify-content:center; padding:20px;">
<div style="background:#181e2e; border:1px solid rgba(56,189,248,0.3); border-radius:24px; max-width:500px; width:100%; overflow:hidden; position:relative;">
<button onclick="closeBeatModal()" style="position:absolute; top:14px; right:14px; background:rgba(255,255,255,0.1); border:none; color:#fff; width:32px; height:32px; border-radius:50%; font-weight:800; cursor:pointer;">✕</button>
<img id="mImg" src="" style="width:100%; height:260px; object-fit:cover;">
<div style="padding:24px;">
<h3 id="mTitle" style="font-size:1.3rem; font-weight:900; color:#fff; margin-bottom:8px;"></h3>
<p id="mDesc" style="font-size:0.88rem; color:#cbd5e1; margin-bottom:16px; line-height:1.6;"></p>
<div style="display:flex; align-items:center; justify-content:space-between;">
<span id="mPrice" style="font-size:1.4rem; font-weight:900; color:#38bdf8;"></span>
<a id="mWa" href="" target="_blank" style="background:#25d366; color:#fff; padding:12px 20px; border-radius:12px; text-decoration:none; font-weight:800;">Consultar por WhatsApp</a>
</div>
</div>
</div>
</div>
<script>
function openBeatModal(title, price, img, desc) {
document.getElementById('mTitle').textContent = title;
document.getElementById('mDesc').textContent = desc;
document.getElementById('mPrice').textContent = '$' + Number(price).toLocaleString('es-AR') + ' ARS';
document.getElementById('mImg').src = img;
document.getElementById('mWa').href = 'https://wa.me/542364320482?text=' + encodeURIComponent('Hola BEAT Audio! Quisiera consultar por la ' + title);
document.getElementById('beatModal').style.display = 'flex';
}
function closeBeatModal() {
document.getElementById('beatModal').style.display = 'none';
}
</script>
<script>
(function() {
try {
const pageTitle = document.title.split('|')[0].trim() || 'Inicio';
const now = new Date();
const dateStr = now.toLocaleDateString('es-AR', { day: '2-digit', month: 'long', year: 'numeric' });
const timeStr = now.toLocaleTimeString('es-AR', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
let userId = localStorage.getItem('neo_visitor_uid');
if (!userId) {
userId = 'USR-' + Math.floor(1000 + Math.random() * 9000);
localStorage.setItem('neo_visitor_uid', userId);
}
let userName = localStorage.getItem('lead_user_name') || 'Anónimo (' + userId + ')';
const ua = navigator.userAgent || '';
let deviceType = 'Desktop';
let brandModel = 'PC / Genérico';
let osName = 'Desconocido';
if (/iPhone/i.test(ua)) {
deviceType = 'Móvil';
brandModel = 'Apple iPhone';
osName = 'iOS ' + ((ua.match(/OS ([\d_]+)/) || [])[1] || '').replace(/_/g, '.');
} else if (/iPad/i.test(ua)) {
deviceType = 'Tablet';
brandModel = 'Apple iPad';
osName = 'iPadOS';
} else if (/Android/i.test(ua)) {
deviceType = /Mobile/i.test(ua) ? 'Móvil' : 'Tablet';
osName = 'Android ' + ((ua.match(/Android ([\d.]+)/) || [])[1] || '');
if (/SM-|Samsung/i.test(ua)) brandModel = 'Samsung Galaxy';
else if (/Motorola|Moto/i.test(ua)) brandModel = 'Motorola';
else if (/Xiaomi|Redmi|POCO/i.test(ua)) brandModel = 'Xiaomi / Redmi';
else if (/Pixel/i.test(ua)) brandModel = 'Google Pixel';
else brandModel = 'Android Genérico';
} else if (/Macintosh|Mac OS X/i.test(ua)) {
deviceType = 'Desktop';
brandModel = 'Apple Mac / MacBook';
osName = 'macOS ' + ((ua.match(/Mac OS X ([\d_]+)/) || [])[1] || '').replace(/_/g, '.');
} else if (/Windows NT/i.test(ua)) {
deviceType = 'Desktop';
brandModel = 'Windows PC';
const ver = (ua.match(/Windows NT ([\d.]+)/) || [])[1];
osName = ver === '10.0' ? 'Windows 10/11' : ('Windows ' + ver);
} else if (/Linux/i.test(ua)) {
deviceType = 'Desktop';
brandModel = 'Linux PC';
osName = 'Linux';
}
let browserName = 'Navegador Web';
let browserVer = '';
if (/Chrome\/([\d.]+)/.test(ua) && !/Edg|OPR|SamsungBrowser/.test(ua)) {
browserName = 'Google Chrome';
browserVer = RegExp.$1.split('.')[0];
} else if (/Safari\/([\d.]+)/.test(ua) && !/Chrome/.test(ua)) {
browserName = 'Apple Safari';
browserVer = ((ua.match(/Version\/([\d.]+)/) || [])[1] || '').split('.')[0];
} else if (/Firefox\/([\d.]+)/.test(ua)) {
browserName = 'Mozilla Firefox';
browserVer = RegExp.$1.split('.')[0];
} else if (/Edg\/([\d.]+)/.test(ua)) {
browserName = 'Microsoft Edge';
browserVer = RegExp.$1.split('.')[0];
} else if (/SamsungBrowser\/([\d.]+)/.test(ua)) {
browserName = 'Samsung Internet';
browserVer = RegExp.$1.split('.')[0];
} else if (/OPR\/([\d.]+)/.test(ua)) {
browserName = 'Opera';
browserVer = RegExp.$1.split('.')[0];
}
const fullBrowser = browserName + (browserVer ? ' v' + browserVer : '');
const screenRes = (screen.width || window.innerWidth) + 'x' + (screen.height || window.innerHeight);
const dpr = window.devicePixelRatio ? window.devicePixelRatio.toFixed(1) + 'x' : '1x';
const orientation = (screen.orientation ? screen.orientation.type : (window.innerWidth > window.innerHeight ? 'Horizontal' : 'Vertical')).includes('portrait') ? 'Vertical' : 'Horizontal';
const cores = navigator.hardwareConcurrency ? navigator.hardwareConcurrency + ' núcleos' : 'N/D';
const ram = navigator.deviceMemory ? navigator.deviceMemory + ' GB' : 'N/D';
const language = navigator.language || 'es-AR';
const referrer = document.referrer ? (new URL(document.referrer).hostname || 'Externo') : 'Directo';
let connType = 'WiFi / Conexión Rápida';
if (navigator.connection) {
connType = (navigator.connection.effectiveType || '').toUpperCase() + (navigator.connection.downlink ? ' (' + navigator.connection.downlink + ' Mbps)' : '');
}
let batteryLevel = 'N/D';
if (navigator.getBattery) {
navigator.getBattery().then(b => {
batteryLevel = Math.round(b.level * 100) + '% ' + (b.charging ? '⚡' : '🔋');
}).catch(()=>{});
}
let sessionRoutes = JSON.parse(sessionStorage.getItem('neo_routes') || '[]');
if (!sessionRoutes.length || sessionRoutes[sessionRoutes.length - 1] !== pageTitle) {
sessionRoutes.push(pageTitle);
sessionStorage.setItem('neo_routes', JSON.stringify(sessionRoutes));
}
const sessionStart = Date.now();
function saveOrMergeVisitor(geo) {
let logs = JSON.parse(localStorage.getItem('site_visitor_history') || '[]');
let userMap = {};
logs.forEach(l => {
const key = l.uid || l.ip || 'USR-UNKNOWN';
if (!userMap[key]) {
userMap[key] = l;
if (!l.sessions) {
l.sessions = [{ time: l.firstTime || l.time, page: l.page, duration: l.durationSec || 1 }];
}
} else {
userMap[key].visitsToday = (userMap[key].visitsToday || 1) + 1;
userMap[key].durationSec = (userMap[key].durationSec || 0) + (l.durationSec || 1);
userMap[key].lastTime = l.lastTime || l.time || userMap[key].lastTime;
(l.routes || []).forEach(r => {
if (!userMap[key].routes.includes(r)) userMap[key].routes.push(r);
});
if (l.sessions) {
userMap[key].sessions = userMap[key].sessions.concat(l.sessions);
}
}
});
if (!userMap[userId]) {
userMap[userId] = {
id: Date.now(),
uid: userId,
name: userName,
date: dateStr,
firstTime: timeStr,
lastTime: timeStr,
visitsToday: 1,
page: pageTitle,
routes: sessionRoutes,
sessions: [{ time: timeStr, page: pageTitle, duration: 1 }],
ip: geo.ip || 'Oculta',
city: geo.city || 'Desconocida',
region: geo.region || 'Buenos Aires',
country: geo.country_name || 'Argentina',
flag: geo.flag || '🇦🇷',
isp: geo.org || '—',
postal: geo.postal || '—',
deviceType: deviceType,
brandModel: brandModel,
os: osName,
browser: fullBrowser,
screen: screenRes,
dpr: dpr,
orientation: orientation,
cores: cores,
ram: ram,
lang: language,
referrer: referrer,
connection: connType,
battery: batteryLevel,
durationSec: 1
};
} else {
const u = userMap[userId];
u.visitsToday = (u.visitsToday || 1) + 1;
u.lastTime = timeStr;
u.page = pageTitle;
sessionRoutes.forEach(r => {
if (!u.routes.includes(r)) u.routes.push(r);
});
if (!u.sessions) u.sessions = [];
u.sessions.push({ time: timeStr, page: pageTitle, duration: 1 });
if (geo.ip && u.ip === 'Oculta') u.ip = geo.ip;
if (geo.city && u.city === 'Desconocida') {
u.city = geo.city;
u.region = geo.region;
u.country = geo.country_name;
u.flag = geo.flag;
u.isp = geo.org;
}
u.connection = connType;
u.battery = batteryLevel;
}
const cleanList = Object.values(userMap);
localStorage.setItem('site_visitor_history', JSON.stringify(cleanList));
}
fetch('https://ipapi.co/json/').then(r => r.json()).then(d => {
const flag = d.country_code ? String.fromCodePoint(...[...d.country_code.toUpperCase()].map(c => 127397 + c.charCodeAt(0))) : '🌐';
saveOrMergeVisitor({
ip: d.ip,
city: d.city,
region: d.region || d.region_code || 'Buenos Aires',
country_name: d.country_name || 'Argentina',
flag: flag,
org: d.org,
postal: d.postal
});
}).catch(() => {
saveOrMergeVisitor({
ip: 'IP Local',
city: 'Buenos Aires',
region: 'Buenos Aires',
country_name: 'Argentina',
flag: '🇦🇷',
org: 'Conexión Directa',
postal: '—'
});
});
setInterval(() => {
let logs = JSON.parse(localStorage.getItem('site_visitor_history') || '[]');
const cur = logs.find(l => l.uid === userId);
if (cur) {
cur.durationSec = (cur.durationSec || 1) + 2;
if (cur.sessions && cur.sessions.length > 0) {
cur.sessions[cur.sessions.length - 1].duration = (cur.sessions[cur.sessions.length - 1].duration || 1) + 2;
}
localStorage.setItem('site_visitor_history', JSON.stringify(logs));
}
}, 2000);
} catch (e) {}
})();
</script>
</body>
</html>