Offline
https://public-rf-upload.minhawebradio.net/249430/slider/fa94c021925d1328f2ff016303ff54f6.png
SensacionesUY - Radio Online
Hora en Uruguay: cargando...
Oyentes en vivo: Cargando...
Abrir App

¿Por qué escuchar SensacionesUY?

Descubre una radio diferente, con música, información y emociones a flor de piel. ¡Conéctate y sé parte de nuestra comunidad!
  • Música variada y de calidad
  • Noticias y actualidad
  • Espacios de participación
  • Conexión con Uruguay y el mundo

Nuestro Canal en YouTube

Cargando videos...
Si no ves videos, revisa que el canal tenga videos públicos y usa el ID de canal (no el nombre de usuario). Puedes obtenerlo en YouTube.

Clima en vivo

Doble click sobre el sitio para ver el clima en la zona.
Verifique el pronóstico del tiempo actual en el mapa del radar. Elija una ciudad en el mapa y vea las condiciones climáticas para los próximos días.
PRONÓSTICO DEL TIEMPO
El pronóstico del tiempo le permitirá observar y predecir las condiciones climáticas actuales.

Contacto

Correo: info@sensacionesuy.com

WhatsApp: +598 95 093 747

Menú

<!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);

        }

 

        // WhatsApp

        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>