Загрузка...

Интерактивная карточка Viral Score Hero с анимированным эквалайзером и счетчиком. Отображает вирусный потенциал и визуализацию фреймворка.
<div class="w-full flex items-center justify-center p-4">
<style>@import url('https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,700,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap');
.hero-card-comp {
font-family: 'Satoshi', 'Helvetica Neue', sans-serif;
}
.hero-card-comp .font-mono {
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
@keyframes gradientSlide {
0% { background-position: 0% 50%; }
100% { background-position: 200% 50%; }
}
.hero-card-comp .score-viral {
background: linear-gradient(90deg, #D97706, #F59E0B, #FCD34D, #F59E0B, #D97706);
background-size: 200% auto;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: gradientSlide 3s linear infinite;
}
.hero-card-comp .score-glow {
filter: drop-shadow(0 0 20px rgba(217, 119, 6, 0.4)) drop-shadow(0 0 40px rgba(217, 119, 6, 0.2));
}
@keyframes ping {
75%, 100% {
transform: scale(2);
opacity: 0;
}
}
.hero-card-comp .animate-ping {
animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes barGrow {
from {
height: 8%;
opacity: 0.3;
}
to {
height: var(--bar-height);
opacity: 1;
}
}
.hero-card-comp .equalizer-bar {
height: 8%;
opacity: 0.3;
}
.hero-card-comp .equalizer-bar.animate {
animation: barGrow 0.6s cubic-bezier(0.4, 0, 0.2, 1) forwards;
animation-delay: var(--bar-delay);
}
.hero-card-comp .bar-glow-gold {
box-shadow: 0 0 8px rgba(217, 119, 6, 0.5);
}
.hero-card-comp .bar-glow-teal {
box-shadow: 0 0 6px rgba(20, 184, 166, 0.4);
}
.hero-card-comp .bar-tooltip {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%) translateY(4px);
opacity: 0;
pointer-events: none;
transition: all 0.2s ease;
white-space: nowrap;
z-index: 50;
font-size: 10px;
}
.hero-card-comp .bar-container:hover .bar-tooltip {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
@keyframes border-spin {
to { --gradient-angle: 360deg; }
}
@keyframes shimmer-fallback {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.hero-card-comp .btn-shiny-hero {
position: relative;
background: linear-gradient(#000000, #000000) padding-box,
conic-gradient(
from var(--gradient-angle),
transparent 0%,
#F97316 10%,
#FDBA74 20%,
#FEF3C7 25%,
#FDBA74 30%,
#F97316 40%,
transparent 50%,
transparent 100%
) border-box;
border: 2px solid transparent;
animation: border-spin 3s linear infinite;
}
@supports not (background: conic-gradient(from 0deg, red, blue)) {
.hero-card-comp .btn-shiny-hero {
background: linear-gradient(#000000, #000000) padding-box,
linear-gradient(
90deg,
transparent 0%,
#F97316 25%,
#FEF3C7 50%,
#F97316 75%,
transparent 100%
) border-box;
background-size: 100% 100%, 200% 100%;
animation: shimmer-fallback 2s linear infinite;
}
}
.hero-card-comp .btn-shiny-hero::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at 2px 2px, rgba(255,255,255,0.8) 0.5px, transparent 0) padding-box;
background-size: 4px 4px;
mask-image: conic-gradient(from var(--gradient-angle), transparent 0%, black 20%, transparent 40%);
border-radius: inherit;
opacity: 0.6;
animation: border-spin 3s linear infinite;
pointer-events: none;
}
@supports not (background: conic-gradient(from 0deg, red, blue)) {
.hero-card-comp .btn-shiny-hero::before {
display: none;
}
}
.hero-card-comp .btn-shiny-hero::after {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, transparent 100%);
opacity: 0;
transition: opacity 0.3s ease;
}
.hero-card-comp .btn-shiny-hero:hover::after {
opacity: 1;
}
.hero-card-comp .btn-shiny-hero:hover {
transform: translateY(-1px);
}
.hero-card-comp .btn-shiny-hero:active {
transform: translateY(0);
}
.hero-card-comp .hero-card {
width: 100%;
max-width: 380px;
min-width: 300px;
}
@media (max-width: 360px) {
.hero-card-comp .hero-card-inner {
padding: 24px !important;
}
.hero-card-comp .score-number {
font-size: 56px !important;
}
.hero-card-comp .equalizer-container {
height: 80px !important;
}
}</style>
<div id="hero-card" class="hero-card-comp hero-card relative bg-neutral-900 rounded-[32px] p-[2px] overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-b from-amber-400 via-orange-500 to-transparent opacity-80 z-0"></div>
<div class="hero-card-inner relative z-10 bg-[#0A0A0A] rounded-[30px] h-full p-8 flex flex-col items-start">
<div class="absolute top-0 right-0 w-full h-48 bg-gradient-to-b
from-orange-500/10 to-transparent pointer-events-none"></div>
<div class="flex justify-between w-full items-start mb-6 relative">
<span class="text-[11px] uppercase font-medium border border-amber-500/30
px-2.5 py-1.5 rounded-md bg-amber-500/10 flex items-center
gap-2 tracking-wider text-amber-400">
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-amber-500"></span>
</span>
</span>
</div>
<h3 class="text-xl text-white mb-1.5 font-medium">Your Viral Potential</h3>
<p class="text-xs text-neutral-400 mb-8 leading-relaxed">Test your idea. See the result.</p>
<div class="w-full mb-6 text-center">
<div class="flex items-baseline justify-center gap-3">
<span id="score-number" class="score-number text-7xl font-bold font-mono tracking-tighter transition-colors duration-100" style="color: #EF4444;">0</span>
<span class="text-sm text-neutral-500 font-medium">/100</span>
</div>
<span id="score-label" class="text-xs uppercase tracking-widest font-medium mt-3
inline-block opacity-0 transform translate-y-2
transition-all duration-300" style="color: #EF4444;">Calculating...</span>
</div>
<div class="w-full mb-8">
<div class="flex items-center justify-between mb-3">
<span class="text-[11px] text-neutral-400 uppercase tracking-wider">Framework Breakdown</span>
</div>
<div id="equalizer" class="equalizer-container flex items-end justify-between h-24
gap-1.5 w-full bg-neutral-900/50 rounded-lg p-3 pt-8 border
border-white/5 relative overflow-visible">
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-amber-400 bg-neutral-900/95 px-2 py-1 rounded border border-amber-500/30">Hook 92</div>
<div class="equalizer-bar bar-glow-gold w-full bg-gradient-to-t from-amber-600 to-amber-400 rounded-t-sm" style="--bar-height: 92%; --bar-delay: 0ms;" data-score="92"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-green-400 bg-neutral-900/95 px-2 py-1 rounded border border-green-500/30">Intro 78</div>
<div class="equalizer-bar w-full bg-gradient-to-t from-green-600 to-green-400 rounded-t-sm" style="--bar-height: 78%; --bar-delay: 50ms;" data-score="78"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-teal-400 bg-neutral-900/95 px-2 py-1 rounded border border-teal-500/30">Value 85</div>
<div class="equalizer-bar bar-glow-teal w-full bg-gradient-to-t from-teal-600 to-teal-400 rounded-t-sm" style="--bar-height: 85%; --bar-delay: 100ms;" data-score="85"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-teal-400 bg-neutral-900/95 px-2 py-1 rounded border border-teal-500/30">Order 81</div>
<div class="equalizer-bar bar-glow-teal w-full bg-gradient-to-t from-teal-600 to-teal-400 rounded-t-sm" style="--bar-height: 81%; --bar-delay: 150ms;" data-score="81"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-teal-400 bg-neutral-900/95 px-2 py-1 rounded border border-teal-500/30">Pacing 89</div>
<div class="equalizer-bar bar-glow-teal w-full bg-gradient-to-t from-teal-600 to-teal-400 rounded-t-sm" style="--bar-height: 89%; --bar-delay: 200ms;" data-score="89"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-green-400 bg-neutral-900/95 px-2 py-1 rounded border border-green-500/30">Emotion 76</div>
<div class="equalizer-bar w-full bg-gradient-to-t from-green-600 to-green-400 rounded-t-sm" style="--bar-height: 76%; --bar-delay: 250ms;" data-score="76"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-teal-400 bg-neutral-900/95 px-2 py-1 rounded border border-teal-500/30">Outro 88</div>
<div class="equalizer-bar bar-glow-teal w-full bg-gradient-to-t from-teal-600 to-teal-400 rounded-t-sm" style="--bar-height: 88%; --bar-delay: 300ms;" data-score="88"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-amber-400 bg-neutral-900/95 px-2 py-1 rounded border border-amber-500/30">Meta 94</div>
<div class="equalizer-bar bar-glow-gold w-full bg-gradient-to-t from-amber-600 to-amber-400 rounded-t-sm" style="--bar-height: 94%; --bar-delay: 350ms;" data-score="94"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-teal-400 bg-neutral-900/95 px-2 py-1 rounded border border-teal-500/30">Psych 83</div>
<div class="equalizer-bar bar-glow-teal w-full bg-gradient-to-t from-teal-600 to-teal-400 rounded-t-sm" style="--bar-height: 83%; --bar-delay: 400ms;" data-score="83"></div>
</div>
<div class="bar-container relative flex-1 h-full flex flex-col justify-end">
<div class="bar-tooltip text-amber-400 bg-neutral-900/95 px-2 py-1 rounded border border-amber-500/30">Algo 91</div>
<div class="equalizer-bar bar-glow-gold w-full bg-gradient-to-t from-amber-600 to-amber-400 rounded-t-sm" style="--bar-height: 91%; --bar-delay: 450ms;" data-score="91"></div>
</div>
</div>
</div>
<button class="btn-shiny-hero group relative flex items-center
justify-center w-full h-[52px] rounded-full text-slate-50
font-sans font-semibold text-base tracking-tight
cursor-pointer overflow-hidden isolate shadow-2xl
shadow-black/50 mb-6 transition-transform duration-200">
<span class="relative z-10 flex items-center gap-2">Test Your Idea</span>
</button>
<div class="relative w-full h-px bg-gradient-to-r from-transparent
via-orange-500/40 to-transparent mb-5 flex items-center
justify-center">
<span class="bg-[#0A0A0A] px-3 text-[10px] text-neutral-400 uppercase tracking-widest">57 Niches × 5 Platforms</span>
</div>
<div class="flex items-center justify-center w-full">
<div class="flex items-center gap-1.5 text-[11px] text-neutral-400">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-amber-500">
<path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" fill="currentColor"></path>
</svg>
</div>
</div>
</div>
</div>
<script>(function() {
const TARGET_SCORE = 96;
const ANIMATION_DURATION = 1500;
const SCORE_RANGES = [
{ min: 0, max: 30, color: '#EF4444', label: 'NEEDS WORK' },
{ min: 31, max: 60, color: '#EAB308', label: 'AVERAGE' },
{ min: 61, max: 80, color: '#22C55E', label: 'GOOD' },
{ min: 81, max: 90, color: '#14B8A6', label: 'EXCELLENT' },
{ min: 91, max: 100, color: '#D97706', label: 'VIRAL READY' }
];
let animationPlayed = false;
function getScoreConfig(score) {
return SCORE_RANGES.find(r => score >= r.min && score <= r.max) || SCORE_RANGES[0];
}
function easeOutExpo(x) {
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
}
function animateScore(targetScore) {
const scoreElement = document.getElementById('score-number');
const labelElement = document.getElementById('score-label');
const startTime = performance.now();
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / ANIMATION_DURATION, 1);
const easedProgress = easeOutExpo(progress);
const currentScore = Math.floor(easedProgress * targetScore);
scoreElement.textContent = currentScore;
const config = getScoreConfig(currentScore);
if (currentScore >= 91) {
scoreElement.classList.add('score-viral', 'score-glow');
scoreElement.style.color = '';
} else {
scoreElement.classList.remove('score-viral', 'score-glow');
scoreElement.style.color = config.color;
}
if (progress < 1) {
requestAnimationFrame(update);
} else {
scoreElement.textContent = targetScore;
const finalConfig = getScoreConfig(targetScore);
labelElement.textContent = finalConfig.label;
labelElement.style.color = finalConfig.color;
labelElement.style.opacity = '1';
labelElement.style.transform = 'translateY(0)';
if (targetScore >= 91) {
scoreElement.classList.add('score-viral', 'score-glow');
}
}
}
requestAnimationFrame(update);
}
function animateEqualizer() {
const bars = document.querySelectorAll('.equalizer-bar');
bars.forEach(bar => {
bar.classList.add('animate');
});
}
function startAnimations() {
if (animationPlayed) return;
animationPlayed = true;
animateScore(TARGET_SCORE);
setTimeout(animateEqualizer, 300);
}
const heroCard = document.getElementById('hero-card');
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.3) {
setTimeout(startAnimations, 200);
observer.unobserve(entry.target);
}
});
}, {
root: null,
rootMargin: '0px',
threshold: 0.3
});
observer.observe(heroCard);
} else {
setTimeout(startAnimations, 500);
}
})();</script>
</div>