Holographic Collectible
Pentagonal collectible badge with a cursor-tracked conic-gradient foil and a tier glyph. The Mythic tier carries its own ambient pulse — visible across the room.
Holographic Collectible the 30th of 30 designs in the 30 CSS Badges collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="holo-card">
<div class="holo-badge holo-mythic">
<div class="holo-face holo-base"></div>
<div class="holo-face holo-foil"></div>
<div class="holo-face holo-sheen"></div>
<div class="holo-face holo-edge"></div>
<div class="holo-glyph">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
<path d="M12 1l3 6 7 1-5 5 1 7-6-3-6 3 1-7-5-5 7-1z"/>
</svg>
<div class="holo-rarity">RARITY</div>
<div class="holo-tier">MYTHIC</div>
</div>
<div class="holo-serial">#00007 / 00050</div>
</div>
<div class="holo-name">The Ascendant</div>
<div class="holo-pop">POP 44</div>
</div> .holo-card {
background: radial-gradient(ellipse at 50% 50%, #0e0a1a 0%, #050208 100%);
padding: 56px 40px;
font-family: 'Geist Mono', ui-monospace, monospace;
text-align: center;
min-height: 360px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.holo-badge {
width: 200px;
height: 230px;
margin: 0 auto 24px;
position: relative;
cursor: pointer;
--mx: 50%;
--my: 50%;
}
.holo-face {
position: absolute;
inset: 0;
clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
}
.holo-base {
background: linear-gradient(135deg, #1a1230 0%, #0a0815 100%);
box-shadow: inset 0 0 20px rgba(255,255,255,0.05);
}
.holo-foil {
background:
conic-gradient(from var(--angle, 0deg) at var(--mx) var(--my),
#ff0080, #ff8c00, #ffd700, #00ff88, #00bfff, #8a2be2, #ff0080);
mix-blend-mode: screen;
opacity: 0.75;
transition: opacity 0.4s;
filter: saturate(1.3) blur(0.4px);
}
.holo-sheen {
background: radial-gradient(circle 80px at var(--mx) var(--my),
rgba(255,255,255,0.6), transparent 70%);
mix-blend-mode: overlay;
opacity: 0;
transition: opacity 0.4s;
}
.holo-edge {
background: linear-gradient(135deg,
rgba(255,215,140,0.6) 0%,
rgba(180,140,255,0.4) 50%,
rgba(120,200,255,0.6) 100%);
clip-path: polygon(
50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%,
5% 27%, 7% 26%, 7% 74%, 50% 97%, 93% 74%, 93% 26%, 50% 3%
);
}
.holo-badge:hover .holo-foil { opacity: 1; }
.holo-badge:hover .holo-sheen { opacity: 1; }
.holo-glyph {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
z-index: 2;
text-shadow: 0 0 12px rgba(255,255,255,0.3);
pointer-events: none;
}
.holo-glyph svg { width: 56px; height: 56px; margin-bottom: 8px; }
.holo-rarity {
font-size: 10px;
letter-spacing: 0.3em;
opacity: 0.85;
margin-bottom: 2px;
}
.holo-tier {
font-size: 16px;
letter-spacing: 0.18em;
font-weight: 600;
}
.holo-serial {
position: absolute;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
font-size: 8px;
letter-spacing: 0.2em;
color: rgba(255,255,255,0.6);
z-index: 2;
}
.holo-name {
font-family: Georgia, serif;
color: #f5f0e0;
font-size: 20px;
font-style: italic;
margin-bottom: 4px;
}
.holo-pop {
font-size: 10px;
letter-spacing: 0.2em;
color: rgba(255,255,255,0.4);
text-transform: uppercase;
}
.holo-mythic .holo-base {
animation: holo-mythic-pulse 3s ease-in-out infinite;
}
@keyframes holo-mythic-pulse {
0%, 100% {
box-shadow: inset 0 0 20px rgba(255,100,255,0.2),
0 0 30px rgba(255,100,255,0.2);
}
50% {
box-shadow: inset 0 0 40px rgba(255,100,255,0.5),
0 0 60px rgba(255,100,255,0.4);
}
}
@media (prefers-reduced-motion: reduce) {
.holo-mythic .holo-base { animation: none; }
} // Cursor-tracked foil. Updates two CSS custom properties on the
// .holo-badge so the conic gradient and the sheen highlight follow
// the pointer. mouseleave resets so the badge isn't stuck mid-tilt.
document.querySelectorAll('.holo-badge').forEach(function (badge) {
badge.addEventListener('mousemove', function (e) {
var r = badge.getBoundingClientRect();
var x = ((e.clientX - r.left) / r.width) * 100;
var y = ((e.clientY - r.top) / r.height) * 100;
badge.style.setProperty('--mx', x + '%');
badge.style.setProperty('--my', y + '%');
badge.style.setProperty('--angle', (x * 3.6) + 'deg');
});
badge.addEventListener('mouseleave', function () {
badge.style.setProperty('--mx', '50%');
badge.style.setProperty('--my', '50%');
});
});