Offline
https://public-rf-upload.minhawebradio.net/249430/slider/fa94c021925d1328f2ff016303ff54f6.png
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>