¡Hola!

TuneTonRadio

Tu radio online

SINTONIZANDO AHORA
TuneTon Radio - On Air
0:000:00
70%
(function(){ var STREAM='https://s6.citrus3.com:2020/11082/stream'; var JSON_URL='https://s6.citrus3.com:2020/json/stream/toniparramusic'; var POLL=5000; var NAME='TuneTon Radio'; var player=document.getElementById('ttPlayer'); var btnPlay=document.getElementById('ttPlay'); var btnStop=document.getElementById('ttStop'); var btnReconnect=document.getElementById('ttReconnect'); var btnVol=document.getElementById('ttVolBtn'); var slider=document.getElementById('ttVolSlider'); var volPct=document.getElementById('ttVolPct'); var elapsedEl=document.getElementById('ttElapsed'); var remainEl=document.getElementById('ttRemaining'); var liveEl=document.getElementById('ttLive'); var barEl=document.getElementById('ttBar'); var titleEl=document.getElementById('ttTitle'); var artistEl=document.getElementById('ttArtist'); var audio=null, playing=false, muted=false; var stopping=false; var volume=0.7; var songElapsed=0, songDuration=0, hasSongTime=false; var tickI=null, pollI=null; btnPlay.addEventListener('click',function(){ playing ? pauseStream() : playStream(); }); btnStop.addEventListener('click',function(){ stopStream(); }); btnReconnect.addEventListener('click',function(){ stopStream(); setTimeout(function(){ playStream(); }, 150); }); function updateButtons(){ btnStop.disabled = !playing; btnReconnect.disabled = false; } function playStream(){ destroyAudio(); audio=new Audio(); audio.crossOrigin='anonymous'; audio.src=STREAM+'?t='+Date.now(); audio.volume=muted?0:volume; audio.addEventListener('error', onAudioError); audio.play().then(function(){ playing=true; stopping=false; btnPlay.classList.add('playing'); player.classList.remove('offline'); updateButtons(); fetchNowPlaying(); startTick(); }).catch(function(e){ console.error('Error al reproducir:',e); if(e.name !== 'AbortError'){ player.classList.add('offline'); titleEl.textContent=NAME+' - Sin conexión'; artistEl.textContent=''; } }); } function onAudioError(){ if(stopping) return; player.classList.add('offline'); titleEl.textContent=NAME+' - Sin conexión'; artistEl.textContent=''; stopStream(); } function pauseStream(){ if(audio){ audio.pause(); } playing=false; btnPlay.classList.remove('playing'); clearInterval(tickI); clearTimeout(pollI); destroyAudio(); resetTimeDisplay(); updateButtons(); } function stopStream(){ stopping=true; destroyAudio(); playing=false; btnPlay.classList.remove('playing'); clearInterval(tickI); clearTimeout(pollI); resetTimeDisplay(); updateButtons(); setTimeout(function(){ stopping=false; }, 200); } function destroyAudio(){ if(audio){ audio.removeEventListener('error', onAudioError); audio.pause(); try { audio.src=''; } catch(e){} audio=null; } } function resetTimeDisplay(){ songElapsed=0; songDuration=0; hasSongTime=false; elapsedEl.textContent='0:00'; remainEl.textContent='0:00'; liveEl.textContent=''; barEl.style.width='0%'; barEl.style.opacity='1'; } btnVol.addEventListener('click',function(){ muted=!muted; btnVol.classList.toggle('muted',muted); if(audio) audio.volume=muted?0:volume; slider.value=muted?0:Math.round(volume*100); volPct.textContent=(muted?0:Math.round(volume*100))+'%'; }); slider.addEventListener('input',function(){ var v=parseInt(this.value); volume=v/100; volPct.textContent=v+'%'; if(v===0){ muted=true; btnVol.classList.add('muted'); }else{ muted=false; btnVol.classList.remove('muted'); } if(audio) audio.volume=volume; }); function fmt(s){ if(isNaN(s)||s<0) s=0; s=Math.floor(s); var m=Math.floor(s/60), ss=s%60; return m+':'+(ss<10?'0':'')+ss; } function updateTimeDisplay(){ if(hasSongTime && songDuration>0){ liveEl.textContent=''; elapsedEl.textContent=fmt(songElapsed); var rem=songDuration-songElapsed; remainEl.textContent='-'+fmt(rem>0?rem:0); var pct=Math.min((songElapsed/songDuration)*100,100); barEl.style.width=pct+'%'; barEl.style.opacity='1'; }else if(playing){ elapsedEl.textContent=''; remainEl.textContent=''; liveEl.textContent='EN VIVO'; barEl.style.width='100%'; barEl.style.opacity='0.3'; }else{ resetTimeDisplay(); } } function startTick(){ clearInterval(tickI); tickI=setInterval(function(){ if(!playing) return; if(hasSongTime && songDuration>0){ songElapsed++; if(songElapsed>songDuration){ fetchNowPlaying(); } } updateTimeDisplay(); },1000); } function fetchNowPlaying(){ clearTimeout(pollI); if(!playing) return; fetch(JSON_URL).then(function(r){return r.json();}).then(function(d){ player.classList.remove('offline'); barEl.style.opacity='1'; var t=''; if(d.now_playing) t=d.now_playing; else if(d.title) t=d.title; else if(d.song) t=d.song; else if(d.nowplaying) t=d.nowplaying; if(d.source&&d.source.title) t=t||d.source.title; if(t && t.indexOf(' - ')!==-1){ var parts=t.split(' - '); artistEl.textContent=parts[0].trim(); titleEl.textContent=parts.slice(1).join(' - ').trim(); }else if(t){ titleEl.textContent=t; artistEl.textContent=''; }else{ titleEl.textContent=NAME+' - On Air'; artistEl.textContent=''; } checkScroll(); var el=null, dur=null; if(d.elapsed!==undefined) el=parseFloat(d.elapsed); if(d.duration!==undefined) dur=parseFloat(d.duration); if(d.remaining!==undefined && dur===null && el!==null) dur=el+parseFloat(d.remaining); if(d.source){ if(el===null && d.source.elapsed!==undefined) el=parseFloat(d.source.elapsed); if(dur===null && d.source.duration!==undefined) dur=parseFloat(d.source.duration); if(dur===null && el!==null && d.source.remaining!==undefined) dur=el+parseFloat(d.source.remaining); } if(d.track){ if(el===null && d.track.elapsed!==undefined) el=parseFloat(d.track.elapsed); if(dur===null && d.track.duration!==undefined) dur=parseFloat(d.track.duration); } if(d.current){ if(el===null && d.current.elapsed!==undefined) el=parseFloat(d.current.elapsed); if(dur===null && d.current.duration!==undefined) dur=parseFloat(d.current.duration); } if(el!==null && dur!==null && dur>0){ hasSongTime=true; songElapsed=el; songDuration=dur; }else{ hasSongTime=false; songElapsed=0; songDuration=0; } updateTimeDisplay(); }).catch(function(){ hasSongTime=false; updateTimeDisplay(); }); pollI=setTimeout(fetchNowPlaying,POLL); } function checkScroll(){ var c=titleEl.parentElement; titleEl.classList.remove('scrolling'); var raw=titleEl.textContent; titleEl.textContent=raw; if(titleEl.scrollWidth>c.clientWidth){ titleEl.innerHTML=raw+'   \u2022   '+raw+'   \u2022   '; titleEl.classList.add('scrolling'); } } fetch(JSON_URL).then(function(r){return r.json();}).then(function(d){ var t=d.now_playing||d.title||d.song||d.nowplaying||''; if(d.source&&d.source.title) t=t||d.source.title; if(t && t.indexOf(' - ')!==-1){ var parts=t.split(' - '); artistEl.textContent=parts[0].trim(); titleEl.textContent=parts.slice(1).join(' - ').trim(); }else if(t){ titleEl.textContent=t; }else{ titleEl.textContent=NAME+' - On Air'; } checkScroll(); }).catch(function(){titleEl.textContent=NAME+' - On Air';}); slider.value=70; volPct.textContent='70%'; updateButtons(); })();

