Index: src/assets/css/audio.css
===================================================================
--- src/assets/css/audio.css	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/assets/css/audio.css	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -82,4 +82,27 @@
   text-overflow: ellipsis;
 }
+
+/* "Open in" Spotify/YouTube/SoundCloud — kleine brand-iconen per track. */
+.pat-links {
+  display: inline-flex; align-items: center; gap: 0.1rem;
+  flex: 0 0 auto;
+}
+/* Single + album-rij (.post-audio-track is flex) → duw de links naar rechts. */
+.post-audio-track .pat-links { margin-left: auto; padding-right: 0.5rem; }
+/* Playlist-rij: de li flex maken zodat de links naast de afspeel-rij passen. */
+.post-album-track-compact { display: flex; align-items: center; }
+.post-album-track-compact .pat-row { flex: 1 1 auto; min-width: 0; }
+.post-album-track-compact .pat-links { padding-right: 0.6rem; }
+.pat-link {
+  display: inline-flex; align-items: center; justify-content: center;
+  width: 26px; height: 26px;
+  opacity: 0.75;
+  transition: opacity 120ms, transform 120ms;
+}
+.pat-link svg { width: 17px; height: 17px; }
+.pat-link:hover { opacity: 1; transform: scale(1.12); }
+.pat-link--spotify    { color: #1DB954; }
+.pat-link--youtube    { color: #FF0000; }
+.pat-link--soundcloud { color: #FF5500; }
 
 /* ============================================================
Index: src/config/database.js
===================================================================
--- src/config/database.js	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/config/database.js	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -92,4 +92,7 @@
   ensureColumn('audio_tracks', 'credit', 'TEXT');   // eigenaar/credit (copyright-houder)
   ensureColumn('audio_tracks', 'license', 'TEXT');  // licentie (bv. "CC BY 4.0", "Alle rechten voorbehouden")
+  ensureColumn('audio_tracks', 'link_spotify',    'TEXT');  // "open in"-links per track
+  ensureColumn('audio_tracks', 'link_youtube',    'TEXT');
+  ensureColumn('audio_tracks', 'link_soundcloud', 'TEXT');
 
   // Playlists (v9 feature) — first-class entity. CREATE IF NOT EXISTS is
Index: src/routes/admin-audio.js
===================================================================
--- src/routes/admin-audio.js	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/routes/admin-audio.js	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -72,4 +72,21 @@
 
 const router = express.Router();
+
+// "Open in"-platformlinks per track: alleen https + de juiste host accepteren
+// (href komt ongeescaped in de view → scheme/host-guard tegen misbruik).
+const LINK_DOMAINS = {
+  spotify: ['spotify.com'],
+  youtube: ['youtube.com', 'youtu.be', 'music.youtube.com'],
+  soundcloud: ['soundcloud.com'],
+};
+function platformLink(url, domains) {
+  const u = String(url || '').trim();
+  if (!u || !/^https:\/\//i.test(u)) return null;
+  try {
+    const h = new URL(u).hostname.toLowerCase();
+    if (domains.some((d) => h === d || h.endsWith('.' + d))) return u;
+  } catch (e) { /* ongeldige URL */ }
+  return null;
+}
 
 router.get('/', requireGod, (req, res) => {
@@ -172,4 +189,7 @@
     const finalCredit  = (req.body.credit  || '').trim() || finalArtist || null;
     const finalLicense = (req.body.license || '').trim() || null;
+    const finalLinkSpotify    = platformLink(req.body.link_spotify, LINK_DOMAINS.spotify);
+    const finalLinkYoutube    = platformLink(req.body.link_youtube, LINK_DOMAINS.youtube);
+    const finalLinkSoundcloud = platformLink(req.body.link_soundcloud, LINK_DOMAINS.soundcloud);
 
     console.log('[admin-audio] upload received:', {
@@ -222,6 +242,6 @@
       console.log('[admin-audio] inserting audio_tracks row (duration=' + finalDuration + ')');
       db.prepare(`
-        INSERT INTO audio_tracks (id, site_id, title, artist, album, duration, cover_url, credit, license, media_id, position)
-        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, COALESCE(
+        INSERT INTO audio_tracks (id, site_id, title, artist, album, duration, cover_url, credit, license, link_spotify, link_youtube, link_soundcloud, media_id, position)
+        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, COALESCE(
           (SELECT MAX(position) + 1 FROM audio_tracks WHERE site_id = ?),
           0
@@ -233,4 +253,5 @@
         coverUrl,
         finalCredit, finalLicense,
+        finalLinkSpotify, finalLinkYoutube, finalLinkSoundcloud,
         mediaId, site.id
       );
@@ -378,5 +399,6 @@
   const t = db.prepare(`
     SELECT t.id, t.title, t.artist, t.album, t.duration, t.cover_url,
-           t.credit, t.license, t.position, t.created_at, m.filename
+           t.credit, t.license, t.link_spotify, t.link_youtube, t.link_soundcloud,
+           t.position, t.created_at, m.filename
     FROM audio_tracks t LEFT JOIN media m ON m.id = t.media_id
     WHERE t.id = ? AND t.site_id = ?
@@ -445,4 +467,13 @@
   if (Object.prototype.hasOwnProperty.call(body, 'license')) {
     fields.push('license = ?'); values.push(String(body.license || '').trim() || null);
+  }
+  if (Object.prototype.hasOwnProperty.call(body, 'link_spotify')) {
+    fields.push('link_spotify = ?'); values.push(platformLink(body.link_spotify, LINK_DOMAINS.spotify));
+  }
+  if (Object.prototype.hasOwnProperty.call(body, 'link_youtube')) {
+    fields.push('link_youtube = ?'); values.push(platformLink(body.link_youtube, LINK_DOMAINS.youtube));
+  }
+  if (Object.prototype.hasOwnProperty.call(body, 'link_soundcloud')) {
+    fields.push('link_soundcloud = ?'); values.push(platformLink(body.link_soundcloud, LINK_DOMAINS.soundcloud));
   }
 
Index: src/routes/posts.js
===================================================================
--- src/routes/posts.js	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/routes/posts.js	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -529,5 +529,6 @@
       const placeholders = trackIds.map(() => '?').join(',');
       const rows = db.prepare(`
-        SELECT t.id, t.title, t.artist, t.cover_url, t.credit, t.license, m.filename
+        SELECT t.id, t.title, t.artist, t.cover_url, t.credit, t.license,
+               t.link_spotify, t.link_youtube, t.link_soundcloud, m.filename
         FROM audio_tracks t LEFT JOIN media m ON m.id = t.media_id
         WHERE t.site_id = ? AND t.id IN (${placeholders})
@@ -544,4 +545,7 @@
           credit: r.credit || '',
           license: r.license || '',
+          link_spotify: r.link_spotify || '',
+          link_youtube: r.link_youtube || '',
+          link_soundcloud: r.link_soundcloud || '',
           url: audioUrl(r.filename),
         };
@@ -554,5 +558,6 @@
       const placeholders = albumNames.map(() => '?').join(',');
       const albumRows = db.prepare(`
-        SELECT t.id, t.title, t.artist, t.album, t.cover_url, t.position, m.filename
+        SELECT t.id, t.title, t.artist, t.album, t.cover_url, t.position,
+               t.link_spotify, t.link_youtube, t.link_soundcloud, m.filename
         FROM audio_tracks t LEFT JOIN media m ON m.id = t.media_id
         WHERE t.site_id = ? AND t.album IN (${placeholders})
@@ -569,4 +574,7 @@
           artist: r.artist || '',
           cover: r.cover_url || '',
+          link_spotify: r.link_spotify || '',
+          link_youtube: r.link_youtube || '',
+          link_soundcloud: r.link_soundcloud || '',
         });
       }
Index: src/services/AudioEmbedService.js
===================================================================
--- src/services/AudioEmbedService.js	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/services/AudioEmbedService.js	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -11,5 +11,29 @@
  */
 
+// "Open in"-iconen (brand-gekleurd via CSS .pat-link--*).
+const OPEN_IN_SVG = {
+  spotify: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2a10 10 0 100 20 10 10 0 000-20zm4.6 14.42a.62.62 0 01-.86.21c-2.35-1.44-5.3-1.76-8.79-.96a.62.62 0 11-.28-1.21c3.8-.87 7.07-.5 9.71 1.11.3.18.39.57.22.85zm1.23-2.73a.78.78 0 01-1.07.26c-2.69-1.66-6.79-2.14-9.97-1.17a.78.78 0 11-.45-1.49c3.63-1.1 8.15-.56 11.24 1.33.36.22.48.7.25 1.07zm.1-2.85C14.66 8.95 9.4 8.78 6.3 9.72a.93.93 0 11-.54-1.79c3.56-1.08 9.37-.87 13.07 1.33a.94.94 0 01-.96 1.61z"/></svg>',
+  youtube: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 7.1a3 3 0 00-2.1-2.12C19.04 4.5 12 4.5 12 4.5s-7.04 0-8.9.48A3 3 0 001 7.1 31.2 31.2 0 00.5 12 31.2 31.2 0 001 16.9a3 3 0 002.1 2.12c1.86.48 8.9.48 8.9.48s7.04 0 8.9-.48A3 3 0 0023 16.9 31.2 31.2 0 0023.5 12 31.2 31.2 0 0023 7.1zM9.75 15.5v-7l6 3.5-6 3.5z"/></svg>',
+  soundcloud: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 14v4M7.5 11v7M11 9v9"/><path d="M14.5 9.5V18h4a3 3 0 100-6 4 4 0 00-4-2.5z"/></svg>',
+};
+
 class AudioEmbedService {
+  // Kleine "open in"-links voor een track (Spotify/YouTube/SoundCloud). De hrefs
+  // zijn server-side al gevalideerd (alleen https + juiste host). Geeft '' als er
+  // geen links zijn. Wordt naast de play-knop gezet (buiten de knop → geen
+  // conflict met afspelen).
+  static openInLinks(t) {
+    if (!t) return '';
+    const out = [];
+    const add = (url, key, label) => {
+      if (!url) return;
+      out.push(`<a class="pat-link pat-link--${key}" href="${this.escape(url)}" target="_blank" rel="noopener noreferrer" title="Open in ${label}" aria-label="Open in ${label}">${OPEN_IN_SVG[key]}</a>`);
+    };
+    add(t.link_spotify, 'spotify', 'Spotify');
+    add(t.link_youtube, 'youtube', 'YouTube');
+    add(t.link_soundcloud, 'soundcloud', 'SoundCloud');
+    return out.length ? `<span class="pat-links">${out.join('')}</span>` : '';
+  }
+
   static detectProvider(url) {
     if (!url || typeof url !== 'string') return null;
@@ -273,4 +297,5 @@
     ${creditBits ? `<div class="pat-credit">${creditBits}</div>` : ''}
   </div>
+  ${this.openInLinks(t)}
 </div>`;
     });
@@ -312,4 +337,5 @@
         ${tArtist && tArtist !== artistH ? `<div class="pat-artist">${tArtist}</div>` : ''}
       </div>
+      ${this.openInLinks(t)}
     </li>`;
       }).join('\n');
@@ -433,4 +459,5 @@
         ${durHtml}
       </button>
+      ${this.openInLinks(t)}
     </li>`;
       }).join('\n');
Index: src/services/PlaylistService.js
===================================================================
--- src/services/PlaylistService.js	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/services/PlaylistService.js	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -94,5 +94,6 @@
     // filenames (only tracks with a media file are playable).
     const tracks = db.prepare(`
-      SELECT t.id, t.title, t.artist, t.duration, t.cover_url, m.filename
+      SELECT t.id, t.title, t.artist, t.duration, t.cover_url,
+             t.link_spotify, t.link_youtube, t.link_soundcloud, m.filename
       FROM playlist_tracks pt
       JOIN audio_tracks t   ON t.id = pt.track_id
@@ -110,4 +111,7 @@
         cover: t.cover_url || p.cover_url || '',
         duration: t.duration || 0,
+        link_spotify: t.link_spotify || '',
+        link_youtube: t.link_youtube || '',
+        link_soundcloud: t.link_soundcloud || '',
         url: urlFor ? urlFor(t.filename) : null,
       }));
Index: src/views/partials/track-editor.ejs
===================================================================
--- src/views/partials/track-editor.ejs	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/views/partials/track-editor.ejs	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -430,4 +430,14 @@
 
             <div class="te-field">
+              <span>Open in <small>(links naar dezelfde track elders)</small></span>
+              <input type="url" id="te-link-spotify" inputmode="url" autocomplete="off" spellcheck="false"
+                     placeholder="Spotify-URL (https://open.spotify.com/…)" value="${esc(track.link_spotify || '')}">
+              <input type="url" id="te-link-youtube" inputmode="url" autocomplete="off" spellcheck="false"
+                     placeholder="YouTube-URL (https://youtu.be/…)" value="${esc(track.link_youtube || '')}">
+              <input type="url" id="te-link-soundcloud" inputmode="url" autocomplete="off" spellcheck="false"
+                     placeholder="SoundCloud-URL (https://soundcloud.com/…)" value="${esc(track.link_soundcloud || '')}">
+            </div>
+
+            <div class="te-field">
               <span>Cover</span>
               <div class="te-cover-row">
@@ -664,4 +674,7 @@
           credit:  $('#te-credit').value.trim() || null,
           license: $('#te-license').value.trim() || null,
+          link_spotify:    $('#te-link-spotify').value.trim() || null,
+          link_youtube:    $('#te-link-youtube').value.trim() || null,
+          link_soundcloud: $('#te-link-soundcloud').value.trim() || null,
           duration: $('#te-duration').value ? Number($('#te-duration').value) : null,
           cover_url: urlInput.value.trim() || null,
Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision 459acd973746ff4a214e65748d6254ae5898a32b)
+++ src/views/shell.ejs	(revision 183875b46fb28dbb72cffa7bc53cedaad373f8cd)
@@ -168,5 +168,5 @@
      anywhere (admin previews, post embeds, etc). The player itself is
      a singleton — see the script tag near </body>. -->
-<link rel="stylesheet" href="/assets/css/audio.css?v=7">
+<link rel="stylesheet" href="/assets/css/audio.css?v=8">
 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) in huisstijl. -->
 <link rel="stylesheet" href="/assets/css/embed.css?v=8">
