{"product_id":"hypno-disc-robot-wars","title":"Hypno Disc – Robot Wars","description":"\u003c!-- ======= ORBIT WAX - TRACKLIST TEMPLATE (paste \u0026 go) ======= --\u003e\n\u003cstyle\u003e\n  \/* === Tracklist met achtergrond-art, lichte overlay \u0026 custom progress === *\/\n  .tracklist{--text:#e5e7eb;--muted:#cbd5e1;--accent:#cbd5e1}\n  .tracklist.bg-art{position:relative;border-radius:14px;overflow:hidden;margin:10px 0}\n  .tracklist.bg-art::before,\n  .tracklist.bg-art::after{\n    content:\"\";position:absolute;inset:0;z-index:0;pointer-events:none; \/* laat klikken door *\/\n  }\n  .tracklist .inner{position:relative;z-index:1;padding:16px}\n\n  .tracklist-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;color:var(--text)}\n  .tracklist-title{font-weight:700;font-size:1.05rem}\n  .tracklist-count{color:var(--muted);font-size:.95rem;margin-left:.5rem;font-weight:500}\n  .tracklist-btn{border:1px solid var(--accent);background:rgba(255,255,255,.06);color:var(--text);padding:6px 10px;border-radius:8px;cursor:pointer}\n  .tracklist-btn[disabled]{opacity:.6;cursor:not-allowed}\n\n  .tracklist-list{list-style:none;margin:0;padding:0;border-radius:10px;overflow:hidden}\n  .tracklist-item{display:flex;align-items:center;gap:10px;padding:12px 14px;cursor:pointer;color:var(--text);background:rgba(15,23,42,.28);border-bottom:1px solid rgba(203,213,225,.08)}\n  .tracklist-item:nth-child(even){background:rgba(15,23,42,.22)}\n  .tracklist-item:hover{background:rgba(203,213,225,.12)}\n  .tracklist-item .state{width:22px;text-align:center;opacity:.9}\n  .tracklist-item.active{outline:1px solid rgba(203,213,225,.4); background:rgba(203,213,225,.18)}\n\n  \/* Voortgangsbalk *\/\n  .playerbar{display:flex;align-items:center;gap:10px;margin-top:10px;color:var(--muted);font-size:.9rem}\n  .progress{position:relative;height:6px;flex:1;background:rgba(203,213,225,.25);border-radius:999px;cursor:pointer}\n  .progress-fill{position:absolute;left:0;top:0;height:100%;width:0;border-radius:999px;background:rgba(203,213,225,.9)}\n  .progress-thumb{position:absolute;top:50%;transform:translate(-50%,-50%);width:12px;height:12px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25)}\n  .time{white-space:nowrap;min-width:80px;text-align:right}\n\n  .toast{position:absolute;right:12px;bottom:12px;background:rgba(0,0,0,.6);color:#fff;padding:6px 10px;border-radius:8px;font-size:.85rem}\n  .sr-only{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}\n\n  @media (prefers-color-scheme: light){\n    .tracklist{--text:#0f172a;--muted:#334155;--accent:#94a3b8}\n    .tracklist-btn{background:rgba(255,255,255,.7)}\n    .tracklist-item{background:rgba(255,255,255,.55);border-bottom:1px solid rgba(51,65,85,.12)}\n    .tracklist-item:nth-child(even){background:rgba(255,255,255,.48)}\n    .tracklist-item.active{outline:1px solid rgba(51,65,85,.28);background:rgba(255,255,255,.72)}\n    .progress{background:rgba(51,65,85,.15)}\n    .progress-fill{background:rgba(51,65,85,.8)}\n    .progress-thumb{background:#0f172a}\n  }\n\u003c\/style\u003e\n\n\u003c!-- Container --\u003e\n\u003cdiv class=\"tracklist bg-art\" id=\"tracklist-ORBITWAX\"\u003e\n  \u003cdiv class=\"inner\"\u003e\n    \u003cdiv class=\"tracklist-header\"\u003e\n      \u003cdiv class=\"tracklist-title\"\u003eTracklist \u003cspan class=\"tracklist-count\"\u003e(–)\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003cbutton class=\"tracklist-btn\" type=\"button\" data-action=\"play-all\"\u003e▶ Play All\u003c\/button\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Hier komt de lijst automatisch in --\u003e\n    \u003cul class=\"tracklist-list\" role=\"listbox\" aria-label=\"Audio previews\"\u003e\u003c\/ul\u003e\n\n    \u003c!-- Gedeelde audio player --\u003e\n    \u003caudio id=\"player-ORBITWAX\" preload=\"metadata\" crossorigin=\"anonymous\"\u003e\u003c\/audio\u003e\n\n    \u003c!-- Voortgangsbalk --\u003e\n    \u003cdiv class=\"playerbar\"\u003e\n      \u003cdiv class=\"progress\" id=\"progress-ORBITWAX\" role=\"slider\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\" tabindex=\"0\"\u003e\n        \u003cdiv class=\"progress-fill\"\u003e\u003c\/div\u003e\n        \u003cdiv class=\"progress-thumb\" style=\"left:0%\"\u003e\u003c\/div\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"time\"\u003e\n\u003cspan class=\"cur\"\u003e0:00\u003c\/span\u003e \/ \u003cspan class=\"dur\"\u003e–:–\u003c\/span\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003cspan class=\"sr-only\" aria-live=\"polite\" id=\"ann-ORBITWAX\"\u003e\u003c\/span\u003e\n    \u003cdiv class=\"toast\" style=\"display:none\" id=\"toast-ORBITWAX\"\u003eCouldn’t start audio. Tap again.\u003c\/div\u003e\n  \u003c\/div\u003e\n\u003c\/div\u003e\n\n\u003cscript\u003e\n\/* ======= CONFIG: vul alleen dit blok in ======= *\/\nconst COVER_URL   = 'https:\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/Front_Sleeve.png?v=1785161910'; \/\/ bv. https:\/\/cdn.shopify.com\/...\/cover.jpg\n\n\/\/ Optie A (snel): alleen audio-URLS plakken in volgorde (A1, A2, B1, B2, C1, ...)\n\/\/ Titels worden automatisch A1, A2, B1, B2, ...\nconst TRACK_URLS = [\n  'https:\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/A1_Robot_Wars.mp3?v=1785163060',\n  'https:\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/A2_REF_BOT.mp3?v=1785163066',\n  'https:\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/B1_Firestorm.mp3?v=1785163074',\n  'https:\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/B2_Matilda.mp3?v=1785163080'\n];\n\n\/\/ Optie B (optioneel): eigen titels opgeven. Als je dit invult, wordt dit gebruikt\n\/\/ i.p.v. de auto-labels. Voorbeeld:\n\/\/ const TRACK_TITLES = ['A1. Give Me A Second','A2. Paratoxical','B1. Sniper','B2. Flying Adder'];\nconst TRACK_TITLES = null;\n\/* ======= EINDE CONFIG ======= *\/\n\n(function(){\n  const root = document.getElementById('tracklist-ORBITWAX');\n  if(!root) return;\n\n  \/\/ Achtergrond instellen + subtiele lichte overlay\n  root.classList.add('bg-art');\n  const styleEl = document.createElement('style');\n  styleEl.textContent = `\n    #${root.id}.bg-art::before{background:url(${CSS.escape(COVER_URL)}) center\/cover no-repeat;\n      filter:grayscale(.05) contrast(1.05) saturate(1.05); transform:scale(1.02)}\n    #${root.id}.bg-art::after{background:linear-gradient(180deg, rgba(9,12,16,.40), rgba(9,12,16,.25));backdrop-filter:blur(.2px)}\n  `;\n  document.head.appendChild(styleEl);\n\n  \/\/ Helpers\n  const itemsUL = root.querySelector('.tracklist-list');\n  const btnPlayAll = root.querySelector('[data-action=\"play-all\"]');\n  const countEl = root.querySelector('.tracklist-count');\n  const player = root.querySelector('#player-ORBITWAX');\n  const announcer = root.querySelector('#ann-ORBITWAX');\n  const toast = root.querySelector('#toast-ORBITWAX');\n\n  const bar = root.querySelector('#progress-ORBITWAX');\n  const fill = bar.querySelector('.progress-fill');\n  const thumb = bar.querySelector('.progress-thumb');\n  const curEl = root.querySelector('.time .cur');\n  const durEl = root.querySelector('.time .dur');\n\n  \/\/ labels A1, A2, B1, B2, C1, ...\n  const side = i =\u003e 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[Math.floor(i\/2)];\n  const num  = i =\u003e (i%2)+1;\n  const autoLabel = i =\u003e `${side(i)}${num(i)}`;\n\n  \/\/ Bouw de lijst\n  const items = TRACK_URLS.filter(Boolean).map((url, i) =\u003e {\n    const li = document.createElement('li');\n    li.className = 'tracklist-item';\n    li.tabIndex = 0;\n    li.dataset.src = url.trim();\n    const title = (TRACK_TITLES \u0026\u0026 TRACK_TITLES[i]) ? TRACK_TITLES[i] : `${autoLabel(i)}`;\n    li.innerHTML = `\u003cspan class=\"state\"\u003e▶\u003c\/span\u003e\u003cspan\u003e\u003cstrong\u003e${title}\u003c\/strong\u003e\u003c\/span\u003e`;\n    itemsUL.appendChild(li);\n    return li;\n  });\n\n  countEl.textContent = `(${items.length} ${items.length===1?'track':'tracks'})`;\n  if(items.length === 0){ itemsUL.innerHTML = '\u003cli class=\"tracklist-item\"\u003eNo previews yet.\u003c\/li\u003e'; return; }\n\n  \/\/ Audio control\n  let current = -1, playingAll = false, dragging = false;\n\n  function fmt(t){ if(!isFinite(t)) return '–:–'; const m = Math.floor(t\/60), s = Math.floor(t%60); return m+':' + (s\u003c10?'0'+s:s); }\n  function setActive(index){\n    items.forEach((el,i)=\u003e{ el.classList.toggle('active', i===index); el.querySelector('.state').textContent = (i===index \u0026\u0026 !player.paused) ? '⏸' : '▶'; });\n  }\n  function showToast(msg){ toast.textContent = msg; toast.style.display='block'; setTimeout(()=\u003etoast.style.display='none', 2200); }\n\n  function loadAndPlay(src, index){\n    player.pause();\n    player.removeAttribute('src');\n    player.src = src;\n    player.load();\n    const tryPlay = ()=\u003e player.play().then(()=\u003e{\n      setActive(index);\n      announcer.textContent = 'Playing ' + items[index].innerText.trim();\n    }).catch(()=\u003e showToast('Couldn’t start audio. Tap again.'));\n    if (player.readyState \u003e= 2) tryPlay();\n    else {\n      const onReady = ()=\u003e{ player.removeEventListener('canplay', onReady); tryPlay(); };\n      player.addEventListener('canplay', onReady);\n    }\n  }\n\n  function playIndex(index){\n    if(index\u003c0 || index\u003e=items.length) return;\n    const src = items[index].dataset.src;\n    if(!src) return;\n    if(index === current \u0026\u0026 !player.paused){ player.pause(); setActive(index); return; }\n    current = index;\n    loadAndPlay(src, index);\n  }\n\n  function updateProgress(){\n    const pct = player.duration ? (player.currentTime \/ player.duration) * 100 : 0;\n    fill.style.width = pct + '%'; thumb.style.left = pct + '%';\n    bar.setAttribute('aria-valuenow', Math.round(pct));\n    curEl.textContent = fmt(player.currentTime); durEl.textContent = fmt(player.duration);\n  }\n  function seekToClientX(x){\n    const r = bar.getBoundingClientRect(); let pct = (x - r.left)\/r.width; pct = Math.max(0,Math.min(1,pct));\n    if(player.duration){ player.currentTime = pct * player.duration; updateProgress(); }\n  }\n\n  \/\/ Events\n  items.forEach((el,i)=\u003e{\n    el.addEventListener('click', ()=\u003e playIndex(i));\n    el.addEventListener('keydown', e=\u003e{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); playIndex(i); }});\n  });\n\n  btnPlayAll.addEventListener('click', ()=\u003e{ playingAll=true; btnPlayAll.disabled=true; playIndex(0); });\n\n  player.addEventListener('loadedmetadata', updateProgress);\n  player.addEventListener('timeupdate', updateProgress);\n  player.addEventListener('play', ()=\u003e setActive(current));\n  player.addEventListener('pause', ()=\u003e setActive(current));\n  player.addEventListener('ended', ()=\u003e{\n    if(playingAll \u0026\u0026 current \u003c items.length-1){ playIndex(current+1); }\n    else { playingAll=false; btnPlayAll.disabled=false; setActive(current); }\n  });\n\n  \/\/ Progressbar interactie\n  bar.addEventListener('mousedown', e=\u003e{ dragging=true; seekToClientX(e.clientX); });\n  window.addEventListener('mousemove', e=\u003e{ if(dragging) seekToClientX(e.clientX); });\n  window.addEventListener('mouseup', ()=\u003e dragging=false);\n  bar.addEventListener('keydown', e=\u003e{\n    if(!player.duration) return;\n    if(e.key==='ArrowRight'){ player.currentTime = Math.min(player.duration, player.currentTime+5); updateProgress(); }\n    if(e.key==='ArrowLeft'){  player.currentTime = Math.max(0, player.currentTime-5); updateProgress(); }\n  });\n})();\n\u003c\/script\u003e\n\u003c!-- ======= \/ORBIT WAX - TRACKLIST TEMPLATE ======= --\u003e\n\n\u003cdiv\u003e\u003cspan\u003eHara Discs is proud to present the first EP from Sheffield-based DJ Harry Shackleton, co-owner of Grub Records and one half of DJ duo Wow \u0026amp; Flutter. This release draws influence from their longstanding residency at underground electro party Control., melding together sounds which have made this one of the North of England’s best kept secrets for the past 7 years. In an extremely long-winded and uncertain move, he has finally donned his rather fetching production hat and completely self generated the alias Hypno Disc with which he aims to unleash some music that is 100% OK.\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003e\u003cbr\u003e\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003eThe EP and alias are a homage to the late 90s and early 00s TV show Robot Wars. The title track combines the carnage of Craig Charles with something a bit UK and tribal. The remaining tracks bear the names of robots which took part in the wars. These are written from the perspective of the robots and as such are internal monologues of what each robot was thinking. The concept comes from an early fascination with this show and how it made the artist feel as someone growing up in the UK around 2000.\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003e\u003cbr\u003e\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003eWe hope you enjoy this release. Complaints will be tolerated.\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003e\u003cbr\u003e\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv\u003e\u003cspan\u003eCEASE!!!\u003c\/span\u003e\u003c\/div\u003e","brand":"Orbit Wax","offers":[{"title":"Default Title","offer_id":54439881703751,"sku":null,"price":20.99,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0921\/7638\/4327\/files\/Front_Sleeve.png?v=1785161910","url":"https:\/\/orbitwax.com\/products\/hypno-disc-robot-wars","provider":"Orbit Wax","version":"1.0","type":"link"}