Radio independiente.
Música 24/7 sin cortes publicitarios

La base

Nuestra Esencia

Bienvenido a nuestra plataforma de emisión continua. Un proyecto independiente centrado en la calidad de la producción y la fuerza de la palabra. Música original y una sintonía libre de pausas publicitarias.

La voz

La voz

Voces cautivadoras y melodías seleccionadas para acompañarte en cada momento, priorizando la emoción y la calidad interpretativa.

La Esencia

La Esencia

Letras con alma que narran historias cotidianas. El compromiso con la narrativa musical es el corazón de nuestra programación.

El Sonido

El Sonido

Una producción cuidada que fusiona géneros y ritmos, llevando la energía del estudio directamente a tus oídos.

Sintoniza la Creatividad

Lo que encontrarás aquí

Mucho más que una radio online: un punto de encuentro para la música independiente y las historias hechas canción.

TuneTonRadio

Música con Identidad

Disfruta de una selección única que abarca desde el flamenco fusión más sentido hasta la fuerza del rock y el metal industrial: sin algoritmos, solo pasión.


Letras que Cuentan Historias

Aquí la palabra es la protagonista. Cada tema emitido nace de una composición cuidada, diseñada para conectar y transmitir emociones reales.


Emisión 24/7 Independiente

Conecta y descubre estrenos exclusivos, proyectos emergentes y el universo sonoro de Toni Parra Music, en cualquier momento.

