/*!
 * CYBOX Academy — Motion Layer / CSS
 * ------------------------------------------------------------------
 * Навмисно крихітний файл. Він НЕ описує анімацій — усім рухом керує
 * GSAP. Тут лише те, що зобов'язане жити в CSS: запобіжники,
 * opt-in утиліти та захист від horizontal overflow і CLS.
 *
 * Жодне правило нижче не змінює геометрію сторінки за замовчуванням.
 * Усе, що щось ховає, вмикається вручну атрибутом і працює тільки
 * при html.motion-ready — тобто коли GSAP реально завантажився.
 */

/* ==================================================================
 * 1. Конфлікт: html { scroll-behavior: smooth } (styles.css:58)
 *
 * Нативний smooth scroll свариться зі ScrollTrigger на scrub-сценах
 * та будь-якому програмному скролі (snap, scrollTo): браузер і
 * ScrollTrigger одночасно рухають одну позицію.
 *
 * Глобально його НЕ вимикаємо — навігація в шапці будується
 * динамічно (main.js), її якорі не отримують JS-обробника
 * initInternalSmoothLinks і покладаються саме на це CSS-правило.
 *
 * Тому вимикання точкове й тимчасове:
 *   CyboxMotion.suspendSmoothScroll() / .resumeSmoothScroll()
 *
 * !important тут обов'язковий, і ось чому: ScrollTrigger під час
 * refresh() читає поточний scroll-behavior скролера, тимчасово
 * ставить auto, а потім ВІДНОВЛЮЄ його як inline-стиль на <html>.
 * Inline б'є будь-який селектор — без !important цей перемикач
 * переставав працювати рівно після першого refresh з піном.
 * ================================================================== */
html.motion-scrolling {
  scroll-behavior: auto !important;
}

/* А ось це — головне.
   ScrollTrigger під час refresh() тимчасово скидає скрол у 0, міряє
   абсолютні позиції й повертає назад. При scroll-behavior: smooth
   повернення анімоване, тож усі start/end запікаються зі зсувом рівно
   на поточний scrollY. Заміряно на #review-proof: start=-2985 замість
   4015 — тригер спрацьовував за 7000px до секції. Вимкнення smooth
   дає рівно 4015; content-visibility, як перевірено окремо, ні до чого.

   Точкової підвіски на подію refreshInit не досить: ScrollTrigger
   маніпулює скролом ще до неї. Тому вимикаємо на весь час життя
   motion-шару. Плавність якорів від цього не страждає: motion-core
   вішає делеговану обробку кліків (див. initAnchorScroll), яка ловить
   і ті посилання меню, що будуються скриптом уже після завантаження.

   Без GSAP клас motion-ready не з'являється — і нативний smooth
   лишається як був. */
html.motion-ready {
  scroll-behavior: auto;
}

/* ==================================================================
 * 2. Підготовка елементів (opt-in)
 *
 * [data-motion-prep] ховає елемент ДО того, як GSAP встигне
 * поставити початковий стан — щоб не було спалаху «видно -> сховано»
 * на елементах у першому екрані.
 *
 * Три запобіжники, щоб контент ніколи не лишився невидимим:
 *   - працює тільки при html.motion-ready (GSAP живий);
 *   - вимикається при motion-unavailable (GSAP не завантажився);
 *   - вимикається при prefers-reduced-motion.
 * Без JS правило не застосовується взагалі.
 * ================================================================== */
html.motion-ready [data-motion-prep] {
  opacity: 0;
}

html.motion-unavailable [data-motion-prep],
html:not(.motion-ready) [data-motion-prep] {
  opacity: 1;
}

/* ==================================================================
 * 3. Захист від horizontal overflow
 *
 * ScrollTrigger при pin створює .pin-spacer навколо елемента.
 * У сітках із gap це інколи дає зайві пікселі по X. html уже має
 * overflow-x: clip, але на старих Safari clip ігнорується — тож
 * страхуємось на рівні самого спейсера.
 * ================================================================== */
.pin-spacer {
  max-width: 100%;
}

/* Opt-in для секцій, у яких parallax-шар виїжджає за межі. */
[data-motion-clip] {
  overflow: hidden;
}

/* ==================================================================
 * 4. prefers-reduced-motion
 *
 * Motion-шар сам не монтує сцени при reduce (див. motion-core,
 * options.reducedMotion). Це — страховка на випадок, якщо сцена
 * встигла поставити inline-трансформ до зміни системної настройки.
 * ================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.motion-ready [data-motion-prep] {
    opacity: 1;
  }

  html.motion-ready [data-motion],
  html.motion-ready [data-motion-prep] {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==================================================================
 * 5. Друк — жодних залишкових трансформів на папері.
 * ================================================================== */
@media print {
  [data-motion],
  [data-motion-prep] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ==================================================================
 * 6. Мобільні: смузність важливіша за декор
 *
 * На вузьких екранах декоративні нескінченні анімації або не видно
 * взагалі, або вони не варті свого кадрового бюджету на слабкому
 * телефоні. Вимикаємо їх зовсім, а не ставимо на паузу.
 * Елементи лишаються на місці у своєму базовому стані, тож ані
 * лейаут, ані кольори не змінюються.
 * ================================================================== */
@media (max-width: 640px) {
  .achievement-card__shine,
  .conversion-screen-shine,
  .conversion-float-card,
  .student-day-window__lights i,
  .day-reward-code i {
    animation: none !important;
  }
}
