CI Build Status Chip
A copy-paste indicators component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.
IndicatorsHTMLJavaScriptCSSany framework
Queued
Copy into your project
HTML
<div class="nuda-in2-cistatus" data-state="queued" role="status" aria-live="polite">
<span class="nuda-in2-cistatus__icon" aria-hidden="true">
<svg class="nuda-in2-cistatus__i-queued" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9" />
<path d="M12 7v5l3 2" />
</svg>
<svg class="nuda-in2-cistatus__i-running" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<path d="M21 12a9 9 0 1 1-3-6.7" />
</svg>
<svg class="nuda-in2-cistatus__i-passed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 6 9 17l-5-5" />
</svg>
</span>
<span class="nuda-in2-cistatus__text">Queued</span>
</div>JavaScript
/* CI Build Status Chip — vanilla JS
Advances queued -> running -> passed once, updating the
visible label so the status is always stated in words. */
(function () {
var STEPS = [
{ key: "queued", text: "Queued", hold: 1400 },
{ key: "running", text: "Running", hold: 2200 },
{ key: "passed", text: "Passed", hold: 4000 },
];
document.querySelectorAll(".nuda-in2-cistatus").forEach(function (el) {
var label = el.querySelector(".nuda-in2-cistatus__text");
var i = 0;
function advance() {
var s = STEPS[i];
el.setAttribute("data-state", s.key);
label.textContent = s.text;
if (i < STEPS.length - 1) {
i++;
setTimeout(advance, s.hold);
}
}
setTimeout(advance, STEPS[0].hold);
});
})();CSS
.nuda-in2-cistatus {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
background: #161616;
border: 1px solid rgba(255,255,255,.1);
border-radius: 8px;
font-size: 11px;
font-weight: 600;
color: #cfcfcf;
}
.nuda-in2-cistatus__icon {
position: relative;
width: 13px;
height: 13px;
flex: 0 0 auto;
}
.nuda-in2-cistatus__icon svg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: none;
}
.nuda-in2-cistatus[data-state="queued"] .nuda-in2-cistatus__i-queued {
display: block;
color: #a0a0a0;
}
.nuda-in2-cistatus[data-state="running"] .nuda-in2-cistatus__i-running {
display: block;
color: #e4ff54;
animation: _nuda-in2cistatus-spin .9s linear infinite;
}
.nuda-in2-cistatus[data-state="passed"] .nuda-in2-cistatus__i-passed {
display: block;
color: #6ee7b7;
}
.nuda-in2-cistatus[data-state="running"] .nuda-in2-cistatus__text {
color: #e4ff54;
}
.nuda-in2-cistatus[data-state="passed"] .nuda-in2-cistatus__text {
color: #6ee7b7;
}
@keyframes _nuda-in2cistatus-spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion:reduce) {
.nuda-in2-cistatus__i-running {
animation: none !important;
}
}
How to use CI Build Status Chip
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.