HTML
Copy
<div><span class="mb-3.5 block text-[.72rem] tracking-[.12em] text-[#9ca3af] uppercase">Now playing screen</span>
<section class="group rounded-3xl border border-[#2a2a36] bg-np-bg text-np-ink [--p:0] [--v:1] flex max-w-[380px] flex-col gap-[18px] bg-[linear-gradient(180deg,#26203a_0,var(--color-np-bg)_320px)] px-[22px] pt-5 pb-[22px]" data-np aria-label="Now playing, Late Night Drive">
<audio src="../audio/track-3.mp3" preload="metadata"></audio>
<p class="text-center text-[.72rem] tracking-[.1em] text-np-muted uppercase">Playing from playlist <b class="mt-[3px] block text-[.88rem] tracking-normal text-np-ink normal-case">Late Night Drive</b></p>
<div class="aspect-square rounded-[18px] shadow-[0_20px_40px_rgba(0,0,0,.5)] [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-cover aria-hidden="true"></div>
<div class="flex items-center gap-4">
<div class="min-w-0 flex-1"><p class="text-[1.3rem] font-extrabold tracking-[-.015em]" data-show="name">Night Bus to Nowhere</p><p class="mt-[3px] text-[.92rem] text-np-muted" data-show="artist">Orla Finch</p></div>
<button type="button" class="grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent aria-pressed:[&_svg]:fill-current" data-like aria-label="Like Night Bus to Nowhere" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-7.5-10.2A4.2 4.2 0 0 1 12 7.3a4.2 4.2 0 0 1 7.5 2.5C19.5 15.4 12 20 12 20z"/></svg></button>
</div>
<div>
<input type="range" class="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-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-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-[color:var(--color-np-ink)] [&::-webkit-slider-thumb]:border-0 focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[color:var(--color-np-ink)] [&::-moz-range-thumb]:border-0 focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] w-full flex-1 hover:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] hover:[&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)]" data-seek min="0" max="30" step="any" value="0" aria-label="Seek" aria-valuetext="0:00 of 0:30">
<div class="mt-1 flex justify-between"><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums" data-cur>0:00</span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums text-right" data-dur>0:30</span></div>
</div>
<div class="flex items-center justify-between">
<button type="button" class="grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent" data-shuffle aria-label="Shuffle" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h4v4M4 20 20 4M20 16v4h-4M15 15l5 5M4 4l5 5"/></svg></button>
<button type="button" class="grid flex-none cursor-pointer place-items-center rounded-full text-np-ink hover:bg-np-raise focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-11" data-prev aria-label="Previous track"><svg class="block size-6" 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 flex-none cursor-pointer place-items-center rounded-full bg-np-ink text-[#0c0c12] hover:bg-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-[60px]" data-play aria-label="Play Night Bus to Nowhere"><svg class="block size-[26px] 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-[26px] 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 flex-none cursor-pointer place-items-center rounded-full text-np-ink hover:bg-np-raise focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-11" data-next aria-label="Next track"><svg class="block size-6" 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>
<button type="button" class="grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent" data-repeat aria-label="Repeat this track" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m17 2 4 4-4 4"/><path d="M3 11V9a3 3 0 0 1 3-3h15"/><path d="m7 22-4-4 4-4"/><path d="M21 13v2a3 3 0 0 1-3 3H3"/></svg></button>
</div>
<div class="flex items-center gap-2">
<button type="button" class="group/m grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent" data-mute aria-label="Mute" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5 6 9H3v6h3l5 4z"/><path class="group-aria-pressed/m:hidden" d="M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13"/><path class="hidden group-aria-pressed/m:inline" d="m16 9 6 6m0-6-6 6"/></svg></button>
<input type="range" class="block h-[14px] min-w-0 cursor-pointer appearance-none bg-transparent [--f:var(--v)] 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-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-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-[color:var(--color-np-ink)] [&::-webkit-slider-thumb]:border-0 focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[color:var(--color-np-ink)] [&::-moz-range-thumb]:border-0 focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] w-full flex-1 hover:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] hover:[&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)]" data-vol min="0" max="1" step="0.05" value="0.7" aria-label="Volume" aria-valuetext="70%">
</div>
<p class="mt-1 -mb-2 text-[.72rem] tracking-[.1em] text-np-muted uppercase">Queue</p>
<ol>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-3.mp3" data-name="Night Bus to Nowhere" data-artist="Orla Finch" aria-current="true">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Night Bus to Nowhere</span><span class="mt-0.5 block text-[.78rem] text-np-muted">Orla Finch</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:30</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-1.mp3" data-name="Harbour Lights" data-artist="Juniper Vale">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Harbour Lights</span><span class="mt-0.5 block text-[.78rem] text-np-muted">Juniper Vale</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:24</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-4.mp3" data-name="Copper Sky" data-artist="Milo & the Tidelines">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Copper Sky</span><span class="mt-0.5 block text-[.78rem] text-np-muted">Milo & the Tidelines</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:29</span></button></li>
</ol>
</section></div>
<div><span class="mb-3.5 block text-[.72rem] tracking-[.12em] text-[#9ca3af] uppercase">Desktop player bar</span>
<section class="group rounded-3xl border border-[#2a2a36] bg-np-bg text-np-ink [--p:0] [--v:1] px-[18px] py-3" data-np aria-label="Player">
<audio src="../audio/track-2.mp3" preload="metadata"></audio>
<div class="grid grid-cols-[minmax(0,1.3fr)_minmax(0,1.5fr)_minmax(0,1fr)] items-center gap-5 max-[720px]:grid-cols-[1fr_auto]">
<div class="flex min-w-0 items-center gap-4">
<div class="size-[52px] flex-none rounded-[10px] [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-cover aria-hidden="true"></div>
<div class="min-w-0"><p class="truncate text-[.95rem] font-extrabold tracking-[-.015em]" data-show="name">Paper Kites</p><p class="mt-[3px] truncate text-[.8rem] text-np-muted" data-show="artist">The Lumen Choir</p></div>
<button type="button" class="grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent aria-pressed:[&_svg]:fill-current" data-like aria-label="Like Paper Kites" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-7.5-10.2A4.2 4.2 0 0 1 12 7.3a4.2 4.2 0 0 1 7.5 2.5C19.5 15.4 12 20 12 20z"/></svg></button>
</div>
<div class="flex flex-col gap-1 max-[720px]:col-span-full max-[720px]:row-start-2">
<div class="flex items-center justify-center gap-2">
<button type="button" class="grid flex-none cursor-pointer place-items-center rounded-full text-np-ink hover:bg-np-raise focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-9" 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 flex-none cursor-pointer place-items-center rounded-full bg-np-ink text-[#0c0c12] hover:bg-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-10" data-play aria-label="Play Paper Kites"><svg class="block size-5 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-5 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 flex-none cursor-pointer place-items-center rounded-full text-np-ink hover:bg-np-raise focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent size-9" 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-[.75rem] text-np-muted tabular-nums" data-cur>0:00</span>
<input type="range" class="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-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-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-[color:var(--color-np-ink)] [&::-webkit-slider-thumb]:border-0 focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[color:var(--color-np-ink)] [&::-moz-range-thumb]:border-0 focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] w-full flex-1 hover:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] hover:[&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)]" 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-[.75rem] text-np-muted tabular-nums text-right" data-dur>0:24</span>
</div>
</div>
<div class="flex items-center justify-end gap-1">
<button type="button" class="grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent aria-expanded:text-np-accent" data-queue aria-label="Queue" aria-expanded="false" aria-controls="np-queue-2"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h11M4 12h11M4 18h7M19 6v10"/><circle cx="17" cy="16.5" r="2"/></svg></button>
<button type="button" class="group/m grid size-10 flex-none cursor-pointer place-items-center rounded-full text-np-muted hover:bg-np-raise hover:text-np-ink aria-pressed:text-np-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-np-accent max-[720px]:hidden" data-mute aria-label="Mute" aria-pressed="false"><svg class="block size-5" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5 6 9H3v6h3l5 4z"/><path class="group-aria-pressed/m:hidden" d="M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13"/><path class="hidden group-aria-pressed/m:inline" d="m16 9 6 6m0-6-6 6"/></svg></button>
<input type="range" class="block h-[14px] min-w-0 cursor-pointer appearance-none bg-transparent [--f:var(--v)] 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-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] [&::-moz-range-track]:h-[4px] [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-ink)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-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-[color:var(--color-np-ink)] [&::-webkit-slider-thumb]:border-0 focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] [&::-moz-range-thumb]:size-[14px] [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[color:var(--color-np-ink)] [&::-moz-range-thumb]:border-0 focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_var(--color-np-bg),0_0_0_5px_var(--color-np-accent)] w-full flex-1 hover:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] hover:[&::-moz-range-track]:bg-[linear-gradient(to_right,var(--color-np-accent)_0_calc(7px_+_(100%_-_14px)_*_var(--f)),var(--color-np-track)_0)] w-24! flex-none! max-[720px]:hidden" data-vol min="0" max="1" step="0.05" value="0.7" aria-label="Volume" aria-valuetext="70%">
</div>
</div>
<ol class="mt-3 grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-1 border-t border-[#2a2a36] pt-2 [&[hidden]]:hidden" id="np-queue-2" hidden>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-2.mp3" data-name="Paper Kites" data-artist="The Lumen Choir" aria-current="true">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Paper Kites</span><span class="mt-0.5 block text-[.78rem] text-np-muted">The Lumen Choir</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:24</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-4.mp3" data-name="Copper Sky" data-artist="Milo & the Tidelines">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Copper Sky</span><span class="mt-0.5 block text-[.78rem] text-np-muted">Milo & the Tidelines</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:29</span></button></li>
<li><button type="button" class="group/item grid w-full cursor-pointer grid-cols-[40px_1fr_auto] items-center gap-3 rounded-xl px-2.5 py-2 text-left hover:bg-np-raise focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-np-accent" data-src="../audio/track-1.mp3" data-name="Harbour Lights" data-artist="Juniper Vale">
<span class="size-10 rounded-lg [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-[.92rem] font-semibold group-aria-[current=true]/item:text-np-accent">Harbour Lights</span><span class="mt-0.5 block text-[.78rem] text-np-muted">Juniper Vale</span></span><span class="min-w-[2.3em] text-[.75rem] text-np-muted tabular-nums">0:24</span></button></li>
</ol>
</section></div>
JavaScript
Copy
// Dark streaming players. Each [data-np] holds one <audio> and a queue of track buttons (data-src, data-name,
// data-artist). Also wires like, shuffle, repeat-one, mute, volume and the queue toggle when they are present.
(() => {
const fmt = s => { s = Math.floor(s || 0); return Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0'); };
const toggle = b => { const on = b.getAttribute('aria-pressed') !== 'true'; b.setAttribute('aria-pressed', String(on)); return on; };
document.querySelectorAll('[data-np]').forEach(root => {
const $ = s => root.querySelector(s);
const audio = $('audio'), play = $('[data-play]'), seek = $('[data-seek]'), cur = $('[data-cur]'), dur = $('[data-dur]');
const vol = $('[data-vol]'), mute = $('[data-mute]'), shuffle = $('[data-shuffle]'), repeat = $('[data-repeat]');
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 sound = () => {
const v = audio.muted ? 0 : audio.volume;
root.style.setProperty('--v', v);
if (vol) { vol.value = v; vol.setAttribute('aria-valuetext', Math.round(v * 100) + '%'); }
if (mute) mute.setAttribute('aria-pressed', String(v === 0));
};
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]; });
root.querySelectorAll('[data-like]').forEach(b => { b.setAttribute('aria-pressed', 'false'); b.setAttribute('aria-label', 'Like ' + item.dataset.name); });
if (cover && art) {
const cs = getComputedStyle(art);
['backgroundImage', 'backgroundPosition', 'backgroundSize', 'backgroundRepeat'].forEach(p => { cover.style[p] = cs[p]; });
}
label();
};
const next = () => {
const on = shuffle && shuffle.getAttribute('aria-pressed') === 'true';
load(on ? (i + 1 + Math.floor(Math.random() * (items.length - 1))) % items.length : i + 1);
start();
};
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', next);
items.forEach((item, n) => item.addEventListener('click', () => {
if (n === i) return play.click();
load(n); start();
}));
root.querySelectorAll('[data-like]').forEach(b => b.addEventListener('click', () => toggle(b)));
if (shuffle) shuffle.addEventListener('click', () => toggle(shuffle));
if (repeat) repeat.addEventListener('click', () => { audio.loop = toggle(repeat); });
root.querySelectorAll('[data-queue]').forEach(b => b.addEventListener('click', () => {
const open = b.getAttribute('aria-expanded') !== 'true';
b.setAttribute('aria-expanded', String(open));
document.getElementById(b.getAttribute('aria-controls')).hidden = !open;
}));
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 || (shuffle && shuffle.getAttribute('aria-pressed') === 'true')) next(); });
audio.addEventListener('loadedmetadata', meta);
audio.addEventListener('volumechange', sound);
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();
});
if (vol) {
audio.volume = vol.value;
vol.addEventListener('input', () => { audio.volume = vol.value; audio.muted = false; });
}
if (mute) mute.addEventListener('click', () => {
if (audio.muted || audio.volume === 0) { audio.muted = false; if (audio.volume === 0) audio.volume = 0.6; }
else audio.muted = true;
});
sound();
});
})();