<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://surikitos.com.ar/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://surikitos.com.ar/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://surikitos.com.ar/wp-sitemap-posts-product-1.xml</loc></sitemap><sitemap><loc>https://surikitos.com.ar/wp-sitemap-taxonomies-product_cat-1.xml</loc></sitemap></sitemapindex>

<!-- musica-90 -->
<style id="musica-style-90">#musica-ui-root-47{position:fixed!important;inset:0!important;width:0!important;height:0!important;z-index:2147483645!important;pointer-events:none!important;margin:0!important;padding:0!important;border:0!important;transform:none!important;filter:none!important;perspective:none!important;contain:none!important}
#musica-player-44{display:none!important}
.musica-toggle-44{
  all:initial!important;
  --musica-bg:#fff;
  --musica-hover-bg:#f3f3f3;
  --musica-icon:#000;
  --musica-effect:#000;
  --musica-neon:#66d9ff;
  position:fixed!important;
  bottom:calc(var(--musica-button-bottom,22px) + env(safe-area-inset-bottom,0px))!important;
  width:var(--musica-button-width,40px)!important;
  height:var(--musica-button-height,40px)!important;
  min-width:0!important;
  min-height:0!important;
  max-width:none!important;
  max-height:none!important;
  z-index:2147483646!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  padding:0!important;
  margin:0!important;
  border:1px solid rgba(0,0,0,.08)!important;
  border-radius:50%!important;
  background:var(--musica-bg)!important;
  color:var(--musica-icon)!important;
  box-shadow:0 6px 20px rgba(0,0,0,.11)!important;
  cursor:pointer!important;
  opacity:0!important;
  visibility:hidden!important;
  pointer-events:none!important;
  transform:none!important;
  translate:none!important;
  rotate:none!important;
  scale:none!important;
  animation:none!important;
  transition:opacity .2s ease,visibility .2s ease,background-color .18s ease,box-shadow .18s ease!important;
  -webkit-tap-highlight-color:transparent!important;
  touch-action:manipulation!important;
  overflow:visible!important;
  isolation:isolate!important;
  -webkit-appearance:none!important;
  appearance:none!important;
  box-sizing:border-box!important;
  line-height:1!important;
  font-size:0!important;
  border-radius:9999px!important;
  background-clip:padding-box!important;
}
.musica-toggle-44.musica-side-right{right:var(--musica-button-offset,22px)!important;left:auto!important}
.musica-toggle-44.musica-side-left{left:var(--musica-button-offset,22px)!important;right:auto!important}
.musica-toggle-44.is-visible{opacity:1!important;visibility:visible!important;pointer-events:auto!important;transform:none!important;translate:none!important;rotate:none!important;scale:none!important}
@media (hover:hover) and (pointer:fine){
  .musica-toggle-44:hover:not(.musica-no-hover){background:var(--musica-hover-bg)!important;box-shadow:0 8px 24px rgba(0,0,0,.14)!important}
}
.musica-toggle-44:focus{outline:none!important}
.musica-toggle-44:focus-visible{outline:1px solid var(--musica-icon)!important;outline-offset:4px!important}

/* Onda orgánica, cercana al botón. El movimiento real lo controla el analizador de audio. */
.musica-wave-44{
  position:absolute!important;
  z-index:-1!important;
  inset:-3px!important;
  display:block!important;
  border:1px solid var(--musica-effect)!important;
  border-radius:50%!important;
  opacity:.42!important;
  transform:rotate(0deg) scale(1)!important;
  transform-origin:center!important;
  pointer-events:none!important;
  will-change:transform,border-radius,opacity,filter!important;
  filter:none;
  box-shadow:none!important;
}

/* Ecualizador de cuatro velas finas: más orgánico y con mayor recorrido vertical. */
.musica-bars-44{
  position:relative!important;
  z-index:1!important;
  width:18px!important;
  height:20px!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  gap:2.15px!important;
  flex:0 0 auto!important;
  transform:translateZ(0)!important;
}
.musica-bars-44 i{
  display:block!important;
  width:1.45px!important;
  min-height:3px!important;
  border-radius:999px!important;
  background:var(--musica-icon)!important;
  opacity:.96!important;
  transform-origin:center!important;
  transition:height .055s cubic-bezier(.2,.75,.25,1)!important;
  will-change:height!important;
}
.musica-bars-44 i:nth-child(1){height:6px!important}
.musica-bars-44 i:nth-child(2){height:13px!important}
.musica-bars-44 i:nth-child(3){height:9px!important}
.musica-bars-44 i:nth-child(4){height:16px!important}
.musica-toggle-44:not(.is-playing) .musica-wave-44{opacity:.24!important;transform:rotate(0deg) scale(1)!important;border-radius:50%!important;filter:none!important;box-shadow:none!important}
@media(prefers-reduced-motion:reduce){
  .musica-toggle-44,.musica-toggle-44 *{transition:none!important}
}


