/* ═══════════════════════════════════════
   Файл: animations.css
   Описание: Все CSS-анимации лендинга СТРОЙ-ДОМ.
             Содержит:
             - @keyframes для всех анимаций
             - Базовые классы появления при скролле (Intersection Observer)
             - Анимация стрелки hero-блока (bounce)
             - Анимация модального окна (fade + scale)
             - Hover-эффекты карточек
             - Параллакс-подготовка
   Проект: Лендинг СТРОЙ-ДОМ
   Автор: Дмитрий Гальченко
   Дата: 2026-04-10
═══════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════
   1. @KEYFRAMES — ОБЪЯВЛЕНИЯ АНИМАЦИЙ
   Здесь объявляются только сами анимации (что происходит).
   Применяются ниже через animation: ... к конкретным классам.
══════════════════════════════════════════════════════════════════════ */

/* ── titleSlide: заголовок выезжает с левого края ────────────────────
   Чистое движение без прыжков и отскоков. */
@keyframes titleSlide {
  from { transform: translateX(-140px); opacity: 0; }
  to   { transform: translateX(0);      opacity: 1; }
}

/* ── ruleGrow: тонкая янтарная черта вырастает слева направо ─────── */
@keyframes ruleGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ── rotateSlow: бесконечное медленное вращение шестерён ───────────
   .gear-cw  — по часовой (clockwise)
   .gear-ccw — против часовой (counter-clockwise, через reverse) */
@keyframes rotateSlow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ── craneSway: покачивание груза на тросе крана ───────────────────
   Небольшой поворот туда-обратно вокруг точки подвеса.
   transform-origin задаётся прямо в классе — верхняя точка троса. */
@keyframes craneSway {
  0%, 100% { transform: rotate(-3deg); }
  50%       { transform: rotate(3deg); }
}

/* ── bounce: анимация стрелки вниз в hero-блоке ────────────────────
   Стрелка плавно покачивается вверх-вниз, приглашая скроллить.
   0% и 100% — исходная позиция, 50% — смещение вниз. */
@keyframes bounce {
  0%, 100% {
    transform: translateX(-50%) translateY(0);
  }
  50% {
    /* Смещаем вниз на 10px в пике анимации */
    transform: translateX(-50%) translateY(10px);
  }
}

/* ── fadeIn: базовое появление (прозрачность) ───────────────────────
   Используется как простой эффект для элементов без сдвига. */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ── fadeInUp: появление снизу вверх ────────────────────────────────
   Элемент появляется снизу (translateY(30px)) и поднимается на место.
   Используется в hero-блоке (title, subtitle, кнопка). */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── fadeInLeft: появление слева ────────────────────────────────────
   Элемент едет из левой стороны. Для текстовых блоков. */
