<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Spinning CD — Animated Background</title>
<style>
:root{
--size: 360px; /* disc diameter, change as needed */
--speed: 6s; /* spin speed */
--bg: #0b0f14; /* page background color */
--gloss-opacity: 0.25;/* glare intensity */
}
html,body{height:100%;margin:0}
body{
background: radial-gradient(1200px 800px at 10% 10%, rgba(255,255,255,0.02), transparent 5%),
radial-gradient(900px 600px at 90% 90%, rgba(255,255,255,0.01), transparent 10%),
var(--bg);
display:flex;align-items:center;justify-content:center;overflow:hidden;
font-family:system-ui,Segoe UI,Roboto,"Helvetica Neue",Arial;
}
/* full-screen subtle animation so the background feels alive */
.stage{
position:fixed;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;
}
.cd-wrap{
width:var(--size);height:var(--size);border-radius:50%;position:relative;transform-style:preserve-3d;
filter:drop-shadow(0 20px 40px rgba(0,0,0,0.55));
}
/* The spinning disc (base) */
.disc{
position:absolute;inset:0;border-radius:50%;overflow:hidden;transform:translateZ(1px);
background: radial-gradient(circle at 60% 35%, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.02) 8%, transparent 30%),
radial-gradient(circle at 35% 65%, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.02) 18%, transparent 40%),
#0f1720;
}
/* rainbow reflection layer created with a conic-gradient and blur, animated to shimmer */
.rainbow{
position:absolute;inset:0;border-radius:50%;mix-blend-mode:screen;opacity:0.95;pointer-events:none;
background: conic-gradient(from 200deg at 50% 50%,
rgba(255,0,90,0.9), rgba(255,140,0,0.9), rgba(255,240,0,0.9), rgba(0,200,80,0.9), rgba(0,160,255,0.9), rgba(120,0,255,0.9), rgba(255,0,90,0.9));
filter: blur(10px) saturate(140%);
transform-origin:50% 50%;
animation: rainbow-rotate calc(var(--speed) * 0.8) linear infinite;
}
@keyframes rainbow-rotate{
from{transform: rotate(0deg) scale(1.12) translateZ(0)}
50%{transform: rotate(180deg) scale(1.06) translateZ(0)}
to{transform: rotate(360deg) scale(1.12) translateZ(0)}
}
/* subtle inner ring to mimic the shiny metal area near the hole */
.inner-ring{
position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:28%;height:28%;border-radius:50%;
background: radial-gradient(circle at 40% 40%, rgba(255,255,255,0.85), rgba(255,255,255,0.45) 10%, rgba(255,255,255,0.08) 20%, transparent 40%),
rgba(20,20,20,0.9);
box-shadow: inset 0 2px 12px rgba(255,255,255,0.06), inset 0 -6px 18px rgba(0,0,0,0.6);
z-index:5;backdrop-filter: blur(2px);
}
/* gloss overlay that travels across the disc to simulate reflection */
.gloss{
position:absolute;inset:-30% -30% -30% -30%;border-radius:50%;pointer-events:none;
background: linear-gradient(120deg, transparent 0%, rgba(255,255,255,var(--gloss-opacity)) 48%, rgba(255,255,255,0.0) 60%);
transform: rotate(-14deg);
animation: gloss-slide 3.6s ease-in-out infinite;
mix-blend-mode: overlay;
z-index:6;
}
@keyframes gloss-slide{
0%{transform: translateX(-30%) rotate(-14deg)}
50%{transform: translateX(30%) rotate(-14deg)}
100%{transform: translateX(-30%) rotate(-14deg)}
}
/* spin the whole cd-wrap to simulate playback */
.playing .cd-wrap{animation: spin var(--speed) linear infinite}
@keyframes spin{from{transform: rotateZ(0)}to{transform: rotateZ(360deg)}}
/* small animated 'play' indicator - pulses while playing */
.indicator{
position:absolute;right:8%;bottom:8%;width:40px;height:40px;border-radius:8px;background:rgba(255,255,255,0.06);
display:grid;place-items:center;backdrop-filter: blur(4px);z-index:8;pointer-events:auto;
}
.indicator .triangle{width:0;height:0;border-left:12px solid rgba(255,255,255,0.9);border-top:8px solid transparent;border-bottom:8px solid transparent;}
.playing .indicator{animation: pulse 1.8s ease-in-out infinite}
@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.08)}100%{transform:scale(1)}}
/* make the whole thing responsive on tiny viewports */
@media (max-width:420px){:root{--size:220px}}
/* optional: a subtle VHS noise texture overlay to make the background feel tactile */
.grain{position:fixed;inset:0;pointer-events:none;mix-blend-mode:overlay;opacity:0.06;background-image:
linear-gradient(transparent 50%, rgba(255,255,255,0.02) 51%);background-size:100% 2px;z-index:20}
</style>
</head>
<body>
<div class="stage playing" aria-hidden="true">
<div class="cd-wrap">
<div class="disc">
<div class="rainbow"></div>
<div class="gloss"></div>
<div class="inner-ring"></div>
</div>
<div class="indicator" title="Playing">
<div class="triangle"></div>
</div>
</div>
</div>
<div class="grain"></div>
<script>
// Small script to toggle the "playing" state when clicked (useful for demos)
document.querySelector('.stage').addEventListener('click', e=>{
const st = document.querySelector('.stage');
st.classList.toggle('playing');
});
// Expose CSS custom properties for convenience so you can control speed/size from JS
window.setDiscSize = sizePx => document.documentElement.style.setProperty('--size', sizePx+'px');
window.setSpinSpeed = seconds => document.documentElement.style.setProperty('--speed', seconds+'s');
</script>
<!--
Text prompts for image models (DALL·E / Stable Diffusion / Midjourney):
Short single-line prompt:
"Photorealistic close-up of a blank compact disc spinning, showing vivid multi-color iridescent reflections and a soft glossy glare, isolated on dark background, cinematic lighting, ultra-detailed, 4k"
Enhanced prompt with style parameters:
"Blank compact disc spinning in place, strong multi-color interference/reflections across the surface (rainbow concentric bands), subtle motion blur, soft glossy specular highlights and a linear sheen, high contrast cinematic lighting, shallow depth of field, studio backdrop, photorealistic, ultra-detailed, 8k --ar 16:9 --v 5 --q 2"
Tips:
- Use 'conic gradient' or 'interference' keywords for generators that support technical words.
- Ask for 'transparent background' if you need the disc as an overlay for web use.
-->
</body>
</html>