Voice Input Waveform
A copy-paste ai / chat ui component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.
AI / Chat UIHTMLCSSany framework
0:07
Copy into your project
HTML
<!-- Voice Input Waveform — recording mic button with live waveform -->
<div class="nuda-ac2-voice">
<button class="nuda-ac2-voice__btn nuda-ac2-voice__btn--active" aria-label="Stop recording" aria-pressed="true" type="button">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<rect x="9" y="2" width="6" height="12" rx="3" />
<path d="M5 11 A 7 7 0 0 0 19 11 M12 18 L12 22 M8 22 L16 22" />
</svg>
</button>
<span class="nuda-ac2-voice__wave" aria-hidden="true">
<i></i><i></i><i></i><i></i><i></i>
</span>
<span class="nuda-ac2-voice__time">0:07</span>
</div>CSS
.nuda-ac2-voice {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 8px 14px 8px 8px;
background: #141414;
border: 1px solid rgba(255,255,255,.1);
border-radius: 999px;
font: 12px ui-sans-serif,system-ui,sans-serif;
}
.nuda-ac2-voice__btn {
position: relative;
width: 44px;
height: 44px;
flex: none;
display: flex;
align-items: center;
justify-content: center;
background: #e4ff54;
color: #0a0a0a;
border: none;
border-radius: 50%;
cursor: pointer;
}
.nuda-ac2-voice__btn svg {
width: 18px;
height: 18px;
position: relative;
z-index: 1;
}
.nuda-ac2-voice__btn--active::after {
content: "";
position: absolute;
inset: -4px;
border-radius: 50%;
border: 1.5px solid #ef4444;
animation: _nuda-ac2voicering 1.6s ease-out infinite;
}
.nuda-ac2-voice__wave {
display: inline-flex;
align-items: center;
gap: 3px;
height: 18px;
}
.nuda-ac2-voice__wave i {
width: 3px;
height: 14px;
background: #e4ff54;
border-radius: 2px;
display: inline-block;
transform-origin: center;
animation: _nuda-ac2voice 1s ease-in-out infinite;
}
.nuda-ac2-voice__wave i:nth-child(1) {
animation-delay: 0s;
}
.nuda-ac2-voice__wave i:nth-child(2) {
animation-delay: .12s;
}
.nuda-ac2-voice__wave i:nth-child(3) {
animation-delay: .24s;
}
.nuda-ac2-voice__wave i:nth-child(4) {
animation-delay: .36s;
}
.nuda-ac2-voice__wave i:nth-child(5) {
animation-delay: .48s;
}
.nuda-ac2-voice__time {
color: #a1a1aa;
font-variant-numeric: tabular-nums;
font-size: 11px;
}
@keyframes _nuda-ac2voicering {
0% {
transform: scale(.8);
opacity: .8;
}
100% {
transform: scale(1.4);
opacity: 0;
}
}
@keyframes _nuda-ac2voice {
0%,100% {
transform: scaleY(.3);
}
50% {
transform: scaleY(1);
}
}
@media (prefers-reduced-motion: reduce) {
.nuda-ac2-voice__btn--active::after {
animation: none !important;
opacity: .5;
}
.nuda-ac2-voice__wave i {
animation: none !important;
transform: scaleY(.7);
}
}
How to use Voice Input Waveform
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.