@keyframes fadeInLeft {
  from {
    opacity: 0;
    transform: translateX(-40px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ── fadeInRight: появление справа ──────────────────────────────────
   Элемент едет из правой стороны. Для фото/изображений. */
@keyframes fadeInRight {
  from {
    opacity: 0;
    transform: translateX(40px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ── scaleIn: появление с масштабированием ──────────────────────────
   Элемент увеличивается с 0.85 до 1. Используется для карточек
   и модального окна. */
@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.85);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* ── modalSlideIn: появление модального окна ────────────────────────
   Комбинированная анимация: fade + лёгкий сдвиг вниз + масштаб.
   Создаёт ощущение "выпрыгивания" диалога. */
@keyframes modalSlideIn {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.92);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* ── shimmer: мерцание заглушек ─────────────────────────────────────
   Декоративная анимация для placeholder-элементов.
   Имитирует "загрузку" контента (skeleton loader). */
@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

/* ── pulse: пульсация акцентных элементов ───────────────────────────
   Используется для привлечения внимания к CTA-кнопкам. */
@keyframes pulse {
  0%, 100% {
    box-shadow: 0 4px 15px rgba(245, 166, 35, 0.3);
  }
  50% {
    box-shadow: 0 8px 32px rgba(245, 166, 35, 0.55);
  }
}

/* ── lineGrow: рост линии под заголовком секции ─────────────────────
   Декоративная черта под .section__title расширяется от 0 до 60px. */
@keyframes lineGrow {
  from {
    width: 0;
  }
  to {
    width: 60px;
  }
}

/* ── countUp: вспомогательная анимация для чисел ────────────────────
   Сами числа считает JS (counter.js).
   Эта анимация — визуальный акцент: число "вспыхивает" при старте. */
@keyframes countHighlight {
  0% {
    color: var(--color-white);
    text-shadow: none;
  }
  30% {
    color: var(--color-accent);
    text-shadow: 0 0 20px rgba(245, 166, 35, 0.6);
  }
  100% {
    color: var(--color-accent);
    text-shadow: none;
  }
}


/* ══════════════════════════════════════════════════════════════════════
   2. АНИМАЦИИ HERO-БЛОКА
   Запускаются сразу при загрузке страницы (без Intersection Observer).
   Классы animate-fade-up и animate-delay-N назначены прямо в HTML.
══════════════════════════════════════════════════════════════════════ */

/* Заголовок hero выезжает слева */
.hero__title {
  animation: titleSlide 1.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.2s both;
}

/* ── Черта вырастает после заголовка ─────────────────────────────── */
.hero__rule {
  transform-origin: left center;
  animation: ruleGrow 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.9s both;
}

/* Базовый класс анимации "появление снизу" для hero-контента.
   Применяется к eyebrow, подзаголовку и CTA-кнопке. */
.animate-fade-up {
  animation: fadeInUp 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Hero eyebrow появляется чуть раньше всего остального */
.hero__eyebrow.animate-fade-up {
  animation-delay: 0.3s;
}

/* Стандартные задержки (используются в других секциях) */
.animate-delay-1 {
  animation-delay: 0.25s;
}

.animate-delay-2 {
  animation-delay: 0.5s;
}

.animate-delay-3 {
  animation-delay: 0.75s;
}

/* Subtitle: 1.2s — заголовок уже встал.
   CTA + second btn: 1.5s. */
.animate-delay-crane-1 {
  animation-delay: 1.2s;
}

.animate-delay-crane-2 {
  animation-delay: 1.5s;
}


/* ══════════════════════════════════════════════════════════════════════
   3. АНИМАЦИИ ПОЯВЛЕНИЯ ПРИ СКРОЛЛЕ (Intersection Observer)
   Работает в паре с main.js: JS добавляет класс .is-visible
   когда элемент попадает в viewport.
   До появления в viewport — элемент невидим (opacity: 0).
   После — запускается анимация.
══════════════════════════════════════════════════════════════════════ */

/* Базовое состояние ДО появления в viewport.
   Все элементы с animate-on-scroll скрыты и смещены вниз. */
.animate-on-scroll {
  opacity: 0;
  transform: translateY(30px);
  /* Плавный переход: opacity + transform одновременно */
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Состояние ПОСЛЕ появления в viewport — JS добавляет этот класс.
   Элемент становится видимым и возвращается на место. */
.animate-on-scroll.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Задержки для поочерёдного появления элементов в одной секции.
   Используются совместно с animate-on-scroll. */
.animate-on-scroll.animate-delay-1 {
  transition-delay: 0.15s;
}

.animate-on-scroll.animate-delay-2 {
  transition-delay: 0.3s;
}

.animate-on-scroll.animate-delay-3 {
  transition-delay: 0.45s;
}

/* Вариант появления слева (для текстовых блоков).
   Если нужно добавить к элементу — добавить класс animate-from-left. */
.animate-from-left {
  opacity: 0;
  transform: translateX(-40px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.animate-from-left.is-visible {
  opacity: 1;
  transform: translateX(0);
}

/* Вариант появления справа (для фото/изображений) */
.animate-from-right {
  opacity: 0;
  transform: translateX(40px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.animate-from-right.is-visible {
  opacity: 1;
  transform: translateX(0);
}

/* Вариант появления с масштабированием (для карточек статистики) */
.animate-scale {
  opacity: 0;
  transform: scale(0.9);
  transition:
    opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.animate-scale.is-visible {
  opacity: 1;
  transform: scale(1);
}


/* ══════════════════════════════════════════════════════════════════════
   4. АНИМАЦИИ ЗАГОЛОВКОВ СЕКЦИЙ
   Декоративная черта под .section__title появляется с анимацией
   роста ширины (lineGrow) когда заголовок попадает в viewport.
══════════════════════════════════════════════════════════════════════ */



/* ══════════════════════════════════════════════════════════════════════
   5. АНИМАЦИЯ СТРЕЛКИ HERO (bounce)
   Объявлена в @keyframes выше, применяется к .hero__scroll-hint.
   Стрелка бесконечно покачивается вниз-вверх, привлекая внимание.
══════════════════════════════════════════════════════════════════════ */

/* Стрелке уже назначена анимация в style.css:
   animation: bounce 2s infinite;
   Здесь дополнительно настраиваем плавность. */
.hero__scroll-hint {
  animation: bounce 2s ease-in-out infinite;
  /* Задержка 1.5s — ждём пока появятся основные элементы hero */
  animation-delay: 1.5s;
}


/* ══════════════════════════════════════════════════════════════════════
   6. АНИМАЦИИ МОДАЛЬНОГО ОКНА
   Модальное окно появляется с fade + scale эффектом.
   JS переключает класс .modal--open на .modal.
══════════════════════════════════════════════════════════════════════ */

/* Когда модал открывается — диалог анимируется */
.modal--open .modal__dialog {
  animation: modalSlideIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Overlay модала: плавное появление */
.modal--open .modal__overlay {
  animation: fadeIn 0.3s ease both;
}

/* Блок успешной отправки — появляется с масштабированием */
.order-form__result:not([hidden]) {
  animation: scaleIn 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
}


/* ══════════════════════════════════════════════════════════════════════
   7. SHIMMER-АНИМАЦИЯ ДЛЯ ЗАГЛУШЕК
   Заглушки мерцают градиентом — как skeleton loader.
   Визуально понятно что это "место под контент".
══════════════════════════════════════════════════════════════════════ */

/* Применяем shimmer ко всем заглушкам кроме логотипа и видео */
.placeholder:not(.placeholder--logo):not(.video-placeholder) {
  background: linear-gradient(
    90deg,
    #d0d5dc 0%,
    #e0e5ea 40%,
    #d0d5dc 80%
  );
  /* Широкий градиент — анимация будет скользить по нему */
  background-size: 200% 100%;
  animation: shimmer 2.5s ease-in-out infinite;
}

/* Выключаем shimmer при hover — чтобы не мешал читать текст */
.placeholder:hover {
  animation-play-state: paused;
}


/* ══════════════════════════════════════════════════════════════════════
   8. HOVER-АНИМАЦИИ КНОПОК CTA
   Кнопки "Заказать расчёт" пульсируют, привлекая внимание.
   Только у главной кнопки в hero-блоке — чтобы не раздражать.
══════════════════════════════════════════════════════════════════════ */

/* Пульсирующая тень у hero-кнопки.
   Кнопка появляется в 1.9s, анимация fadeInUp длится 0.9s → конец ≈ 2.8s.
   Пульсация стартует после — в 3.0s. */
.hero__cta {
  animation: pulse 3s ease-in-out infinite;
  animation-delay: 3.0s;
}

/* При hover останавливаем пульсацию — она больше не нужна */
.hero__cta:hover {
  animation: none;
}


/* ══════════════════════════════════════════════════════════════════════
   9. HOVER-АНИМАЦИИ КАРТОЧЕК
   Дополнительные эффекты поверх тех что в style.css.
   style.css: translateY + box-shadow через transition.
   Здесь: дополнительные эффекты внутри карточек.
══════════════════════════════════════════════════════════════════════ */

/* Заглушка карточки направления — лёгкий zoom при hover на карточку */
.direction-card:hover .placeholder--card-img {
  transform: scale(1.03);
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Overflow hidden нужен чтобы zoom не выходил за пределы карточки */
.direction-card .placeholder--card-img {
  overflow: hidden;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Заголовок карточки направления — небольшой сдвиг при hover */
.direction-card:hover .direction-card__title {
  color: var(--color-accent);
  transition: color var(--transition-base);
}

/* Заглушка фото проекта — zoom при hover на карточку */
.project-card:hover .placeholder--project-photo {
  transform: scale(1.05);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.project-card .placeholder--project-photo {
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}


/* ══════════════════════════════════════════════════════════════════════
   10. АНИМАЦИЯ СЧЁТЧИКОВ (вспомогательная)
   Когда JS запускает анимацию чисел (counter.js),
   добавляем CSS-эффект "вспышки" на число.
   JS добавляет класс .is-counting на элемент .stats__number.
══════════════════════════════════════════════════════════════════════ */

/* Вспышка цвета при старте счётчика */
.stats__number.is-counting {
  animation: countHighlight 5s ease both;
}


/* ══════════════════════════════════════════════════════════════════════
   11. АНИМАЦИЯ НАВИГАЦИИ (мобильное меню)
   Пункты мобильного меню появляются поочерёдно при открытии.
══════════════════════════════════════════════════════════════════════ */

/* Каждый пункт мобильного меню имеет задержку по очереди */
.mobile-menu--open .mobile-menu__list li:nth-child(1) {
  animation: fadeInUp 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.05s both;
}

.mobile-menu--open .mobile-menu__list li:nth-child(2) {
  animation: fadeInUp 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both;
}

.mobile-menu--open .mobile-menu__list li:nth-child(3) {
  animation: fadeInUp 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
}

.mobile-menu--open .mobile-menu__list li:nth-child(4) {
  animation: fadeInUp 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.2s both;
}

.mobile-menu--open .mobile-menu__list li:nth-child(5) {
  animation: fadeInUp 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.25s both;
}


/* ══════════════════════════════════════════════════════════════════════
   12. ПАРАЛЛАКС-ПОДГОТОВКА
   Настоящий параллакс реализован в main.js через JS (requestAnimationFrame).
   Здесь CSS-часть: переходы и will-change для GPU-ускорения.
══════════════════════════════════════════════════════════════════════ */

/* will-change: transform — подсказка браузеру что элемент будет
   трансформироваться. Браузер переносит его на отдельный GPU-слой.
   Применяем только к hero-заглушке видео (параллакс-фон). */
.hero__video-placeholder {
  will-change: transform;
  /* Плавный transition на случай если JS параллакс отключён */
  transition: transform 0.1s linear;
}

/* Аналогично для оверлея — он тоже участвует в параллаксе */
.hero__overlay {
  will-change: opacity;
}


/* ══════════════════════════════════════════════════════════════════════
   13. АНИМАЦИИ ФОНОВЫХ SVG-ИЛЛЮСТРАЦИЙ
   Шестерни в секции Производство, груз крана в секции Направления.
   Анимируются бесконечно и плавно — создают живой фон секций.
══════════════════════════════════════════════════════════════════════ */

/* Шестерня по часовой — медленно, 30 секунд на оборот */
.gear-cw {
  animation: rotateSlow 30s linear infinite;
  /* transform-origin задан инлайн в HTML (зависит от координат каждой шестерни) */
}

/* Шестерня против часовой — reverse разворачивает keyframes */
.gear-ccw {
  animation: rotateSlow 30s linear infinite reverse;
}

/* Груз крана: покачивается вокруг верхней точки троса.
   transform-origin: точка подвеса (x=265, y=167 из SVG-координат) */
.crane-art__load {
  transform-origin: 265px 167px;
  animation: craneSway 4s ease-in-out infinite;
}
