/* ══════════════════════════════════════════════════════════════════════════
   ШАР РУХУ
   ══════════════════════════════════════════════════════════════════════════

   Зчитано з живих сторінок (getComputedStyle, не на око):

     Linear   — вся взаємодія це **0.1s і 0.16s**, одна крива на все:
                cubic-bezier(0.25, 0.46, 0.45, 0.94) (easeOutQuad). Рухаються
                тільки color / background / box-shadow / transform / filter.
                Фонова анімація — сітка крапок, де кожна має власну затримку.
     Stripe   — поява елемента **0.5s** із cubic-bezier(0.33, 1, 0.68, 1)
                (easeOutCubic). Рухомий градієнт у них на <canvas>.

   🛑 Головний висновок: **преміум — це швидко й тихо.** Довга анімація на
   натисканні читається як гальмо, а не як дорого. Тому тут два різні
   бюджети: взаємодія 120–160 мс, поява 460 мс. Одна крива на взаємодію,
   одна на появу — більше не потрібно.

   🛑 Рухомий градієнт НЕ через canvas. Canvas у застосунку означає постійну
   роботу GPU під кожним екраном — на ноутбуці це вентилятор і з'їдена
   батарея заради фону. Тут те саме враження дає псевдоелемент із двома
   радіальними плямами, який повільно їде трансформом: композитор рухає
   готовий шар, перемальовування немає взагалі.

   🛑 Рухаємо ЛИШЕ transform і opacity. `top/left/width/height` змушують
   браузер рахувати розкладку в кожному кадрі — на списку з сотні карток це
   помітно навіть на потужній машині.

   Два свідомі винятки, зміряні прогоном по всіх 18 розділах: смуги прогресу
   `.bl-bar-fill` (Підписка) і `.info-progress-fill` (Інформація) анімують
   `width`. Це по ОДНОМУ елементу на розділ і рівно один раз при
   завантаженні — переписувати їх на scaleX означало б чіпати два модулі
   заради виграшу, якого не видно приладом. Правило лишається правилом; ці
   два випадки просто відомі.

   Останній блок вимикає геть усе за `prefers-reduced-motion`. Це не
   формальність: рух на весь екран здатний викликати нудоту в людей із
   вестибулярними розладами, і система вже знає про це з налаштувань.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Взаємодія: натискання, наведення, зміна стану. */
  --m-fast: 120ms;
  --m-base: 160ms;
  /* Поява: елемент, якого щойно не було. */
  --m-enter: 460ms;
  /* Одна крива на взаємодію (easeOutQuad) і одна на появу (easeOutCubic). */
  --m-ease: cubic-bezier(.25, .46, .45, .94);
  --m-ease-enter: cubic-bezier(.33, 1, .68, 1);
}

/* ── 1. Рухомий градієнт ──────────────────────────────────────────────────
   Дві плями їдуть по діагоналі й трохи обертаються, 30 секунд у обидва боки.
   Період навмисно довгий: рух, який видно, — це вже атракціон. Тут людина
   не має його помітити, вона має відчути, що поверхня жива.

   z-index: -1 кладе пляму МІЖ фоном елемента і його вмістом (саме такий
   порядок малювання в CSS), тож текст лишається зверху без жодних обгорток.
   `isolation: isolate` замикає це в межах картки. */
.ui-drift { position: relative; overflow: hidden; isolation: isolate; }
.ui-drift::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -35%;
  pointer-events: none;
  background:
    radial-gradient(34% 34% at 28% 30%, rgba(var(--hue, var(--hue-amber)), .30), transparent 72%),
    radial-gradient(30% 30% at 72% 70%, rgba(var(--hue2, var(--hue-rose)), .22), transparent 72%);
  animation: uiDrift 30s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes uiDrift {
  from { transform: translate3d(-3%, -2%, 0) scale(1.04) rotate(0deg); }
  to   { transform: translate3d(4%, 3%, 0) scale(1.16) rotate(8deg); }
}

/* Повільніший і тихіший варіант — для порожніх станів і заглушок вітрини.
   Їх на екрані буває багато, тож рух має бути на межі помітності. */
.ui-drift-soft::before { animation-duration: 46s; opacity: .7; }

/* ── 2. Поява розділу ─────────────────────────────────────────────────────
   Перемикання вкладки без руху читається як перезавантаження сторінки.

   🛑 БЕЗ transform, і це не стилістичне рішення. Елемент із
   трансформом стає **containing block для position:fixed нащадків** — а в
   секції розділу живуть усі модалки застосунку й меню випадайників. Коли тут
   стояв `translate3d(0,6px,0)`, вони починали рахувати координати від секції
   замість вікна й з'їжджали рівно на ширину бічного меню. Ефект «підйому»
   натомість дає каскад карток нижче: він рухає ВМІСТ, а не контейнер.

   Chrome тримає елемент containing-block-ом, поки анімація трансформу
   «застосована» — а з `fill-mode: both` це назавжди. Тобто дефект не зникав
   після завершення анімації, і зловити його на око було майже неможливо. */
