Countdown Boxed
<section class="p-6 max-w-md mx-auto">
<div class="bg-gradient-to-br from-slate-900 to-slate-800 rounded-2xl p-8 shadow-xl">
<div class="flex justify-between items-center mb-8">
<div class="h-1 w-16 bg-gradient-to-r from-amber-400 to-orange-400 rounded-full"></div>
<h3 class="text-xl font-bold text-black text-center">Limited Time Offer</h3>
<div class="h-1 w-16 bg-gradient-to-r from-amber-400 to-orange-400 rounded-full"></div>
</div>
<div class="flex justify-center space-x-6">
<div class="flex flex-col items-center">
<div class="relative perspective">
<div class="relative w-20 h-28">
<div class="w-20 h-14 rounded-t-lg bg-slate-700 border-b border-slate-900 flex items-center justify-center shadow-inner overflow-hidden">
<span id="hours-top" class="text-4xl font-bold text-black">08</span>
</div>
<div class="w-20 h-14 rounded-b-lg bg-slate-600 flex items-center justify-center shadow-lg overflow-hidden">
<span id="hours-bottom" class="text-4xl font-bold text-black">08</span>
</div>
<div class="absolute left-0 right-0 h-0.5 bg-slate-900 top-1/2 z-10"></div>
<div class="absolute -left-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-l"></div>
<div class="absolute -right-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-r"></div>
<div class="absolute inset-x-0 top-0 h-3 bg-gradient-to-b from-black to-transparent opacity-20"></div>
<div class="absolute inset-x-0 bottom-0 h-3 bg-gradient-to-t from-black to-transparent opacity-20"></div>
</div>
</div>
<span class="text-xs mt-3 text-amber-400 font-semibold tracking-wider uppercase">HOURS</span>
</div>
<div class="flex flex-col items-center">
<div class="relative perspective">
<div class="relative w-20 h-28">
<div class="w-20 h-14 rounded-t-lg bg-slate-700 border-b border-slate-900 flex items-center justify-center shadow-inner overflow-hidden">
<span id="minutes-top" class="text-4xl font-bold text-black">23</span>
</div>
<div class="w-20 h-14 rounded-b-lg bg-slate-600 flex items-center justify-center shadow-lg overflow-hidden">
<span id="minutes-bottom" class="text-4xl font-bold text-black">23</span>
</div>
<div class="absolute left-0 right-0 h-0.5 bg-slate-900 top-1/2 z-10"></div>
<div class="absolute -left-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-l"></div>
<div class="absolute -right-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-r"></div>
<div class="absolute inset-x-0 top-0 h-3 bg-gradient-to-b from-black to-transparent opacity-20"></div>
<div class="absolute inset-x-0 bottom-0 h-3 bg-gradient-to-t from-black to-transparent opacity-20"></div>
</div>
</div>
<span class="text-xs mt-3 text-amber-400 font-semibold tracking-wider uppercase">MINUTES</span>
</div>
<div class="flex flex-col items-center">
<div class="relative perspective" id="seconds-flip-container">
<div class="relative w-20 h-28">
<div class="w-20 h-14 rounded-t-lg bg-slate-700 border-b border-slate-900 flex items-center justify-center shadow-inner overflow-hidden">
<span id="seconds-top" class="text-4xl font-bold text-black">45</span>
</div>
<div class="w-20 h-14 rounded-b-lg bg-slate-600 flex items-center justify-center shadow-lg overflow-hidden">
<span id="seconds-bottom" class="text-4xl font-bold text-black">45</span>
</div>
<div id="flip-card" class="absolute inset-0 opacity-0">
<div class="w-20 h-14 rounded-t-lg bg-slate-700 border-b border-slate-900 flex items-center justify-center shadow-inner overflow-hidden origin-bottom" id="flip-top">
<span class="text-4xl font-bold text-black">45</span>
</div>
</div>
<div class="absolute left-0 right-0 h-0.5 bg-slate-900 top-1/2 z-10"></div>
<div class="absolute -left-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-l"></div>
<div class="absolute -right-1 top-0 bottom-0 w-1 bg-slate-900 opacity-50 rounded-r"></div>
<div class="absolute inset-x-0 top-0 h-3 bg-gradient-to-b from-black to-transparent opacity-20"></div>
<div class="absolute inset-x-0 bottom-0 h-3 bg-gradient-to-t from-black to-transparent opacity-20"></div>
</div>
</div>
<span class="text-xs mt-3 text-amber-400 font-semibold tracking-wider uppercase">SECONDS</span>
</div>
</div>
<div class="mt-8 text-center">
<p class="text-slate-400 text-sm">Don't miss out on this exclusive deal</p>
</div>
</div>
<style>
.perspective {
perspective: 1000px;
}
@keyframes flipTop {
0% { transform: rotateX(0deg); }
100% { transform: rotateX(-90deg); }
}
.flip-active {
animation: flipTop 0.3s ease-in;
animation-fill-mode: forwards;
}
</style>
<script>
function getTimeRemaining(endtime) {
const total = Date.parse(endtime) - Date.now();
const seconds = Math.floor((total / 1000) % 60);
const minutes = Math.floor((total / 1000 / 60) % 60);
const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
const days = Math.floor(total / (1000 * 60 * 60 * 24));
return {
total,
days,
hours,
minutes,
seconds
};
}
function formatNumber(num) {
return num < 10 ? `0${num}` : num;
}
function initBoxedCountdown(endtime) {
const hoursTopElement = document.getElementById('hours-top');
const hoursBottomElement = document.getElementById('hours-bottom');
const minutesTopElement = document.getElementById('minutes-top');
const minutesBottomElement = document.getElementById('minutes-bottom');
const secondsTopElement = document.getElementById('seconds-top');
const secondsBottomElement = document.getElementById('seconds-bottom');
let lastHours = -1;
let lastMinutes = -1;
let lastSeconds = -1;
function updateClock() {
const t = getTimeRemaining(endtime);
if (t.hours !== lastHours) {
if (hoursTopElement) hoursTopElement.textContent = formatNumber(t.hours);
if (hoursBottomElement) hoursBottomElement.textContent = formatNumber(t.hours);
lastHours = t.hours;
}
if (t.minutes !== lastMinutes) {
if (minutesTopElement) minutesTopElement.textContent = formatNumber(t.minutes);
if (minutesBottomElement) minutesBottomElement.textContent = formatNumber(t.minutes);
lastMinutes = t.minutes;
}
if (t.seconds !== lastSeconds) {
if (secondsTopElement) secondsTopElement.textContent = formatNumber(t.seconds);
if (secondsBottomElement) secondsBottomElement.textContent = formatNumber(t.seconds);
lastSeconds = t.seconds;
}
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
const timeinterval = setInterval(updateClock, 1000);
return timeinterval;
}
const deadline = new Date();
deadline.setHours(deadline.getHours() + 8);
initBoxedCountdown(deadline);
let lastFlipSeconds = -1;
function animateFlip() {
const t = getTimeRemaining(deadline);
const flipCard = document.getElementById('flip-card');
const flipTop = document.getElementById('flip-top');
const secondsTop = document.getElementById('seconds-top');
if (t.seconds !== lastFlipSeconds && flipCard && flipTop && secondsTop) {
const secondsSpan = flipTop.querySelector('span');
if (secondsSpan) {
secondsSpan.textContent = formatNumber(lastFlipSeconds >= 0 ? lastFlipSeconds : t.seconds);
}
flipCard.style.opacity = '1';
flipTop.classList.add('flip-active');
setTimeout(() => {
flipCard.style.opacity = '0';
flipTop.classList.remove('flip-active');
lastFlipSeconds = t.seconds;
}, 300);
}
}
setInterval(animateFlip, 1000);
</script>
</section>
Copied to clipboard