Переписаны компоенты главной страницы
This commit is contained in:
parent
2b087c02b7
commit
284e37fa94
7 changed files with 320 additions and 227 deletions
|
|
@ -40,6 +40,17 @@ 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">
|
||||
<!-- Заголовок секции -->
|
||||
|
|
@ -59,19 +70,16 @@ const {
|
|||
<div class="steps-container">
|
||||
{steps.map((step: Step, index: number) => (
|
||||
<div class="step-card-wrapper animate-on-scroll" data-animation="fade-up" data-delay={index * 100 + 200}>
|
||||
<!-- Вертикальный соединитель (только для мобильной версии, кроме первого элемента) -->
|
||||
{index > 0 && (
|
||||
<div class="mobile-connector mobile-only">
|
||||
<div class="mobile-connector-line"></div>
|
||||
<div class="mobile-connector-dot"></div>
|
||||
</div>
|
||||
<div class="mobile-connector mobile-only">
|
||||
<div class="mobile-connector-line"></div>
|
||||
<div class="mobile-connector-dot"></div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<div class="step-card">
|
||||
<!-- Декоративный фон -->
|
||||
<div class="step-bg"></div>
|
||||
|
||||
<!-- Заголовок с номером и иконкой -->
|
||||
<div class="step-header">
|
||||
<div class="step-number">{step.number}</div>
|
||||
<div class="step-icon-wrapper">
|
||||
|
|
@ -82,7 +90,6 @@ const {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Контент -->
|
||||
<div class="step-content">
|
||||
<h3 class="step-title">{step.title}</h3>
|
||||
<p class="step-description">{step.description}</p>
|
||||
|
|
@ -146,7 +153,6 @@ const {
|
|||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
/* Декоративные элементы фона */
|
||||
.steps-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
|
@ -177,7 +183,6 @@ const {
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Заголовок секции */
|
||||
.section-header {
|
||||
margin-bottom: 4rem;
|
||||
text-align: center;
|
||||
|
|
@ -226,14 +231,14 @@ const {
|
|||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* --- АНИМАЦИИ ПРИ СКРОЛЛИНГЕ --- */
|
||||
/* ИСПРАВЛЕНИЕ LCP: opacity: 1 по умолчанию! */
|
||||
.animate-on-scroll {
|
||||
opacity: 0;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
[data-animation="fade-up"] {
|
||||
transform: translateY(40px);
|
||||
transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
|
@ -243,7 +248,6 @@ const {
|
|||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Контейнер шагов */
|
||||
.steps-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
@ -258,7 +262,6 @@ const {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
/* Вертикальный соединитель для мобильной версии (скрыт по умолчанию) */
|
||||
.mobile-connector {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
|
@ -288,7 +291,6 @@ const {
|
|||
box-shadow: 0 0 10px var(--color-accent);
|
||||
}
|
||||
|
||||
/* Карточка шага */
|
||||
.step-card {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
|
|
@ -303,8 +305,6 @@ const {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Убрана верхняя полоса внутри карточки */
|
||||
|
||||
.step-card:hover {
|
||||
transform: translateY(-8px);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
|
|
@ -328,7 +328,6 @@ const {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Заголовок шага */
|
||||
.step-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -402,7 +401,6 @@ const {
|
|||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
/* Текст шага */
|
||||
.step-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
@ -422,7 +420,6 @@ const {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
/* Статистика */
|
||||
.stats-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
@ -465,7 +462,6 @@ const {
|
|||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* CTA кнопка */
|
||||
.steps-cta {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -515,7 +511,6 @@ const {
|
|||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* --- АДАПТИВНОСТЬ --- */
|
||||
@media (max-width: 1024px) {
|
||||
.steps-container {
|
||||
flex-direction: column;
|
||||
|
|
@ -531,7 +526,6 @@ const {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Показываем вертикальные соединители */
|
||||
.mobile-connector {
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -619,12 +613,11 @@ const {
|
|||
}
|
||||
}
|
||||
|
||||
/* Уважаем prefers-reduced-motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.animate-on-scroll {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
transition: none;
|
||||
opacity: 1 !important;
|
||||
transform: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.step-card,
|
||||
|
|
@ -651,7 +644,6 @@ const {
|
|||
const duration = 1500;
|
||||
const startTime = performance.now();
|
||||
|
||||
// Easing функция (ease-out cubic)
|
||||
const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
|
||||
|
||||
function update(currentTime: number) {
|
||||
|
|
@ -679,11 +671,9 @@ const {
|
|||
setTimeout(() => {
|
||||
el.classList.add('is-visible');
|
||||
|
||||
// Если это stats-bar, запускаем анимацию счётчиков
|
||||
if (el.id === 'stats-bar') {
|
||||
const counters = el.querySelectorAll('.stat-number');
|
||||
counters.forEach((counter, index) => {
|
||||
// Небольшая задержка между счётчиками для каскадного эффекта
|
||||
setTimeout(() => {
|
||||
animateCounter(counter as HTMLElement);
|
||||
}, index * 150);
|
||||
|
|
@ -696,7 +686,6 @@ const {
|
|||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Наблюдаем за всеми анимируемыми элементами
|
||||
document.querySelectorAll('.animate-on-scroll').forEach((el) => {
|
||||
observer.observe(el);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue