Index: src/assets/css/embed.css
===================================================================
--- src/assets/css/embed.css	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/assets/css/embed.css	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -119,40 +119,4 @@
   width: 320px;
   height: 60px;
-  opacity: 0;
-  pointer-events: none;
-}
-/* Verborgen YouTube-audio-speler ván de site-audiospeler (onderbalk). Off-screen
- * met echte grootte zodat de browser 'm niet pauzeert; alleen het geluid telt. */
-#pcms-yt-host {
-  position: absolute;
-  left: -99999px;
-  top: 0;
-  width: 320px;
-  height: 180px;
-  opacity: 0;
-  pointer-events: none;
-}
-/* YouTube-afspeellijst als album-kaart: geen losse embed-card-chrome, de
- * .post-album-stijl (uit style.css) stuurt de weergave. */
-.pcms-ytalbum { background: none; border: 0; padding: 0; margin: 1.5rem 0; }
-.pcms-ytalbum-msg { padding: .75rem 1rem; color: var(--ink-soft, #6b6560); font-size: .9rem; }
-
-/* Audio-only embed-kaart die nu via de onderbalk speelt = launcher-hint. */
-.pcms-embed-elsewhere { opacity: .9; }
-.pcms-embed-elsewhere .pcms-embed-title::after {
-  content: ' — speelt in de speler ↓';
-  font-weight: normal;
-  opacity: .6;
-  font-size: .85em;
-}
-
-/* Audio-only YouTube: de YT-speler draait verborgen (off-screen) maar moet een
- * echte grootte houden, anders pauzeert de browser 'm. Alleen het geluid telt. */
-.pcms-embed-card--youtube.pcms-embed-audio-mode .pcms-embed-mount {
-  position: absolute;
-  left: -99999px;
-  top: 0;
-  width: 320px;
-  height: 180px;
   opacity: 0;
   pointer-events: none;
Index: src/assets/js/audio-player.js
===================================================================
--- src/assets/js/audio-player.js	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/assets/js/audio-player.js	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -289,100 +289,4 @@
   });
 
-  // ============================================================
-  // 4a. YouTube-backend — speelt YT-AUDIO via een verborgen IFrame-speler in de
-  // (persistente) speler-root. Zo speelt YouTube net als de site-tracks door bij
-  // htmx-navigatie en is 't bedienbaar in de onderbalk. Video wordt niet getoond.
-  // ============================================================
-  let ytMode = false, ytPlayer = null, ytReady = false, ytApiLoading = null, ytTick = null;
-
-  function loadYTApi() {
-    if (window.YT && window.YT.Player) return Promise.resolve(window.YT);
-    if (ytApiLoading) return ytApiLoading;
-    ytApiLoading = new Promise((resolve) => {
-      const prev = window.onYouTubeIframeAPIReady;
-      window.onYouTubeIframeAPIReady = function () { if (prev) { try { prev(); } catch (e) {} } resolve(window.YT); };
-      if (!document.querySelector('script[src*="youtube.com/iframe_api"]')) {
-        const s = document.createElement('script'); s.src = 'https://www.youtube.com/iframe_api'; s.async = true; document.head.appendChild(s);
-      }
-      setTimeout(() => { if (window.YT && window.YT.Player) resolve(window.YT); }, 8000);
-    });
-    return ytApiLoading;
-  }
-
-  function ensureYT() {
-    if (ytPlayer) return Promise.resolve(ytPlayer);
-    return loadYTApi().then((YT) => new Promise((resolve) => {
-      if (!YT || !YT.Player) { resolve(null); return; }
-      let host = document.getElementById('pcms-yt-host');
-      if (!host) {
-        host = document.createElement('div'); host.id = 'pcms-yt-host';
-        const m = document.createElement('div'); m.id = 'pcms-yt-mount'; host.appendChild(m);
-        root.appendChild(host);
-      }
-      ytPlayer = new YT.Player('pcms-yt-mount', {
-        host: 'https://www.youtube-nocookie.com',
-        playerVars: { controls: 0, playsinline: 1, rel: 0, modestbranding: 1, iv_load_policy: 3, origin: window.location.origin },
-        events: {
-          onReady: () => { ytReady = true; try { ytPlayer.setVolume(audio.muted ? 0 : Math.round(audio.volume * 100)); } catch (e) {} resolve(ytPlayer); },
-          onStateChange: onYTState,
-        },
-      });
-      setTimeout(() => resolve(ytPlayer), 8000);
-    }));
-  }
-
-  function onYTState(e) {
-    if (!ytMode) return;
-    const s = e.data;  // 1 playing, 2 paused, 0 ended
-    if (s === 1) {
-      isPlaying = true; root.classList.add('is-playing'); root.classList.remove('audio-needs-tap');
-      // We startten gedempt (autoplay-policy) → nu 't speelt het geluid terugzetten,
-      // tenzij de gebruiker zelf gedempt heeft.
-      try { if (!audio.muted) { ytPlayer.unMute(); ytPlayer.setVolume(Math.round(audio.volume * 100)); } } catch (e) {}
-      mediaRegistry().setActive(registrySelf); startYTTick(); pullYTMeta();
-    } else if (s === 2) {
-      isPlaying = false; root.classList.remove('is-playing'); stopYTTick();
-    } else if (s === 0) {
-      stopYTTick();
-      // Bij een afspeellijst regelt YouTube zelf het doorschakelen → niet dubbel.
-      const t = queue[currentIndex];
-      if (!(t && t.ytList)) next();
-    }
-  }
-
-  function startYTTick() {
-    if (ytTick) return;
-    ytTick = setInterval(() => {
-      if (!ytPlayer || !ytMode) return;
-      try { updateProgressUI(ytPlayer.getCurrentTime() || 0, ytPlayer.getDuration() || 0); } catch (e) {}
-    }, 250);
-  }
-  function stopYTTick() { if (ytTick) { clearInterval(ytTick); ytTick = null; } }
-
-  function pullYTMeta() {
-    try {
-      const t = queue[currentIndex]; if (!t || (!t.yt && !t.ytList) || !ytPlayer.getVideoData) return;
-      const vd = ytPlayer.getVideoData() || {};
-      // Bij een afspeellijst wisselt de titel per nummer → altijd bijwerken.
-      if (vd.title && (t.ytList || !t.title || t.title === 'YouTube')) {
-        titleEl.textContent = vd.title; sheetTitle.textContent = vd.title;
-        if (!t.ytList) t.title = vd.title;
-      }
-      if (vd.video_id) {
-        setYtCover(vd.video_id);
-        markPlaying(vd.video_id);  // licht de bijbehorende album-rij op (id="track-<videoId>")
-      }
-    } catch (e) {}
-  }
-
-  // Gedeelde voortgang-UI (beide backends). Audio gebruikt 'timeupdate', YT de tick.
-  function updateProgressUI(cur, dur) {
-    if (!dur || isNaN(dur)) return;
-    const pct = Math.max(0, Math.min(100, (cur / dur) * 100));
-    seekFill.style.width = pct + '%'; sheetSeekFill.style.width = pct + '%';
-    currentEl.textContent = formatTime(cur); totalEl.textContent = formatTime(dur);
-    sheetCurrent.textContent = formatTime(cur); sheetTotal.textContent = formatTime(dur);
-  }
-
   function loadTrack(index, autoplay, metaOnly) {
     if (!queue[index]) {
@@ -392,8 +296,14 @@
     currentIndex = index;
     const t = queue[index];
-    // Metadata + chrome update synchronously (geldt voor beide backends).
-    titleEl.textContent  = t.title  || (t.yt ? 'YouTube' : 'Untitled');
+    if (!t.url) {
+      console.error('[pcms-audio] track has no url', t);
+      return;
+    }
+    console.log('[pcms-audio] loading', t.title, t.url, metaOnly ? '(meta only)' : '');
+    // Metadata + chrome update synchronously so the UI reacts instantly while
+    // the bytes download.
+    titleEl.textContent  = t.title  || 'Untitled';
     artistEl.textContent = t.artist || '';
-    sheetTitle.textContent  = t.title  || (t.yt ? 'YouTube' : 'Untitled');
+    sheetTitle.textContent  = t.title  || 'Untitled';
     sheetArtist.textContent = t.artist || '';
     sheetAlbum.textContent  = albumName || '';
@@ -406,41 +316,4 @@
 
     if (metaOnly) return;
-
-    // YouTube-bron (los nummer óf afspeellijst/album) → verborgen YT-speler.
-    if (t.yt || t.ytList) {
-      ytMode = true;
-      try { audio.pause(); } catch (e) {}
-      loadSeq++; dropPreload();
-      updateProgressUI(0, 1); currentEl.textContent = '0:00'; totalEl.textContent = '0:00';
-      seekFill.style.width = '0%'; sheetSeekFill.style.width = '0%';
-      root.classList.add('audio-loading');
-      ensureYT().then((p) => {
-        if (queue[currentIndex] !== t) return;  // inmiddels andere track gekozen
-        root.classList.remove('audio-loading');
-        if (!p) { onLoadError(new Error('YT API niet beschikbaar'), loadSeq); return; }
-        try {
-          // Gedempt starten = autoplay is ALTIJD toegestaan (YouTube blokkeert
-          // anders het geluid). onYTState ontdempt zodra 't echt speelt.
-          if (autoplay) { try { p.mute(); } catch (e) {} }
-          if (t.ytList) {
-            const idx = t.ytIndex || 0;
-            // listType:'playlist' is vereist voor de object-vorm; zonder dit laadt
-            // (en speelt) de afspeellijst niet betrouwbaar.
-            if (autoplay) p.loadPlaylist({ listType: 'playlist', list: t.ytList, index: idx });
-            else p.cuePlaylist({ listType: 'playlist', list: t.ytList, index: idx });
-          } else {
-            if (autoplay) p.loadVideoById(t.yt); else p.cueVideoById(t.yt);
-          }
-          p.setVolume(audio.muted ? 0 : Math.round(audio.volume * 100));
-        } catch (e) {}
-      });
-      return;
-    }
-
-    // Normale blob-audio track.
-    ytMode = false;
-    stopYTTick();
-    try { if (ytPlayer && ytPlayer.stopVideo) ytPlayer.stopVideo(); } catch (e) {}
-    if (!t.url) { console.error('[pcms-audio] track has no url', t); return; }
 
     const mySeq = ++loadSeq;
@@ -494,9 +367,4 @@
 
   function play() {
-    if (ytMode) {
-      if (ytPlayer && ytReady) { try { ytPlayer.playVideo(); } catch (e) {} }
-      else if (queue[currentIndex]) loadTrack(currentIndex, true);
-      return;
-    }
     if (!audio.src) {
       // Nothing fetched yet (pre-seed showed metadata only, or a load is still
@@ -520,15 +388,11 @@
     }
   }
-  function pause()      { if (ytMode) { try { ytPlayer && ytPlayer.pauseVideo(); } catch (e) {} return; } audio.pause(); }
-  function togglePlay() { if (ytMode) { isPlaying ? pause() : play(); return; } audio.paused ? play() : pause(); }
+  function pause()      { audio.pause(); }
+  function togglePlay() { audio.paused ? play() : pause(); }
   function next() {
-    const t = queue[currentIndex];
-    if (t && t.ytList && ytPlayer && ytMode) { try { ytPlayer.nextVideo(); } catch (e) {} return; }
     if (!queue.length) return;
     loadTrack((currentIndex + 1) % queue.length, true);
   }
   function prev() {
-    const t = queue[currentIndex];
-    if (t && t.ytList && ytPlayer && ytMode) { try { ytPlayer.previousVideo(); } catch (e) {} return; }
     if (!queue.length) return;
     loadTrack(currentIndex === 0 ? queue.length - 1 : currentIndex - 1, true);
@@ -540,6 +404,4 @@
     document.body.classList.remove('has-audio-player');
     closeSheet();
-    ytMode = false; stopYTTick();
-    try { if (ytPlayer && ytPlayer.stopVideo) ytPlayer.stopVideo(); } catch (e) {}
     queue = [];
     albumName = '';
@@ -600,5 +462,5 @@
     return r;
   }
-  const registrySelf = { pause() { try { audio.pause(); } catch (e) {} try { if (ytPlayer && ytPlayer.pauseVideo) ytPlayer.pauseVideo(); } catch (e) {} } };
+  const registrySelf = { pause() { try { audio.pause(); } catch (e) {} } };
 
   // ============================================================
@@ -636,6 +498,12 @@
   audio.addEventListener('volumechange', () => { root.classList.toggle('is-muted', audio.muted || audio.volume === 0); });
   audio.addEventListener('timeupdate', () => {
-    if (ytMode) return;  // YT-voortgang loopt via de tick
-    updateProgressUI(audio.currentTime, audio.duration);
+    if (!audio.duration || isNaN(audio.duration)) return;
+    const pct = (audio.currentTime / audio.duration) * 100;
+    seekFill.style.width = pct + '%';
+    sheetSeekFill.style.width = pct + '%';
+    currentEl.textContent  = formatTime(audio.currentTime);
+    totalEl.textContent    = formatTime(audio.duration);
+    sheetCurrent.textContent = formatTime(audio.currentTime);
+    sheetTotal.textContent   = formatTime(audio.duration);
   });
 
@@ -648,11 +516,7 @@
   function attachSeek(seekEl) {
     seekEl.addEventListener('click', (e) => {
+      if (!audio.duration) return;
       const rect = seekEl.getBoundingClientRect();
       const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
-      if (ytMode) {
-        try { const d = ytPlayer.getDuration() || 0; if (d) ytPlayer.seekTo(ratio * d, true); } catch (e2) {}
-        return;
-      }
-      if (!audio.duration) return;
       audio.currentTime = ratio * audio.duration;
     });
@@ -663,14 +527,8 @@
   audio.volume = 0.8;
   volumeSlider.addEventListener('input', () => {
-    const v = parseInt(volumeSlider.value, 10) || 0;
-    audio.volume = v / 100;
-    if (v > 0) audio.muted = false;
-    if (ytPlayer) { try { ytPlayer.setVolume(v); if (v > 0 && ytPlayer.unMute) ytPlayer.unMute(); } catch (e) {} }
-  });
-  muteBtn.addEventListener('click', () => {
-    audio.muted = !audio.muted;
-    if (ytPlayer) { try { audio.muted ? ytPlayer.mute() : ytPlayer.unMute(); } catch (e) {} }
-    root.classList.toggle('is-muted', audio.muted);
-  });
+    audio.volume = volumeSlider.value / 100;
+    if (volumeSlider.value > 0) audio.muted = false;
+  });
+  muteBtn.addEventListener('click', () => { audio.muted = !audio.muted; });
 
   // ============================================================
@@ -939,60 +797,6 @@
   // 9. Public API
   // ============================================================
-  // Speel een YouTube-bron als AUDIO af in deze (persistente) site-speler — door
-  // de embed-speler aangeroepen voor een audio-only YouTube-embed. Zo verschijnt
-  // 'ie in de onderbalk én speelt 'ie door bij navigeren.
-  function playYouTube(opts) {
-    if (!opts || (!opts.id && !opts.list)) return;
-    setQueue([{
-      yt: opts.id || null,
-      ytList: opts.list || null,     // YouTube-afspeellijst/album (OLAK…/PL…)
-      ytIndex: opts.index || 0,      // startindex binnen de lijst
-      title: opts.title || 'YouTube',
-      artist: opts.artist || '',
-      cover: opts.cover || '',
-      postUrl: opts.postUrl || '',
-    }], 0);
-    // De scherpe cover + echte titel komen via pullYTMeta() zodra het nummer speelt.
-  }
-
-  // Zet de bar-cover op de thumbnail van een video (mqdefault = balkloos), en
-  // upgrade async naar de scherpe maxresdefault als die bestaat.
-  function setYtCover(videoId) {
-    if (!videoId) return;
-    const mq = 'https://i.ytimg.com/vi/' + videoId + '/mqdefault.jpg';
-    setCoverImage(cover, mq); setCoverImage(sheetCover, mq);
-    try {
-      const maxres = 'https://i.ytimg.com/vi/' + videoId + '/maxresdefault.jpg';
-      const im = new Image();
-      im.onload = () => {
-        if (im.naturalWidth <= 120) return;
-        const cur = ytPlayer && ytPlayer.getVideoData ? (ytPlayer.getVideoData() || {}).video_id : null;
-        if (cur === videoId) { setCoverImage(cover, maxres); setCoverImage(sheetCover, maxres); }
-      };
-      im.src = maxres;
-    } catch (e) {}
-  }
-
-  // Speel een YouTube-AFSPEELLIJST af door 'm te expanderen naar onze eigen queue
-  // van losse YouTube-tracks (elk via loadVideoById = bewezen betrouwbaar; next/
-  // prev/ended lopen via onze queue). items = [{yt,title,cover,postUrl}, …].
-  function playYouTubeList(items, startIndex) {
-    if (!Array.isArray(items) || !items.length) return;
-    setQueue(items.map((it) => ({
-      yt: it.yt,
-      title: it.title || 'YouTube',
-      artist: it.artist || '',
-      cover: it.cover || '',
-      postUrl: it.postUrl || '',
-    })), startIndex || 0);
-  }
-
-  // Maak de verborgen YT-speler vast aan (zonder iets te spelen), zodat 'ie bij de
-  // eerste klik al klaar staat → loadVideoById valt dan binnen de user-gesture en
-  // YouTube's autoplay-policy blokkeert het niet.
-  function prewarmYouTube() { try { ensureYT(); } catch (e) {} }
-
   window.pcmsAudioPlayer = {
-    setQueue, play, pause, next, prev, close, openSheet, closeSheet, playYouTube, playYouTubeList, prewarmYouTube,
+    setQueue, play, pause, next, prev, close, openSheet, closeSheet,
     isPlaying: () => isPlaying,
     currentTrack: () => queue[currentIndex] || null,
Index: src/assets/js/embed-player.js
===================================================================
--- src/assets/js/embed-player.js	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/assets/js/embed-player.js	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -162,10 +162,4 @@
     if (!provider) return;
 
-    // Audio-only YouTube met een afspeellijst (?list=…) → album-kaart met tracklijst.
-    if (provider === 'youtube' && el.dataset.embedMode === 'audio') {
-      const lm = url.match(/[?&]list=([A-Za-z0-9_-]+)/);
-      if (lm) { try { buildYtAlbum(el, lm[1]); } catch (e) { console.error('[pcms-embed] yt-album faalde', e); } return; }
-    }
-
     el.classList.add('pcms-embed-card', 'pcms-embed-card--' + provider);
     el.classList.remove('pcms-embed-loading');
@@ -189,18 +183,8 @@
 
     // --- UI ophangen (verschilt per provider-type) ---
-    // Audio-only YouTube (data-embed-mode="audio"): render als audio-kaart met
-    // onze controls; de YT-speler draait verborgen (off-screen) en levert alleen
-    // het geluid. Video blijft de default.
-    const audioOnly = provider === 'youtube' && el.dataset.embedMode === 'audio';
-    if (audioOnly) el.classList.add('pcms-embed-audio-mode');
-    const isVideo = provider === 'youtube' && !audioOnly;
-    // Audio-only YT speelt via de site-onderbalk → geen eigen in-kaart controlebar.
-    const custom = (provider === 'youtube' || provider === 'soundcloud') && !audioOnly;
+    const isVideo = provider === 'youtube';
+    const custom = provider === 'youtube' || provider === 'soundcloud'; // eigen controls
     const poster = provider === 'youtube'
       ? `https://i.ytimg.com/vi/${ytId(ref, url)}/hqdefault.jpg` : '';
-    // 16:9-thumbnail ZONDER zwarte balken (mqdefault) voor de vierkante cover —
-    // hqdefault is 4:3 met letterbox en vult een vierkant niet schoon.
-    const ytThumb = provider === 'youtube'
-      ? `https://i.ytimg.com/vi/${ytId(ref, url)}/mqdefault.jpg` : '';
 
     el.innerHTML = ''
@@ -238,24 +222,4 @@
     let vol = 100;       // huidige volume 0-100 (wordt op de adapter toegepast)
     let preMuteVol = 100;
-    // Audio-only YouTube: zet de thumbnail als albumhoes op de audio-kaart.
-    let ytTitle = '';  // echte videotitel (via same-origin oEmbed-proxy)
-    if (audioOnly && ytThumb) {
-      const art0 = el.querySelector('.pcms-embed-art');
-      if (art0) { art0.style.backgroundImage = `url('${ytThumb}')`; art0.classList.add('has-art'); }
-      // Speler vast aanmaken → eerste klik valt binnen de user-gesture (autoplay).
-      if (window.pcmsAudioPlayer && window.pcmsAudioPlayer.prewarmYouTube) window.pcmsAudioPlayer.prewarmYouTube();
-      // Haal de echte titel op (server-proxy, want YT-oEmbed heeft geen CORS) en
-      // toon 'm i.p.v. "YouTube".
-      fetch('/audio/yt-title?url=' + encodeURIComponent(url))
-        .then((r) => (r.ok ? r.json() : null))
-        .then((d) => {
-          if (d && d.title) {
-            ytTitle = d.title;
-            const tt = el.querySelector('.pcms-embed-title');
-            if (tt) tt.textContent = d.title;
-          }
-        })
-        .catch(() => {});
-    }
 
     function setPlayingUI(on) {
@@ -332,11 +296,4 @@
     // Eerste interactie → adapter mounten + spelen. Daarna toggelt de knop.
     async function ensureMountedAndPlay() {
-      // Audio-only YouTube → speel via de site-audiospeler (onderbalk): zichtbaar
-      // én doorspelen bij navigeren. De inline-kaart is enkel de launcher.
-      if (audioOnly && window.pcmsAudioPlayer && typeof window.pcmsAudioPlayer.playYouTube === 'function') {
-        window.pcmsAudioPlayer.playYouTube({ id: ytId(ref, url), title: ytTitle || undefined, cover: ytThumb, postUrl: location.pathname + location.search });
-        el.classList.add('pcms-embed-elsewhere');
-        return;
-      }
       if (mounted) { if (adapter) adapter.play(); return; }
       mounted = true;
@@ -391,95 +348,4 @@
   }
 
-  // Haal de video-IDs van een YouTube-afspeellijst op via een verborgen,
-  // tijdelijke speler (cuePlaylist → getPlaylist). Geen API-key nodig.
-  function ytPlaylistIds(listId) {
-    return ytApi().then((YT) => new Promise((resolve) => {
-      if (!YT || !YT.Player) { resolve([]); return; }
-      const host = document.createElement('div');
-      host.style.cssText = 'position:absolute;left:-99999px;top:0;width:320px;height:180px;opacity:0;pointer-events:none';
-      const mount = document.createElement('div'); host.appendChild(mount); document.body.appendChild(host);
-      let done = false;
-      const finish = (ids) => { if (done) return; done = true; try { p.destroy(); } catch (e) {} try { host.remove(); } catch (e) {} resolve(ids || []); };
-      const p = new YT.Player(mount, {
-        host: 'https://www.youtube-nocookie.com', playerVars: { playsinline: 1 },
-        events: { onReady: () => {
-          try { p.cuePlaylist({ listType: 'playlist', list: listId }); } catch (e) {}
-          setTimeout(() => { let ids = []; try { ids = p.getPlaylist() || []; } catch (e) {} finish(ids); }, 2500);
-        } },
-      });
-      setTimeout(() => finish([]), 9000);
-    }));
-  }
-
-  // Render een audio-only YouTube-AFSPEELLIJST als album-kaart (zelfde stijl als
-  // de eigen albums) met tracklijst; afspelen loopt via de site-audiospeler.
-  async function buildYtAlbum(el, listId) {
-    el.className = 'folio-embed pcms-ytalbum';  // geen losse card-chrome; .post-album stuurt de stijl
-    const thumb = (id) => `https://i.ytimg.com/vi/${id}/mqdefault.jpg`;
-    el.innerHTML = ''
-      + '<div class="post-album">'
-      +   '<div class="post-album-header">'
-      +     '<button type="button" class="post-album-cover-btn" aria-label="Album afspelen">'
-      +       '<img class="post-album-cover-img" src="" alt="">'
-      +       '<span class="post-album-play-overlay" aria-hidden="true"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 4l12 8-12 8z"/></svg></span>'
-      +     '</button>'
-      +     '<div class="post-album-info">'
-      +       '<h3 class="post-album-title">Album laden…</h3>'
-      +       '<p class="post-album-artist"></p>'
-      +       '<p class="post-album-count">YouTube</p>'
-      +     '</div>'
-      +   '</div>'
-      +   '<ol class="post-album-tracks"><li class="pcms-ytalbum-msg">Tracks laden…</li></ol>'
-      + '</div>';
-    const coverImg = el.querySelector('.post-album-cover-img');
-    const titleEl = el.querySelector('.post-album-title');
-    const countEl = el.querySelector('.post-album-count');
-    const olEl = el.querySelector('.post-album-tracks');
-    const coverBtn = el.querySelector('.post-album-cover-btn');
-
-    // Albumnaam via de oEmbed-proxy (playlist-url).
-    fetch('/audio/yt-title?url=' + encodeURIComponent('https://www.youtube.com/playlist?list=' + listId))
-      .then((r) => (r.ok ? r.json() : null)).then((d) => { if (d && d.title) titleEl.textContent = d.title; }).catch(() => {});
-
-    let ids = [];
-    try { ids = await ytPlaylistIds(listId); } catch (e) { ids = []; }
-    if (!ids.length) { olEl.innerHTML = '<li class="pcms-ytalbum-msg">Kon de afspeellijst niet laden.</li>'; return; }
-    countEl.textContent = ids.length + ' track' + (ids.length === 1 ? '' : 's');
-    if (coverImg) coverImg.src = thumb(ids[0]);
-    // Speler vast aanmaken → eerste klik valt binnen de user-gesture (autoplay).
-    if (window.pcmsAudioPlayer && window.pcmsAudioPlayer.prewarmYouTube) window.pcmsAudioPlayer.prewarmYouTube();
-
-    olEl.innerHTML = ids.map((id, i) =>
-      `<li class="post-album-track-compact" id="track-${id}" data-yt-id="${id}" data-yt-index="${i}">`
-      + `<button type="button" class="pat-row" aria-label="Speel track ${i + 1}">`
-      +   `<span class="pat-cover" style="background-image:url('${thumb(id)}')" aria-hidden="true"></span>`
-      +   `<span class="pat-meta"><span class="pat-title">Track ${i + 1}</span><span class="pat-artist"></span></span>`
-      +   `<span class="pat-duration pat-duration-empty">—:—</span>`
-      + `</button></li>`
-    ).join('');
-
-    // Tracktitels lazy invullen (oEmbed-proxy per video).
-    ids.forEach((id, i) => {
-      fetch('/audio/yt-title?url=' + encodeURIComponent('https://www.youtube.com/watch?v=' + id))
-        .then((r) => (r.ok ? r.json() : null))
-        .then((d) => { if (d && d.title) { const tt = olEl.querySelector(`[data-yt-index="${i}"] .pat-title`); if (tt) tt.textContent = d.title; } })
-        .catch(() => {});
-    });
-
-    function playAt(i) {
-      if (!(window.pcmsAudioPlayer && window.pcmsAudioPlayer.playYouTubeList)) return;
-      // Expandeer naar losse YT-tracks (betrouwbaarder dan loadPlaylist).
-      const items = ids.map((id, j) => ({
-        yt: id,
-        title: (olEl.querySelector(`[data-yt-index="${j}"] .pat-title`) || {}).textContent || ('Track ' + (j + 1)),
-        cover: thumb(id),
-        postUrl: location.pathname + location.search,
-      }));
-      window.pcmsAudioPlayer.playYouTubeList(items, i);
-    }
-    coverBtn.addEventListener('click', () => playAt(0));
-    olEl.addEventListener('click', (e) => { const li = e.target.closest('[data-yt-index]'); if (li) playAt(parseInt(li.dataset.ytIndex, 10) || 0); });
-  }
-
   // ============================================================
   // 4. Adapters — normaliseren de 3 zeer verschillende API's naar 1 vorm.
@@ -503,9 +369,6 @@
           events: {
             onReady() {
-              let d = 0; const meta = {};
-              try { d = player.getDuration() || 0; } catch (e) {}
-              try { const vd = player.getVideoData(); if (vd && vd.title) meta.title = vd.title; } catch (e) {}
-              meta.duration = d;
-              hooks.onReady(meta);
+              let d = 0; try { d = player.getDuration() || 0; } catch (e) {}
+              hooks.onReady({ duration: d });
               resolve({
                 play() { try { player.playVideo(); } catch (e) {} },
Index: src/routes/audio.js
===================================================================
--- src/routes/audio.js	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/routes/audio.js	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -158,29 +158,3 @@
 });
 
-// Same-origin proxy voor de YouTube-titel (oEmbed). YouTube's oEmbed stuurt geen
-// CORS-header, dus de browser kan 'm niet direct fetchen — wij halen 'm server-
-// side op (geen CORS) en cachen 't. Gebruikt door de audio-only YT-embed om de
-// echte videotitel te tonen i.p.v. "YouTube".
-const ytTitleCache = new Map();
-router.get('/yt-title', async (req, res) => {
-  const url = String(req.query.url || '');
-  if (!/^https:\/\/(www\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\//i.test(url)) {
-    return res.status(400).json({ error: 'bad url' });
-  }
-  if (ytTitleCache.has(url)) return res.json({ title: ytTitleCache.get(url) });
-  try {
-    const ac = new AbortController();
-    const timer = setTimeout(() => ac.abort(), 6000);
-    const r = await fetch('https://www.youtube.com/oembed?format=json&url=' + encodeURIComponent(url), { signal: ac.signal });
-    clearTimeout(timer);
-    if (!r.ok) { ytTitleCache.set(url, ''); return res.json({ title: '' }); }
-    const d = await r.json();
-    const title = (d && d.title) ? String(d.title).slice(0, 200) : '';
-    ytTitleCache.set(url, title);
-    res.json({ title });
-  } catch (e) {
-    res.status(502).json({ error: 'fetch failed' });
-  }
-});
-
 export default router;
Index: src/services/AudioEmbedService.js
===================================================================
--- src/services/AudioEmbedService.js	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/services/AudioEmbedService.js	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -67,5 +67,5 @@
       case 'youtube':
         return this.embedPlaceholder('youtube', config.id, 'video',
-          config.url || `https://youtu.be/${config.id}`, config.mode);
+          config.url || `https://youtu.be/${config.id}`);
       case 'soundcloud':
         return this.embedPlaceholder('soundcloud', config.url, 'track', config.url);
@@ -91,10 +91,9 @@
    * ALLE waarden via escape() — post.content_html wordt ongeescaped uitgevoerd.
    */
-  static embedPlaceholder(provider, ref, type, url, mode) {
+  static embedPlaceholder(provider, ref, type, url) {
     const attrs = [
       `data-embed-provider="${this.escape(provider)}"`,
       `data-embed-ref="${this.escape(ref)}"`,
       type ? `data-embed-type="${this.escape(type)}"` : '',
-      mode ? `data-embed-mode="${this.escape(mode)}"` : '',
       `data-embed-url="${this.escape(url)}"`,
     ].filter(Boolean).join(' ');
@@ -228,17 +227,11 @@
   static embedMediaShortcodes(html) {
     if (!html) return html;
-    return html.replace(/\[\[embed:([^\]]+)\]\]/gi, (match, rawSpec) => {
-      // Optionele modus-prefix: [[embed:audio:URL]] = alleen-audio speler,
-      // [[embed:video:URL]] / [[embed:URL]] = normaal (video waar van toepassing).
-      let spec = rawSpec.trim();
-      let mode = null;
-      const mm = spec.match(/^(audio|video):(.+)$/i);
-      if (mm) { mode = mm[1].toLowerCase(); spec = mm[2].trim(); }
-      const url = spec.replace(/&amp;/g, '&');
+    return html.replace(/\[\[embed:([^\]]+)\]\]/gi, (match, rawUrl) => {
+      const url = rawUrl.trim().replace(/&amp;/g, '&');
       const detected = this.detectProvider(url);
       if (!detected) {
         return `<div class="post-embed-missing"><em>Embed: niet-ondersteunde of ongeldige URL.</em></div>`;
       }
-      return this.generateIframe(detected.provider, { ...detected, mode }) || match;
+      return this.generateIframe(detected.provider, detected) || match;
     });
   }
Index: src/views/pages/post-edit.ejs
===================================================================
--- src/views/pages/post-edit.ejs	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/views/pages/post-edit.ejs	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -1463,11 +1463,5 @@
       const url = raw.trim();
       if (!/^https?:\/\//i.test(url)) { alert('Geef een volledige URL (https://…).'); return; }
-      // YouTube: keuze audio-only (alleen geluid) of video.
-      let val = url;
-      if (/(youtube\.com|youtu\.be)/i.test(url)) {
-        const audioOnly = window.confirm('YouTube — alleen audio afspelen?\n\nOK = audio-only speler (geen video)\nAnnuleren = video');
-        if (audioOnly) val = 'audio:' + url;
-      }
-      insertChip('embed', val);
+      insertChip('embed', url);
     });
   }
Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision 8ab20b69298b549929cc22114fe7f484a0164bc8)
+++ src/views/shell.ejs	(revision fef781eb8f9efb0e0be591707a4e79aa60191494)
@@ -170,5 +170,5 @@
 <link rel="stylesheet" href="/assets/css/audio.css?v=6">
 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) in huisstijl. -->
-<link rel="stylesheet" href="/assets/css/embed.css?v=7">
+<link rel="stylesheet" href="/assets/css/embed.css?v=8">
 
 <%- include('partials/shared-styles') %>
@@ -300,8 +300,8 @@
      ?v=N — cache-buster: bump bij elke audio-player.js wijziging zodat
      Cloudflare (max-age=1y) niet de oude versie blijft serveren. -->
-<script src="/assets/js/audio-player.js?v=27"></script>
+<script src="/assets/js/audio-player.js?v=28"></script>
 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) via de echte
      player-API's + gedeelde mutual-exclusion registry met de site-speler. -->
-<script src="/assets/js/embed-player.js?v=15" defer></script>
+<script src="/assets/js/embed-player.js?v=16" defer></script>
 <% if (site && site.enable_audio_player && audioTracks && audioTracks.length > 0) { %>
   <script>window.PCMS_SITE_TRACKS = <%- JSON.stringify(audioTracks) %>;</script>
