<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#E91E63">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Sensaciones UY">
<meta name="description" content="Radio online de Uruguay 24/7">
<title>Sensaciones UY - Radio Online</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root { --primary: #E91E63; --primary-dark: #AD1457; --bg-dark: #0a0a14; --bg-card: rgba(255,255,255,0.05); }
body { font-family: 'Poppins', sans-serif; background: var(--bg-dark); min-height: 100vh; color: white; overflow-x: hidden; }
/* Loading */
.loading-screen { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--bg-dark); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 20000; }
.loading-screen.hidden { display: none; }
.loading-spinner { width: 50px; height: 50px; border: 3px solid rgba(233,30,99,0.2); border-top-color: var(--primary); border-radius: 50%; animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text { margin-top: 20px; color: rgba(255,255,255,0.6); }
/* Selector de modo */
.mode-selector { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--bg-dark); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 10000; }
.mode-selector.hidden { display: none; }
.mode-selector h1 { color: var(--primary); font-size: 2em; margin-bottom: 10px; }
.mode-selector p { color: rgba(255,255,255,0.6); margin-bottom: 30px; }
.mode-btn { display: flex; align-items: center; gap: 15px; background: var(--bg-card); border: 2px solid rgba(255,255,255,0.1); color: white; padding: 20px 40px; border-radius: 15px; margin: 10px; cursor: pointer; font-size: 1.1em; transition: all 0.3s; min-width: 280px; }
.mode-btn:hover { border-color: var(--primary); transform: scale(1.02); }
.mode-btn .material-icons { font-size: 32px; color: var(--primary); }
/* Login */
.admin-login { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--bg-dark); display: none; align-items: center; justify-content: center; z-index: 9999; }
.admin-login.show { display: flex; }
.login-box { background: rgba(255,255,255,0.1); backdrop-filter: blur(20px); border-radius: 20px; padding: 40px; text-align: center; max-width: 400px; width: 90%; }
.login-box h2 { color: var(--primary); margin-bottom: 10px; }
.login-box p { color: rgba(255,255,255,0.6); margin-bottom: 20px; }
.login-box input { width: 100%; padding: 15px; border: 2px solid rgba(255,255,255,0.1); border-radius: 10px; background: rgba(0,0,0,0.3); color: white; font-size: 1em; text-align: center; margin-bottom: 15px; }
.login-box input:focus { outline: none; border-color: var(--primary); }
.login-box button { width: 100%; padding: 15px; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border: none; border-radius: 10px; color: white; font-size: 1.1em; cursor: pointer; }
.login-error { background: rgba(244,67,54,0.2); color: #ff6b6b; padding: 10px; border-radius: 8px; margin-bottom: 15px; display: none; }
.login-error.show { display: block; }
/* App */
.app-container { max-width: 430px; margin: 0 auto; min-height: 100vh; position: relative; z-index: 1; display: none; }
.app-container.show { display: block; }
.particles { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; z-index: 0; }
.particle { position: absolute; width: 4px; height: 4px; background: var(--primary); border-radius: 50%; opacity: 0.3; animation: float 15s infinite; }
@keyframes float { 0%, 100% { transform: translateY(100vh) rotate(0deg); opacity: 0; } 10% { opacity: 0.3; } 90% { opacity: 0.3; } 100% { transform: translateY(-100vh) rotate(720deg); opacity: 0; } }
.header { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; background: linear-gradient(180deg, rgba(10,10,20,0.9) 0%, transparent 100%); position: sticky; top: 0; z-index: 50; }
.listeners-badge { display: flex; align-items: center; gap: 6px; background: rgba(233,30,99,0.2); padding: 6px 12px; border-radius: 20px; font-size: 12px; }
.listeners-dot { width: 8px; height: 8px; background: #4CAF50; border-radius: 50%; animation: blink 1s infinite; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.share-btn { background: var(--bg-card); border: none; color: white; padding: 8px 14px; border-radius: 20px; font-size: 12px; cursor: pointer; display: flex; align-items: center; gap: 5px; }
.nav-tabs { display: flex; background: rgba(10, 10, 20, 0.95); backdrop-filter: blur(20px); position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 430px; z-index: 100; border-top: 1px solid rgba(255,255,255,0.1); }
.nav-tab { flex: 1; padding: 10px 0; text-align: center; cursor: pointer; transition: all 0.3s; color: rgba(255,255,255,0.4); }
.nav-tab.active { color: var(--primary); }
.nav-tab .material-icons { font-size: 22px; display: block; margin-bottom: 3px; }
.nav-tab span:last-child { font-size: 10px; }
.page { display: none; padding: 0 20px 100px; animation: fadeIn 0.3s ease; }
.page.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.page-title { font-size: 24px; font-weight: 700; margin-bottom: 5px; }
.page-subtitle { color: rgba(255,255,255,0.5); font-size: 13px; margin-bottom: 20px; }
.visualizer { display: flex; justify-content: center; align-items: flex-end; gap: 3px; height: 60px; margin: 20px 0; }
.visualizer-bar { width: 4px; background: linear-gradient(to top, var(--primary), var(--primary-dark)); border-radius: 2px; transition: height 0.1s; }
.logo-container { width: 180px; height: 180px; margin: 10px auto; position: relative; }
.logo-ring { position: absolute; width: 100%; height: 100%; border: 2px solid var(--primary); border-radius: 50%; opacity: 0.3; }
.logo-ring.playing { animation: ring-pulse 1.5s ease-out infinite; }
@keyframes ring-pulse { 0% { transform: scale(1); opacity: 0.3; } 100% { transform: scale(1.5); opacity: 0; } }
.logo { width: 100%; height: 100%; border-radius: 50%; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 0 60px rgba(233, 30, 99, 0.4); position: relative; z-index: 2; }
.logo.playing { animation: rotate 8s linear infinite; }
@keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.logo .material-icons { font-size: 50px; margin-bottom: 5px; }
.logo-text { font-size: 14px; font-weight: 700; letter-spacing: 2px; }
.logo-subtext { font-size: 10px; opacity: 0.8; letter-spacing: 3px; }
.now-playing { text-align: center; margin: 20px 0; }
.now-playing-label { font-size: 11px; color: var(--primary); text-transform: uppercase; letter-spacing: 2px; margin-bottom: 8px; }
.song-title { font-size: 20px; font-weight: 600; margin-bottom: 5px; }
.song-artist { color: rgba(255,255,255,0.5); font-size: 14px; }
.controls { display: flex; align-items: center; justify-content: center; gap: 25px; margin: 25px 0; }
.btn-secondary { width: 50px; height: 50px; border-radius: 50%; background: var(--bg-card); border: none; cursor: pointer; color: rgba(255,255,255,0.7); transition: all 0.3s; display: flex; align-items: center; justify-content: center; }
.btn-secondary:hover { background: rgba(255,255,255,0.15); color: white; }
.btn-secondary .material-icons { font-size: 28px; }
.btn-play { width: 80px; height: 80px; border-radius: 50%; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border: none; cursor: pointer; color: white; box-shadow: 0 0 30px rgba(233, 30, 99, 0.5); transition: all 0.3s; display: flex; align-items: center; justify-content: center; }
.btn-play:hover { transform: scale(1.05); box-shadow: 0 0 50px rgba(233, 30, 99, 0.7); }
.btn-play .material-icons { font-size: 45px; }
.volume-container { display: flex; align-items: center; gap: 10px; padding: 0 10px; margin: 20px 0; }
.volume-container .material-icons { color: rgba(255,255,255,0.4); font-size: 20px; }
.volume-slider { flex: 1; -webkit-appearance: none; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.1); outline: none; }
.volume-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%; background: var(--primary); cursor: pointer; }
.whatsapp-section { text-align: center; padding: 20px; }
.whatsapp-btn { display: inline-flex; align-items: center; gap: 12px; background: linear-gradient(135deg, #25D366, #128C7E); color: white; padding: 18px 35px; border-radius: 30px; text-decoration: none; font-size: 18px; font-weight: 600; box-shadow: 0 5px 30px rgba(37,211,102,0.4); }
.quick-msg { background: var(--bg-card); padding: 16px; border-radius: 15px; margin-bottom: 12px; cursor: pointer; display: flex; align-items: center; gap: 12px; transition: all 0.3s; }
.quick-msg:hover { background: rgba(255,255,255,0.1); }
.programa-card { display: flex; align-items: center; gap: 15px; background: var(--bg-card); padding: 15px; border-radius: 12px; margin-bottom: 10px; }
.programa-card.live { border: 1px solid var(--primary); background: rgba(233,30,99,0.1); }
.programa-icon { width: 45px; height: 45px; border-radius: 12px; background: rgba(255,255,255,0.1); display: flex; align-items: center; justify-content: center; }
.programa-info { flex: 1; }
.programa-nombre { font-weight: 600; font-size: 14px; }
.programa-dias { font-size: 12px; color: rgba(255,255,255,0.5); }
.programa-hora { font-size: 12px; color: rgba(255,255,255,0.4); }
.live-badge { background: var(--primary); padding: 4px 10px; border-radius: 12px; font-size: 10px; font-weight: 600; }
.contest-hero { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border-radius: 20px; padding: 25px; text-align: center; margin-bottom: 20px; }
.contest-timer { display: flex; justify-content: center; gap: 15px; margin: 20px 0; }
.timer-item { text-align: center; }
.timer-value { font-size: 32px; font-weight: 700; }
.timer-label { font-size: 10px; opacity: 0.8; }
.contest-btn { background: white; color: var(--primary-dark); border: none; padding: 14px 35px; border-radius: 25px; font-weight: 600; cursor: pointer; }
.install-section { background: var(--bg-card); border-radius: 20px; padding: 25px; text-align: center; margin: 20px 0; }
.install-btn { display: inline-flex; align-items: center; gap: 10px; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: white; padding: 15px 30px; border-radius: 25px; border: none; font-size: 16px; font-weight: 600; cursor: pointer; margin: 15px 0; }
.install-steps { text-align: left; background: rgba(0,0,0,0.2); border-radius: 10px; padding: 15px; margin-top: 15px; }
.install-steps h4 { color: var(--primary); margin-bottom: 10px; }
.install-steps ol { padding-left: 20px; color: rgba(255,255,255,0.7); }
.install-steps li { margin: 8px 0; }
.toast { position: fixed; bottom: 100px; left: 50%; transform: translateX(-50%) translateY(100px); background: rgba(0,0,0,0.9); color: white; padding: 12px 24px; border-radius: 25px; font-size: 14px; opacity: 0; transition: all 0.3s; z-index: 1000; }
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
.toast.success { background: linear-gradient(135deg, #4CAF50, #388E3C); }
.toast.error { background: linear-gradient(135deg, #f44336, #c62828); }
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); display: none; align-items: center; justify-content: center; z-index: 200; }
.modal-overlay.show { display: flex; }
.modal { background: linear-gradient(135deg, #1a1a2e, #16213e); border-radius: 20px; padding: 30px; max-width: 350px; width: 90%; text-align: center; }
.modal-title { font-size: 20px; margin-bottom: 10px; }
.modal-text { color: rgba(255,255,255,0.6); font-size: 14px; margin-bottom: 20px; }
.modal-input { width: 100%; padding: 14px; border: 2px solid rgba(255,255,255,0.1); border-radius: 12px; background: rgba(0,0,0,0.3); color: white; font-size: 16px; text-align: center; margin-bottom: 15px; }
.modal-btn { width: 100%; padding: 14px; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border: none; border-radius: 12px; color: white; font-size: 16px; font-weight: 600; cursor: pointer; }
/* Admin Panel */
.admin-panel { display: none; padding: 20px; max-width: 800px; margin: 0 auto; }
.admin-panel.show { display: block; }
.admin-panel h1 { text-align: center; color: var(--primary); margin-bottom: 10px; }
.admin-panel h2 { text-align: center; color: rgba(255,255,255,0.5); font-size: 14px; margin-bottom: 30px; }
.admin-card { background: rgba(255,255,255,0.1); border-radius: 15px; padding: 20px; margin-bottom: 20px; }
.admin-card h3 { color: var(--primary); margin-bottom: 15px; display: flex; align-items: center; gap: 10px; }
.admin-card label { color: rgba(255,255,255,0.7); font-size: 13px; display: block; margin-top: 12px; margin-bottom: 5px; }
.admin-card input, .admin-card textarea, .admin-card select { width: 100%; padding: 12px; border: 1px solid rgba(255,255,255,0.1); border-radius: 10px; background: rgba(0,0,0,0.3); color: white; font-size: 14px; }
.admin-card input:focus, .admin-card textarea:focus { outline: none; border-color: var(--primary); }
.admin-btn { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: white; border: none; padding: 12px 25px; border-radius: 25px; cursor: pointer; font-size: 14px; font-weight: 600; margin: 5px; transition: all 0.3s; }
.admin-btn:hover { transform: scale(1.02); box-shadow: 0 5px 20px rgba(233,30,99,0.3); }
.admin-btn.secondary { background: rgba(255,255,255,0.1); }
.admin-btn.success { background: linear-gradient(135deg, #4CAF50, #388E3C); }
.back-btn { position: fixed; top: 20px; left: 20px; background: rgba(255,255,255,0.1); border: none; color: white; padding: 10px 20px; border-radius: 20px; cursor: pointer; z-index: 100; display: flex; align-items: center; gap: 5px; }
.toggle-row { display: flex; align-items: center; gap: 15px; margin: 10px 0; }
.toggle { width: 50px; height: 26px; background: #666; border-radius: 13px; position: relative; cursor: pointer; transition: background 0.3s; }
.toggle.active { background: #4CAF50; }
.toggle::after { content: ''; position: absolute; width: 22px; height: 22px; background: white; border-radius: 50%; top: 2px; left: 2px; transition: left 0.3s; }
.toggle.active::after { left: 26px; }
.sync-status { display: inline-flex; align-items: center; gap: 8px; padding: 10px 20px; border-radius: 20px; font-size: 13px; margin: 10px 0; }
.sync-status.synced { background: rgba(76,175,80,0.2); color: #4CAF50; }
.sync-status.syncing { background: rgba(255,152,0,0.2); color: #FF9800; }
.sync-status.error { background: rgba(244,67,54,0.2); color: #f44336; }
.info-box { background: rgba(233,30,99,0.1); border: 1px solid rgba(233,30,99,0.3); border-radius: 10px; padding: 15px; margin-top: 15px; }
.info-box p { font-size: 13px; color: rgba(255,255,255,0.7); line-height: 1.6; }
</style>
</head>
<body>
<!-- LOADING -->
<div class="loading-screen" id="loadingScreen">
<div class="loading-spinner"></div>
<p class="loading-text">Cargando Sensaciones UY...</p>
</div>
<!-- SELECTOR DE MODO -->
<div class="mode-selector hidden" id="modeSelector">
<h1> Sensaciones UY</h1>
<p>Selecciona una opción</p>
<button class="mode-btn" onclick="openApp()">
<span class="material-icons">radio</span>
<div><strong>Escuchar Radio</strong><div style="font-size: 12px; opacity: 0.7;">Abrir la aplicación</div></div>
</button>
<button class="mode-btn" onclick="openAdminLogin()">
<span class="material-icons">admin_panel_settings</span>
<div><strong>Administración</strong><div style="font-size: 12px; opacity: 0.7;">Panel de control</div></div>
</button>
</div>
<!-- LOGIN ADMIN -->
<div class="admin-login" id="adminLogin">
<div class="login-box">
<div style="font-size: 50px; margin-bottom: 15px;"></div>
<h2>Administración</h2>
<p>Ingresa la contraseña</p>
<div class="login-error" id="loginError">❌ Contraseña incorrecta</div>
<input type="password" id="adminPassword" placeholder="Contraseña" onkeypress="if(event.key==='Enter')checkAdminPassword()">
<button onclick="checkAdminPassword()">Ingresar</button>
<p style="margin-top: 15px;"><a href="#" onclick="backToSelector()" style="color: rgba(255,255,255,0.5);">← Volver</a></p>
</div>
</div>
<!-- PANEL ADMIN -->
<div class="admin-panel" id="adminPanel">
<button class="back-btn" onclick="backToSelector()"><span class="material-icons" style="font-size: 18px;">arrow_back</span> Salir</button>
<h1> Panel de Administración</h1>
<h2>Los cambios se sincronizan con TODOS los usuarios</h2>
<div style="text-align: center;">
<div class="sync-status synced" id="syncStatus">
<span class="material-icons" style="font-size: 18px;">cloud_done</span>
<span id="syncText">Sincronizado</span>
</div>
</div>
<!-- Sorteos -->
<div class="admin-card">
<h3><span class="material-icons">emoji_events</span> Sorteos</h3>
<div class="toggle-row">
<div class="toggle" id="toggleSorteo" onclick="toggleSorteo()"></div>
<span>Sorteos <strong id="sorteoEstado">Desactivados</strong></span>
</div>
<label>Título del sorteo:</label>
<input type="text" id="adminSorteoTitulo" placeholder=" SORTEO NAVIDEÑO">
<label>Premio:</label>
<input type="text" id="adminSorteoPremio" placeholder="Auriculares Bluetooth">
<label>Fecha de finalización:</label>
<input type="datetime-local" id="adminSorteoFecha">
<button class="admin-btn success" onclick="guardarEnNube()" style="margin-top: 15px; width: 100%;">
<span class="material-icons" style="font-size: 18px; vertical-align: middle;">cloud_upload</span>
Guardar Cambios
</button>
</div>
<!-- Contacto -->
<div class="admin-card">
<h3><span class="material-icons">contact_phone</span> Contacto y Redes</h3>
<label>WhatsApp (sin + ni espacios):</label>
<input type="text" id="adminWhatsapp" placeholder="59895093747">
<label>Email:</label>
<input type="email" id="adminEmail" placeholder="correo@ejemplo.com">
<label>Instagram (sin @):</label>
<input type="text" id="adminInstagram" placeholder="usuario">
<label>YouTube (sin @):</label>
<input type="text" id="adminYoutube" placeholder="canal">
<label>TikTok (sin @):</label>
<input type="text" id="adminTiktok" placeholder="usuario">
<button class="admin-btn success" onclick="guardarEnNube()" style="margin-top: 15px; width: 100%;">
<span class="material-icons" style="font-size: 18px; vertical-align: middle;">cloud_upload</span>
Guardar Cambios
</button>
</div>
<!-- Programación -->
<div class="admin-card">
<h3><span class="material-icons">calendar_today</span> Programación</h3>
<p style="color: rgba(255,255,255,0.5); font-size: 12px; margin-bottom: 15px;">Edita los programas de la radio</p>
<div id="adminProgramacion"></div>
<div style="display: flex; gap: 10px; margin-top: 15px; flex-wrap: wrap;">
<button class="admin-btn secondary" onclick="agregarPrograma()">
<span class="material-icons" style="font-size: 16px; vertical-align: middle;">add</span> Agregar programa
</button>
<button class="admin-btn success" onclick="guardarEnNube()">
<span class="material-icons" style="font-size: 16px; vertical-align: middle;">cloud_upload</span> Guardar
</button>
</div>
</div>
<!-- Configuración de Stream -->
<div class="admin-card">
<h3><span class="material-icons">settings_input_antenna</span> Stream de Audio</h3>
<label>URL del Stream:</label>
<input type="text" id="adminStreamUrl" placeholder="https://servidor.com:puerto/live">
<p style="color: rgba(255,255,255,0.4); font-size: 11px; margin-top: 5px;">⚠️ Solo cambiar si tienes una nueva URL de streaming</p>
<button class="admin-btn success" onclick="guardarEnNube()" style="margin-top: 15px; width: 100%;">
<span class="material-icons" style="font-size: 18px; vertical-align: middle;">cloud_upload</span>
Guardar Cambios
</button>
</div>
<!-- Nombre de la Radio -->
<div class="admin-card">
<h3><span class="material-icons">badge</span> Información de la Radio</h3>
<label>Nombre de la radio:</label>
<input type="text" id="adminRadioNombre" placeholder="Sensaciones UY">
<label>Slogan/Descripción corta:</label>
<input type="text" id="adminRadioSlogan" placeholder="Radio en Vivo 24/7">
<button class="admin-btn success" onclick="guardarEnNube()" style="margin-top: 15px; width: 100%;">
<span class="material-icons" style="font-size: 18px; vertical-align: middle;">cloud_upload</span>
Guardar Cambios
</button>
</div>
<!-- Contraseña -->
<div class="admin-card">
<h3><span class="material-icons">lock</span> Seguridad</h3>
<label>Nueva contraseña de admin:</label>
<input type="text" id="adminNewPassword" placeholder="Nueva contraseña (mínimo 4 caracteres)">
<button class="admin-btn" onclick="cambiarPassword()" style="margin-top: 10px;">Cambiar contraseña</button>
</div>
<div class="info-box" style="text-align: center; margin-top: 20px;">
<p>☁️ <strong>Sincronización en la Nube</strong><br>
Los cambios que guardes aquí serán visibles para TODOS los usuarios de la app automáticamente.</p>
</div>
</div>
<!-- APP PRINCIPAL -->
<div class="app-container" id="appContainer">
<div class="particles" id="particles"></div>
<header class="header">
<div class="listeners-badge"><div class="listeners-dot"></div><span id="listeners-count">847</span> en vivo</div>
<button class="share-btn" onclick="shareApp()"><span class="material-icons" style="font-size: 16px;">share</span> Compartir</button>
</header>
<!-- En Vivo -->
<div id="page-player" class="page active">
<div class="visualizer" id="visualizer"></div>
<div class="logo-container">
<div class="logo-ring" id="logo-ring"></div>
<div class="logo" id="logo">
<span class="material-icons">radio</span>
<div class="logo-text">SENSACIONES</div>
<div class="logo-subtext">URUGUAY</div>
</div>
</div>
<div class="now-playing">
<div class="now-playing-label">Ahora suena</div>
<div class="song-title">Sensaciones UY</div>
<div class="song-artist">Radio en Vivo 24/7</div>
</div>
<div class="controls">
<button class="btn-secondary" onclick="stopAudio()"><span class="material-icons">stop</span></button>
<button class="btn-play" onclick="togglePlay()"><span class="material-icons" id="play-icon">play_arrow</span></button>
<button class="btn-secondary" onclick="showPage('chat')"><span class="material-icons">chat</span></button>
</div>
<div class="volume-container">
<span class="material-icons">volume_down</span>
<input type="range" class="volume-slider" min="0" max="100" value="100" oninput="setVolume(this.value)">
<span class="material-icons">volume_up</span>
</div>
</div>
<!-- Chat/WhatsApp -->
<div id="page-chat" class="page">
<h1 class="page-title"> Escríbenos</h1>
<p class="page-subtitle">Comunícate por WhatsApp</p>
<div class="whatsapp-section">
<a href="#" onclick="openWhatsApp()" class="whatsapp-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="white"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg>
Abrir WhatsApp
</a>
</div>
<div style="margin-top: 30px;">
<h3 style="font-size: 14px; color: var(--primary); margin-bottom: 15px; text-align: center;"> Mensajes rápidos</h3>
<div class="quick-msg" onclick="sendQuickMsg('saludo')"><span style="font-size: 24px;"></span><div><strong>Enviar saludo</strong><div style="font-size: 12px; opacity: 0.6;">Saluda a la radio</div></div><span class="material-icons" style="margin-left: auto; color: var(--primary);">chevron_right</span></div>
<div class="quick-msg" onclick="sendQuickMsg('pedido')"><span style="font-size: 24px;"></span><div><strong>Pedir canción</strong><div style="font-size: 12px; opacity: 0.6;">Solicita tu tema favorito</div></div><span class="material-icons" style="margin-left: auto; color: var(--primary);">chevron_right</span></div>
<div class="quick-msg" onclick="sendQuickMsg('dedicatoria')"><span style="font-size: 24px;">❤️</span><div><strong>Dedicar canción</strong><div style="font-size: 12px; opacity: 0.6;">Envía una dedicatoria</div></div><span class="material-icons" style="margin-left: auto; color: var(--primary);">chevron_right</span></div>
</div>
</div>
<!-- Sorteos -->
<div id="page-contests" class="page">
<h1 class="page-title"> Sorteos</h1>
<p class="page-subtitle">Participa y gana premios</p>
<div class="contest-hero" id="contestHero">
<h2 id="contestTitle"> SORTEO</h2>
<p id="contestPrize">Premio</p>
<div class="contest-timer">
<div class="timer-item"><div class="timer-value" id="timer-days">00</div><div class="timer-label">DÍAS</div></div>
<div class="timer-item"><div class="timer-value" id="timer-hours">00</div><div class="timer-label">HORAS</div></div>
<div class="timer-item"><div class="timer-value" id="timer-mins">00</div><div class="timer-label">MIN</div></div>
<div class="timer-item"><div class="timer-value" id="timer-secs">00</div><div class="timer-label">SEG</div></div>
</div>
<button class="contest-btn" onclick="joinContest()"> Participar</button>
</div>
</div>
<!-- Programación -->
<div id="page-schedule" class="page">
<h1 class="page-title"> Programación</h1>
<p class="page-subtitle">Nuestra grilla semanal</p>
<div id="schedule-list"></div>
</div>
<!-- Instalar -->
<div id="page-install" class="page">
<h1 class="page-title"> Instalar App</h1>
<p class="page-subtitle">Lleva la radio siempre contigo</p>
<div class="install-section">
<div style="font-size: 60px; margin-bottom: 15px;"></div>
<h3>Instala Sensaciones UY</h3>
<p style="color: rgba(255,255,255,0.6); margin: 10px 0;">La app se instala desde tu navegador</p>
<button class="install-btn" onclick="installApp()"><span class="material-icons">download</span> Instalar Ahora</button>
<div class="install-steps">
<h4> iPhone/iPad:</h4>
<ol><li>Toca <strong>Compartir</strong> (cuadrado con flecha)</li><li>Selecciona <strong>"Añadir a inicio"</strong></li></ol>
</div>
<div class="install-steps" style="margin-top: 15px;">
<h4> Android:</h4>
<ol><li>Menú <strong>⋮</strong> del navegador</li><li>Selecciona <strong>"Instalar app"</strong></li></ol>
</div>
</div>
</div>
<nav class="nav-tabs">
<div class="nav-tab active" onclick="showPage('player')"><span class="material-icons">radio</span><span>En Vivo</span></div>
<div class="nav-tab" onclick="showPage('chat')"><span class="material-icons">chat</span><span>Chat</span></div>
<div class="nav-tab" onclick="showPage('contests')"><span class="material-icons">emoji_events</span><span>Sorteos</span></div>
<div class="nav-tab" onclick="showPage('schedule')"><span class="material-icons">calendar_today</span><span>Horarios</span></div>
<div class="nav-tab" onclick="showPage('install')"><span class="material-icons">download</span><span>Instalar</span></div>
</nav>
</div>
<div class="toast" id="toast"></div>
<div class="modal-overlay" id="nameModal">
<div class="modal">
<h2 class="modal-title"> ¡Bienvenido!</h2>
<p class="modal-text">¿Cómo te llamas?</p>
<input type="text" class="modal-input" id="usernameInput" placeholder="Tu nombre" maxlength="20">
<button class="modal-btn" onclick="setUsername()">Continuar</button>
</div>
</div>
<audio id="audio" preload="none"></audio>
<script>
// ============================================
// CONFIGURACIÓN DE JSONBIN (SINCRONIZACIÓN EN LA NUBE)
// ============================================
const JSONBIN_BIN_ID = '695168e243b1c97be90a7073';
const JSONBIN_API_KEY = '$2a$10$uf3DXTIoyLlktEZ.9m0Aa.CyV15gJIczLwcvjKUxuLzkjyOE29Elu';
// Configuración por defecto (se sobrescribe con la de la nube)
let CONFIG = {
STREAM_URL: 'https://servidor17.brlogic.com:7166/live',
RADIO_NOMBRE: 'Sensaciones UY',
RADIO_SLOGAN: 'Radio en Vivo 24/7',
WHATSAPP: '59895093747',
EMAIL: 'beatrizmandagaran@gmail.com',
INSTAGRAM: 'Sensacionesuy_oficial',
YOUTUBE: 'BeatrizMandagaransensaciones',
TIKTOK: 'Sensacionesuy',
ADMIN_PASSWORD: 'sensaciones2025',
SORTEO_ACTIVO: true,
SORTEO_TITULO: ' SORTEO NAVIDEÑO',
SORTEO_PREMIO: 'Auriculares Bluetooth Premium',
SORTEO_FECHA: '2025-12-31T23:59',
PROGRAMACION: [
{ dia: 'Lunes a Viernes', horarios: [
{ hora: '06:00 - 09:00', programa: '☀️ Despertando', conductor: 'DJ Carlos' },
{ hora: '09:00 - 12:00', programa: ' Mañanas Musicales', conductor: 'Ana María' },
{ hora: '12:00 - 15:00', programa: '️ Mediodía Latino', conductor: 'Roberto' },
{ hora: '15:00 - 18:00', programa: ' Tarde de Éxitos', conductor: 'Laura' },
{ hora: '18:00 - 21:00', programa: ' Drive Time', conductor: 'Miguel' },
{ hora: '21:00 - 00:00', programa: ' Noches', conductor: 'DJ Luna' },
]},
{ dia: 'Sábado', horarios: [
{ hora: '08:00 - 12:00', programa: ' Sábado Tropical', conductor: 'DJ Caribe' },
{ hora: '12:00 - 20:00', programa: ' Mix Weekend', conductor: 'DJ Flow' },
{ hora: '20:00 - 02:00', programa: ' Fiesta', conductor: 'DJ Party' },
]},
{ dia: 'Domingo', horarios: [
{ hora: '09:00 - 14:00', programa: '☕ Domingo Relax', conductor: 'Sofía' },
{ hora: '14:00 - 20:00', programa: ' Clásicos', conductor: 'Pedro' },
{ hora: '20:00 - 00:00', programa: '❤️ Baladas', conductor: 'Carmen' },
]},
]
};
// ============================================
// FUNCIONES DE SINCRONIZACIÓN CON LA NUBE
// ============================================
async function cargarDesdeNube() {
try {
const response = await fetch(`https://api.jsonbin.io/v3/b/${JSONBIN_BIN_ID}/latest`, {
headers: { 'X-Access-Key': JSONBIN_API_KEY }
});
if (response.ok) {
const data = await response.json();
CONFIG = { ...CONFIG, ...data.record };
console.log('✅ Configuración cargada desde la nube');
return true;
}
} catch (error) {
console.log('⚠️ Usando configuración local:', error);
}
return false;
}
async function guardarEnNube() {
const syncStatus = document.getElementById('syncStatus');
const syncText = document.getElementById('syncText');
// Recoger valores del formulario
CONFIG.STREAM_URL = document.getElementById('adminStreamUrl')?.value || CONFIG.STREAM_URL;
CONFIG.RADIO_NOMBRE = document.getElementById('adminRadioNombre')?.value || CONFIG.RADIO_NOMBRE;
CONFIG.RADIO_SLOGAN = document.getElementById('adminRadioSlogan')?.value || CONFIG.RADIO_SLOGAN;
CONFIG.WHATSAPP = document.getElementById('adminWhatsapp')?.value || CONFIG.WHATSAPP;
CONFIG.EMAIL = document.getElementById('adminEmail')?.value || CONFIG.EMAIL;
CONFIG.INSTAGRAM = document.getElementById('adminInstagram')?.value || CONFIG.INSTAGRAM;
CONFIG.YOUTUBE = document.getElementById('adminYoutube')?.value || CONFIG.YOUTUBE;
CONFIG.TIKTOK = document.getElementById('adminTiktok')?.value || CONFIG.TIKTOK;
CONFIG.SORTEO_TITULO = document.getElementById('adminSorteoTitulo')?.value || CONFIG.SORTEO_TITULO;
CONFIG.SORTEO_PREMIO = document.getElementById('adminSorteoPremio')?.value || CONFIG.SORTEO_PREMIO;
CONFIG.SORTEO_FECHA = document.getElementById('adminSorteoFecha')?.value || CONFIG.SORTEO_FECHA;
// Mostrar estado de sincronización
syncStatus.className = 'sync-status syncing';
syncText.textContent = 'Guardando...';
try {
const response = await fetch(`https://api.jsonbin.io/v3/b/${JSONBIN_BIN_ID}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': JSONBIN_API_KEY
},
body: JSON.stringify(CONFIG)
});
if (response.ok) {
syncStatus.className = 'sync-status synced';
syncText.textContent = 'Sincronizado ✓';
showToast('☁️ ¡Guardado en la nube! Todos los usuarios verán los cambios.', 'success');
} else {
throw new Error('Error: ' + response.status);
}
} catch (error) {
console.error('Error guardando:', error);
syncStatus.className = 'sync-status error';
syncText.textContent = 'Error - Ver alternativa';
// Si falla, mostrar alternativa para copiar
mostrarAlternativaGuardado();
}
}
function mostrarAlternativaGuardado() {
// Crear modal con el JSON para copiar
const jsonStr = JSON.stringify(CONFIG, null, 2);
const modal = document.createElement('div');
modal.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);z-index:99999;display:flex;align-items:center;justify-content:center;padding:20px;';
modal.innerHTML = `
<div style="background:#1a1a2e;border-radius:20px;padding:25px;max-width:500px;width:100%;max-height:90vh;overflow:auto;">
<h3 style="color:#E91E63;margin-bottom:15px;">⚠️ Guardar Manualmente</h3>
<p style="color:rgba(255,255,255,0.7);font-size:13px;margin-bottom:15px;">
Para guardar desde archivo local, ve a JSONBin y actualiza manualmente:
</p>
<ol style="color:rgba(255,255,255,0.6);font-size:12px;margin-bottom:15px;padding-left:20px;">
<li>Ve a <a href="https://jsonbin.io/app/bins" target="_blank" style="color:#E91E63;">jsonbin.io/app/bins</a></li>
<li>Abre tu bin: <strong>${JSONBIN_BIN_ID}</strong></li>
<li>Click en "Edit"</li>
<li>Pega el código de abajo</li>
<li>Click en "Save"</li>
</ol>
<textarea id="jsonCopyArea" readonly style="width:100%;height:200px;background:#0a0a14;border:1px solid #333;border-radius:10px;color:#4CAF50;padding:10px;font-family:monospace;font-size:11px;">${jsonStr}</textarea>
<div style="display:flex;gap:10px;margin-top:15px;">
<button onclick="navigator.clipboard.writeText(document.getElementById('jsonCopyArea').value);this.textContent='✓ Copiado!'" style="flex:1;padding:12px;background:#4CAF50;border:none;border-radius:10px;color:white;font-weight:600;cursor:pointer;"> Copiar JSON</button>
<button onclick="this.parentElement.parentElement.parentElement.remove()" style="flex:1;padding:12px;background:#666;border:none;border-radius:10px;color:white;cursor:pointer;">Cerrar</button>
</div>
<p style="color:#FF9800;font-size:11px;margin-top:15px;text-align:center;">
<strong>Tip:</strong> Sube este archivo a un servidor web para que el guardado automático funcione.
</p>
</div>
`;
document.body.appendChild(modal);
}
// Variables globales
const audio = document.getElementById('audio');
let isPlaying = false;
let username = localStorage.getItem('sensaciones_username') || '';
let deferredPrompt = null;
// ============================================
// INICIALIZACIÓN
// ============================================
async function init() {
await cargarDesdeNube();
document.getElementById('loadingScreen').classList.add('hidden');
document.getElementById('modeSelector').classList.remove('hidden');
}
// Iniciar al cargar
init();
// ============================================
// NAVEGACIÓN
// ============================================
function openApp() {
document.getElementById('modeSelector').classList.add('hidden');
document.getElementById('appContainer').classList.add('show');
initApp();
}
function openAdminLogin() {
document.getElementById('modeSelector').classList.add('hidden');
document.getElementById('adminLogin').classList.add('show');
}
function backToSelector() {
document.getElementById('modeSelector').classList.remove('hidden');
document.getElementById('adminLogin').classList.remove('show');
document.getElementById('adminPanel').classList.remove('show');
document.getElementById('appContainer').classList.remove('show');
}
function checkAdminPassword() {
const input = document.getElementById('adminPassword');
if (input.value === CONFIG.ADMIN_PASSWORD) {
document.getElementById('adminLogin').classList.remove('show');
document.getElementById('adminPanel').classList.add('show');
cargarAdmin();
} else {
document.getElementById('loginError').classList.add('show');
input.value = '';
setTimeout(() => document.getElementById('loginError').classList.remove('show'), 3000);
}
}
function cargarAdmin() {
document.getElementById('adminWhatsapp').value = CONFIG.WHATSAPP;
document.getElementById('adminEmail').value = CONFIG.EMAIL;
document.getElementById('adminInstagram').value = CONFIG.INSTAGRAM;
document.getElementById('adminYoutube').value = CONFIG.YOUTUBE;
document.getElementById('adminTiktok').value = CONFIG.TIKTOK;
document.getElementById('adminSorteoTitulo').value = CONFIG.SORTEO_TITULO;
document.getElementById('adminSorteoPremio').value = CONFIG.SORTEO_PREMIO;
document.getElementById('adminSorteoFecha').value = CONFIG.SORTEO_FECHA;
document.getElementById('adminStreamUrl').value = CONFIG.STREAM_URL;
document.getElementById('adminRadioNombre').value = CONFIG.RADIO_NOMBRE;
document.getElementById('adminRadioSlogan').value = CONFIG.RADIO_SLOGAN;
const toggle = document.getElementById('toggleSorteo');
if (CONFIG.SORTEO_ACTIVO) toggle.classList.add('active');
else toggle.classList.remove('active');
document.getElementById('sorteoEstado').textContent = CONFIG.SORTEO_ACTIVO ? 'Activados' : 'Desactivados';
renderAdminProgramacion();
}
function renderAdminProgramacion() {
let html = '';
CONFIG.PROGRAMACION.forEach((dia, diaIndex) => {
html += `<div style="background: rgba(0,0,0,0.2); border-radius: 10px; padding: 15px; margin-bottom: 15px;">
<h4 style="color: var(--primary); margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center;">
${dia.dia}
<button onclick="agregarHorario(${diaIndex})" style="background: rgba(255,255,255,0.1); border: none; color: white; padding: 5px 10px; border-radius: 5px; cursor: pointer; font-size: 11px;">+ Horario</button>
</h4>`;
dia.horarios.forEach((prog, progIndex) => {
html += `<div style="background: rgba(255,255,255,0.05); padding: 10px; border-radius: 8px; margin: 8px 0; display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 8px; align-items: center;">
<input type="text" value="${prog.hora}" onchange="actualizarPrograma(${diaIndex}, ${progIndex}, 'hora', this.value)" placeholder="00:00 - 00:00" style="padding: 8px; font-size: 12px;">
<input type="text" value="${prog.programa}" onchange="actualizarPrograma(${diaIndex}, ${progIndex}, 'programa', this.value)" placeholder="Nombre programa" style="padding: 8px; font-size: 12px;">
<input type="text" value="${prog.conductor}" onchange="actualizarPrograma(${diaIndex}, ${progIndex}, 'conductor', this.value)" placeholder="Conductor" style="padding: 8px; font-size: 12px;">
<button onclick="eliminarPrograma(${diaIndex}, ${progIndex})" style="background: #f44336; border: none; color: white; padding: 8px 12px; border-radius: 5px; cursor: pointer;">✕</button>
</div>`;
});
html += `</div>`;
});
document.getElementById('adminProgramacion').innerHTML = html;
}
function actualizarPrograma(diaIndex, progIndex, campo, valor) {
CONFIG.PROGRAMACION[diaIndex].horarios[progIndex][campo] = valor;
}
function eliminarPrograma(diaIndex, progIndex) {
if (confirm('¿Eliminar este programa?')) {
CONFIG.PROGRAMACION[diaIndex].horarios.splice(progIndex, 1);
renderAdminProgramacion();
showToast('Programa eliminado. Guarda para aplicar cambios.');
}
}
function agregarHorario(diaIndex) {
CONFIG.PROGRAMACION[diaIndex].horarios.push({ hora: '00:00 - 00:00', programa: ' Nuevo Programa', conductor: 'DJ' });
renderAdminProgramacion();
showToast('Programa agregado. Edítalo y guarda los cambios.');
}
function agregarPrograma() {
const opciones = CONFIG.PROGRAMACION.map((d, i) => `${i}: ${d.dia}`).join('\n');
const dia = prompt(`¿En qué día agregar?\n${opciones}`);
if (dia !== null && CONFIG.PROGRAMACION[parseInt(dia)]) {
agregarHorario(parseInt(dia));
}
}
function toggleSorteo() {
const toggle = document.getElementById('toggleSorteo');
toggle.classList.toggle('active');
CONFIG.SORTEO_ACTIVO = toggle.classList.contains('active');
document.getElementById('sorteoEstado').textContent = CONFIG.SORTEO_ACTIVO ? 'Activados' : 'Desactivados';
}
async function cambiarPassword() {
const newPass = document.getElementById('adminNewPassword').value;
if (newPass && newPass.length >= 4) {
CONFIG.ADMIN_PASSWORD = newPass;
await guardarEnNube();
document.getElementById('adminNewPassword').value = '';
showToast(' Contraseña cambiada y sincronizada', 'success');
} else {
showToast('⚠️ Mínimo 4 caracteres');
}
}
// ============================================
// APP
// ============================================
function initApp() {
createParticles();
createVisualizer();
loadSchedule();
startContestTimer();
updateListeners();
if (!username) setTimeout(() => document.getElementById('nameModal').classList.add('show'), 1000);
setInterval(updateListeners, 30000);
}
function createParticles() {
const container = document.getElementById('particles');
for (let i = 0; i < 20; i++) {
const p = document.createElement('div');
p.className = 'particle';
p.style.left = Math.random() * 100 + '%';
p.style.animationDelay = Math.random() * 15 + 's';
container.appendChild(p);
}
}
function createVisualizer() {
const v = document.getElementById('visualizer');
for (let i = 0; i < 25; i++) {
const bar = document.createElement('div');
bar.className = 'visualizer-bar';
bar.style.height = '5px';
v.appendChild(bar);
}
}
function animateVisualizer() {
document.querySelectorAll('.visualizer-bar').forEach(bar => {
bar.style.height = (isPlaying ? Math.random() * 50 + 10 : 5) + 'px';
});
if (isPlaying) requestAnimationFrame(() => setTimeout(animateVisualizer, 100));
}
function togglePlay() { isPlaying ? pauseAudio() : playAudio(); }
function playAudio() {
document.getElementById('play-icon').textContent = 'hourglass_empty';
audio.src = CONFIG.STREAM_URL;
audio.play().then(() => {
isPlaying = true;
document.getElementById('play-icon').textContent = 'pause';
document.getElementById('logo').classList.add('playing');
document.getElementById('logo-ring').classList.add('playing');
animateVisualizer();
showToast(' ¡Reproduciendo!');
}).catch(() => {
document.getElementById('play-icon').textContent = 'play_arrow';
showToast('❌ Error de conexión');
});
}
function pauseAudio() {
audio.pause();
isPlaying = false;
document.getElementById('play-icon').textContent = 'play_arrow';
document.getElementById('logo').classList.remove('playing');
document.getElementById('logo-ring').classList.remove('playing');
}
function stopAudio() {
audio.pause();
audio.src = '';
isPlaying = false;
document.getElementById('play-icon').textContent = 'play_arrow';
document.getElementById('logo').classList.remove('playing');
document.getElementById('logo-ring').classList.remove('playing');
}
function setVolume(v) { audio.volume = v / 100; }
function showPage(page) {
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-tab').forEach(t => t.classList.remove('active'));
document.getElementById('page-' + page).classList.add('active');
event?.currentTarget?.classList.add('active');
}
function updateListeners() {
document.getElementById('listeners-count').textContent = 800 + Math.floor(Math.random() * 200);
}
function openWhatsApp() {
window.open(`https://wa.me/${CONFIG.WHATSAPP}?text=¡Hola Sensaciones UY! `, '_blank');
}
function sendQuickMsg(tipo) {
if (!username) { document.getElementById('nameModal').classList.add('show'); return; }
let msg = '';
switch(tipo) {
case 'saludo': msg = ` *SALUDO*%0A%0AHola! Soy ${encodeURIComponent(username)} y los estoy escuchando. ¡Saludos! `; break;
case 'pedido': msg = ` *PEDIDO*%0A%0ASoy ${encodeURIComponent(username)}%0AQuiero pedir: [CANCIÓN]%0AArtista: [ARTISTA]`; break;
case 'dedicatoria': msg = `❤️ *DEDICATORIA*%0A%0ASoy ${encodeURIComponent(username)}%0ACanción: [CANCIÓN]%0APara: [NOMBRE]%0AMensaje: [TU MENSAJE]`; break;
}
window.open(`https://wa.me/${CONFIG.WHATSAPP}?text=${msg}`, '_blank');
}
// Sorteos
function startContestTimer() {
if (!CONFIG.SORTEO_ACTIVO) {
document.getElementById('contestHero').innerHTML = `<div style="padding: 30px;"><span class="material-icons" style="font-size: 50px; opacity: 0.3;">emoji_events</span><h3 style="margin: 15px 0; opacity: 0.5;">No hay sorteos activos</h3><p style="opacity: 0.4;">¡Mantente atento!</p></div>`;
return;
}
document.getElementById('contestTitle').textContent = CONFIG.SORTEO_TITULO;
document.getElementById('contestPrize').textContent = 'Premio: ' + CONFIG.SORTEO_PREMIO;
const end = new Date(CONFIG.SORTEO_FECHA);
setInterval(() => {
const diff = end - new Date();
if (diff > 0) {
document.getElementById('timer-days').textContent = Math.floor(diff / 86400000).toString().padStart(2, '0');
document.getElementById('timer-hours').textContent = Math.floor((diff % 86400000) / 3600000).toString().padStart(2, '0');
document.getElementById('timer-mins').textContent = Math.floor((diff % 3600000) / 60000).toString().padStart(2, '0');
document.getElementById('timer-secs').textContent = Math.floor((diff % 60000) / 1000).toString().padStart(2, '0');
}
}, 1000);
}
function joinContest() {
if (!username) { document.getElementById('nameModal').classList.add('show'); return; }
const msg = ` *PARTICIPAR EN SORTEO*%0A%0ASoy ${encodeURIComponent(username)} y quiero participar en: ${encodeURIComponent(CONFIG.SORTEO_TITULO)}`;
window.open(`https://wa.me/${CONFIG.WHATSAPP}?text=${msg}`, '_blank');
}
// Programación
function loadSchedule() {
const hour = new Date().getHours();
let html = '';
CONFIG.PROGRAMACION.forEach(dia => {
html += `<h4 style="color: var(--primary); margin: 20px 0 10px; font-size: 14px;">${dia.dia}</h4>`;
dia.horarios.forEach(prog => {
const [start] = prog.hora.split(' - ')[0].split(':');
const [end] = prog.hora.split(' - ')[1].split(':');
const live = hour >= parseInt(start) && hour < parseInt(end);
html += `<div class="programa-card ${live ? 'live' : ''}"><div class="programa-icon"><span class="material-icons">radio</span></div><div class="programa-info"><div class="programa-nombre">${prog.programa}</div><div class="programa-dias">${prog.conductor}</div></div>${live ? '<span class="live-badge">EN VIVO</span>' : `<div class="programa-hora">${prog.hora}</div>`}</div>`;
});
});
document.getElementById('schedule-list').innerHTML = html;
}
// Usuario
function setUsername() {
const name = document.getElementById('usernameInput').value.trim();
if (!name) { showToast('Ingresa tu nombre'); return; }
username = name;
localStorage.setItem('sensaciones_username', name);
document.getElementById('nameModal').classList.remove('show');
showToast(`¡Bienvenido ${name}! `);
}
// Instalar
window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; });
function installApp() {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choice) => { if (choice.outcome === 'accepted') showToast(' ¡App instalada!'); deferredPrompt = null; });
} else { showToast(' Usa las instrucciones de abajo'); }
}
// Utilidades
function shareApp() {
const data = { title: 'Sensaciones UY', text: ' Escucha Sensaciones UY!', url: window.location.href };
if (navigator.share) navigator.share(data);
else { navigator.clipboard.writeText(window.location.href); showToast(' Link copiado!'); }
}
function showToast(msg, type = '') {
const t = document.getElementById('toast');
t.textContent = msg;
t.className = 'toast show ' + type;
setTimeout(() => t.classList.remove('show'), 3000);
}
// Media Session
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({ title: 'Sensaciones UY', artist: 'Radio en Vivo' });
navigator.mediaSession.setActionHandler('play', playAudio);
navigator.mediaSession.setActionHandler('pause', pauseAudio);
}
</script>
</body>
</html>
