HTML
Copy
<div><span class="mb-3.5 block text-[.72rem] tracking-[.12em] text-[#56657a] uppercase">Album with track list</span>
<section class="group overflow-hidden rounded-[22px] border border-[#e2e8f0] bg-white text-[#0f172a] shadow-[0_10px_30px_rgba(15,23,42,.07)] [--p:0]" data-pl aria-label="Low Tide Radio playlist">
<audio src="../audio/track-1.mp3" preload="metadata"></audio>
<div class="grid grid-cols-[150px_1fr] items-center gap-[22px] border-b border-[#e2e8f0] p-[22px] max-[560px]:grid-cols-[96px_1fr] max-[560px]:gap-4 max-[560px]:p-4">
<div class="aspect-square rounded-[14px] [background:radial-gradient(circle_at_68%_40%,#fde68a_0_11%,transparent_11.5%),repeating-linear-gradient(180deg,transparent_0_6%,rgba(253,230,138,.3)_6%_7.5%)_bottom/100%_42%_no-repeat,linear-gradient(180deg,#fb923c,#e11d48_58%,#312e81_58%,#1e1b4b)]" data-cover aria-hidden="true"></div>
<div class="flex min-w-0 flex-col gap-4">
<div><p class="text-[.7rem] font-bold tracking-[.12em] text-pl-accent uppercase">Playlist · Low Tide Radio</p><p class="mt-1 text-[1.3rem] font-extrabold tracking-[-.02em]" data-show="name">Harbour Lights</p><p class="mt-0.5 text-[.9rem] text-pl-muted" data-show="artist">Juniper Vale</p></div>
<div class="flex items-center gap-2">
<button type="button" class="grid size-10 cursor-pointer place-items-center rounded-full text-[#0f172a] hover:bg-[#f1f5f9] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-prev aria-label="Previous track"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M5 5h2.2v14H5zM19.5 6.2v11.6a.8.8 0 0 1-1.24.67L9.6 12.67a.8.8 0 0 1 0-1.34l8.66-5.8a.8.8 0 0 1 1.24.67z"/></svg></button>
<button type="button" class="grid size-12 cursor-pointer place-items-center rounded-full bg-pl-accent text-white shadow-[0_6px_16px_rgba(4,120,87,.3)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-play aria-label="Play Harbour Lights"><svg class="block size-[22px] group-data-playing:hidden" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M8 5.5v13a1 1 0 0 0 1.5.86l10.5-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5z"/></svg><svg class="hidden size-[22px] group-data-playing:block" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><rect x="6.5" y="5" width="4" height="14" rx="1.2"/><rect x="13.5" y="5" width="4" height="14" rx="1.2"/></svg></button>
<button type="button" class="grid size-10 cursor-pointer place-items-center rounded-full text-[#0f172a] hover:bg-[#f1f5f9] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-next aria-label="Next track"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M16.8 5H19v14h-2.2zM4.5 6.2v11.6a.8.8 0 0 0 1.24.67l8.66-5.8a.8.8 0 0 0 0-1.34L5.74 5.53a.8.8 0 0 0-1.24.67z"/></svg></button>
</div>
<div class="flex items-center gap-2">
<span class="min-w-[2.3em] text-[.78rem] text-pl-muted tabular-nums" data-cur>0:00</span>
<input type="range" class="flex-1 block h-[14px] min-w-0 cursor-pointer appearance-none bg-transparent [--f:var(--p)] focus-visible:outline-none [&::-webkit-slider-runnable-track]:h-[4px] [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-pl-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-pl-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-pl-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-pl-track)_0)] [&::-webkit-slider-thumb]:-mt-[5px] [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-[14px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[#fff] [&::-webkit-slider-thumb]:box-border [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-solid [&::-webkit-slider-thumb]:border-[color:var(--color-pl-accent)] focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_#fff,0_0_0_5px_var(--color-pl-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[#fff] [&::-moz-range-thumb]:box-border [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-solid [&::-moz-range-thumb]:border-[color:var(--color-pl-accent)] focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_#fff,0_0_0_5px_var(--color-pl-accent)]" data-seek min="0" max="24" step="any" value="0" aria-label="Seek" aria-valuetext="0:00 of 0:24">
<span class="min-w-[2.3em] text-[.78rem] text-pl-muted tabular-nums text-right" data-dur>0:24</span>
</div>
</div>
</div>
<ol class="p-2">
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-1.mp3" data-name="Harbour Lights" data-artist="Juniper Vale" aria-current="true">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">1</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:radial-gradient(circle_at_68%_40%,#fde68a_0_11%,transparent_11.5%),repeating-linear-gradient(180deg,transparent_0_6%,rgba(253,230,138,.3)_6%_7.5%)_bottom/100%_42%_no-repeat,linear-gradient(180deg,#fb923c,#e11d48_58%,#312e81_58%,#1e1b4b)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Harbour Lights</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">Juniper Vale</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:24</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-2.mp3" data-name="Paper Kites" data-artist="The Lumen Choir">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">2</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:linear-gradient(to_bottom_right,transparent_50%,#fde047_50%)_37.5%_26.67%/20%_25%_no-repeat,linear-gradient(to_bottom_left,transparent_50%,#f97316_50%)_62.5%_26.67%/20%_25%_no-repeat,linear-gradient(to_top_right,transparent_50%,#fb923c_50%)_37.5%_69.23%/20%_35%_no-repeat,linear-gradient(to_top_left,transparent_50%,#facc15_50%)_62.5%_69.23%/20%_35%_no-repeat,linear-gradient(to_bottom_right,transparent_calc(50%_-_1px),rgba(255,255,255,.85)_0_calc(50%_+_1px),transparent_0)_41.86%_100%/14%_20%_no-repeat,linear-gradient(160deg,#0ea5e9,#14b8a6_55%,#84cc16)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Paper Kites</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">The Lumen Choir</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:24</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-3.mp3" data-name="Night Bus to Nowhere" data-artist="Orla Finch">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">3</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:radial-gradient(circle_at_68%_30%,#fef3c7_0_9%,rgba(254,243,199,.16)_9.5%_15%,transparent_15.5%),radial-gradient(circle_at_20%_25%,#fff_0_1.2%,transparent_2%),radial-gradient(circle_at_38%_55%,#fff_0_.9%,transparent_1.6%),radial-gradient(circle_at_86%_64%,#fff_0_1%,transparent_1.7%),radial-gradient(circle_at_12%_70%,#c4b5fd_0_1%,transparent_1.7%),linear-gradient(180deg,#0f172a,#312e81_70%,#7c3aed)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Night Bus to Nowhere</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">Orla Finch</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:30</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-4.mp3" data-name="Copper Sky" data-artist="Milo & the Tidelines">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">4</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:radial-gradient(circle_at_50%_100%,#fff7ed_0_24%,#fdba74_24%_27%,transparent_27.5%),linear-gradient(180deg,#7c2d12_0_22%,#9a3412_22%_40%,#c2410c_40%_56%,#ea580c_56%_70%,#f59e0b_70%_84%,#fcd34d_84%)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Copper Sky</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">Milo & the Tidelines</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:29</span></button></li>
</ol>
</section></div>
<div><span class="mb-3.5 block text-[.72rem] tracking-[.12em] text-[#56657a] uppercase">Side-by-side queue</span>
<section class="group overflow-hidden rounded-[22px] border border-[#e2e8f0] bg-white text-[#0f172a] shadow-[0_10px_30px_rgba(15,23,42,.07)] [--p:0] grid grid-cols-[280px_1fr] max-[560px]:grid-cols-1" data-pl aria-label="Late night queue">
<audio src="../audio/track-3.mp3" preload="metadata"></audio>
<div class="flex flex-col gap-4 border-r border-[#e2e8f0] p-[22px] max-[560px]:border-r-0 max-[560px]:border-b">
<div class="aspect-square rounded-[14px] [background:radial-gradient(circle_at_68%_30%,#fef3c7_0_9%,rgba(254,243,199,.16)_9.5%_15%,transparent_15.5%),radial-gradient(circle_at_20%_25%,#fff_0_1.2%,transparent_2%),radial-gradient(circle_at_38%_55%,#fff_0_.9%,transparent_1.6%),radial-gradient(circle_at_86%_64%,#fff_0_1%,transparent_1.7%),radial-gradient(circle_at_12%_70%,#c4b5fd_0_1%,transparent_1.7%),linear-gradient(180deg,#0f172a,#312e81_70%,#7c3aed)] max-[560px]:aspect-[2/1]" data-cover aria-hidden="true"></div>
<div><p class="mt-1 text-[1.3rem] font-extrabold tracking-[-.02em]" data-show="name">Night Bus to Nowhere</p><p class="mt-0.5 text-[.9rem] text-pl-muted" data-show="artist">Orla Finch</p></div>
<div class="flex items-center gap-2">
<span class="min-w-[2.3em] text-[.78rem] text-pl-muted tabular-nums" data-cur>0:00</span>
<input type="range" class="flex-1 block h-[14px] min-w-0 cursor-pointer appearance-none bg-transparent [--f:var(--p)] focus-visible:outline-none [&::-webkit-slider-runnable-track]:h-[4px] [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-pl-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-pl-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-pl-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-pl-track)_0)] [&::-webkit-slider-thumb]:-mt-[5px] [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-[14px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[#fff] [&::-webkit-slider-thumb]:box-border [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-solid [&::-webkit-slider-thumb]:border-[color:var(--color-pl-accent)] focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_#fff,0_0_0_5px_var(--color-pl-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[#fff] [&::-moz-range-thumb]:box-border [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-solid [&::-moz-range-thumb]:border-[color:var(--color-pl-accent)] focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_#fff,0_0_0_5px_var(--color-pl-accent)]" data-seek min="0" max="30" step="any" value="0" aria-label="Seek" aria-valuetext="0:00 of 0:30">
<span class="min-w-[2.3em] text-[.78rem] text-pl-muted tabular-nums text-right" data-dur>0:30</span>
</div>
<div class="flex items-center justify-center gap-2">
<button type="button" class="grid size-10 cursor-pointer place-items-center rounded-full text-[#0f172a] hover:bg-[#f1f5f9] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-prev aria-label="Previous track"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M5 5h2.2v14H5zM19.5 6.2v11.6a.8.8 0 0 1-1.24.67L9.6 12.67a.8.8 0 0 1 0-1.34l8.66-5.8a.8.8 0 0 1 1.24.67z"/></svg></button>
<button type="button" class="grid size-12 cursor-pointer place-items-center rounded-full bg-pl-accent text-white shadow-[0_6px_16px_rgba(4,120,87,.3)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-play aria-label="Play Night Bus to Nowhere"><svg class="block size-[22px] group-data-playing:hidden" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M8 5.5v13a1 1 0 0 0 1.5.86l10.5-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5z"/></svg><svg class="hidden size-[22px] group-data-playing:block" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><rect x="6.5" y="5" width="4" height="14" rx="1.2"/><rect x="13.5" y="5" width="4" height="14" rx="1.2"/></svg></button>
<button type="button" class="grid size-10 cursor-pointer place-items-center rounded-full text-[#0f172a] hover:bg-[#f1f5f9] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pl-accent" data-next aria-label="Next track"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M16.8 5H19v14h-2.2zM4.5 6.2v11.6a.8.8 0 0 0 1.24.67l8.66-5.8a.8.8 0 0 0 0-1.34L5.74 5.53a.8.8 0 0 0-1.24.67z"/></svg></button>
</div>
</div>
<div class="px-1.5 py-3.5">
<p class="px-4 pt-2 text-[.75rem] tracking-[.12em] text-pl-muted uppercase">Queue</p>
<ol class="p-2">
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-3.mp3" data-name="Night Bus to Nowhere" data-artist="Orla Finch" aria-current="true">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">1</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:radial-gradient(circle_at_68%_30%,#fef3c7_0_9%,rgba(254,243,199,.16)_9.5%_15%,transparent_15.5%),radial-gradient(circle_at_20%_25%,#fff_0_1.2%,transparent_2%),radial-gradient(circle_at_38%_55%,#fff_0_.9%,transparent_1.6%),radial-gradient(circle_at_86%_64%,#fff_0_1%,transparent_1.7%),radial-gradient(circle_at_12%_70%,#c4b5fd_0_1%,transparent_1.7%),linear-gradient(180deg,#0f172a,#312e81_70%,#7c3aed)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Night Bus to Nowhere</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">Orla Finch</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:30</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-4.mp3" data-name="Copper Sky" data-artist="Milo & the Tidelines">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">2</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:radial-gradient(circle_at_50%_100%,#fff7ed_0_24%,#fdba74_24%_27%,transparent_27.5%),linear-gradient(180deg,#7c2d12_0_22%,#9a3412_22%_40%,#c2410c_40%_56%,#ea580c_56%_70%,#f59e0b_70%_84%,#fcd34d_84%)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Copper Sky</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">Milo & the Tidelines</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:29</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[28px_40px_1fr_auto] items-center gap-3 rounded-xl px-3 py-2 text-left hover:bg-[#f8fafc] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-pl-accent aria-[current=true]:bg-pl-soft max-[560px]:grid-cols-[22px_36px_1fr_auto] max-[560px]:gap-2.5 max-[560px]:p-2" data-src="../audio/track-2.mp3" data-name="Paper Kites" data-artist="The Lumen Choir">
<span class="text-center text-[.85rem] text-pl-muted tabular-nums"><span class="group-aria-[current=true]/item:hidden">3</span><span class="hidden h-3.5 items-end justify-center gap-0.5 group-aria-[current=true]/item:flex" aria-hidden="true"><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-full motion-safe:group-data-playing:animate-pl-bounce"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[60%] motion-safe:group-data-playing:animate-pl-bounce-2"></i><i class="w-[3px] origin-bottom rounded-[1px] bg-pl-accent h-[80%] motion-safe:group-data-playing:animate-pl-bounce-3"></i></span></span>
<span class="size-10 rounded-lg max-[560px]:size-9 [background:linear-gradient(to_bottom_right,transparent_50%,#fde047_50%)_37.5%_26.67%/20%_25%_no-repeat,linear-gradient(to_bottom_left,transparent_50%,#f97316_50%)_62.5%_26.67%/20%_25%_no-repeat,linear-gradient(to_top_right,transparent_50%,#fb923c_50%)_37.5%_69.23%/20%_35%_no-repeat,linear-gradient(to_top_left,transparent_50%,#facc15_50%)_62.5%_69.23%/20%_35%_no-repeat,linear-gradient(to_bottom_right,transparent_calc(50%_-_1px),rgba(255,255,255,.85)_0_calc(50%_+_1px),transparent_0)_41.86%_100%/14%_20%_no-repeat,linear-gradient(160deg,#0ea5e9,#14b8a6_55%,#84cc16)]" data-art></span>
<span><span class="block text-[.95rem] font-semibold group-aria-[current=true]/item:text-[#065f46]">Paper Kites</span><span class="mt-0.5 block text-[.8rem] text-pl-muted">The Lumen Choir</span></span>
<span class="text-[.8rem] text-pl-muted tabular-nums">0:24</span></button></li>
</ol>
</div>
</section></div>
JavaScript
Copy
// Playlist players. Each [data-pl] holds one <audio> and a list of track buttons that carry
// data-src, data-name and data-artist. The current track button gets aria-current="true".
(() => {
const fmt = s => { s = Math.floor(s || 0); return Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0'); };
document.querySelectorAll('[data-pl]').forEach(root => {
const $ = s => root.querySelector(s);
const audio = $('audio'), play = $('[data-play]'), seek = $('[data-seek]'), cur = $('[data-cur]'), dur = $('[data-dur]');
const cover = $('[data-cover]'), items = [...root.querySelectorAll('[data-src]')];
let i = Math.max(0, items.findIndex(b => b.getAttribute('aria-current') === 'true')), raf = 0;
const label = () => play.setAttribute('aria-label', (audio.paused ? 'Play ' : 'Pause ') + items[i].dataset.name);
const length = () => audio.duration || +seek.max;
const sync = () => {
const t = audio.currentTime, d = length(), text = fmt(t) + ' of ' + fmt(d);
seek.value = t;
root.style.setProperty('--p', d ? t / d : 0);
cur.textContent = fmt(t);
if (seek.getAttribute('aria-valuetext') !== text) seek.setAttribute('aria-valuetext', text);
};
const tick = () => { sync(); raf = requestAnimationFrame(tick); };
const meta = () => { seek.max = audio.duration; dur.textContent = fmt(audio.duration); sync(); };
const start = () => {
document.querySelectorAll('audio').forEach(a => { if (a !== audio) a.pause(); });
audio.play().catch(() => {});
};
// Switch to track n: mark it current, swap the source, title, artist and cover art.
const load = n => {
i = (n + items.length) % items.length;
const item = items[i], art = item.querySelector('[data-art]');
items.forEach(b => b.removeAttribute('aria-current'));
item.setAttribute('aria-current', 'true');
audio.src = item.dataset.src;
root.querySelectorAll('[data-show]').forEach(el => { el.textContent = item.dataset[el.dataset.show]; });
if (cover && art) {
const cs = getComputedStyle(art);
['backgroundImage', 'backgroundPosition', 'backgroundSize', 'backgroundRepeat'].forEach(p => { cover.style[p] = cs[p]; });
}
label();
};
play.addEventListener('click', () => (audio.paused ? start() : audio.pause()));
$('[data-prev]').addEventListener('click', () => {
if (audio.currentTime > 3) audio.currentTime = 0; else load(i - 1);
start();
});
$('[data-next]').addEventListener('click', () => { load(i + 1); start(); });
items.forEach((item, n) => item.addEventListener('click', () => {
if (n === i) return play.click();
load(n); start();
}));
audio.addEventListener('play', () => { root.setAttribute('data-playing', ''); label(); tick(); });
audio.addEventListener('pause', () => { root.removeAttribute('data-playing'); label(); cancelAnimationFrame(raf); sync(); });
audio.addEventListener('ended', () => { if (i < items.length - 1) { load(i + 1); start(); } });
audio.addEventListener('loadedmetadata', meta);
if (audio.readyState > 0) meta();
seek.addEventListener('input', () => { audio.currentTime = seek.value; sync(); });
// Arrow keys jump 5 seconds; Home and End work natively.
seek.addEventListener('keydown', e => {
const step = { ArrowLeft: -5, ArrowDown: -5, ArrowRight: 5, ArrowUp: 5 }[e.key];
if (!step) return;
e.preventDefault();
audio.currentTime = Math.min(Math.max(audio.currentTime + step, 0), length());
sync();
});
});
})();