/**
* Klonkt Audio Player — v9 mini-player + Spotify-style sheet.
*
* Two surfaces:
* 1. .audio-player — bottom strip: cover + meta + controls + progress + volume
* 2. .audio-sheet — full-height now-playing panel (slides up from bottom)
*
* Features:
* - Click cover/meta on mini-player → open sheet
* - Sheet handle (pill) or backdrop click → close
* - Touch swipe-down on the drag-zone → close (mobile only; desktop has the X)
* - Reads data-pcms-track-url + data-pcms-track + data-pcms-album from posts
* - body.has-audio-player adds bottom padding when player visible
* - body.audio-sheet-locked prevents body scroll when sheet open
* - Survives HTMX swaps + history-restores via event delegation on document.body
*
* Singleton — guards against double-init.
*/
(function() {
if (window.pcmsAudioPlayer) return;
const SVG = {
play: '',
pause: '',
prev: '',
next: '',
vol: '',
mute: '',
musicNote: '',
};
// ============================================================
// 1. Build DOM
// ============================================================
const root = document.createElement('aside');
root.id = 'pcms-audio-player';
root.className = 'audio-player';
root.setAttribute('aria-label', 'Audio speler');
root.innerHTML = `
`;
document.body.appendChild(root);
// FIX: Move .audio-sheet out of the .audio-player root so its
// position:fixed is anchored to the viewport, not to the mini-bar.
// The mini-bar has backdrop-filter, which makes it a containing
// block for fixed descendants — that broke the sheet's left/right/top/bottom.
const _detachedSheet = root.querySelector('.audio-sheet');
if (_detachedSheet) document.body.appendChild(_detachedSheet);
// ============================================================
// 2. Element references
// ============================================================
const $ = (id) => document.getElementById(id);
const audio = $('audio-element');
const cover = $('audio-cover');
const titleEl = $('audio-title');
const artistEl = $('audio-artist');
const seek = $('audio-seek');
const seekFill = $('audio-seek-fill');
const currentEl = $('audio-current');
const totalEl = $('audio-total');
const playBtn = $('audio-play');
const prevBtn = $('audio-prev');
const nextBtn = $('audio-next');
const muteBtn = $('audio-mute');
const volumeSlider = $('audio-volume');
const expandTrigger = $('audio-expand-trigger');
const sheet = $('audio-sheet');
const sheetBackdrop = $('audio-sheet-backdrop');
const sheetPanel = sheet.querySelector('.audio-sheet-panel');
const sheetClose = $('audio-sheet-close');
const sheetCover = $('audio-sheet-cover');
const sheetTitle = $('audio-sheet-title');
const sheetArtist = $('audio-sheet-artist');
const sheetAlbum = $('audio-sheet-album');
const sheetSeek = $('audio-sheet-seek');
const sheetSeekFill = $('audio-sheet-seek-fill');
const sheetCurrent = $('audio-sheet-current');
const sheetTotal = $('audio-sheet-total');
const sheetPlay = $('audio-sheet-play');
const sheetPrev = $('audio-sheet-prev');
const sheetNext = $('audio-sheet-next');
const sheetQueue = $('audio-sheet-queue');
const sheetQueueList = $('audio-sheet-queue-list');
const dragZone = $('audio-sheet-drag-zone');
// ============================================================
// 3. State
// ============================================================
let queue = [];
let currentIndex = 0;
let isPlaying = false;
let albumName = '';
// Playback pipeline. We fetch each track's bytes ourselves (X-Audio-Player
// gate; no plain media URL is ever exposed to the page) and feed them to the
//