Copy Code
:root{
--bg: #0f172a;
--card: #0b1220;
--accent: linear-gradient(90deg,#7c3aed,#06b6d4);
--muted: #94a3b8;
--glass: rgba(255,255,255,0.04);
--success: #10b981;
}
*{box-sizing:border-box}
body{
margin:0;
font-family:Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
background: radial-gradient(1200px 600px at 10% 10%, rgba(124,58,237,0.10), transparent),
radial-gradient(800px 400px at 90% 90%, rgba(6,182,212,0.06), transparent),
var(--bg);
color:#e6eef8;
min-height:100vh;
display:flex;
align-items:center;
justify-content:center;
padding:32px;
}
.card{
background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
border-radius:16px;
padding:28px;
width:360px;
box-shadow: 0 10px 30px rgba(2,6,23,0.6);
border: 1px solid rgba(255,255,255,0.04);
}
h1{font-size:18px;margin:0 0 12px 0}
p{margin:0 0 18px 0;color:var(--muted);font-size:13px}
.download-wrap{
display:flex;
gap:12px;
align-items:center;
}
.btn{
--pad:12px 18px;
display:inline-flex;
align-items:center;
gap:10px;
padding:var(--pad);
border-radius:12px;
background:var(--glass);
border:1px solid rgba(255,255,255,0.04);
cursor:pointer;
user-select:none;
transition:transform .15s ease, box-shadow .15s ease;
box-shadow: 0 6px 18px rgba(2,6,23,0.5);
position:relative;
overflow:hidden;
min-width:160px;
justify-content:center;
}
.btn:active{transform:translateY(2px)}
.btn .label{font-weight:600;font-size:14px}
.btn::before{
content:"";
position:absolute;
left:-40%;top:0;height:100%;width:40%;
background:var(--accent);
filter:blur(18px);
opacity:0.35;
transform:skewX(-12deg);
transition: left .9s cubic-bezier(.2,.9,.3,1);
}
.btn.pulse::before{left:120%}
.icon{width:18px;height:18px;flex:0 0 18px}
.btn:hover{transform:translateY(-3px); box-shadow: 0 12px 30px rgba(2,6,23,0.6)}
.bar{
position:absolute;left:0;bottom:0;height:4px;background:var(--accent);width:0%;
transition: width .2s linear;
}
.btn.success{
background:linear-gradient(180deg, rgba(16,185,129,0.12), rgba(16,185,129,0.06));
border-color:rgba(16,185,129,0.18);
}
.note{font-size:12px;color:var(--muted);margin-top:10px}
@keyframes shine {
from { transform: translateX(-130%) skewX(-12deg); opacity:0 }
40% { opacity:0.6 }
to { transform: translateX(130%) skewX(-12deg); opacity:0 }
}
.btn .shine{
position:absolute;left:-130%;top:0;height:100%;width:36%;
background:linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,0.12), rgba(255,255,255,0));
transform:skewX(-12deg);
pointer-events:none;opacity:0
}
.btn.shining .shine{animation: shine 1.1s ease-in-out forwards}
.check{
width:18px;height:18px;display:inline-block;
transform:scale(0);transition:transform .28s cubic-bezier(.2,.9,.3,1);opacity:0
}
.btn.success .check{transform:scale(1);opacity:1}
.btn:focus{outline:3px solid rgba(99,102,241,0.18);outline-offset:4px}
@media (max-width:420px){.card{width:100%}}
Copy Code
const btn = document.getElementById('downloadBtn');
const bar = btn.querySelector('.bar');
const percent = document.getElementById('percent');
const label = btn.querySelector('.label');
let running = false;
function simulateDownload(){
if(running) return;
running = true;
btn.classList.remove('success');
btn.classList.add('pulse','shining');
label.textContent = 'Preparing...';
let p = 0;
setTimeout(()=> btn.classList.remove('shining'), 1100);
const step = () => {
const delta = 2 + Math.random()*8;
p = Math.min(100, p + delta);
bar.style.width = p + '%';
percent.textContent = Math.round(p) + '%';
if(p < 100){
if(Math.random() < 0.25) btn.classList.add('shining');
setTimeout(()=>{btn.classList.remove('shining')}, 900);
setTimeout(step, 140 + Math.random()*360);
} else {
finishDownload();
}
}
setTimeout(step, 300);
}
function finishDownload(){
label.textContent = 'Downloaded';
btn.classList.remove('pulse');
btn.classList.add('success');
percent.textContent = '100%';
const content = 'This is a demo file generated at ' + new Date().toLocaleString();
const blob = new Blob([content], {type: 'text/plain'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'demo-file.txt';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
running = false;
setTimeout(()=>{
bar.style.width = '0%';
percent.textContent = '0%';
label.textContent = 'Download';
btn.classList.remove('success');
}, 2500);
}
btn.addEventListener('click', simulateDownload);
btn.addEventListener('keydown', (e)=>{
if(e.key === 'Enter' || e.key === ' ') { e.preventDefault(); simulateDownload(); }
});