Новые изменения в компоненте Steps.astro

This commit is contained in:
Web-serfer 2026-04-22 21:59:25 +05:00
parent 69442d5e0f
commit 27c4d64d73

View file

@ -40,16 +40,7 @@ const {
} = Astro.props;
---
<!-- КРИТИЧНО: Инлайн-скрипт скрывает элементы ДО рендера, но только если JS работает -->
<script is:inline>
(function() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const style = document.createElement('style');
style.textContent = '.animate-on-scroll{opacity:0;transform:translateY(40px)}';
document.head.appendChild(style);
})();
</script>
<section class="steps-section" id="how-we-work">
<div class="site-container">
@ -117,12 +108,7 @@ const {
</div>
</div>
<!-- Кнопка CTA -->
<div class="steps-cta animate-on-scroll" data-animation="fade-up" data-delay="800">
<Button variant="gold" size="lg" id="consultation-btn" data-modal-target="consultation-modal">
<span class="cta-text">Начать консультацию бесплатно</span>
</Button>
</div>
</div>
</section>
@ -462,54 +448,7 @@ const {
background: rgba(255, 255, 255, 0.1);
}
.steps-cta {
text-align: center;
}
.steps-cta .btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 0.875rem 1.5rem;
font-size: 1.125rem;
font-weight: 700;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
text-transform: none;
letter-spacing: normal;
position: relative;
overflow: hidden;
border: none;
min-height: 3.25rem;
}
.steps-cta .btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
.steps-cta .btn:hover::before {
left: 100%;
}
.steps-cta .btn:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
.steps-cta .btn:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
@media (max-width: 1024px) {
.steps-container {
@ -629,64 +568,3 @@ const {
}
</style>
<script>
// Intersection Observer для анимаций при скроллинге
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.15
};
// Анимация счётчиков
function animateCounter(el: HTMLElement) {
const target = parseInt(el.dataset.target || '0');
const suffix = el.dataset.suffix || '';
const duration = 1500;
const startTime = performance.now();
const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
function update(currentTime: number) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOutCubic(progress);
const currentValue = Math.round(easedProgress * target);
el.textContent = `${currentValue}${suffix}`;
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target as HTMLElement;
const delay = parseInt(el.dataset.delay || '0');
setTimeout(() => {
el.classList.add('is-visible');
if (el.id === 'stats-bar') {
const counters = el.querySelectorAll('.stat-number');
counters.forEach((counter, index) => {
setTimeout(() => {
animateCounter(counter as HTMLElement);
}, index * 150);
});
}
}, delay);
observer.unobserve(el);
}
});
}, observerOptions);
document.querySelectorAll('.animate-on-scroll').forEach((el) => {
observer.observe(el);
});
</script>