<!doctype html>

<html lang="es">

<head>

  <meta charset="utf-8" />

  <meta name="viewport" content="width=device-width,initial-scale=1" />

  <title>Audio Player</title>

  <style>

    :root{

      --bg:#ffffff; --text:#111; --muted:#6b7280; --line:#e5e7eb;

      --chip:#f3f4f6; --chip2:#eef2ff;

      --radius:18px;

    }

    *{box-sizing:border-box}

    body{margin:0;background:var(--bg);color:var(--text);font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial}

    .wrap{max-width:860px;margin:22px auto;padding:0 14px}

    .panel{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}

    .top{

      display:flex;align-items:center;justify-content:space-between;gap:12px;

      padding:14px 14px;border-bottom:1px solid var(--line);background:#fafafa;

    }

    .title{font-weight:600;font-size:14px}

    .now{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:60vw}

    .controls{display:flex;align-items:center;gap:10px}

    .btn{

      border:1px solid var(--line);background:#fff;border-radius:999px;

      width:40px;height:40px;display:grid;place-items:center;cursor:pointer;

      user-select:none;

    }

    .btn:active{transform:translateY(1px)}

    .pill{border:1px solid var(--line);background:#fff;border-radius:999px;padding:6px 10px;font-size:12px;color:var(--muted)}

    input[type="range"]{width:140px}


    .progress{padding:10px 14px;border-bottom:1px solid var(--line);background:#fff}

    .seek{width:100%}


    .list{display:block;background:#fff}

    .row{

      display:grid;grid-template-columns: 44px 1fr 90px;

      align-items:center;gap:12px;

      padding:10px 14px;border-bottom:1px solid var(--line);

    }

    .row:last-child{border-bottom:0}

    .playcell{display:flex;align-items:center;justify-content:center}

    .mini{

      width:34px;height:34px;border-radius:999px;border:1px solid var(--line);

      display:grid;place-items:center;cursor:pointer;background:#fff;

    }

    .mini:active{transform:translateY(1px)}

    .name{font-size:13px;font-weight:600}

    .sub{font-size:12px;color:var(--muted)}

    .time{font-variant-numeric:tabular-nums;font-size:12px;color:var(--muted);text-align:right}

    .active{background:linear-gradient(0deg, var(--chip2), var(--chip2));}

    .footer{padding:10px 14px;border-top:1px solid var(--line);background:#fafafa;font-size:12px;color:var(--muted)}

    audio{display:none}

  </style>

</head>

<body>

  <div class="wrap">

    <div class="panel">

      <div class="top">

        <div>

          <div class="title">Player</div>

          <div class="now" id="now">Listo</div>

        </div>


        <div class="controls">

          <div class="btn" id="prev" title="Anterior">⏮</div>

          <div class="btn" id="play" title="Play/Pause">▶️</div>

          <div class="btn" id="next" title="Siguiente">⏭</div>

          <span class="pill">Vol</span>

          <input id="vol" type="range" min="0" max="1" step="0.01" value="1" />

        </div>

      </div>


      <div class="progress">

        <input class="seek" id="seek" type="range" min="0" max="1000" value="0" />

        <div style="display:flex;justify-content:space-between;margin-top:6px">

          <span class="sub" id="tcur">0:00</span>

          <span class="sub" id="tdur">0:00</span>

        </div>

      </div>


      <div class="list" id="list"></div>


      <div class="footer">Tip: si Canva no deja incrustar, usa el enlace de Cloudflare Pages (pages.dev).</div>

    </div>

  </div>


  <audio id="audio" preload="metadata"></audio>


  <script>

    // Tus canciones (rutas exactamente como en /audio/)

    const tracks = [

      { title: "Basshouse",        file: "audio/01-basshouse-mixing.mp3" },

      { title: "DnB",              file: "audio/02-dnb-mixing.mp3" },

      { title: "R&B Latin",        file: "audio/03-rb-latin-mixing.mp3" },

      { title: "DnB Latin",        file: "audio/04-dnb-latin-mix.mp3" },

      { title: "Garage UK",        file: "audio/05-garage-uk-mixing.mp3" },

      { title: "Acid House",       file: "audio/06-acid-house-mixing.mp3" },

      { title: "Reggaeton",        file: "audio/07-reggaeton-mixing.mp3" },

      { title: "House UK",         file: "audio/08-house-uk-mixing.mp3" },

      { title: "House UK 2",       file: "audio/09-house-uk-2-mixing.mp3" },

      { title: "Synthwave",        file: "audio/10-synthwave-mixing.mp3" },

      { title: "UK House",         file: "audio/11-uk-house-mixing.mp3" },

      { title: "Lofi 1",           file: "audio/12-lofi-1-mixing.mp3" },

      { title: "Lofi",             file: "audio/13-lofi-mixing.mp3" },

      // ojo: este aún tiene espacios en tu screenshot → renómbralo a 14-lofi-mixing-02.mp3

      { title: "Lofi 2",           file: "audio/14-lofi-mixing-02.mp3" },

      { title: "Jazz",             file: "audio/15-jazz-mixing.mp3" },

      { title: "Ambient 1",        file: "audio/16-ambient-mixing-01.mp3" },

      { title: "Ambient",          file: "audio/17-ambient-mixing.mp3" },

    ];


    const audio = document.getElementById("audio");

    const list  = document.getElementById("list");

    const now   = document.getElementById("now");

    const play  = document.getElementById("play");

    const prev  = document.getElementById("prev");

    const next  = document.getElementById("next");

    const vol   = document.getElementById("vol");

    const seek  = document.getElementById("seek");

    const tcur  = document.getElementById("tcur");

    const tdur  = document.getElementById("tdur");


    let i = 0;

    let seeking = false;


    function fmt(s){

      if (!isFinite(s)) return "0:00";

      s = Math.max(0, Math.floor(s));

      const m = Math.floor(s/60);

      const r = String(s%60).padStart(2,"0");

      return `${m}:${r}`;

    }


    function render(){

      list.innerHTML = "";

      tracks.forEach((t, idx) => {

        const row = document.createElement("div");

        row.className = "row" + (idx===i ? " active" : "");

        row.innerHTML = `

          <div class="playcell">

            <div class="mini" data-idx="${idx}" title="Reproducir">${idx===i && !audio.paused ? "⏸" : "▶️"}</div>

          </div>

          <div>

            <div class="name">${String(idx+1).padStart(2,"0")} · ${t.title}</div>

            <div class="sub">${t.file}</div>

          </div>

          <div class="time" id="time-${idx}">--:--</div>

        `;

        row.querySelector(".mini").onclick = () => {

          if (idx !== i) load(idx, true);

          else toggle();

        };

        list.appendChild(row);

      });

    }


    function setNow(){

      now.textContent = `Sonando: ${tracks[i].title}`;

    }


    function load(idx, autoplay=false){

      i = idx;

      audio.src = tracks[i].file;

      setNow();

      render();

      if (autoplay) audio.play();

      syncPlay();

    }


    function syncPlay(){

      play.textContent = audio.paused ? "▶️" : "⏸";

      // actualiza iconos mini sin re-render completo

      [...document.querySelectorAll(".mini")].forEach((el) => {

        const idx = Number(el.dataset.idx);

        el.textContent = (idx===i && !audio.paused) ? "⏸" : "▶️";

      });

    }


    function toggle(){

      if (!audio.src) load(i,false);

      if (audio.paused) audio.play(); else audio.pause();

      syncPlay();

    }


    play.onclick = toggle;

    prev.onclick = () => load((i-1+tracks.length)%tracks.length, true);

    next.onclick = () => load((i+1)%tracks.length, true);


    vol.oninput = () => audio.volume = Number(vol.value);


    audio.addEventListener("loadedmetadata", () => {

      tdur.textContent = fmt(audio.duration);

      // si quieres, aquí podríamos precargar duraciones por pista (más adelante)

    });


    audio.addEventListener("timeupdate", () => {

      if (!seeking) {

        const v = audio.duration ? (audio.currentTime / audio.duration) * 1000 : 0;

        seek.value = String(Math.floor(v));

      }

      tcur.textContent = fmt(audio.currentTime);

      tdur.textContent = fmt(audio.duration);

    });


    seek.addEventListener("input", () => { seeking = true; });

    seek.addEventListener("change", () => {

      const p = Number(seek.value) / 1000;

      if (audio.duration) audio.currentTime = p * audio.duration;

      seeking = false;

    });


    audio.addEventListener("play", syncPlay);

    audio.addEventListener("pause", syncPlay);

    audio.addEventListener("ended", () => next.click());


    // IMPORTANTE: tu pista 14 en la captura aún tiene espacios.

    // Renómbrala a: 14-lofi-mixing-02.mp3 para que funcione con este HTML.


    render();

    load(0, false);

  </script>

</body>

</html>