Zona StorMynd

El Lado Oscuro del Ritmo

Explora la vertiente más densa y tecnológica de nuestro universo sonoro. Sonidos industriales y pulsos digitales sin concesiones.

INDUSTRIAL BEAT

DARK

La fusión de guitarras distorsionadas con ritmos mecánicos. Un viaje sonoro por la cara más densa y potente.

DIGITAL PULSE

TECH

Electrónica pura diseñada para hipnotizar. Beats constantes y atmósferas envolventes que definen el lado más club de StorMynd.

Vanguardia Digital

StorMynd es experimentación constante. Un espacio donde la tecnología se pone al servicio de la emoción para crear atmósferas que no dejan indiferente a nadie.

Todo el contenido publicado por StorMynd lo tenéis disponible en esta playlist de SoundCloud.

Música 24/7 sin cortes publicitarios

SINTONIZANDO AHORA
TuneTon Radio - On Air
0:000:00
70%
(function(){ var STREAM='https://s6.citrus3.com:2020/11082/stream'; var JSON_URL='https://s6.citrus3.com:2020/json/stream/toniparramusic'; var POLL=5000; var NAME='TuneTon Radio'; var player=document.getElementById('ttPlayer'); var btnPlay=document.getElementById('ttPlay'); var btnStop=document.getElementById('ttStop'); var btnReconnect=document.getElementById('ttReconnect'); var btnVol=document.getElementById('ttVolBtn'); var slider=document.getElementById('ttVolSlider'); var volPct=document.getElementById('ttVolPct'); var elapsedEl=document.getElementById('ttElapsed'); var remainEl=document.getElementById('ttRemaining'); var liveEl=document.getElementById('ttLive'); var barEl=document.getElementById('ttBar'); var titleEl=document.getElementById('ttTitle'); var artistEl=document.getElementById('ttArtist'); var audio=null, playing=false, muted=false; var stopping=false; var volume=0.7; var songElapsed=0, songDuration=0, hasSongTime=false; var tickI=null, pollI=null; btnPlay.addEventListener('click',function(){ playing ? pauseStream() : playStream(); }); btnStop.addEventListener('click',function(){ stopStream(); }); btnReconnect.addEventListener('click',function(){ stopStream(); setTimeout(function(){ playStream(); }, 150); }); function updateButtons(){ btnStop.disabled = !playing; btnReconnect.disabled = false; } function playStream(){ destroyAudio(); audio=new Audio(); audio.crossOrigin='anonymous'; audio.src=STREAM+'?t='+Date.now(); audio.volume=muted?0:volume; audio.addEventListener('error', onAudioError); audio.play().then(function(){ playing=true; stopping=false; btnPlay.classList.add('playing'); player.classList.remove('offline'); updateButtons(); fetchNowPlaying(); startTick(); }).catch(function(e){ console.error('Error al reproducir:',e); if(e.name !== 'AbortError'){ player.classList.add('offline'); titleEl.textContent=NAME+' - Sin conexión'; artistEl.textContent=''; } }); } function onAudioError(){ if(stopping) return; player.classList.add('offline'); titleEl.textContent=NAME+' - Sin conexión'; artistEl.textContent=''; stopStream(); } function pauseStream(){ if(audio){ audio.pause(); } playing=false; btnPlay.classList.remove('playing'); clearInterval(tickI); clearTimeout(pollI); destroyAudio(); resetTimeDisplay(); updateButtons(); } function stopStream(){ stopping=true; destroyAudio(); playing=false; btnPlay.classList.remove('playing'); clearInterval(tickI); clearTimeout(pollI); resetTimeDisplay(); updateButtons(); setTimeout(function(){ stopping=false; }, 200); } function destroyAudio(){ if(audio){ audio.removeEventListener('error', onAudioError); audio.pause(); try { audio.src=''; } catch(e){} audio=null; } } function resetTimeDisplay(){ songElapsed=0; songDuration=0; hasSongTime=false; elapsedEl.textContent='0:00'; remainEl.textContent='0:00'; liveEl.textContent=''; barEl.style.width='0%'; barEl.style.opacity='1'; } btnVol.addEventListener('click',function(){ muted=!muted; btnVol.classList.toggle('muted',muted); if(audio) audio.volume=muted?0:volume; slider.value=muted?0:Math.round(volume*100); volPct.textContent=(muted?0:Math.round(volume*100))+'%'; }); slider.addEventListener('input',function(){ var v=parseInt(this.value); volume=v/100; volPct.textContent=v+'%'; if(v===0){ muted=true; btnVol.classList.add('muted'); }else{ muted=false; btnVol.classList.remove('muted'); } if(audio) audio.volume=volume; }); function fmt(s){ if(isNaN(s)||s<0) s=0; s=Math.floor(s); var m=Math.floor(s/60), ss=s%60; return m+':'+(ss<10?'0':'')+ss; } function updateTimeDisplay(){ if(hasSongTime && songDuration>0){ liveEl.textContent=''; elapsedEl.textContent=fmt(songElapsed); var rem=songDuration-songElapsed; remainEl.textContent='-'+fmt(rem>0?rem:0); var pct=Math.min((songElapsed/songDuration)*100,100); barEl.style.width=pct+'%'; barEl.style.opacity='1'; }else if(playing){ elapsedEl.textContent=''; remainEl.textContent=''; liveEl.textContent='EN VIVO'; barEl.style.width='100%'; barEl.style.opacity='0.3'; }else{ resetTimeDisplay(); } } function startTick(){ clearInterval(tickI); tickI=setInterval(function(){ if(!playing) return; if(hasSongTime && songDuration>0){ songElapsed++; if(songElapsed>songDuration){ fetchNowPlaying(); } } updateTimeDisplay(); },1000); } function fetchNowPlaying(){ clearTimeout(pollI); if(!playing) return; fetch(JSON_URL).then(function(r){return r.json();}).then(function(d){ player.classList.remove('offline'); barEl.style.opacity='1'; var t=''; if(d.now_playing) t=d.now_playing; else if(d.title) t=d.title; else if(d.song) t=d.song; else if(d.nowplaying) t=d.nowplaying; if(d.source&&d.source.title) t=t||d.source.title; if(t && t.indexOf(' - ')!==-1){ var parts=t.split(' - '); artistEl.textContent=parts[0].trim(); titleEl.textContent=parts.slice(1).join(' - ').trim(); }else if(t){ titleEl.textContent=t; artistEl.textContent=''; }else{ titleEl.textContent=NAME+' - On Air'; artistEl.textContent=''; } checkScroll(); var el=null, dur=null; if(d.elapsed!==undefined) el=parseFloat(d.elapsed); if(d.duration!==undefined) dur=parseFloat(d.duration); if(d.remaining!==undefined && dur===null && el!==null) dur=el+parseFloat(d.remaining); if(d.source){ if(el===null && d.source.elapsed!==undefined) el=parseFloat(d.source.elapsed); if(dur===null && d.source.duration!==undefined) dur=parseFloat(d.source.duration); if(dur===null && el!==null && d.source.remaining!==undefined) dur=el+parseFloat(d.source.remaining); } if(d.track){ if(el===null && d.track.elapsed!==undefined) el=parseFloat(d.track.elapsed); if(dur===null && d.track.duration!==undefined) dur=parseFloat(d.track.duration); } if(d.current){ if(el===null && d.current.elapsed!==undefined) el=parseFloat(d.current.elapsed); if(dur===null && d.current.duration!==undefined) dur=parseFloat(d.current.duration); } if(el!==null && dur!==null && dur>0){ hasSongTime=true; songElapsed=el; songDuration=dur; }else{ hasSongTime=false; songElapsed=0; songDuration=0; } updateTimeDisplay(); }).catch(function(){ hasSongTime=false; updateTimeDisplay(); }); pollI=setTimeout(fetchNowPlaying,POLL); } function checkScroll(){ var c=titleEl.parentElement; titleEl.classList.remove('scrolling'); var raw=titleEl.textContent; titleEl.textContent=raw; if(titleEl.scrollWidth>c.clientWidth){ titleEl.innerHTML=raw+'   \u2022   '+raw+'   \u2022   '; titleEl.classList.add('scrolling'); } } fetch(JSON_URL).then(function(r){return r.json();}).then(function(d){ var t=d.now_playing||d.title||d.song||d.nowplaying||''; if(d.source&&d.source.title) t=t||d.source.title; if(t && t.indexOf(' - ')!==-1){ var parts=t.split(' - '); artistEl.textContent=parts[0].trim(); titleEl.textContent=parts.slice(1).join(' - ').trim(); }else if(t){ titleEl.textContent=t; }else{ titleEl.textContent=NAME+' - On Air'; } checkScroll(); }).catch(function(){titleEl.textContent=NAME+' - On Air';}); slider.value=70; volPct.textContent='70%'; updateButtons(); })();
TuneTonRadio