@keyframes uiViewIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
section.view.active { animation: uiViewIn var(--m-enter) var(--m-ease-enter) both; }

/* ── 3. Каскад ────────────────────────────────────────────────────────────
   Картки з'являються по черзі з кроком 35 мс. Крок дрібний навмисно: при
   80–100 мс останній елемент ряду приїжджає помітно пізніше за перший, і
   сітка починає читатись як завантаження, а не як поява. Обмежено вісьмома
   — далі затримка була б довшою за саму анімацію. */
@keyframes uiRise {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: none; }
}
.ui-stagger > * { animation: uiRise var(--m-enter) var(--m-ease-enter) both; }
.ui-stagger > *:nth-child(1) { animation-delay: 0ms; }
.ui-stagger > *:nth-child(2) { animation-delay: 35ms; }
.ui-stagger > *:nth-child(3) { animation-delay: 70ms; }
.ui-stagger > *:nth-child(4) { animation-delay: 105ms; }
.ui-stagger > *:nth-child(5) { animation-delay: 140ms; }
.ui-stagger > *:nth-child(6) { animation-delay: 175ms; }
.ui-stagger > *:nth-child(7) { animation-delay: 210ms; }
.ui-stagger > *:nth-child(n + 8) { animation-delay: 245ms; }

/* ── 4. Фізика натискання ─────────────────────────────────────────────────
   Кнопка, яка не зрушила під пальцем, читається як мертва — особливо коли
   відповідь приходить із мережі через півсекунди. 1.5% стиснення вистачає:
   його не видно свідомо, але відсутність видно одразу. */
.btn, .chip, .nav-item, .ui-sel-btn, .ui-seg-btn, .ui-tile, .icon-btn {
  transition:
    background var(--m-base) var(--m-ease),
    color var(--m-base) var(--m-ease),
    box-shadow var(--m-base) var(--m-ease),
    transform var(--m-fast) var(--m-ease);
}
.btn:active, .chip:active, .ui-sel-btn:active, .ui-seg-btn:active, .icon-btn:active {
  transform: scale(.985);
}
.ui-tile:active { transform: scale(.99); }

/* ── 5. Шеврон, що знає свій стан ─────────────────────────────────────── */
.ui-sel-chev, .st-advanced-summary .chev { transition: transform var(--m-base) var(--m-ease); }
.ui-sel.open .ui-sel-chev { transform: rotate(180deg); }

/* ── 6. Меню випадайника ──────────────────────────────────────────────────
   Розкривається від краю кнопки, а не з'являється в повітрі: 4px зсуву й
   99% масштабу вистачає, щоб око пов'язало список із полем. */
@keyframes uiMenuIn {
  from { opacity: 0; transform: translate3d(0, -4px, 0) scale(.99); }
  to   { opacity: 1; transform: none; }
}
.ui-sel-menu { animation: uiMenuIn var(--m-base) var(--m-ease) both; transform-origin: top center; }

/* ── 7. Смуга завантаження ────────────────────────────────────────────────
   Замінює «завантаження…» текстом там, де вже відомо, якої форми буде
   вміст. Порожнє місце з рухом читається як робота; порожнє місце без руху
   — як поламане. */
@keyframes uiSheen { from { transform: translate3d(-100%, 0, 0); } to { transform: translate3d(100%, 0, 0); } }
.ui-loading { position: relative; overflow: hidden; isolation: isolate; }
.ui-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .06), transparent);
  animation: uiSheen 1.5s var(--m-ease) infinite;
}

/* ── 8. Живий показник ────────────────────────────────────────────────────
   Число, що змінилось, коротко підсвічується бурштином. Без цього оновлення
   балансу чи черги проходить непоміченим — цифра просто інша, і незрозуміло,
   чи вона щойно приїхала, чи стояла так весь час. */
@keyframes uiTick {
  0%   { color: var(--accent); transform: translate3d(0, 2px, 0); }
  100% { color: inherit; transform: none; }
}
.ui-tick { animation: uiTick 520ms var(--m-ease-enter); }

/* ── 9. Наведення на рядок і плитку ───────────────────────────────────── */
.ui-row, .prov-card, .lp-card, .gal-item.gp-card {
  transition: background var(--m-base) var(--m-ease), transform var(--m-base) var(--m-ease);
}

