HTML
<label class="tg-wav">
<input class="tg-wav-input" type="checkbox" checked>
<span class="tg-wav-body" aria-hidden="true">
<span class="tg-wav-bars">
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span>
</span>
<span class="tg-wav-text">Microphone</span>
<span class="tg-wav-dot"></span>
</span>
</label> CSS
.tg-wav {
--tg-wav-rim: #14141e;
--tg-wav-wire: #1e1e2e;
--tg-wav-fog: #3a3a52;
--tg-wav-ash: #7a7a98;
--tg-wav-ice: #00e5ff;
display: inline-block;
cursor: pointer;
font-family: "Inter", "Segoe UI", system-ui, sans-serif;
font-size: 14px;
user-select: none;
}
.tg-wav-input {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden; clip: rect(0,0,0,0);
white-space: nowrap; border: 0;
}
.tg-wav-body {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 14px;
border-radius: 12px;
background: var(--tg-wav-rim);
border: 1px solid var(--tg-wav-wire);
min-width: 240px;
transition: border-color 0.3s ease, background 0.3s ease;
}
.tg-wav-bars {
display: flex;
align-items: center;
gap: 2.5px;
height: 28px;
}
.tg-wav-bars span {
display: block;
width: 3px;
border-radius: 2px;
background: var(--tg-wav-fog);
transition: background 0.3s ease, height 0.3s ease;
}
/* Static heights (off state) — each bar has its own resting height. */
.tg-wav-bars span:nth-child(1) { height: 8px; }
.tg-wav-bars span:nth-child(2) { height: 14px; }
.tg-wav-bars span:nth-child(3) { height: 20px; }
.tg-wav-bars span:nth-child(4) { height: 26px; }
.tg-wav-bars span:nth-child(5) { height: 18px; }
.tg-wav-bars span:nth-child(6) { height: 24px; }
.tg-wav-bars span:nth-child(7) { height: 12px; }
.tg-wav-bars span:nth-child(8) { height: 20px; }
.tg-wav-bars span:nth-child(9) { height: 8px; }
.tg-wav-text {
font-size: 13px;
color: var(--tg-wav-ash);
transition: color 0.3s ease;
}
.tg-wav-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--tg-wav-wire);
margin-left: auto;
flex-shrink: 0;
transition: background 0.3s ease, box-shadow 0.3s ease;
}
/* Each bar oscillates between its resting height and ~30% of it. The
varied durations + delays keep the pattern from looking robotic. */
@keyframes tg-wav-breathe {
0%, 100% { height: var(--tg-wav-h); }
50% { height: calc(var(--tg-wav-h) * 0.3 + 4px); }
}
.tg-wav-input:checked ~ .tg-wav-body {
border-color: rgba(0,229,255,0.3);
background: rgba(0,229,255,0.04);
}
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span {
background: var(--tg-wav-ice);
}
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(1) { animation: tg-wav-breathe 0.9s ease-in-out infinite; --tg-wav-h: 8px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(2) { animation: tg-wav-breathe 0.7s ease-in-out 0.1s infinite; --tg-wav-h: 14px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(3) { animation: tg-wav-breathe 1.1s ease-in-out 0.2s infinite; --tg-wav-h: 20px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(4) { animation: tg-wav-breathe 0.8s ease-in-out 0.05s infinite; --tg-wav-h: 26px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(5) { animation: tg-wav-breathe 1.0s ease-in-out 0.15s infinite; --tg-wav-h: 18px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(6) { animation: tg-wav-breathe 0.6s ease-in-out 0.25s infinite; --tg-wav-h: 24px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(7) { animation: tg-wav-breathe 0.9s ease-in-out 0.08s infinite; --tg-wav-h: 12px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(8) { animation: tg-wav-breathe 1.2s ease-in-out 0.18s infinite; --tg-wav-h: 20px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span:nth-child(9) { animation: tg-wav-breathe 0.75s ease-in-out 0.3s infinite; --tg-wav-h: 8px; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-text { color: var(--tg-wav-ice); }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-dot {
background: var(--tg-wav-ice);
box-shadow: 0 0 8px var(--tg-wav-ice);
}
.tg-wav-input:focus-visible ~ .tg-wav-body {
outline: 2px solid var(--tg-wav-ice);
outline-offset: 4px;
}
@media (prefers-reduced-motion: reduce) {
.tg-wav-body,
.tg-wav-bars span,
.tg-wav-dot,
.tg-wav-text { transition: none; }
.tg-wav-input:checked ~ .tg-wav-body .tg-wav-bars span { animation: none; }
}