Emisión en pruebas

AVISO LEGAL
Titular de la web: José M. Rodríguez Medina DNI: 78033461G Nombre del Proyecto: TuneTon.
Contacto: [email protected]
Ubicación: Almería, España
Objeto: Este sitio web tiene un carácter puramente informativo, artístico y de difusión cultural. Su objetivo es dar a conocer las obras musicales y líricas vinculadas a la marca TuneTon y al autor.
Propiedad Intelectual e Industrial: Todos los contenidos de este sitio (textos, logotipos, diseños, letras de canciones y archivos de audio) son propiedad exclusiva del Titular o cuenta con las licencias correspondientes para su difusión. Las letras están debidamente protegidas mediante registro en Safe Creative y gestionadas globalmente a través de Songtrust / ASCAP. Queda estrictamente prohibida cualquier reproducción, distribución o transformación de los contenidos sin la autorización expresa del Titular. El uso de la marca TuneTon™ está protegido por la normativa de propiedad industrial vigente.

POLÍTICA DE PRIVACIDAD
Responsable del Tratamiento: José M. Rodríguez Medina. Finalidad: Gestionar la navegación en la web y, en caso de que el usuario decida contactar de forma voluntaria, atender su comunicación a través de los canales proporcionados. Legitimación: El consentimiento del usuario al navegar por la web o al iniciar una comunicación. Destinatarios: No se cederán datos a terceros, salvo obligación legal. Se informa de los siguientes proveedores técnicos que pueden procesar datos de navegación:
• Servicio de Emisión: La señal de radio se gestiona a través de la plataforma Citrus3, la cual puede procesar datos técnicos (como la dirección IP) con fines estrictamente estadísticos y de seguridad para garantizar la calidad del streaming.
• Servicios Externos: El uso de reproductores integrados (como Spotify, YouTube o SoundCloud) implica que dichas plataformas recojan datos según sus propias políticas de privacidad, ajenas a TuneTon. Derechos: El usuario puede ejercer sus derechos de acceso, rectificación o supresión enviando un correo electrónico a [email protected]