/* ── 12. ГЛИБИНА ДРУГОРЯДНИХ КНОПОК ───────────────────────────────────────
   Акцентна кнопка вже лежить НАД поверхнею: внутрішня волосінь світла згори
   плюс кольорова тінь. Сіра лишалась плоскою плямою заливки — і через це
   читалась не як кнопка, а як підсвічений прямокутник. А таких на екрані
   більшість: «Слоти», «Оновити», «Чернетка», «Запланувати», навігація
   календаря.

   Той самий рецепт, але нейтральний: світло згори (поверхня має товщину),
   чорна тінь знизу (вона лежить вище за фон), підйом на 1px під курсором.
   \U0001F6D1 Тінь чорна, а не кольорова — кольорову бачить око як «це теж
   акцент», і різниця між головною дією та рештою знову зникає.

   `.btn-ghost` навмисно лишається плоскою: це третій рівень («дія є, але
   вона тут не про що»), і глибина в нього забрала б сенс. */
/* 🛑 Тінь потрібна У СПОКОЇ, а не з'являтись під курсором. Кнопка,
   яку видно тільки коли на неї навели, для ока не кнопка — це підсвічений
   прямокутник, який доводиться шукати. Перша спроба ставила сюди
   `0 1px 2px rgba(0,0,0,.28)`: формально тінь була, практично її не було
   видно на темному тлі.

   Рецепт узято з плиток рейла в Studio, які працюють: заливка з ледь
   помітним переливом згори вниз (поверхня має об'єм), світла кромка по
   верхньому краю (товщина), і достатньо глибока тінь під низом (лежить НАД
   фоном, а не в ньому). */
.btn:not(.btn-primary):not(.btn-ghost):not(.btn-danger),
.cmpz-chip,
.icon-btn,
.st-aspect-btn,
.cs-suggestion {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, 0) 62%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .12),
    0 1px 1px rgba(0, 0, 0, .30),
    0 3px 7px -2px rgba(0, 0, 0, .45);
}
.btn:not(.btn-primary):not(.btn-ghost):not(.btn-danger):hover:not(:disabled),
.cmpz-chip:hover:not(:disabled),
.icon-btn:hover,
.st-aspect-btn:hover:not(:disabled),
.cs-suggestion:hover {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .16),
    0 1px 1px rgba(0, 0, 0, .30),
    0 6px 14px -3px rgba(0, 0, 0, .55);
  transform: translateY(-1px);
}
/* Натискання — протилежність спокою: кнопка ВТИСКАЄТЬСЯ. Тінь під низом
   зникає, натомість з'являється внутрішня — поверхня пішла вглиб. */
.btn:not(.btn-primary):not(.btn-ghost):not(.btn-danger):active:not(:disabled),
.cmpz-chip:active:not(:disabled),
.icon-btn:active,
.st-aspect-btn:active:not(:disabled),
.cs-suggestion:active {
  transform: translateY(1px) scale(.985);
  background-image: none;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .34);
}
.btn:disabled { box-shadow: none; }

/* М'який акцент (бурштин на 16%) — це теж другорядна кнопка, просто тепла:
   вона мусить мати ту саму товщину, інакше поруч із сірою виглядає
   провалено. */
.btn-primary[style], #cmpAssistDraftBtn.btn-primary,
#btStartBtn.btn-primary, #apStartBtn.btn-primary,
#brSurveyBtn.btn-primary, #brProcessBtn.btn-primary,
#audScrapeBtn.btn-primary, #anaInsightsGenBtn.btn-primary,
.empty-state .es-action.btn-primary, .svc-card .btn-primary,
.prov-card .pc-connect.btn-primary, .gal-use.btn-primary {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .06) inset,
    inset 0 0 0 1px var(--accent-edge),
    0 1px 2px rgba(0, 0, 0, .28);
}

/* ── 10. Повага до налаштувань системи ────────────────────────────────────
   Не «менше руху», а НУЛЬ. Половинчасті рішення тут гірші за жодне: людина,
   яка вимкнула анімації, вимкнула їх не для краси. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .ui-drift::before { animation: none !important; transform: none !important; }
  .ui-loading::after { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   11. ЛИСК — те, що відрізняє «акуратно» від «дорого»
   ══════════════════════════════════════════════════════════════════════════
   Досі шар руху був навмисно скромним, і це була помилка балансу: тихо ≠
   непомітно. Нижче — прийоми, зчитані з Linear і Stripe, які дають відчуття
   матеріалу, не додаючи жодного зайвого руху на екран.

   Усе тут — тільки box-shadow, background і transform. Жодної анімації
   розкладки, жодного нового елемента в DOM. */

/* ── Головна дія світиться ────────────────────────────────────────────────
   У Stripe акцентна кнопка має вертикальний перелив від прозорого до
   світлішого відтінку — знизу вона ніби підсвічена. Плюс кольорова тінь
   того ж тону: кнопка перестає бути наліпкою й починає лежати НАД
   поверхнею. Тінь кольорова, а не чорна — чорна на темному фоні невидима. */
