HTML Copy
<button class="pp-wave" type="button" aria-pressed="false" aria-label="Play" data-pp>
<svg viewBox="0 0 200 40" preserveAspectRatio="none" class="pp-wave-svg" aria-hidden="true">
<path
class="pp-wave-path"
d="M0 20 Q 20 0 40 20 T 80 20 T 120 20 T 160 20 T 200 20"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<span class="pp-wave-icon" aria-hidden="true"></span>
</button> CSS Copy
.pp-wave {
position: relative;
width: 140px;
height: 56px;
background: linear-gradient(135deg, #0c4a6e, #075985);
border: 1px solid rgba(56, 189, 248, 0.3);
border-radius: 14px;
color: #38bdf8;
cursor: pointer;
overflow: hidden;
display: grid;
place-items: center;
transition:
border-color 0.2s,
transform 0.15s;
}
.pp-wave:hover {
border-color: rgba(56, 189, 248, 0.6);
transform: translateY(-1px);
}
.pp-wave:focus-visible {
outline: 3px solid rgba(56, 189, 248, 0.4);
outline-offset: 3px;
}
.pp-wave-svg {
position: absolute;
inset: 0;
width: 200%;
height: 100%;
opacity: 0.6;
}
.pp-wave[aria-pressed="true"] .pp-wave-svg {
animation: ppWaveScroll 2.4s linear infinite;
}
@keyframes ppWaveScroll {
to {
transform: translateX(-50%);
}
}
.pp-wave-icon {
position: relative;
width: 0;
height: 0;
border-style: solid;
border-width: 9px 0 9px 13px;
border-color: transparent transparent transparent #38bdf8;
margin-left: 4px;
transition:
border-width 0.25s,
margin-left 0.25s;
}
.pp-wave[aria-pressed="true"] .pp-wave-icon {
border-width: 0 4px 0 4px;
border-color: transparent #38bdf8 transparent #38bdf8;
height: 18px;
margin-left: 0;
}
@media (prefers-reduced-motion: reduce) {
.pp-wave,
.pp-wave * {
animation: none !important;
}
}
JS Copy
// ── Drop this on every page where you render a play/pause button ──
// Toggles aria-pressed + aria-label on click. The CSS handles all visuals.
document.querySelectorAll('[data-pp]').forEach(function (btn) {
btn.addEventListener('click', function () {
var playing = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', String(!playing));
btn.setAttribute('aria-label', !playing ? 'Pause' : 'Play');
});
});