Download beat.html from minispace/links: direct link, hf CLI and curl.
- Browser
- Download file 50 kB
-
https://huggingface.co/spaces/minispace/links/resolve/main/beat.html
- Command line
-
hf download hf://spaces/minispace/links/beat.html
-
curl -L -o beat.html https://huggingface.co/spaces/minispace/links/resolve/main/beat.html
50 kB
| <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 ; } | |
| .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 ; | |
| user-drag: none ; | |
| user-select: none ; | |
| } | |
| .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 ; | |
| border: none ; | |
| box-shadow: none ; | |
| padding: 0 ; | |
| 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 ; | |
| 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> | |