.btn-primary {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .14), rgba(255, 255, 255, 0) 62%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .22) inset,
    0 6px 18px -6px var(--accent-glow);
}
.btn-primary:hover:not(:disabled) {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .3) inset,
    0 10px 26px -6px var(--accent-glow-hi);
  transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) { transform: translateY(0) scale(.985); }
.btn-primary:disabled { box-shadow: none; background-image: none; }

/* ── Скляна кромка панелей ────────────────────────────────────────────────
   Волосінь світла по верхньому краю. Це те, чим темні інтерфейси показують
   товщину поверхні: без неї панель читається як діра у фоні, з нею — як
   пластина, що лежить зверху. */
.panel, .modal-card, .ui-sel-menu, .brand-card, .svc-card {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .045) inset,
    var(--card-shadow);
}
.ui-sel-menu {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .06) inset,
    0 0 0 1px var(--border),
    var(--shadow-pop);
}

/* ── Активний пункт навігації: смужка, що виїжджає ────────────────────────
   Просто інший колір — це стан. Смужка, яка ВИРОСТАЄ з нуля, — це подія:
   око ловить рух і без свідомої уваги розуміє, що розділ змінився. */
.nav-item { position: relative; }
.nav-item::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 50%;
  width: 2.5px;
  height: 15px;
  border-radius: 2px;
  background: var(--accent-solid);
  transform: translateY(-50%) scaleY(0);
  transform-origin: center;
  opacity: 0;
  transition: transform var(--m-base) var(--m-ease-enter), opacity var(--m-fast) var(--m-ease);
}
.nav-item.active::before { transform: translateY(-50%) scaleY(1); opacity: 1; }

/* ── Наведення на картку: тепле кільце ────────────────────────────────── */
.ui-tile-media, .lp-thumb, .gp-thumb, .cat-card, .st-recent-card {
  transition:
    box-shadow var(--m-base) var(--m-ease),
    transform var(--m-base) var(--m-ease-enter);
}

/* ── Фокус із клавіатури ──────────────────────────────────────────────────
   Системне синє кільце посеред бурштинового інтерфейсу читається як чужий
   елемент. Свій колір, і тільки для клавіатури: :focus-visible не спрацьовує
   на клік мишею, тож кільце не миготить там, де його ніхто не просив. */
:focus-visible {
  outline: 2px solid var(--accent-glow-hi);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ── Великі числа з'являються знизу ───────────────────────────────────────
   Показник, що просто виник, читається як щось, що стояло тут завжди. Той
   самий підйом, що й у карток, але помітніший: число — головне на смузі. */
@keyframes uiNumIn {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to   { opacity: 1; transform: none; }
}
.ov-stat .v, .tl-val, .bl-big, .ui-stat-v, .info-hero .info-progress-pct {
  animation: uiNumIn 520ms var(--m-ease-enter) both;
}
.ov-stat:nth-child(2) .v, .tiles > *:nth-child(2) .tl-val { animation-delay: 60ms; }
.ov-stat:nth-child(3) .v, .tiles > *:nth-child(3) .tl-val { animation-delay: 120ms; }
.tiles > *:nth-child(4) .tl-val { animation-delay: 180ms; }

/* ── Смуга прогресу з рухомим блиском ─────────────────────────────────────
   Поки прогрес не повний, по заповненій частині раз на 2.4 с проходить
   світло. Це той самий сигнал «система працює», що й у смузі завантаження,
   але вбудований у сам показник. */
@keyframes uiBarSheen { from { background-position: -120% 0; } to { background-position: 220% 0; } }
.bl-bar-fill:not(.done), .info-progress-fill:not(.done) {
  background-image: linear-gradient(90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, .28) 50%,
    rgba(255, 255, 255, 0) 100%);
  background-size: 55% 100%;
  background-repeat: no-repeat;
  animation: uiBarSheen 2.4s var(--m-ease) infinite;
}

/* ── Шапка як скло ────────────────────────────────────────────────────────
   🛑 Розмиття вже стоїть у style.css — тут ЛИШЕ насиченість, і не через
   `backdrop-filter` повторно, а через `saturate` у тому самому наборі. Друге
   оголошення `backdrop-filter` перезаписало б перше й прибрало префіксний
   варіант для старих WebKit. І окремо: `backdrop-filter` робить елемент
   containing block для fixed-нащадків — саме той механізм, що вже зламав
   випадайники. У шапці такі нащадки є (панель сповіщень, перемикач бренду),
   тож нових фільтрів тут не додаємо. */

/* Ті самі правила, що вище, мусять гаснути за reduced-motion — блок нижче
   в кінці файлу вже покриває це через `*`. */