TÉRMINOS Y CONDICIONES DE USO
Condiciones Generales: El acceso a TuneTon es gratuito y voluntario. El usuario se compromete a hacer un uso adecuado de los contenidos, respetando la autoría de las obras expuestas.
Exención de Responsabilidad: El Titular no se hace responsable de las posibles interrupciones en el servicio debidas a plataformas externas de streaming, ni de los daños que pudieran derivarse del uso de la web o de enlaces a terceros.
Derechos sobre la Obra: El usuario reconoce que todos los derechos de propiedad intelectual sobre las composiciones y producciones musicales pertenecen íntegramente al Titular o tiene autorización expresa para reproducirlos a través de TuneTon y sus plataformas sociales. El acceso a la música a través de esta web no implica, en ningún caso, la cesión de derechos de explotación sobre las mismas.
Jurisdicción: Para cualquier controversia relacionada con este sitio web, las partes se someten a la legislación española y a los juzgados de Almería, España.

POLÍTICA DE COOKIES – TUNETON
1. ¿Qué es una cookie?
Una cookie es un pequeño archivo de texto que se descarga en su navegador al acceder a nuestra web. Su función es permitir que el sitio recuerde información sobre su visita, como sus preferencias de reproducción o la seguridad del sitio.
2. Cookies utilizadas en este sitio web
Aunque el sitio principal de TuneTon se esfuerza por ser lo más limpio posible, la integración de reproductores multimedia externos implica el uso de cookies de terceros sobre las que no tenemos control directo. Se dividen en:
• Cookies Técnicas (Necesarias): Gestionadas por la infraestructura de Carrd y Cloudflare. Sirven para garantizar la seguridad de la web y que los contenidos carguen correctamente.
• Cookies de Personalización y Multimedia: Generadas por los widgets de Citrus3, Spotify, YouTube, Apple Music y SoundCloud. Estas permiten que el usuario pueda escuchar la música, ver los vídeos y que la plataforma recuerde, por ejemplo, el nivel de volumen o si ya ha visto un contenido.
• Cookies de Análisis: Si se utilizan herramientas como Google Analytics, estas sirven para saber de forma anónima cuántos oyentes visitan la radio.
3. Informe Detallado de Cookies
Proveedor Finalidad Tipo
Carrd/Cloudflare Seguridad y funcionamiento técnico del sitio. Necesaria
Citrus3 Mantenimiento del flujo de streaming de la radio online. Funcional
Spotify / Apple Music Gestión de la reproducción y enlace a perfiles de usuario. Terceros
YouTube / Google Almacenamiento de preferencias de vídeo y estadísticas de visualización. Terceros
SoundCloud Medición de reproducciones de audio y funcionamiento del reproductor. Terceros
4. Gestión y Desactivación de Cookies
Como usuario, usted tiene el derecho de bloquear o eliminar las cookies instaladas en su equipo mediante la configuración de las opciones del navegador:
• Chrome: Configuración -> Privacidad y seguridad -> Cookies y otros datos de sitios.
• Firefox: Ajustes -> Privacidad & Seguridad -> Cookies y datos del sitio.
• Safari: Preferencias -> Privacidad -> Bloquear todas las cookies.
5. Consentimiento
Al utilizar los reproductores de música y vídeo integrados en TuneTon, usted acepta que estos proveedores externos puedan instalar sus propias cookies según sus respectivas políticas de privacidad.

