All Prompts
All Prompts

carddashboardtailwindanalyticsgamificationinteractiveanimated
Gamified Analytics Stat Card with XP Progress
Интерактивная карта аналитики с прогрессом XP: счетчики, кольцо/полоса прогресса, уровень, монеты, кнопка Gain XP. Для дашбордов, геймификации.
Prompt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Level Up Growth</title>
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@theme {
--font-sans: "Fredoka", ui-sans-serif, system-ui, sans-serif;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(-20px) rotate(5deg); }
}
@keyframes float-reverse {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(20px) rotate(-5deg); }
}
@keyframes coin-up {
0% { transform: translateY(0) scale(1); opacity: 1; }
100% { transform: translateY(-120px) scale(1.5); opacity: 0; }
}
@keyframes confetti-fall {
0% { transform: translateY(-10vh) rotate(0deg); opacity: 1; }
100% { transform: translateY(100vh) rotate(720deg); opacity: 0; }
}
@keyframes pulse-soft {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.animate-float { animation: float 6s ease-in-out infinite; }
.animate-float-reverse { animation: float-reverse 7s ease-in-out infinite; }
.animate-pulse-soft { animation: pulse-soft 2s ease-in-out infinite; }
.animate-coin-up { animation: coin-up 0.8s ease-out forwards; }
.animate-confetti { animation: confetti-fall 2.5s ease-out forwards; }
.btn-3d {
transition: all 0.1s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 8px 0 #0284c7;
}
.btn-3d:active {
transform: translateY(8px);
box-shadow: 0 0px 0 #0284c7;
}
</style>
</head>
<body
class="min-h-screen bg-[#E0E7FF] flex items-center justify-center p-4 relative overflow-hidden font-sans selection:bg-pink-200">
<!-- Background shapes -->
<!-- Main Card -->
<div
class="bg-white/90 backdrop-blur-xl rounded-[48px] p-8 w-full max-w-md shadow-[0_30px_60px_rgba(0,0,0,0.1)] relative z-10 border-[6px] border-white">
<!-- Header -->
<div class="flex justify-between items-center mb-10">
<div class="flex items-center gap-3">
<div
class="w-14 h-14 bg-purple-100 rounded-[20px] flex items-center justify-center text-3xl shadow-sm border-2 border-white">
🚀
</div>
<h1 class="text-2xl font-extrabold text-slate-800 tracking-tight leading-tight">Level
Up<br/><span class="text-purple-600">Growth</span></h1>
</div>
<div class="flex items-center gap-2 bg-yellow-100 px-5 py-3 rounded-full shadow-sm border-2 border-white">
<span class="text-2xl drop-shadow-sm">🪙</span>
<span id="coin-display" class="font-extrabold text-yellow-700 text-xl">0</span>
</div>
</div>
<!-- Level Badge & XP -->
<div class="flex flex-col items-center mb-10">
<div class="relative mb-8">
<div
class="w-40 h-40 bg-gradient-to-br from-indigo-400 via-purple-500 to-pink-500 rounded-full flex items-center justify-center shadow-[0_15px_35px_rgba(168,85,247,0.4)] animate-pulse-soft border-[6px] border-white">
<div class="text-center text-white drop-shadow-md">
<div class="text-sm font-bold uppercase tracking-widest opacity-90 mb-1">Level</div>
<div id="level-display" class="text-7xl font-black leading-none">12</div>
</div>
</div>
<div
class="absolute -bottom-2 -right-2 w-14 h-14 bg-yellow-400 rounded-full flex items-center justify-center text-3xl shadow-lg border-[4px] border-white transform rotate-12 hover:rotate-45 transition-transform duration-300">
⭐
</div>
</div>
<div class="w-full px-2">
<div class="flex justify-between text-sm font-bold text-slate-500 mb-3 px-2">
<span class="uppercase tracking-wider">XP Progress</span>
<span id="xp-text" class="text-purple-600">450 / 1000</span>
</div>
<div class="h-8 bg-slate-100 rounded-full overflow-hidden shadow-inner p-1.5 border-2 border-slate-200/50">
<div id="xp-bar"
class="h-full bg-gradient-to-r from-green-400 to-emerald-500 rounded-full transition-all duration-500 ease-out relative shadow-sm"
style="width: 45%">
<div class="absolute inset-0 bg-white/30 w-full h-1/2 rounded-t-full"></div>
</div>
</div>
</div>
</div>
<!-- Stat Cards -->
<div class="grid grid-cols-2 gap-4 mb-10 max-w-sm mx-auto place-items-center">
<div
class="bg-[#E0F2FE] rounded-[28px] p-5 flex flex-col justify-between shadow-sm border-4 border-white relative overflow-hidden transition-transform hover:scale-105 duration-300">
<div class="absolute -right-2 -top-2 text-6xl opacity-20 filter blur-[1px]">👥</div>
<div class="flex items-center gap-3 mb-3 relative z-10">
<div class="w-10 h-10 bg-white rounded-2xl flex items-center justify-center text-xl shadow-sm text-[#0284C7]">
👥</div>
<span class="font-bold text-slate-700 text-sm tracking-wide">Users</span>
</div>
<div id="stat-users" class="text-3xl font-extrabold text-[#0284C7] relative z-10 drop-shadow-sm">0</div>
</div>
<div
class="bg-[#DCFCE7] rounded-[28px] p-5 flex flex-col justify-between shadow-sm border-4 border-white relative overflow-hidden transition-transform hover:scale-105 duration-300">
<div class="absolute -right-2 -top-2 text-6xl opacity-20 filter blur-[1px]">💰</div>
<div class="flex items-center gap-3 mb-3 relative z-10">
<div class="w-10 h-10 bg-white rounded-2xl flex items-center justify-center text-xl shadow-sm text-[#16A34A]">
💰</div>
<span class="font-bold text-slate-700 text-sm tracking-wide">Revenue</span>
</div>
<div id="stat-revenue" class="text-3xl font-extrabold text-[#16A34A] relative z-10 drop-shadow-sm">$0</div>
</div>
<div
class="bg-[#FEF3C7] rounded-[28px] p-5 flex flex-col justify-between shadow-sm border-4 border-white relative overflow-hidden transition-transform hover:scale-105 duration-300">
<div class="absolute -right-2 -top-2 text-6xl opacity-20 filter blur-[1px]">📱</div>
<div class="flex items-center gap-3 mb-3 relative z-10">
<div class="w-10 h-10 bg-white rounded-2xl flex items-center justify-center text-xl shadow-sm text-[#D97706]">
📱</div>
<span class="font-bold text-slate-700 text-sm tracking-wide">Sessions</span>
</div>
<div id="stat-sessions" class="text-3xl font-extrabold text-[#D97706] relative z-10 drop-shadow-sm">0</div>
</div>
<div
class="bg-[#FCE7F3] rounded-[28px] p-5 flex flex-col justify-between shadow-sm border-4 border-white relative overflow-hidden transition-transform hover:scale-105 duration-300">
<div class="absolute -right-2 -top-2 text-6xl opacity-20 filter blur-[1px]">⚡</div>
<div class="flex items-center gap-3 mb-3 relative z-10">
<div class="w-10 h-10 bg-white rounded-2xl flex items-center justify-center text-xl shadow-sm text-[#DB2777]">
⚡</div>
<span class="font-bold text-slate-700 text-sm tracking-wide">Conversion</span>
</div>
<div id="stat-conversion" class="text-3xl font-extrabold text-[#DB2777] relative z-10 drop-shadow-sm">0%</div>
</div>
</div>
<!-- Action Button -->
<button id="gain-xp-btn" class="w-full bg-[#38BDF8] hover:bg-[#0EA5E9] text-white text-3xl font-black py-6 rounded-[32px] btn-3d relative overflow-hidden group border-4 border-white/20 cursor-pointer">
<span class="relative z-10 flex items-center justify-center gap-3 drop-shadow-md pointer-events-none">
Gain XP <span class="text-4xl group-hover:scale-125 group-hover:rotate-12 transition-transform duration-300">✨</span>
</span>
<div class="absolute inset-0 bg-white/20 w-full h-1/3 rounded-t-[32px] pointer-events-none"></div>
</button>
</div>
<!-- Containers for dynamic elements -->
<div id="floating-coins-container"></div>
<div id="confetti-container" class="fixed inset-0 pointer-events-none z-50 overflow-hidden hidden"></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Animation function for counters
function animateCounter(el, start, end, duration, prefix = '', suffix = '', decimals = 0) {
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const easeProgress = 1 - Math.pow(1 - progress, 4);
const current = easeProgress * (end - start) + start;
el.textContent = `${prefix}${current.toFixed(decimals)}${suffix}`;
if (progress < 1) {
window.requestAnimationFrame(step);
} else {
el.textContent = `${prefix}${end.toFixed(decimals)}${suffix}`;
}
}
window.requestAnimationFrame(step);
}
// Initial animations
animateCounter(document.getElementById('stat-users'), 0, 12450, 1500);
animateCounter(document.getElementById('stat-revenue'), 0, 8420, 1500, '$');
animateCounter(document.getElementById('stat-sessions'), 0, 45200, 1500);
animateCounter(document.getElementById('stat-conversion'), 0, 4.8, 1500, '', '%', 1);
animateCounter(document.getElementById('coin-display'), 0, 1250, 1000);
// Game State
let level = 12;
let xp = 450;
const maxXp = 1000;
let coins = 1250;
// DOM Elements
const xpBar = document.getElementById('xp-bar');
const xpText = document.getElementById('xp-text');
const levelDisplay = document.getElementById('level-display');
const coinDisplay = document.getElementById('coin-display');
const gainXpBtn = document.getElementById('gain-xp-btn');
const floatingCoinsContainer = document.getElementById('floating-coins-container');
const confettiContainer = document.getElementById('confetti-container');
function updateUI() {
xpBar.style.width = `${(xp / maxXp) * 100}%`;
xpText.textContent = `${xp} / ${maxXp}`;
levelDisplay.textContent = level;
coinDisplay.textContent = Math.floor(coins);
}
function triggerConfetti() {
confettiContainer.innerHTML = '';
confettiContainer.classList.remove('hidden');
const colors = ['#FF6B6B', '#4ECDC4', '#FFE66D', '#FF9F1C', '#2EC4B6', '#C77DFF'];
for (let i = 0; i < 60; i++) {
const confetti = document.createElement('div');
const left = Math.random() * 100;
const animationDelay = Math.random() * 0.5;
const size = Math.random() * 12 + 6;
const color = colors[Math.floor(Math.random() * colors.length)];
const shape = Math.random() > 0.5 ? '50%' : '4px';
confetti.className = 'absolute top-0 animate-confetti';
confetti.style.left = `${left}%`;
confetti.style.width = `${size}px`;
confetti.style.height = `${size}px`;
confetti.style.backgroundColor = color;
confetti.style.borderRadius = shape;
confetti.style.animationDelay = `${animationDelay}s`;
confettiContainer.appendChild(confetti);
}
setTimeout(() => {
confettiContainer.classList.add('hidden');
}, 3000);
}
gainXpBtn.addEventListener('click', (e) => {
// Spawn floating coin
const rect = gainXpBtn.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top;
const coin = document.createElement('div');
coin.className = 'fixed text-5xl animate-coin-up pointer-events-none z-50 drop-shadow-lg';
coin.style.left = `${x - 24}px`;
coin.style.top = `${y - 24}px`;
coin.textContent = '🪙';
floatingCoinsContainer.appendChild(coin);
setTimeout(() => coin.remove(), 800);
// Update state
coins += 15;
xp += 180;
if (xp >= maxXp) {
level += 1;
xp -= maxXp;
triggerConfetti();
}
updateUI();
});
});
</script>
</body>
</html>