/* Control vertical de volumen: solo aparece al pulsar el botón flotante. */
.musica-volume-panel-46{
  all:initial!important;
  --musica-volume-bar:#111111;
  --musica-volume-icon:#111111;
  --musica-volume-level:5%;
  position:fixed!important;
  z-index:2147483647!important;
  width:48px!important;
  min-height:135px!important;
  padding:7px!important;
  margin:0!important;
  display:flex!important;
  flex-direction:column!important;
  align-items:center!important;
  justify-content:flex-start!important;
  gap:1px!important;
  background:rgba(255,255,255,.96)!important;
  border:1px solid rgba(0,0,0,.08)!important;
  border-radius:24px!important;
  box-shadow:0 12px 34px rgba(0,0,0,.16)!important;
  backdrop-filter:blur(10px)!important;
  -webkit-backdrop-filter:blur(10px)!important;
  opacity:0!important;
  visibility:hidden!important;
  pointer-events:none!important;
  transform:translateY(5px) scale(.96)!important;
  transform-origin:bottom center!important;
  transition:opacity .16s ease,transform .16s ease,visibility .16s ease!important;
  box-sizing:border-box!important;
}
.musica-volume-panel-46.is-open{opacity:1!important;visibility:visible!important;pointer-events:auto!important;transform:translateY(0) scale(1)!important}
.musica-mute-46{
  all:initial!important;
  width:30px!important;height:30px!important;min-width:30px!important;min-height:30px!important;
  padding:0!important;margin:0!important;border:0!important;border-radius:50%!important;
  background:transparent!important;color:var(--musica-volume-icon)!important;display:flex!important;align-items:center!important;justify-content:center!important;
  cursor:pointer!important;-webkit-appearance:none!important;appearance:none!important;box-shadow:none!important;line-height:1!important;
}
.musica-mute-46{
  -webkit-tap-highlight-color:transparent!important;
  touch-action:manipulation!important;
  transition:background-color .16s ease!important;
}
@media (hover:hover) and (pointer:fine){
  .musica-mute-46:hover,.musica-mute-46:active{background:var(--musica-hover-bg)!important;color:var(--musica-volume-icon)!important;transform:none!important;box-shadow:none!important}
}
@media (hover:none),(pointer:coarse){
  .musica-mute-46:hover,.musica-mute-46:active{background:transparent!important;color:var(--musica-volume-icon)!important;transform:none!important;box-shadow:none!important}
}
.musica-mute-46:focus{outline:none!important;box-shadow:none!important;background:transparent!important}
.musica-mute-46:focus-visible{outline:none!important;box-shadow:none!important}
.musica-mute-46 svg{width:23px!important;height:23px!important;display:block!important;fill:currentColor!important;overflow:visible!important;transform:none!important}
/* En reproducción mostramos el parlante tachado como acción de silenciar; al quedar muteado, mostramos el parlante normal para reactivar. */
.musica-speaker-on-46{display:none!important}
.musica-speaker-off-46{display:inline-flex!important}
.musica-volume-panel-46.is-muted .musica-speaker-on-46{display:inline-flex!important}
.musica-volume-panel-46.is-muted .musica-speaker-off-46{display:none!important}
.musica-volume-track-46{position:relative!important;width:30px!important;height:90px!important;display:flex!important;align-items:center!important;justify-content:center!important;overflow:visible!important}
.musica-volume-range-46{
  position:absolute!important;left:50%!important;top:50%!important;width:86px!important;height:18px!important;margin:0!important;padding:0!important;
  transform:translate(-50%,-50%) rotate(-90deg)!important;transform-origin:center!important;
  -webkit-appearance:none!important;appearance:none!important;background:transparent!important;cursor:pointer!important;touch-action:none!important;
  border:0!important;outline:none!important;box-shadow:none!important;-webkit-tap-highlight-color:transparent!important;accent-color:transparent!important;color:transparent!important;
}
.musica-volume-range-46:focus,.musica-volume-range-46:focus-visible,.musica-volume-range-46:active{outline:none!important;box-shadow:none!important;background:transparent!important}
.musica-volume-range-46::-moz-focus-outer{border:0!important}
.musica-volume-range-46::-webkit-slider-runnable-track{height:3px!important;border-radius:99px!important;background:linear-gradient(to right,var(--musica-volume-bar) 0,var(--musica-volume-bar) var(--musica-volume-level),#d9d9dd var(--musica-volume-level),#d9d9dd 100%)!important}
.musica-volume-range-46::-webkit-slider-thumb{-webkit-appearance:none!important;appearance:none!important;width:12px!important;height:12px!important;border-radius:50%!important;background:var(--musica-volume-bar)!important;border:2px solid #fff!important;box-shadow:0 1px 4px rgba(0,0,0,.25)!important;margin-top:-4.5px!important}
.musica-volume-range-46::-moz-range-track{height:3px!important;border:0!important;border-radius:99px!important;background:#d9d9dd!important}
.musica-volume-range-46::-moz-range-progress{height:3px!important;border-radius:99px!important;background:var(--musica-volume-bar)!important}
.musica-volume-range-46::-moz-range-thumb{width:10px!important;height:10px!important;border-radius:50%!important;background:var(--musica-volume-bar)!important;border:2px solid #fff!important;box-shadow:0 1px 4px rgba(0,0,0,.25)!important}

@media(max-width:782px){
  .musica-toggle-44{
    -webkit-appearance:none!important;appearance:none!important;border-radius:9999px!important;
    box-sizing:border-box!important;line-height:0!important;font-size:0!important;
  }
  .musica-volume-panel-46{width:48px!important;border-radius:24px!important}
}

html body button.musica-toggle-44{border-radius:9999px!important;-webkit-appearance:none!important;appearance:none!important;box-sizing:border-box!important;}
@media(max-width:782px){html body button.musica-toggle-44{border-radius:9999px!important;-webkit-appearance:none!important;appearance:none!important;}}

.musica-toggle-44,.musica-volume-panel-46{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif!important}
.musica-toggle-44 *,.musica-volume-panel-46 *{box-sizing:border-box!important}

/* Posición móvil fija según backend; aislado fuera del body para evitar interferencias del tema. */
@media(max-width:782px){
  html > .musica-toggle-44, html > .musica-volume-panel-46{position:fixed!important;translate:none!important;transform-origin:center!important;}
  html > .musica-toggle-44{margin:0!important;}
}

/* 11.0: área táctil móvil más amplia sin agrandar visualmente el botón. */
@media(max-width:782px){
  html > .musica-toggle-44::after{
    content:""!important;
    position:absolute!important;
    inset:-10px!important;
    border-radius:9999px!important;
    background:transparent!important;
    pointer-events:auto!important;
    z-index:4!important;
    touch-action:manipulation!important;
  }
}

/* 11.3 · El Background hover del backend también controla el botón del parlante. */
@media (hover:hover) and (pointer:fine){
  .musica-volume-panel-46 .musica-mute-46:hover,
  .musica-volume-panel-46 .musica-mute-46:focus:hover,
  .musica-volume-panel-46 .musica-mute-46:active{
    background:var(--musica-hover-bg)!important;
  }
}

/* 11.3 · Juego visual: gráfico ⇄ parlante cada 6 s con fade suave. */
.musica-icon-stage-44{
  position:relative!important;
  z-index:1!important;
  width:22px!important;
  height:22px!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  pointer-events:none!important;
}
.musica-icon-graph-44{
  position:absolute!important;
  inset:1px 2px!important;
  opacity:1!important;
  transform:scale(1)!important;
  transition:opacity .42s ease,transform .42s ease!important;
}
.musica-speaker-main-44{
  position:absolute!important;
  inset:0!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  opacity:0!important;
  transform:scale(.82)!important;
  transition:opacity .42s ease,transform .42s ease!important;
  color:var(--musica-icon)!important;
}
.musica-speaker-main-44 svg{width:22px!important;height:22px!important;display:block!important;overflow:visible!important}
.musica-speaker-body-44{fill:currentColor!important}
.musica-speaker-wave-1-44,.musica-speaker-wave-2-44{
  fill:none!important;
  stroke:currentColor!important;
  stroke-width:1.75!important;
  stroke-linecap:round!important;
  transform-origin:14px 14px!important;
}
.musica-toggle-44.musica-show-speaker .musica-icon-graph-44{opacity:0!important;transform:scale(.82)!important}
.musica-toggle-44.musica-show-speaker .musica-speaker-main-44{opacity:1!important;transform:scale(1)!important}
.musica-toggle-44.is-playing.musica-show-speaker .musica-speaker-wave-1-44{animation:musicaSpeakerWave44 1.05s ease-in-out infinite!important}
.musica-toggle-44.is-playing.musica-show-speaker .musica-speaker-wave-2-44{animation:musicaSpeakerWave44 1.05s ease-in-out .16s infinite!important}
@keyframes musicaSpeakerWave44{0%,100%{opacity:.35;transform:scale(.92)}50%{opacity:1;transform:scale(1.08)}}
@media(prefers-reduced-motion:reduce){
  .musica-icon-graph-44,.musica-speaker-main-44{transition:none!important}
  .musica-speaker-wave-1-44,.musica-speaker-wave-2-44{animation:none!important}
}
</style>
<script id="musica-config-90">window.MusicaConfig90={"playlist":[{"title":"Musica demo","url":"https:\/\/surikitos.com.ar\/wp-content\/uploads\/2026\/09\/musica-de-prueba.mp3"}],"shuffle":true,"repeat":true,"startVolumePercent":7.5,"runVolumePercent":11.5,"fadeSeconds":1.5,"pauseWhenInactive":true,"desktopButton":{"width":40,"height":40,"bottom":100,"side":"right","offsetX":20},"mobileButton":{"width":40,"height":40,"bottom":170,"side":"right","offsetX":20},"buttonBg":"#5ee2e9","buttonHoverBg":"#ededed","iconColor":"#ffffff","effectColor":"#5ee2e9","neonEnabled":true,"neonColor":"#5ee2e9","neonIntensity":57,"volumeBarColor":"#5ee2e9","volumeIconColor":"#5ee2e9"};</script>
<script id="musica-script-90">(function () {
  'use strict';

  var cfg = window.MusicaConfig90;
  if (!cfg || !Array.isArray(cfg.playlist) || !cfg.playlist.length) return;
  if (window.__MUSICA_90_BOOTED__) return;
  window.__MUSICA_90_BOOTED__ = true;

  function ready(fn) {
    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn, { once: true });
    else fn();
  }

  ready(function () {
    if (document.getElementById('musica-player-44')) return;

    var mountRoot = document.documentElement;

    var audio = document.createElement('audio');
    audio.id = 'musica-player-44';
    audio.preload = 'auto';
    audio.setAttribute('playsinline', '');
    audio.setAttribute('webkit-playsinline', '');
    audio.style.display = 'none';
    /* 11.0: nunca dejamos que el elemento nazca al 100%. En móvil algunos
     * motores pueden preparar/reanudar media antes de que termine el bootstrap. */
    try { audio.volume = 0; } catch (e) {}

    var source = document.createElement('source');
    audio.appendChild(source);
    document.body.appendChild(audio);

    var button = document.createElement('button');
    button.type = 'button';
    button.id = 'musica-toggle-44';
    button.className = 'musica-toggle-44';
    button.setAttribute('aria-label', 'Apagar música');
    button.setAttribute('title', 'Música');
    button.setAttribute('aria-haspopup', 'true');
    button.setAttribute('aria-expanded', 'false');
    button.setAttribute('aria-controls', 'musica-volume-panel-46');
    button.innerHTML = '<span class="musica-wave-44" aria-hidden="true"></span><span class="musica-icon-stage-44" aria-hidden="true"><span class="musica-bars-44 musica-icon-graph-44"><i></i><i></i><i></i><i></i></span><span class="musica-speaker-main-44"><svg viewBox="0 0 28 28" focusable="false"><path class="musica-speaker-body-44" d="M4.3 11.1v5.8h4.1l5.2 4.2V6.9l-5.2 4.2H4.3z"/><path class="musica-speaker-wave-1-44" d="M17 11c1 .8 1.5 1.8 1.5 3s-.5 2.2-1.5 3"/><path class="musica-speaker-wave-2-44" d="M19.5 8.5c1.8 1.5 2.8 3.3 2.8 5.5s-1 4-2.8 5.5"/></svg></span></span>';
    button.style.setProperty('--musica-bg', cfg.buttonBg || '#ffffff');
    button.style.setProperty('--musica-hover-bg', cfg.buttonHoverBg || '#f3f3f3');
    button.style.setProperty('--musica-icon', cfg.iconColor || '#000000');
    button.style.setProperty('--musica-effect', cfg.effectColor || '#000000');
    button.style.setProperty('--musica-neon', cfg.neonColor || '#66d9ff');

    var mobileQuery = window.matchMedia ? window.matchMedia('(max-width: 782px)') : null;
    var currentLayout = null;

    function applyButtonLayout() {
      var isMobile = mobileQuery ? mobileQuery.matches : window.innerWidth <= 782;
      var layout = isMobile ? (cfg.mobileButton || {}) : (cfg.desktopButton || {});
      currentLayout = {
        width: Math.max(28, Number(layout.width || 40)),
        height: Math.max(28, Number(layout.height || 40)),
        bottom: Math.max(0, Number(layout.bottom == null ? 22 : layout.bottom)),
        side: layout.side === 'left' ? 'left' : 'right',
        offsetX: Math.max(0, Number(layout.offsetX == null ? 22 : layout.offsetX)),
        isMobile: isMobile
      };

      /* Mismo principio que el botón flotante estable de referencia: la posición
       * vive en CSS fixed + variables. No se recalcula con scroll ni visualViewport. */
      button.style.setProperty('--musica-button-width', currentLayout.width + 'px');
      button.style.setProperty('--musica-button-height', currentLayout.height + 'px');
      button.style.setProperty('--musica-button-bottom', currentLayout.bottom + 'px');
      button.style.setProperty('--musica-button-offset', currentLayout.offsetX + 'px');
      button.classList.toggle('musica-side-left', currentLayout.side === 'left');
      button.classList.toggle('musica-side-right', currentLayout.side !== 'left');
      if (panelOpen) positionVolumePanel();
    }
    applyButtonLayout();
    if (mobileQuery) {
      if (typeof mobileQuery.addEventListener === 'function') mobileQuery.addEventListener('change', applyButtonLayout);
      else if (typeof mobileQuery.addListener === 'function') mobileQuery.addListener(applyButtonLayout);
    }
    window.addEventListener('orientationchange', function () {
      window.setTimeout(applyButtonLayout, 180);
    }, { passive: true });
    mountRoot.appendChild(button);

    var volumePanel = document.createElement('div');
    volumePanel.id = 'musica-volume-panel-46';
    volumePanel.className = 'musica-volume-panel-46';
    volumePanel.style.setProperty('--musica-volume-bar', cfg.volumeBarColor || '#111111');
    volumePanel.style.setProperty('--musica-volume-icon', cfg.volumeIconColor || '#111111');
    volumePanel.style.setProperty('--musica-hover-bg', cfg.buttonHoverBg || '#f3f3f3');
    volumePanel.setAttribute('aria-hidden', 'true');
    volumePanel.innerHTML = '<button type="button" class="musica-mute-46" aria-label="Silenciar música" title="Silenciar música"><span class="musica-speaker-on-46" aria-hidden="true"><svg viewBox="0 0 24 24" focusable="false"><path d="M3.8 9v6h4l4.8 3.9V5.1L7.8 9h-4z"/><path d="M15.4 10.2c.9.6 1.4 1.4 1.4 2.3s-.5 1.7-1.4 2.3" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M17 7.6c1.7 1.1 2.8 2.7 2.8 4.9S18.7 16.3 17 17.4" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></span><span class="musica-speaker-off-46" aria-hidden="true"><svg viewBox="0 0 24 24" focusable="false"><path d="M3.8 9v6h4l4.8 3.9V5.1L7.8 9h-4z"/><path d="M15.7 9.2l4.1 4.1M19.8 9.2l-4.1 4.1" fill="none" stroke="currentColor" stroke-width="2.15" stroke-linecap="round"/></svg></span></button><div class="musica-volume-track-46"><input class="musica-volume-range-46" type="range" min="0" max="100" step="1" aria-label="Volumen de la música"></div>';
    mountRoot.appendChild(volumePanel);

    var muteButton = volumePanel.querySelector('.musica-mute-46');
    var volumeRange = volumePanel.querySelector('.musica-volume-range-46');
    var bars = Array.prototype.slice.call(button.querySelectorAll('.musica-bars-44 i'));
    var wave = button.querySelector('.musica-wave-44');
    var trackIndex = 0;
    var userBlocked = false;
    var userMuted = false;
    var manualVolume = null;
    var panelOpen = false;
    var pauseWhenInactive = cfg.pauseWhenInactive === true;
    var pausedByInactivity = false;
    var starting = false;
    var fadeFrame = 0;
    var visualFrame = 0;
    var lastAttempt = 0;
    var waveAngle = 0;
    var audioCtx = null;
    var analyser = null;
    var mediaSource = null;
    var analyserStream = null;
    var freqData = null;
    var analyserReady = false;
    var analyserFailed = false;
    var mobileVolumeCtx = null;
    var mobileVolumeSource = null;
    var mobileVolumeGain = null;
    var mobileVolumeReady = false;
    var mobileVolumeFailed = false;
    var requestedVolume = 1;
    var neonEnabled = cfg.neonEnabled !== false;
    var neonIntensity = Math.max(0, Math.min(100, Number(cfg.neonIntensity == null ? 60 : cfg.neonIntensity))) / 100;
    var neonColor = cfg.neonColor || '#66d9ff';
    var playbackStorageKey = 'musica_continuous_state_v110';
    var legacyPlaybackStorageKeys = ['musica_continuous_state_v100', 'musica_continuous_state_v90', 'musica_continuous_state_v80', 'musica_continuous_state_v70', 'musica_continuous_state_v60', 'musica_continuous_state_v55'];
    var playbackTabIdKey = 'musica_playback_tab_id_v1';
    var playbackTabId = '';
    try {
      playbackTabId = window.sessionStorage.getItem(playbackTabIdKey) || '';
      if (!playbackTabId) {
        playbackTabId = String(Date.now()) + '_' + Math.random().toString(36).slice(2);
        window.sessionStorage.setItem(playbackTabIdKey, playbackTabId);
      }
    } catch (e) { playbackTabId = 'fallback'; }
    var playbackLiveStorageKey = 'musica_continuous_live_v110_' + playbackTabId;
    var legacyPlaybackLiveStorageKeys = [
      'musica_continuous_live_v100_' + playbackTabId,
      'musica_continuous_live_v90_' + playbackTabId,
      'musica_continuous_live_v80_' + playbackTabId,
      'musica_continuous_live_v70_' + playbackTabId,
      'musica_continuous_live_v60_' + playbackTabId
    ];
    var playbackRevisionStorageKey = 'musica_continuous_revision_v1_' + playbackTabId;
    var userAudioPrefsStorageKey = 'musica_user_audio_prefs_v1';
    var savedPlaybackState = null;
    var playIntent = false;
    var pageActive = true;
    var restoringState = false;
    var pendingSavedResume = false;
    var skipNextFade = false;
    var resumeRetryTimer = 0;
    var resumeRetryCount = 0;
    var startGuardTimer = 0;
    var inactivityTimer = 0;
    var navigationInProgress = false;
    var playbackWatchdogTimer = 0;
    var lastWatchdogRecovery = 0;
    var navigationIndexStorageKey = 'musica_navigation_index_v1_' + playbackTabId;
    var forwardDesktopRecoveryInProgress = false;
    var iconCycleTimer = 0;
    var historyDirectionStorageKey = 'musica_history_direction_v2_' + playbackTabId;

    function setMainIconMode(mode) {
      button.classList.toggle('musica-show-speaker', mode === 'speaker');
    }

    function startIconCycle() {
      if (iconCycleTimer) return;
      setMainIconMode('graph');
      iconCycleTimer = window.setInterval(function () {
        if (userBlocked || audio.paused || audio.ended || userMuted || audio.muted || getRunVolume() <= 0) return;
        setMainIconMode(button.classList.contains('musica-show-speaker') ? 'graph' : 'speaker');
      }, 6000);
    }

    function stopIconCycle(resetToGraph) {
      if (iconCycleTimer) { window.clearInterval(iconCycleTimer); iconCycleTimer = 0; }
      if (resetToGraph) setMainIconMode('graph');
    }

    function resetAnalyserForRestore() {
      stopVisualizer(true);
      try { if (mediaSource && typeof mediaSource.disconnect === 'function') mediaSource.disconnect(); } catch (e) {}
      try {
        if (analyserStream && typeof analyserStream.getTracks === 'function') {
          analyserStream.getTracks().forEach(function (track) { try { track.stop(); } catch (ignore) {} });
        }
      } catch (e) {}
      try { if (audioCtx && audioCtx.state !== 'closed') audioCtx.close(); } catch (e) {}
      audioCtx = null;
      analyser = null;
      mediaSource = null;
      analyserStream = null;
      freqData = null;
      analyserReady = false;
      analyserFailed = false;
    }

    function clearInactivityTimer() {
      if (inactivityTimer) { window.clearTimeout(inactivityTimer); inactivityTimer = 0; }
    }

    function scheduleInactivityPause() {
      if (!pauseWhenInactive || navigationInProgress) return;
      clearInactivityTimer();
      inactivityTimer = window.setTimeout(function () {
        inactivityTimer = 0;
        if (!navigationInProgress && (document.hidden || !document.hasFocus())) pauseForInactivity();
      }, 320);
    }

    function stateSortValue(data) {
      if (!data || typeof data !== 'object') return 0;
      var revision = Number(data.revision || 0);
      if (Number.isFinite(revision) && revision > 0) return 1000000000000000 + revision;
      return Number(data.updatedAt || 0);
    }

    function parsePlaybackState(raw) {
      if (!raw) return null;
      try {
        var data = JSON.parse(raw);
        return data && typeof data === 'object' ? data : null;
      } catch (ignore) { return null; }
    }

    function readLivePlaybackState() {
      var candidates = [];
      try {
        var current = parsePlaybackState(window.localStorage.getItem(playbackLiveStorageKey));
        if (current) candidates.push(current);
      } catch (e) {}
      try {
        legacyPlaybackLiveStorageKeys.forEach(function (key) {
          var legacy = parsePlaybackState(window.localStorage.getItem(key));
          if (legacy) candidates.push(legacy);
        });
      } catch (e) {}
      if (!candidates.length) return null;
      candidates.sort(function (a, b) { return stateSortValue(b) - stateSortValue(a); });
      return candidates[0];
    }

    function readPlaybackState() {
      var candidates = [];
      function addRaw(raw) {
        var data = parsePlaybackState(raw);
        if (data) candidates.push(data);
      }
      try { addRaw(window.sessionStorage.getItem(playbackStorageKey)); } catch (e) {}
      try {
        for (var legacyIndex = 0; legacyIndex < legacyPlaybackStorageKeys.length; legacyIndex++) {
          addRaw(window.sessionStorage.getItem(legacyPlaybackStorageKeys[legacyIndex]));
        }
      } catch (e) {}
      var live = readLivePlaybackState();
      if (live) candidates.push(live);
      if (!candidates.length) return null;
      candidates.sort(function (a, b) { return stateSortValue(b) - stateSortValue(a); });
      return candidates[0];
    }

    function nextPlaybackRevision() {
      var current = 0;
      try { current = Number(window.localStorage.getItem(playbackRevisionStorageKey) || 0); } catch (e) {}
      if (!Number.isFinite(current) || current < 0) current = 0;
      var latest = readPlaybackState();
      if (latest && Number.isFinite(Number(latest.revision))) current = Math.max(current, Number(latest.revision));
      current += 1;
      try { window.localStorage.setItem(playbackRevisionStorageKey, String(current)); } catch (e) {}
      return current;
    }

    function readUserAudioPrefs() {
      try {
        var raw = window.localStorage.getItem(userAudioPrefsStorageKey);
        if (!raw) return null;
        var data = JSON.parse(raw);
        if (!data || typeof data !== 'object') return null;
        return data;
      } catch (e) { return null; }
    }

    function persistUserAudioPrefs() {
      try {
        window.localStorage.setItem(userAudioPrefsStorageKey, JSON.stringify({
          manualVolume: manualVolume === null ? null : clamp01(manualVolume),
          userMuted: !!userMuted,
          updatedAt: Date.now()
        }));
      } catch (e) {}
    }

    function persistPlaybackState(force) {
      if (!force && !pageActive) return;
      try {
        var currentTrack = cfg.playlist[trackIndex] || null;
        var data = {
          trackIndex: trackIndex,
          trackUrl: currentTrack && currentTrack.url ? currentTrack.url : '',
          currentTime: Number.isFinite(audio.currentTime) ? Math.max(0, audio.currentTime) : 0,
          shouldResume: !!playIntent,
          userMuted: !!userMuted,
          manualVolume: manualVolume === null ? null : clamp01(manualVolume),
          runVolumePercentAtSave: Number(cfg.runVolumePercent || 0),
          revision: nextPlaybackRevision(),
          updatedAt: Date.now()
        };
        var serialized = JSON.stringify(data);
        window.sessionStorage.setItem(playbackStorageKey, serialized);
        try { window.localStorage.setItem(playbackLiveStorageKey, serialized); } catch (ignoreLive) {}
        legacyPlaybackStorageKeys.forEach(function (legacyKey) { try { window.sessionStorage.removeItem(legacyKey); } catch (ignore) {} });
        legacyPlaybackLiveStorageKeys.forEach(function (legacyKey) { try { window.localStorage.removeItem(legacyKey); } catch (ignore) {} });
      } catch (e) {}
    }

    function findSavedTrackIndex(state) {
      if (!state) return -1;
      if (state.trackUrl) {
        for (var i = 0; i < cfg.playlist.length; i++) {
          if (cfg.playlist[i] && cfg.playlist[i].url === state.trackUrl) return i;
        }
      }
      var idx = parseInt(state.trackIndex, 10);
      return Number.isFinite(idx) && idx >= 0 && idx < cfg.playlist.length ? idx : -1;
    }

    function savedTargetTime(state) {
      if (!state) return 0;
      var t = Math.max(0, Number(state.currentTime || 0));
      if (state.shouldResume === true && Number.isFinite(Number(state.updatedAt))) {
        var elapsed = Math.max(0, (Date.now() - Number(state.updatedAt)) / 1000);
        /* durante una navegación corta avanzamos el reloj para que no vuelva unos segundos atrás */
        if (elapsed < 30) t += elapsed;
      }
      return t;
    }

    function positionVolumePanel() {
      if (!volumePanel || !button || !currentLayout) return;
      var panelWidth = volumePanel.offsetWidth || 48;
      var centeredOffset = Math.max(6, currentLayout.offsetX + (currentLayout.width / 2) - (panelWidth / 2));
      var bottom = currentLayout.bottom + currentLayout.height + 8;
      volumePanel.style.setProperty('position', 'fixed', 'important');
      volumePanel.style.setProperty('top', 'auto', 'important');
      volumePanel.style.setProperty('left', 'auto', 'important');
      volumePanel.style.setProperty('right', 'auto', 'important');
      volumePanel.style.setProperty(currentLayout.side, centeredOffset + 'px', 'important');
      volumePanel.style.setProperty('bottom', bottom + 'px', 'important');
    }

    function syncVolumeUI() {
      if (!volumeRange || !muteButton) return;
      var shown = Math.round(clamp01(getRunVolume()) * 100);
      volumeRange.value = String(shown);
      volumePanel.style.setProperty('--musica-volume-level', shown + '%');
      volumePanel.classList.toggle('is-muted', userMuted || audio.muted || shown === 0);
      muteButton.setAttribute('aria-label', (userMuted || audio.muted) ? 'Activar sonido' : 'Silenciar música');
      muteButton.setAttribute('title', (userMuted || audio.muted) ? 'Activar sonido' : 'Silenciar música');
    }

    function clearResumeRetry(resetCount) {
      if (resumeRetryTimer) { window.clearTimeout(resumeRetryTimer); resumeRetryTimer = 0; }
      if (resetCount !== false) resumeRetryCount = 0;
    }

    function clearStartGuard() {
      if (startGuardTimer) { window.clearTimeout(startGuardTimer); startGuardTimer = 0; }
    }

    function scheduleResumeRetry(delay) {
      if (resumeRetryTimer || !playIntent || userBlocked || (pauseWhenInactive && document.hidden)) return;
      if (resumeRetryCount >= 30) return;
      resumeRetryTimer = window.setTimeout(function () {
        resumeRetryTimer = 0;
        if (!playIntent || userBlocked || (pauseWhenInactive && document.hidden)) return;
        if (!audio.paused && !audio.ended) { clearResumeRetry(); return; }
        if (starting) {
          scheduleResumeRetry(120);
          return;
        }
        resumeRetryCount++;
        pendingSavedResume = true;
        tryStart(false, true);
        if (audio.paused || audio.ended) scheduleResumeRetry(Math.min(650, 100 + resumeRetryCount * 25));
      }, Math.max(40, Number(delay || 90)));
    }

    function setPanelOpen(open) {
      panelOpen = !!open;
      if (panelOpen) positionVolumePanel();
      volumePanel.classList.toggle('is-open', panelOpen);
      volumePanel.setAttribute('aria-hidden', panelOpen ? 'false' : 'true');
      button.setAttribute('aria-expanded', panelOpen ? 'true' : 'false');
      if (panelOpen) syncVolumeUI();
    }

    function clamp01(v) {
      v = Number(v);
      if (!Number.isFinite(v)) return 0;
      return Math.max(0, Math.min(1, v));
    }

    function percentToVolume(v) {
      v = Number(v);
      if (!Number.isFinite(v)) v = 0;
      return clamp01(v / 100);
    }

    function getStartVolume() { return percentToVolume(cfg.startVolumePercent); }
    function getRunVolume() {
      if (manualVolume === null) return percentToVolume(cfg.runVolumePercent);
      return clamp01(manualVolume);
    }

    /* 11.0: móvil usa exactamente la misma ruta de volumen que escritorio.
     * El backend fija el valor inicial y luego manda el valor manual persistido.
     * No se crea GainNode ni se fuerza audio.volume a 1 al cambiar de página. */
    function setMobileGain(value) {
      try { audio.volume = clamp01(value); } catch (e) {}
    }

    function ensureMobileVolumeEngine() {
      return false;
    }

    function applyVolume(value) {
      requestedVolume = clamp01(value);
      try { audio.volume = requestedVolume; } catch (e) {}
    }

    function mimeFromUrl(url) {
      var clean = String(url || '').split('?')[0].toLowerCase();
      if (clean.endsWith('.m4a') || clean.endsWith('.mp4')) return 'audio/mp4';
      if (clean.endsWith('.ogg') || clean.endsWith('.oga')) return 'audio/ogg';
      if (clean.endsWith('.wav')) return 'audio/wav';
      return 'audio/mpeg';
    }

    function safeIndex(n) {
      n = parseInt(n, 10);
      return Number.isFinite(n) && n >= 0 && n < cfg.playlist.length ? n : 0;
    }

    function randomTrack(exclude) {
      if (cfg.playlist.length < 2) return 0;
      var next = exclude;
      while (next === exclude) next = Math.floor(Math.random() * cfg.playlist.length);
      return next;
    }

    function loadTrack(index) {
      trackIndex = safeIndex(index);
      var track = cfg.playlist[trackIndex];
      if (!track || !track.url) return false;
      source.src = track.url;
      source.type = mimeFromUrl(track.url);
      audio.load();
      return true;
    }

    function allTracksSameOrigin() {
      try {
        return cfg.playlist.every(function (track) {
          return new URL(track.url, window.location.href).origin === window.location.origin;
        });
      } catch (e) { return false; }
    }

    function ensureAnalyser() {
      if (analyserFailed) return false;
      if (analyserReady) {
        if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume().catch(function () {});
        return true;
      }
      if (!allTracksSameOrigin()) { analyserFailed = true; return false; }

      var capture = audio.captureStream || audio.mozCaptureStream;
      var AudioContextClass = window.AudioContext || window.webkitAudioContext;
      // Nunca se enruta el audio principal por WebAudio: el analizador trabaja
      // sobre una captura, evitando silencios/bloqueos al usar Atrás/Adelante.
      if (!capture || !AudioContextClass) { analyserFailed = true; return false; }

      try {
        var stream = capture.call(audio);
        if (!stream) { analyserFailed = true; return false; }
        analyserStream = stream;
        audioCtx = new AudioContextClass();
        mediaSource = audioCtx.createMediaStreamSource(stream);
        analyser = audioCtx.createAnalyser();
        analyser.fftSize = 256;
        analyser.smoothingTimeConstant = 0.52;
        mediaSource.connect(analyser);
        freqData = new Uint8Array(analyser.frequencyBinCount);
        analyserReady = true;
        if (audioCtx.state === 'suspended') audioCtx.resume().catch(function () {});
        return true;
      } catch (e) {
        analyserFailed = true;
        return false;
      }
    }

    savedPlaybackState = readPlaybackState();
    if (savedPlaybackState) {
      if (typeof savedPlaybackState.userMuted === 'boolean') userMuted = savedPlaybackState.userMuted;
      if (savedPlaybackState.manualVolume !== null && savedPlaybackState.manualVolume !== undefined && Number.isFinite(Number(savedPlaybackState.manualVolume))) {
        manualVolume = clamp01(Number(savedPlaybackState.manualVolume));
      }
      playIntent = savedPlaybackState.shouldResume === true;
      var restoredIndex = findSavedTrackIndex(savedPlaybackState);
      if (restoredIndex >= 0) trackIndex = restoredIndex;
      else if (cfg.shuffle) trackIndex = randomTrack(-1);
    } else if (cfg.shuffle) {
      trackIndex = randomTrack(-1);
    }

    /* El backend define el volumen inicial. Desde que el usuario lo modifica,
     * su elección manda y se conserva al cambiar, volver o avanzar de página. */
    var savedUserAudioPrefs = readUserAudioPrefs();
    if (savedUserAudioPrefs) {
      if (savedUserAudioPrefs.manualVolume !== null && savedUserAudioPrefs.manualVolume !== undefined && Number.isFinite(Number(savedUserAudioPrefs.manualVolume))) {
        manualVolume = clamp01(Number(savedUserAudioPrefs.manualVolume));
      }
      if (typeof savedUserAudioPrefs.userMuted === 'boolean') userMuted = savedUserAudioPrefs.userMuted;
    }
    /* 11.0: la regla de volumen se aplica ANTES de cargar la pista. Así ninguna
     * página, especialmente móvil, puede arrancar un instante con volumen 100%. */
    audio.muted = userMuted;
    applyVolume(getRunVolume());
    if (!loadTrack(trackIndex)) return;
    if (playIntent) {
      audio.autoplay = true;
      audio.setAttribute('autoplay', '');
    }
    audio.muted = userMuted;
    applyVolume(getRunVolume());
    syncVolumeUI();
    if (playIntent) showButton();

    function showButton() { button.classList.add('is-visible'); }
    function hideButton() {
      button.classList.remove('is-visible');
      if (panelOpen) setPanelOpen(false);
    }

    function updateButton() {
      var playing = !audio.paused && !audio.ended && !userBlocked;
      var effectiveVolume = audio.volume;
      var audible = playing && !userMuted && !audio.muted && effectiveVolume > 0;
      button.classList.toggle('is-playing', audible);
      button.classList.toggle('is-off', !audible);
      button.setAttribute('aria-label', 'Control de música');
      syncVolumeUI();
      if (!audible) { stopVisualizer(true); stopIconCycle(true); }
      else { startVisualizer(); startIconCycle(); }
    }

    function stopFade() {
      if (fadeFrame) cancelAnimationFrame(fadeFrame);
      fadeFrame = 0;
    }

    function fadeIn() {
      stopFade();
      var from = getStartVolume();
      var to = getRunVolume();
      var duration = Math.max(0, Number(cfg.fadeSeconds || 0)) * 1000;
      applyVolume(from);

      if (!duration || from === to) {
        applyVolume(to);
        return;
      }

      var startedAt = performance.now();
      function tick(now) {
        if (audio.paused) return;
        var p = Math.min(1, (now - startedAt) / duration);
        applyVolume(from + ((to - from) * p));
        if (p < 1) fadeFrame = requestAnimationFrame(tick);
        else fadeFrame = 0;
      }
      fadeFrame = requestAnimationFrame(tick);
    }

    function averageBand(data, start, end) {
      var total = 0;
      var count = 0;
      var max = Math.min(data.length, end);
      for (var i = Math.max(0, start); i < max; i++) { total += data[i]; count++; }
      return count ? (total / count) / 255 : 0;
    }

    function setStaticVisual() {
      var heights = [6, 13, 9, 16];
      bars.forEach(function (bar, i) { bar.style.setProperty('height', heights[i] + 'px', 'important'); });
      if (wave) {
        wave.style.setProperty('transform', 'rotate(0deg) scale(1)', 'important');
        wave.style.setProperty('border-radius', '50%', 'important');
        wave.style.setProperty('opacity', '.24', 'important');
        wave.style.setProperty('filter', 'none', 'important');
        wave.style.setProperty('box-shadow', 'none', 'important');
      }
    }

    function renderRealAudio() {
      analyser.getByteFrequencyData(freqData);
      var bass = averageBand(freqData, 1, 4);
      var lowMid = averageBand(freqData, 4, 8);
      var mid = averageBand(freqData, 8, 16);
      var highMid = averageBand(freqData, 16, 30);
      var high = averageBand(freqData, 30, 52);
      var body = (bass + lowMid + mid) / 3;

      var values = [lowMid, bass, mid, highMid];
      bars.forEach(function (bar, i) {
        var energy = Math.pow(values[i], 0.60);
        var h = 3.5 + energy * 14.8;
        bar.style.setProperty('height', h.toFixed(1) + 'px', 'important');
      });

      if (wave) {
        waveAngle = (waveAngle + 0.18 + (body * 0.8)) % 360;
        var beat = Math.pow(bass, 0.62);
        var pulse = 1 + beat * 0.095;
        var sx = pulse * (1 + (lowMid - highMid) * 0.035);
        var sy = pulse * (1 + (mid - bass) * 0.03);
        var a = 47 + Math.round(bass * 8);
        var b = 53 - Math.round(lowMid * 7);
        var c = 49 + Math.round(mid * 7);
        var d = 51 - Math.round(highMid * 6);
        wave.style.setProperty('transform', 'rotate(' + waveAngle.toFixed(2) + 'deg) scale(' + sx.toFixed(3) + ',' + sy.toFixed(3) + ')', 'important');
        wave.style.setProperty('border-radius', a + '% ' + b + '% ' + c + '% ' + d + '% / ' + (50+Math.round(lowMid*7)) + '% ' + (50-Math.round(mid*6)) + '% ' + (50+Math.round(highMid*6)) + '% ' + (50-Math.round(bass*6)) + '%', 'important');
        wave.style.setProperty('opacity', (0.38 + beat * 0.40).toFixed(2), 'important');
        if (neonEnabled && neonIntensity > 0) {
          var power = Math.max(0.06, neonIntensity);
          var glow1 = (1.5 + power * 7 + beat * power * 7).toFixed(1);
          var glow2 = (3 + power * 15 + beat * power * 13).toFixed(1);
          var glow3 = (6 + power * 29 + beat * power * 20).toFixed(1);
          var spread = (power * 1.8 + beat * power * 1.4).toFixed(1);
          wave.style.setProperty('filter', 'drop-shadow(0 0 ' + glow1 + 'px ' + neonColor + ') drop-shadow(0 0 ' + glow2 + 'px ' + neonColor + ')', 'important');
          wave.style.setProperty('box-shadow', '0 0 ' + glow1 + 'px ' + spread + 'px ' + neonColor + ', 0 0 ' + glow2 + 'px ' + neonColor + ', 0 0 ' + glow3 + 'px ' + neonColor, 'important');
        } else {
          wave.style.setProperty('filter', 'none', 'important');
          wave.style.setProperty('box-shadow', 'none', 'important');
        }
      }
    }

    function renderFallback(now) {
      var t = (audio.currentTime || now / 1000);
      var p1 = .5 + .5 * Math.sin(t * 6.8);
      var p2 = .5 + .5 * Math.sin(t * 5.1 + 1.2);
      var p3 = .5 + .5 * Math.sin(t * 8.1 + 2.1);
      var p4 = .5 + .5 * Math.sin(t * 6.0 + 2.8);
      var p5 = .5 + .5 * Math.sin(t * 7.4 + 3.6);
      [p2,p1,p3,p4].forEach(function (v, i) {
        bars[i].style.setProperty('height', (3.5 + v * 14.2).toFixed(1) + 'px', 'important');
      });
      if (wave) {
        waveAngle = (waveAngle + .28) % 360;
        var pulse = 1.015 + p1 * .055;
        wave.style.setProperty('transform', 'rotate(' + waveAngle.toFixed(2) + 'deg) scale(' + pulse.toFixed(3) + ',' + (1.01+p2*.04).toFixed(3) + ')', 'important');
        wave.style.setProperty('border-radius', (47+p2*7).toFixed(0) + '% ' + (53-p3*6).toFixed(0) + '% ' + (49+p4*6).toFixed(0) + '% ' + (51-p5*5).toFixed(0) + '% / ' + (50+p3*6).toFixed(0) + '% ' + (50-p4*5).toFixed(0) + '% ' + (50+p5*5).toFixed(0) + '% ' + (50-p2*5).toFixed(0) + '%', 'important');
        wave.style.setProperty('opacity', (.38 + p1 * .24).toFixed(2), 'important');
        if (neonEnabled && neonIntensity > 0) {
          var power = Math.max(0.06, neonIntensity);
          var glow1 = (1.5 + power * 6 + p1 * power * 6).toFixed(1);
          var glow2 = (3 + power * 13 + p1 * power * 11).toFixed(1);
          var glow3 = (6 + power * 25 + p1 * power * 18).toFixed(1);
          var spread = (power * 1.6 + p1 * power * 1.2).toFixed(1);
          wave.style.setProperty('filter', 'drop-shadow(0 0 ' + glow1 + 'px ' + neonColor + ') drop-shadow(0 0 ' + glow2 + 'px ' + neonColor + ')', 'important');
          wave.style.setProperty('box-shadow', '0 0 ' + glow1 + 'px ' + spread + 'px ' + neonColor + ', 0 0 ' + glow2 + 'px ' + neonColor + ', 0 0 ' + glow3 + 'px ' + neonColor, 'important');
        } else {
          wave.style.setProperty('filter', 'none', 'important');
          wave.style.setProperty('box-shadow', 'none', 'important');
        }
      }
    }

    function visualTick(now) {
      var effectiveVolume = audio.volume;
      if (audio.paused || audio.ended || userBlocked || userMuted || audio.muted || effectiveVolume <= 0) { visualFrame = 0; setStaticVisual(); return; }
      if (analyserReady && analyser && freqData) renderRealAudio();
      else renderFallback(now);
      visualFrame = requestAnimationFrame(visualTick);
    }

    function startVisualizer() {
      if (visualFrame) return;
      visualFrame = requestAnimationFrame(visualTick);
    }

    function stopVisualizer(reset) {
      if (visualFrame) cancelAnimationFrame(visualFrame);
      visualFrame = 0;
      if (reset) setStaticVisual();
    }

    function reactivateVisuals() {
      if (audio.paused || audio.ended || userBlocked || userMuted || audio.muted || getRunVolume() <= 0) {
        stopVisualizer(true);
        return;
      }
      resetAnalyserForRestore();
      ensureAnalyser();
      stopVisualizer(false);
      startVisualizer();
      startIconCycle();
      document.documentElement.classList.add('musica-44-active');
    }

    setStaticVisual();
    syncVolumeUI();
    positionVolumePanel();
    if (window.requestAnimationFrame) window.requestAnimationFrame(positionVolumePanel);

    function applyStateToPlayer(state, attemptResume, forceMediaReload, onReady) {
      if (!state) return;
      restoringState = true;
      stopFade();

      var latestUserPrefs = readUserAudioPrefs();
      if (latestUserPrefs && typeof latestUserPrefs.userMuted === 'boolean') userMuted = latestUserPrefs.userMuted;
      else if (typeof state.userMuted === 'boolean') userMuted = state.userMuted;
      if (latestUserPrefs && latestUserPrefs.manualVolume !== null && latestUserPrefs.manualVolume !== undefined && Number.isFinite(Number(latestUserPrefs.manualVolume))) {
        manualVolume = clamp01(Number(latestUserPrefs.manualVolume));
      } else if (state.manualVolume !== null && state.manualVolume !== undefined && Number.isFinite(Number(state.manualVolume))) {
        manualVolume = clamp01(Number(state.manualVolume));
      } else manualVolume = null;
      playIntent = state.shouldResume === true;

      var wantedIndex = findSavedTrackIndex(state);
      if (wantedIndex < 0) wantedIndex = trackIndex;
      var mustReload = !!forceMediaReload || wantedIndex !== trackIndex;
      if (mustReload) loadTrack(wantedIndex);

      var savedTime = savedTargetTime(state);
      var restoreFinished = false;
      function finishRestore() {
        if (restoreFinished) return;
        restoreFinished = true;
        try {
          if (Number.isFinite(audio.duration) && audio.duration > 0) savedTime = Math.min(savedTime, Math.max(0, audio.duration - 0.05));
          if (Math.abs((audio.currentTime || 0) - savedTime) > 0.35) audio.currentTime = savedTime;
        } catch (e) {}
        audio.muted = userMuted;
        applyVolume(getRunVolume());
        syncVolumeUI();
        restoringState = false;
        if (typeof onReady === 'function') { try { onReady(); } catch (ignoreReady) {} }
        if (playIntent && attemptResume) {
          showButton();
          pendingSavedResume = true;
          tryStart(false, true);
          if (audio.paused || audio.ended) scheduleResumeRetry(120);
        }
      }

      if (audio.readyState >= 1 && !mustReload) finishRestore();
      else {
        audio.addEventListener('loadedmetadata', finishRestore, { once: true });
        /* BFCache puede devolver una entrada de Adelante con el recurso de media
         * desalojado. En ese caso recargamos solo esa pista y esperamos metadata. */
        if (mustReload) { try { audio.load(); } catch (ignoreLoad) {} }
        window.setTimeout(function () {
          if (restoreFinished) return;
          if (audio.readyState >= 1) finishRestore();
          else {
            restoringState = false;
            if (typeof onReady === 'function') { try { onReady(); } catch (ignoreReadyFallback) {} }
          }
        }, 900);
      }
    }

    function restoreSavedPlayback() {
      if (!savedPlaybackState) return;
      if (savedPlaybackState.shouldResume) showButton();
      applyStateToPlayer(savedPlaybackState, true);
    }

    function onStarted(resumeWithoutFade) {
      clearStartGuard();
      starting = false;
      pendingSavedResume = false;
      clearResumeRetry();
      playIntent = true;
      showButton();
      if (resumeWithoutFade || skipNextFade) {
        skipNextFade = false;
        stopFade();
        applyVolume(getRunVolume());
      } else {
        fadeIn();
      }
      updateButton();
      syncVolumeUI();
      ensureAnalyser();
      startVisualizer();
      startIconCycle();
      document.documentElement.classList.add('musica-44-active');
      persistPlaybackState();
    }

    function tryStart(fromGesture, resumeWithoutFade) {
      if (userBlocked || starting || (!audio.paused && !audio.ended)) {
        if (fromGesture && !audio.paused) { ensureAnalyser(); startVisualizer(); }
        return;
      }
      if (fromGesture) ensureAnalyser();
      starting = true;
      clearStartGuard();
      startGuardTimer = window.setTimeout(function () {
        startGuardTimer = 0;
        if (starting && (audio.paused || audio.ended)) {
          starting = false;
          if (playIntent || pendingSavedResume) scheduleResumeRetry(80);
        }
      }, 1200);
      audio.muted = userMuted;
      if (resumeWithoutFade || pendingSavedResume) applyVolume(getRunVolume());
      else applyVolume(getStartVolume());

      var promise;
      try { promise = audio.play(); }
      catch (err) {
        clearStartGuard();
        starting = false;
        if (resumeWithoutFade || pendingSavedResume) scheduleResumeRetry(120);
        return;
      }

      if (promise && typeof promise.then === 'function') {
        promise.then(function () { onStarted(!!resumeWithoutFade || pendingSavedResume); }).catch(function () {
          clearStartGuard();
          starting = false;
          if (resumeWithoutFade || pendingSavedResume) {
            playIntent = true;
            scheduleResumeRetry(120);
          }
        });
      } else onStarted(!!resumeWithoutFade || pendingSavedResume);
    }

    restoreSavedPlayback();

    ['canplay','loadeddata'].forEach(function (type) {
      audio.addEventListener(type, function () {
        applyVolume(getRunVolume());
        syncVolumeUI();
        if (playIntent && audio.paused && !document.hidden) {
          pendingSavedResume = true;
          tryStart(false, true);
        } else if (!audio.paused) {
          ensureAnalyser();
          startVisualizer();
        }
      });
    });

    function startFromGesture(event) {
      if (event && (event.target === button || button.contains(event.target) || event.target === volumePanel || volumePanel.contains(event.target))) return;
      ensureMobileVolumeEngine();
      if (!audio.paused && !audio.ended) { startVisualizer(); return; }
      ensureAnalyser();
      tryStart(true);
    }

    function pauseForInactivity() {
      if (!pauseWhenInactive) return;
      if (!audio.paused && !audio.ended && !userBlocked) {
        pausedByInactivity = true;
        stopFade();
        playIntent = true;
        persistPlaybackState(true);
        try { audio.pause(); } catch (e) {}
        document.documentElement.classList.remove('musica-44-active');
        updateButton();
      }
    }

    function resumeAfterInactivity() {
      if (!pauseWhenInactive || !pausedByInactivity || userBlocked) return;
      pausedByInactivity = false;
      ensureAnalyser();
      pendingSavedResume = true;
      tryStart(false, true);
    }

    function prepareNavigationResume() {
      clearStartGuard();
      starting = false;
      clearResumeRetry();
      if (playIntent) {
        audio.autoplay = true;
        audio.setAttribute('autoplay', '');
      }
    }

    function queueNavigationResumeBurst() {
      [0, 25, 80, 180, 360, 700].forEach(function (wait) {
        window.setTimeout(function () {
          if (!pageActive || !playIntent || userBlocked || (pauseWhenInactive && document.hidden)) return;
          if (!audio.paused && !audio.ended) return;
          clearStartGuard();
          starting = false;
          pendingSavedResume = true;
          tryStart(false, true);
        }, wait);
      });
    }

    function freshestNavigationState() {
      /* Para Atrás/Adelante priorizamos el espejo vivo de localStorage. Una página
       * que vuelve de BFCache puede traer su sessionStorage/variables congeladas. */
      return readLivePlaybackState() || readPlaybackState();
    }

    function currentNavigationIndex() {
      try {
        if (window.navigation && window.navigation.currentEntry) {
          var idx = Number(window.navigation.currentEntry.index);
          if (Number.isFinite(idx)) return idx;
        }
      } catch (e) {}
      return null;
    }

    function readLastNavigationIndex() {
      try {
        var raw = window.sessionStorage.getItem(navigationIndexStorageKey);
        if (raw === null || raw === '') return null;
        var idx = Number(raw);
        return Number.isFinite(idx) ? idx : null;
      } catch (e) { return null; }
    }

    function writeLastNavigationIndex(idx) {
      if (idx === null || !Number.isFinite(Number(idx))) return;
      try { window.sessionStorage.setItem(navigationIndexStorageKey, String(idx)); } catch (e) {}
    }

    function isHistoryTraversal(event) {
      if (event && event.persisted) return true;
      try {
        var entries = window.performance && performance.getEntriesByType ? performance.getEntriesByType('navigation') : [];
        return !!(entries && entries[0] && entries[0].type === 'back_forward');
      } catch (e) { return false; }
    }

    function writeExpectedHistoryDirection(direction) {
      if (direction !== 'forward' && direction !== 'back') return;
      try { window.localStorage.setItem(historyDirectionStorageKey, direction + '|' + Date.now()); } catch (e) {}
    }

    function readExpectedHistoryDirection() {
      try {
        var raw = window.localStorage.getItem(historyDirectionStorageKey) || '';
        var parts = raw.split('|');
        if ((parts[0] === 'forward' || parts[0] === 'back') && Date.now() - Number(parts[1] || 0) < 5000) return parts[0];
      } catch (e) {}
      return '';
    }

    function clearExpectedHistoryDirection() {
      try { window.localStorage.removeItem(historyDirectionStorageKey); } catch (e) {}
    }

    function historyDirection(event) {
      var current = currentNavigationIndex();
      var previous = readLastNavigationIndex();
      var direction = readExpectedHistoryDirection();
      if (!direction && isHistoryTraversal(event) && current !== null && previous !== null) {
        if (current > previous) direction = 'forward';
        else if (current < previous) direction = 'back';
      }
      writeLastNavigationIndex(current);
      clearExpectedHistoryDirection();
      return direction;
    }

    /* 11.3: recuperación exclusiva de Adelante en escritorio. Atrás no se toca.
     * Primero conserva el media element restaurado. Solo hace load() si el navegador
     * realmente devolvió el recurso vacío (NETWORK_EMPTY/currentSrc vacío). */
    function recoverForwardDesktop(state) {
      var isMobileNow = mobileQuery ? mobileQuery.matches : window.innerWidth <= 782;
      if (isMobileNow || forwardDesktopRecoveryInProgress || userBlocked || !state || !state.shouldResume) return;
      if (!audio.paused && !audio.ended) return;

      forwardDesktopRecoveryInProgress = true;
      playIntent = true;
      pendingSavedResume = true;
      showButton();
      clearStartGuard();
      starting = false;
      clearResumeRetry();

      var wantedIndex = findSavedTrackIndex(state);
      if (wantedIndex < 0) wantedIndex = trackIndex;
      var targetTime = savedTargetTime(state);
      var wantedTrack = cfg.playlist[safeIndex(wantedIndex)];
      if (!wantedTrack || !wantedTrack.url) { forwardDesktopRecoveryInProgress = false; return; }

      function syncForwardPosition() {
        trackIndex = safeIndex(wantedIndex);
        try {
          if (Number.isFinite(audio.duration) && audio.duration > 0) targetTime = Math.min(targetTime, Math.max(0, audio.duration - 0.05));
          if (Math.abs((audio.currentTime || 0) - targetTime) > 0.3) audio.currentTime = Math.max(0, targetTime);
        } catch (e) {}
        audio.muted = userMuted;
        applyVolume(getRunVolume());
        syncVolumeUI();
      }

      function directPlay() {
        if (!pageActive || userBlocked || (pauseWhenInactive && document.hidden)) return;
        syncForwardPosition();
        var promise;
        try { promise = audio.play(); } catch (e) { return; }
        if (promise && typeof promise.then === 'function') {
          promise.then(function () {
            forwardDesktopRecoveryInProgress = false;
            onStarted(true);
          }).catch(function () {});
        } else {
          forwardDesktopRecoveryInProgress = false;
          onStarted(true);
        }
      }

      var currentUrl = '';
      try { currentUrl = audio.currentSrc || source.src || ''; } catch (e) {}
      var resourceEmpty = audio.networkState === 0 || !currentUrl;
      var wrongTrack = currentUrl && wantedTrack.url && currentUrl !== wantedTrack.url;

      if (wrongTrack || resourceEmpty) {
        trackIndex = safeIndex(wantedIndex);
        source.src = wantedTrack.url;
        source.type = mimeFromUrl(wantedTrack.url);
        audio.addEventListener('loadedmetadata', directPlay, { once: true });
        audio.addEventListener('canplay', directPlay, { once: true });
        try { audio.load(); } catch (e) {}
      } else {
        directPlay();
      }

      [25, 90, 220, 520, 1100].forEach(function (wait) {
        window.setTimeout(function () {
          if (!audio.paused && !audio.ended) { forwardDesktopRecoveryInProgress = false; return; }
          directPlay();
        }, wait);
      });
      window.setTimeout(function () { forwardDesktopRecoveryInProgress = false; }, 1600);
    }

    function resumeNavigationState(latest, delay) {
      prepareNavigationResume();
      latest = latest || freshestNavigationState();
      if (latest && latest.shouldResume) {
        playIntent = true;
        showButton();

        /* 11.1: nunca hacemos audio.load() al restaurar Atrás/Adelante.
         * Si BFCache dejó el media element vacío, audio.play() inicia la carga sin
         * destruir la continuidad/autorización de reproducción de la sesión. */
        applyStateToPlayer(latest, false, false);
        if (!(pauseWhenInactive && document.hidden)) {
          pendingSavedResume = true;
          clearStartGuard();
          starting = false;
          tryStart(false, true);
          queueNavigationResumeBurst();
          scheduleResumeRetry(delay || 35);
        }
      } else if (playIntent && !(pauseWhenInactive && document.hidden)) {
        pendingSavedResume = true;
        clearStartGuard();
        starting = false;
        tryStart(false, true);
        queueNavigationResumeBurst();
        scheduleResumeRetry(delay || 35);
      }

      if (!audio.paused && !audio.ended) {
        ensureAnalyser();
        startVisualizer();
      }
    }

    function ensureContinuousPlayback() {
      if (!pageActive || userBlocked || !playIntent || pausedByInactivity || restoringState) return;
      if (pauseWhenInactive && document.hidden) return;
      if (!audio.paused || audio.ended || starting) return;
      var now = Date.now();
      if (now - lastWatchdogRecovery < 450) return;
      lastWatchdogRecovery = now;
      var latest = freshestNavigationState();
      if (latest && latest.shouldResume) {
        pendingSavedResume = true;
        applyStateToPlayer(latest, true, false);
      } else {
        pendingSavedResume = true;
        tryStart(false, true);
      }
    }

    /* Si el navegador pausa el media element al restaurar historial, no dejamos
     * que quede detenido esperando otro clic. Solo actúa mientras la sesión quería
     * seguir reproduciendo; no cambia mute, volumen ni selección del usuario. */
    playbackWatchdogTimer = window.setInterval(ensureContinuousPlayback, 500);

    if ('onpageswap' in window) {
      window.addEventListener('pageswap', function () {
        navigationInProgress = true;
        clearInactivityTimer();
        persistPlaybackState(true);
      });
    }

    window.addEventListener('pagehide', function () {
      /* Cambiar de página / Atrás / Adelante NO se trata como inactividad.
       * Guardamos el estado pero no pausamos manualmente el audio: si la página
       * entra en BFCache el navegador puede conservar el reproductor tal cual. */
      navigationInProgress = true;
      clearInactivityTimer();
      persistPlaybackState(true);
      pageActive = false;
      stopFade();
      stopIconCycle(true);
      clearResumeRetry();
      /* 11.1: liberamos solo el analizador auxiliar. El audio principal no se
       * pausa ni se recarga, y al restaurar se vuelve a conectar el visualizador. */
      resetAnalyserForRestore();
    });
    /* No usamos beforeunload: además de ser redundante con pagehide/enlaces,
     * puede volver menos fiable la BFCache en algunos navegadores. */
    window.addEventListener('pageshow', function (event) {
      navigationInProgress = false;
      clearInactivityTimer();
      pageActive = true;
      clearStartGuard();
      starting = false;
      var direction = historyDirection(event);
      var latest = freshestNavigationState();
      if (latest && latest.shouldResume) showButton();

      if (pauseWhenInactive && pausedByInactivity && !document.hidden) {
        pausedByInactivity = false;
      }
      if ((latest && latest.shouldResume) || playIntent) {
        resumeNavigationState(latest, 35);
        [0, 40, 140, 360, 900].forEach(function (wait) {
          window.setTimeout(function () {
            var freshest = freshestNavigationState();
            if ((freshest && freshest.shouldResume) || playIntent) resumeNavigationState(freshest, 30);
            ensureContinuousPlayback();
          }, wait);
        });
        if (window.requestAnimationFrame) window.requestAnimationFrame(function () {
          var freshest = freshestNavigationState();
          if ((freshest && freshest.shouldResume) || playIntent) resumeNavigationState(freshest, 25);
        });

        /* Solo Adelante en escritorio: primero dejamos actuar la recuperación
         * normal (la misma que ya funciona para Atrás). Si BFCache sigue dejando
         * el audio pausado, refrescamos exclusivamente ese media element. */
        if (direction === 'forward') {
          [40, 180, 520, 1100].forEach(function (wait) {
            window.setTimeout(function () {
              var freshest = freshestNavigationState();
              if (audio.paused && freshest && freshest.shouldResume) recoverForwardDesktop(freshest);
            }, wait);
          });
        }
      }
    });

    document.addEventListener('visibilitychange', function () {
      if (document.hidden) {
        if (pauseWhenInactive) scheduleInactivityPause();
        return;
      }
      clearInactivityTimer();
      navigationInProgress = false;
      if (pauseWhenInactive && pausedByInactivity && document.hasFocus()) {
        resumeAfterInactivity();
        return;
      }
      var latest = freshestNavigationState();
      if ((latest && latest.shouldResume) || playIntent) resumeNavigationState(latest, 50);
    });

    if (pauseWhenInactive) window.addEventListener('blur', scheduleInactivityPause);
    window.addEventListener('focus', function () {
      clearInactivityTimer();
      navigationInProgress = false;
      if (pauseWhenInactive && pausedByInactivity && !document.hidden) {
        resumeAfterInactivity();
        return;
      }
      if (!document.hidden && playIntent) {
        var latest = freshestNavigationState();
        resumeNavigationState(latest, 40);
      }
    });

    if (window.navigation && typeof window.navigation.addEventListener === 'function') {
      window.navigation.addEventListener('navigate', function (event) {
        if (event && event.sameDocument) return;
        try {
          if (event && event.navigationType === 'traverse' && event.destination && window.navigation.currentEntry) {
            var fromIndex = Number(window.navigation.currentEntry.index);
            var toIndex = Number(event.destination.index);
            if (Number.isFinite(fromIndex) && Number.isFinite(toIndex)) {
              if (toIndex > fromIndex) writeExpectedHistoryDirection('forward');
              else if (toIndex < fromIndex) writeExpectedHistoryDirection('back');
            }
          }
        } catch (e) {}
        navigationInProgress = true;
        clearInactivityTimer();
        persistPlaybackState(true);
      });
    }

    window.addEventListener('pagereveal', function () {
      navigationInProgress = false;
      clearInactivityTimer();
      pageActive = true;
      var latest = freshestNavigationState();
      if ((latest && latest.shouldResume) || playIntent) resumeNavigationState(latest, 40);
    });

    window.addEventListener('popstate', function () {
      [0, 35, 120, 320].forEach(function (wait) {
        window.setTimeout(function () {
          var latest = freshestNavigationState();
          if ((latest && latest.shouldResume) || playIntent) resumeNavigationState(latest, 30);
        }, wait);
      });
    });

    document.addEventListener('click', function (event) {
      var node = event.target;
      while (node && node !== document && node.tagName !== 'A') node = node.parentNode;
      if (!node || node.tagName !== 'A' || !node.href) return;
      try {
        var targetUrl = new URL(node.href, window.location.href);
        if (targetUrl.origin === window.location.origin && !node.hasAttribute('download') && (node.target || '').toLowerCase() !== '_blank') {
          navigationInProgress = true;
          clearInactivityTimer();
          persistPlaybackState(true);
        }
      } catch (e) {}
    }, true);

    document.addEventListener('submit', function () { navigationInProgress = true; clearInactivityTimer(); persistPlaybackState(true); }, true);

    function startFromScroll() {
      if (userBlocked || (!audio.paused && !audio.ended)) return;
      ensureMobileVolumeEngine();
      var now = Date.now();
      if (now - lastAttempt < 650) return;
      lastAttempt = now;
      tryStart(false);
    }

    window.addEventListener('scroll', startFromScroll, { passive: true });
    window.addEventListener('wheel', startFromScroll, { passive: true });
    window.addEventListener('touchmove', startFromScroll, { passive: true });

    document.addEventListener('pointerdown', startFromGesture, true);
    document.addEventListener('touchstart', startFromGesture, true);
    document.addEventListener('mousedown', startFromGesture, true);
    document.addEventListener('keydown', function (event) {
      if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'PageDown') { ensureMobileVolumeEngine(); ensureAnalyser(); tryStart(true); }
    }, true);

    var lastButtonActivation = 0;
    function activateMusicButton(event) {
      if (event) {
        event.preventDefault();
        event.stopPropagation();
      }
      var now = Date.now();
      if (now - lastButtonActivation < 280) return;
      lastButtonActivation = now;
      button.classList.add('musica-no-hover');

      /* 11.0: el panel se abre antes de inicializar AudioContext/analizador.
       * El primer toque móvil queda instantáneo y la parte pesada ocurre después. */
      setPanelOpen(!panelOpen);

      window.setTimeout(function () {
        ensureMobileVolumeEngine();
        if (playIntent && (audio.paused || audio.ended)) {
          ensureAnalyser();
          pendingSavedResume = true;
          clearStartGuard();
          starting = false;
          tryStart(true, true);
        } else if (!audio.paused && !audio.ended) {
          ensureAnalyser();
          startVisualizer();
        }
      }, 0);
    }

    /* En táctil abrimos en pointerdown para que no espere al ciclo completo del tap.
     * Click queda como fallback para mouse, teclado y navegadores antiguos. */
    button.addEventListener('pointerdown', function (event) {
      event.stopPropagation();
      if (event.pointerType === 'touch' || event.pointerType === 'pen') activateMusicButton(event);
    }, true);
    button.addEventListener('touchstart', function (event) {
      event.stopPropagation();
      if (!window.PointerEvent) activateMusicButton(event);
    }, { passive: false, capture: true });
    button.addEventListener('mousedown', function (event) { event.stopPropagation(); }, true);
    button.addEventListener('pointerleave', function () { button.classList.remove('musica-no-hover'); });
    button.addEventListener('mouseenter', function () { if (!button.matches(':active')) button.classList.remove('musica-no-hover'); });
    button.addEventListener('click', activateMusicButton, false);

    ['pointerdown','touchstart','mousedown','click'].forEach(function (type) {
      volumePanel.addEventListener(type, function (event) { event.stopPropagation(); }, false);
    });

    muteButton.addEventListener('click', function (event) {
      event.preventDefault();
      event.stopPropagation();
      ensureMobileVolumeEngine();
      userMuted = !userMuted;
      audio.muted = userMuted;
      if (!userMuted && Number(volumeRange.value) <= 0) {
        manualVolume = Math.max(0.01, percentToVolume(cfg.runVolumePercent));
        applyVolume(manualVolume);
      }
      updateButton();
      if (!userMuted) reactivateVisuals();
      else document.documentElement.classList.remove('musica-44-active');
      syncVolumeUI();
      persistUserAudioPrefs();
      persistPlaybackState();
      try { muteButton.blur(); } catch (e) {}
    });

    volumeRange.addEventListener('input', function (event) {
      event.stopPropagation();
      ensureMobileVolumeEngine();
      stopFade();
      var wasMuted = userMuted || audio.muted;
      var percent = Math.max(0, Math.min(100, Number(this.value || 0)));
      manualVolume = percent / 100;
      applyVolume(manualVolume);
      userMuted = percent <= 0;
      audio.muted = userMuted;
      updateButton();
      if (wasMuted && !userMuted) reactivateVisuals();
      else if (userMuted) document.documentElement.classList.remove('musica-44-active');
      syncVolumeUI();
      persistUserAudioPrefs();
      persistPlaybackState();
    });

    document.addEventListener('pointerdown', function (event) {
      if (!panelOpen) return;
      if (event.target === button || button.contains(event.target) || event.target === volumePanel || volumePanel.contains(event.target)) return;
      setPanelOpen(false);
    }, true);


    var lastPersistAt = 0;
    audio.addEventListener('playing', function () {
      clearResumeRetry();
      if (!fadeFrame) applyVolume(getRunVolume());
      syncVolumeUI();
      playIntent = true;
      showButton();
      updateButton();
      ensureAnalyser();
      startVisualizer();
      startIconCycle();
      persistPlaybackState();
    });
    audio.addEventListener('pause', function () {
      updateButton();
      stopVisualizer(true);
      stopIconCycle(true);
      /* Una pausa automática durante navegación no convierte la sesión en pausada. */
      if (!restoringState && pageActive && !navigationInProgress) persistPlaybackState();
    });
    audio.addEventListener('timeupdate', function () {
      var now = Date.now();
      if (pageActive && now - lastPersistAt >= 1000) { lastPersistAt = now; persistPlaybackState(); }
    });

    audio.addEventListener('loadedmetadata', function () {
      if (manualVolume === null) applyVolume(getRunVolume());
      syncVolumeUI();
    });

    audio.addEventListener('error', function () {
      starting = false;
      stopVisualizer(true);
      stopIconCycle(true);
      resetAnalyserForRestore();
      if (cfg.playlist.length < 2) return;
      var next = cfg.shuffle ? randomTrack(trackIndex) : trackIndex + 1;
      if (next >= cfg.playlist.length) next = 0;
      if (loadTrack(next) && !userBlocked) tryStart(false);
    });

    audio.addEventListener('ended', function () {
      stopFade();
      stopVisualizer(true);
      stopIconCycle(true);
      /* 11.3: al cambiar de canción la captura del analizador anterior puede quedar
       * finalizada. La recreamos para que gráfico, onda y neón vuelvan a moverse. */
      resetAnalyserForRestore();
      if (userBlocked) return;

      if (cfg.playlist.length === 1) {
        if (cfg.repeat) {
          audio.currentTime = 0;
          playIntent = true;
          tryStart(false, true);
        } else {
          playIntent = false;
          persistPlaybackState();
        }
        return;
      }

      var next = cfg.shuffle ? randomTrack(trackIndex) : trackIndex + 1;
      if (next >= cfg.playlist.length) {
        if (!cfg.repeat) {
          playIntent = false;
          persistPlaybackState();
          return;
        }
        next = 0;
      }
      if (loadTrack(next)) {
        playIntent = true;
        tryStart(false, true);
      }
    });
  });
})();
</script>
<!-- /musica-90 -->
