landing: эффект прожектора на карточках (свечение следует за курсором, timeweb-style)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
wasrusgen 2026-06-03 19:59:02 +03:00
parent 32f1a0241b
commit ada8b9ab1c
2 changed files with 48 additions and 0 deletions

View File

@ -224,6 +224,16 @@
.problem-card, .funnel-step, .demo-card { transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease; }
.problem-card:hover, .funnel-step:hover, .demo-card:hover { transform: translateY(-3px); border-color: rgba(16,185,129,.4); box-shadow: 0 12px 30px rgba(0,0,0,.25); }
/* «Прожектор» — свечение следует за курсором (timeweb-style) */
.feature-card, .demo-card, .funnel-step { overflow: hidden; }
.feature-card::after, .problem-card::after, .funnel-step::after, .demo-card::after {
content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
border-radius: inherit; opacity: 0; transition: opacity .35s ease;
background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), rgba(16,185,129,.18), transparent 62%);
}
.feature-card:hover::after, .problem-card:hover::after, .funnel-step:hover::after, .demo-card:hover::after { opacity: 1; }
.feature-card > *, .problem-card > *, .funnel-step > *, .demo-card > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
.hero-content > *, .reveal, .pulse-chip, .pulse-chip svg polyline { animation: none !important; transition: none !important; opacity:1 !important; transform:none !important; stroke-dashoffset:0 !important; }
}
@ -426,6 +436,20 @@
}, {threshold:0.12, rootMargin:'0px 0px -8% 0px'});
document.querySelectorAll('.reveal').forEach(function(el){io.observe(el);});
})();
/* «Прожектор» за курсором на карточках */
(function(){
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
if (window.matchMedia && window.matchMedia('(hover: none)').matches) return;
var cards = document.querySelectorAll('.feature-card, .problem-card, .funnel-step, .demo-card');
cards.forEach(function(c){
c.addEventListener('mousemove', function(e){
var r = c.getBoundingClientRect();
c.style.setProperty('--mx', (e.clientX - r.left) + 'px');
c.style.setProperty('--my', (e.clientY - r.top) + 'px');
});
});
})();
</script>
</body>
</html>

View File

@ -224,6 +224,16 @@
.problem-card, .funnel-step, .demo-card { transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease; }
.problem-card:hover, .funnel-step:hover, .demo-card:hover { transform: translateY(-3px); border-color: rgba(16,185,129,.4); box-shadow: 0 12px 30px rgba(0,0,0,.25); }
/* «Прожектор» — свечение следует за курсором (timeweb-style) */
.feature-card, .demo-card, .funnel-step { overflow: hidden; }
.feature-card::after, .problem-card::after, .funnel-step::after, .demo-card::after {
content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
border-radius: inherit; opacity: 0; transition: opacity .35s ease;
background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), rgba(16,185,129,.18), transparent 62%);
}
.feature-card:hover::after, .problem-card:hover::after, .funnel-step:hover::after, .demo-card:hover::after { opacity: 1; }
.feature-card > *, .problem-card > *, .funnel-step > *, .demo-card > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
.hero-content > *, .reveal, .pulse-chip, .pulse-chip svg polyline { animation: none !important; transition: none !important; opacity:1 !important; transform:none !important; stroke-dashoffset:0 !important; }
}
@ -426,6 +436,20 @@
}, {threshold:0.12, rootMargin:'0px 0px -8% 0px'});
document.querySelectorAll('.reveal').forEach(function(el){io.observe(el);});
})();
/* «Прожектор» за курсором на карточках */
(function(){
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
if (window.matchMedia && window.matchMedia('(hover: none)').matches) return;
var cards = document.querySelectorAll('.feature-card, .problem-card, .funnel-step, .demo-card');
cards.forEach(function(c){
c.addEventListener('mousemove', function(e){
var r = c.getBoundingClientRect();
c.style.setProperty('--mx', (e.clientX - r.left) + 'px');
c.style.setProperty('--my', (e.clientY - r.top) + 'px');
});
});
})();
</script>
</body>
</html>