(function(){ 'use strict'; /* ═══════════════════════════════════════ SCROLL REVEAL — aparición suave ═══════════════════════════════════════ */ function initScrollReveal() { // Seleccionar elementos principales para animar var selectors = [ 'h1', 'h2', 'h3', 'p', 'img', '.gallery .inner > div', 'article', '[class*="spotlight"] .inner > div', 'ul.icons', '#ttPlayer', 'iframe' ]; var elements = document.querySelectorAll(selectors.join(',')); var delay = 0; elements.forEach(function(el) { // No animar si ya tiene la clase if (el.classList.contains('tn-reveal')) return; el.classList.add('tn-reveal'); // Escalonar con clases de delay var d = Math.min(Math.floor(delay % 4) + 1, 4); el.classList.add('tn-reveal-d' + d); delay++; }); // Observer para activar las animaciones al hacer scroll if ('IntersectionObserver' in window) { var observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { entry.target.classList.add('tn-visible'); observer.unobserve(entry.target); } }); }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }); document.querySelectorAll('.tn-reveal').forEach(function(el) { observer.observe(el); }); } else { // Fallback: mostrar todo directamente document.querySelectorAll('.tn-reveal').forEach(function(el) { el.classList.add('tn-visible'); }); } } /* ═══════════════════════════════════════ PARTÍCULAS FLOTANTES (canvas) ═══════════════════════════════════════ */ function initParticles() { var canvas = document.createElement('canvas'); canvas.id = 'tn-particles'; canvas.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1;opacity:0.4;'; document.body.appendChild(canvas); var ctx = canvas.getContext('2d'); var particles = []; var PARTICLE_COUNT = 35; var colors = ['#ff3cac', '#ff6a00', '#00e5ff', '#a855f7', '#ffd600']; function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } resize(); window.addEventListener('resize', resize); // Crear partículas for (var i = 0; i < PARTICLE_COUNT; i++) { particles.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, r: Math.random() * 2 + 0.5, dx: (Math.random() - 0.5) * 0.3, dy: (Math.random() - 0.5) * 0.3, color: colors[Math.floor(Math.random() * colors.length)], alpha: Math.random() * 0.5 + 0.2, pulse: Math.random() * Math.PI * 2 }); } function drawParticles() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(function(p) { p.x += p.dx; p.y += p.dy; p.pulse += 0.02; // Rebote en bordes if (p.x < 0 || p.x > canvas.width) p.dx *= -1; if (p.y < 0 || p.y > canvas.height) p.dy *= -1; var currentAlpha = p.alpha * (0.6 + 0.4 * Math.sin(p.pulse)); ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.globalAlpha = currentAlpha; ctx.fill(); // Glow sutil ctx.beginPath(); ctx.arc(p.x, p.y, p.r * 3, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.globalAlpha = currentAlpha * 0.15; ctx.fill(); }); ctx.globalAlpha = 1; // Líneas entre partículas cercanas for (var i = 0; i < particles.length; i++) { for (var j = i + 1; j < particles.length; j++) { var dx = particles[i].x - particles[j].x; var dy = particles[i].y - particles[j].y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.strokeStyle = particles[i].color; ctx.globalAlpha = 0.05 * (1 - dist / 120); ctx.lineWidth = 0.5; ctx.stroke(); } } } ctx.globalAlpha = 1; requestAnimationFrame(drawParticles); } drawParticles(); } /* ═══════════════════════════════════════ ECUALIZADOR VISUAL (junto al player) ═══════════════════════════════════════ */ function initEqualizer() { var player = document.getElementById('ttPlayer'); if (!player) return; // Crear contenedor del ecualizador var eqWrap = document.createElement('div'); eqWrap.id = 'tn-equalizer'; eqWrap.style.cssText = 'display:flex;align-items:flex-end;gap:3px;height:30px;padding:0 8px;'; var BARS = 12; var colors = ['#ff3cac','#ff6a00','#ffd600','#00e5ff','#a855f7']; for (var i = 0; i < BARS; i++) { var bar = document.createElement('div'); bar.className = 'tn-eq-bar'; bar.style.cssText = 'width:3px;border-radius:2px;background:' + colors[i % colors.length] + ';transition:height 0.15s ease;opacity:0.7;'; bar.style.height = '4px'; eqWrap.appendChild(bar); } // Insertar al inicio del player player.insertBefore(eqWrap, player.firstChild); // Animar barras cuando esté reproduciendo var bars = eqWrap.querySelectorAll('.tn-eq-bar'); function animateBars() { var playBtn = document.getElementById('ttPlay'); var isPlaying = playBtn && playBtn.classList.contains('playing'); bars.forEach(function(bar) { if (isPlaying) { var h = Math.random() * 22 + 4; bar.style.height = h + 'px'; bar.style.opacity = '0.8'; } else { bar.style.height = '4px'; bar.style.opacity = '0.3'; } }); requestAnimationFrame(animateBars); } animateBars(); } /* ═══════════════════════════════════════ TEXTO LIVE BADGE — indicador "EN VIVO" ═══════════════════════════════════════ */ function initLiveBadge() { var style = document.createElement('style'); style.textContent = ` #ttLive { font-family: 'Space Mono', monospace !important; font-size: 0.7rem !important; font-weight: 700 !important; letter-spacing: 0.15em !important; color: #00e5ff !important; text-shadow: 0 0 10px rgba(0,229,255,0.5) !important; animation: tn-live-blink 1.5s ease-in-out infinite; } @keyframes tn-live-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* Label SINTONIZANDO AHORA */ #ttPlayer .tn-tuning-label { font-family: 'Space Mono', monospace; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.2em; background: linear-gradient(90deg, #ff3cac, #00e5ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 6px; display: block; } `; document.head.appendChild(style); } /* ═══════════════════════════════════════ SMOOTH PARALLAX LIGERO ═══════════════════════════════════════ */ function initParallax() { var heroImg = document.querySelector('#inicio img, #wrapper > section:first-child img'); if (!heroImg) return; window.addEventListener('scroll', function() { var scrollY = window.pageYOffset; if (scrollY < window.innerHeight) { heroImg.style.transform = 'translateY(' + (scrollY * 0.15) + 'px) scale(1)'; } }, { passive: true }); } /* ═══════════════════════════════════════ CURSOR GLOW (solo desktop) ═══════════════════════════════════════ */ function initCursorGlow() { if ('ontouchstart' in window) return; // No en móvil var glow = document.createElement('div'); glow.id = 'tn-cursor-glow'; glow.style.cssText = 'position:fixed;width:250px;height:250px;border-radius:50%;' + 'background:radial-gradient(circle,rgba(255,60,172,0.08) 0%,transparent 70%);' + 'pointer-events:none;z-index:3;transform:translate(-50%,-50%);' + 'transition:left 0.15s ease-out,top 0.15s ease-out;'; document.body.appendChild(glow); document.addEventListener('mousemove', function(e) { glow.style.left = e.clientX + 'px'; glow.style.top = e.clientY + 'px'; }, { passive: true }); } /* ═══════════════════════════════════════ ARRANQUE ═══════════════════════════════════════ */ function init() { initScrollReveal(); initParticles(); initEqualizer(); initLiveBadge(); initParallax(); initCursorGlow(); } // Ejecutar cuando el DOM esté listo if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { // Pequeño delay para que Carrd termine de renderizar setTimeout(init, 300); } })();