/* ═══ RUKH — шар руху бібліотеки глибини ════════════════════════════════════
 * Надбудова над `yadro.css` (там вимикач `--ruh` і токени `--t-*` від мови).
 * Тут — те, чого над ними бракує: ПРОФІЛЬ ергономіки, родини кривих,
 * тривалість за відстанню, stagger і партитура входу.
 *
 * ТРИ ТВЕРДІ ПРАВИЛА ШАРУ
 * 1. **Рухаються лише `transform`, `opacity`, `filter`.** Усе інше повертає
 *    сторінку на layout щокадру. Гейт-7 (`prostir-rukh/scripts/rukh_qa.js`)
 *    ловить порушення навіть усередині `@keyframes`.
 * 2. **Тривалість — за відстанню, не однакова на все.** Однаковий тайминг на
 *    мікровідгук і на висувну панель — головна ознака аматорського руху.
 * 3. **`prefers-reduced-motion` глушить УСЕ, включно з 3D-нахилом.** Обертання
 *    провокує вестибулярну реакцію сильніше за зсув.
 *
 * ПРОФІЛЬ. `data-ruh` на <html>:
 *   `min`       — ні руху, ні глибини;
 *   `tryvymir`  — ГЛИБИНА БЕЗ АНІМАЦІЙ (нахил, шари по Z, тіні; нічого не летить);
 *   `norm` · `vyrazno` · `povnyi` — глибина + партитура, за зростанням амплітуди.
 * Атрибут — ТОЙ САМИЙ, що вимикач ядра, а не другий поряд. Два атрибути для
 * одного поняття (`data-ruh` + `data-rukh`) неминуче розходяться: людина
 * вимикає рух одним, а профіль лишається жити в другому.
 * Профіль множить ДВІ величини окремо — тривалість (`--ruh`) і амплітуду
 * (`--ampl`). Це не одне й те саме: довший рух читається як млявий, більший —
 * як виразний. Виразність нарощується амплітудою, а не секундами.
 *
 * Числа — з `prostir-rukh/references/kanon-rukhu.md` (вимір 6 продуктів
 * 08.08.2026), не з голови.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── ПРОФІЛЬ ЕРГОНОМІКИ ────────────────────────────────────────────────────── */
:root{
  --ampl:1;                    /* множник амплітуди (зсув, підйом, нахил) */
  --krok-stagger:28ms;         /* затримка між сусідами в черзі */
  --stagger-styelya:220ms;     /* стеля сумарної затримки: далі люди чекають */
}
/* `min` уже обнуляє `--ruh` у yadro; тут добиваємо амплітуду, інакше елементи
   без переходу СТРИБАЮТЬ на 12 px — рух вимкнено, а зсув лишився. */
/* «Лише 3D» — глибина без анімацій. Час у нуль, простір лишається:
   картка нахиляється за рукою, шари стоять по Z, тіні тримають ієрархію,
   але ніщо не «прилітає», не пульсує й не відкручує числа.
   Це не «min з нахилом»: `min` глушить і простір теж. Розділення можливе саме
   тому, що тривалість і амплітуда — два різні токени. */
:root[data-ruh=tryvymir]{--ampl:1.5;--krok-stagger:0ms;--ruh:0}

:root[data-ruh=min]{--ampl:0;--krok-stagger:0ms}
:root[data-ruh=norm]{--ampl:1;--krok-stagger:24ms}
:root[data-ruh=vyrazno]{--ampl:1.5;--krok-stagger:34ms}
:root[data-ruh=povnyi] {--ampl:2;  --krok-stagger:44ms;--ruh:1.15}

/* `:root[data-ruh]` тут не для краси. Просте `:root` має нижчу специфічність за
   `:root[data-ruh=vyrazno]`, тож профіль ПЕРЕМАГАВ медіа-запит: анімація входу
   глухла (її знімає окреме правило), а от амплітуда лишалась 1.5 — нахил і
   підйом продовжували рухатись у людини, яка рух вимкнула. Виміряно
   08.08.2026. Селектор із тією самою вагою, поставлений нижче, забирає
   останнє слово. */
@media (prefers-reduced-motion:reduce){
  :root,:root[data-ruh]{--ampl:0;--krok-stagger:0ms;--ruh:0}
}

/* ── РОДИНИ КРИВИХ ─────────────────────────────────────────────────────────
   Одна крива на все — те саме, що один шрифт на все. Вхід гальмує (обʼєкт
   прибуває й зупиняється), вихід розганяється (зник — і байдуже, як саме),
   стандарт для змін на місці.
   Пружина в `linear()` — точки з симуляції затухання; жоден із шести виміряних
   продуктів її не вживає, тож це наш вибір, а не запозичення. */
:root{
  --e-vhid:var(--ease,cubic-bezier(.16,1,.3,1));
  --e-vyhid:cubic-bezier(.4,0,1,1);
  --e-zmina:var(--ease,cubic-bezier(.2,.8,.28,1));
  --pruzhyna:linear(0,.106 3%,.4 8%,.822 15%,1.02 19%,1.083 22%,1.096 25%,
    1.075 29%,1.03 34%,.999 39%,.986 45%,.995 58%,1.001 74%,1);
}

/* ── ТРИВАЛІСТЬ ЗА ВІДСТАННЮ ───────────────────────────────────────────────
   Чотири щаблі, а не «швидко/повільно». Мова задає базу (`--t-*`), профіль
   множить, клас обирає щабель. */
:root{
  --d-mikro:var(--d-instant);   /* стан контрола: колір, кільце фокуса */
  --d-blyzko:var(--d-fast);     /* рух у межах картки: підйом, розкриття */
  --d-daleko:var(--d);          /* через екран: тост, картка з колонки в колонку */
  --d-panel:var(--d-slow);      /* висувна панель, діалог, зміна екрана */
}

/* ── ПАРТИТУРА ВХОДУ ───────────────────────────────────────────────────────
   Вхід екрана має ЗАКІНЧУВАТИСЬ. Стеля сумарної затримки тримає його в
   бюджеті ≤500 мс навіть на списку з двохсот рядків: після 8-го сусіда
   затримка перестає рости (`min()`), інакше двохсотий рядок чекав би 5,6 с.

   `--i` ставить розмітка або `rukh.js`. Немає `--i` → 0, тобто елемент
   зʼявляється одразу: відсутність індексу не має ламати сторінку. */
/* `backwards`, а НЕ `both` — і це не дрібниця. `both` = `forwards` теж, тобто
   анімація НАЗАВЖДИ утримує свій останній кадр (`transform: none`). Анімація
   в каскаді сильніша за звичайні правила Й за інлайновий стиль, тож після
   входу елемент більше не приймає жодного `transform`: помирає і нахил
   (`.nahyl`), і підйом (`.pidiym:hover`), і будь-який рух, доданий пізніше.
   Виявлено 09.08.2026 виміром: токени кута ставились (±2,8°), а обчислена
   матриця лишалась одиничною — тобто «3D є в розмітці, але його немає».
   `backwards` тримає ПОЧАТКОВИЙ кадр під час затримки stagger (без нього
   елемент блимає до своєї черги) і ВІДПУСКАЄ елемент після завершення. */
.vhid{
  animation:rukh-vhid calc(var(--d-daleko)) var(--e-vhid) backwards;
  animation-delay:min(calc(var(--i,0) * var(--krok-stagger)),
                      var(--stagger-styelya));
}
.vhid-znyzu{--vhid-zsuv:calc(10px * var(--ampl))}
.vhid-zvorotnyi{--vhid-zsuv:calc(-10px * var(--ampl))}
@keyframes rukh-vhid{
  from{opacity:0;transform:translate3d(0,var(--vhid-zsuv,calc(8px * var(--ampl))),0)}
  to{opacity:1;transform:none}
}
/* Амплітуда 0 не робить рух миттєвим — вона робить його НЕВИДИМИМ, а анімація
   з нульовим зсувом усе одно тримає `opacity:0` на початку і блимає. Тому при
   вимкненому русі анімація знімається цілком. */
:root[data-ruh=min] .vhid,
:root[data-ruh=tryvymir] .vhid{animation:none}
@media (prefers-reduced-motion:reduce){.vhid{animation:none}}

/* ── ВІДГУК КОНТРОЛА ───────────────────────────────────────────────────────
   Натиснення мусить бути видно РАНІШЕ за відповідь сервера — інакше людина
   тисне вдруге. Масштаб, а не зсув: зсув у щільному ряду читається як зміна
   порядку. */
/* ── СКЛАДАННЯ ТРАНСФОРМАЦІЙ ───────────────────────────────────────────────
   `transform` — ОДНА властивість. Два ефекти, написані на неї окремими
   правилами, не додаються: перемагає важчий селектор, а другий зникає мовчки.
   Саме так `.pidiym:hover` (0,2,0) з'їдав `.nahyl` (0,1,0), і нахил за
   вказівником не працював ніде, хоча клас стояв (вимір 09.08.2026).

   Тому кожен ефект пише СВІЙ токен, а `transform` збирається в одному місці.
   Порядок множників сталий: підйом → нахил → рука. Порожній фолбек `var(--x,)`
   означає «цього доданка немає» і нічого не ламає. */
.pidiym,.nahyl,.v-poloti,.vidhuk,.mahnit{
  transform:var(--t-pidiym,) var(--t-nahyl,) var(--t-ruka,) var(--t-vidhuk,)
            var(--t-mahnit,)}

.vidhuk{transition:transform var(--d-mikro) var(--e-zmina)}
.vidhuk:active{--t-vidhuk:scale(calc(1 - .02 * var(--ampl)))}

/* ── МАГНІТ ────────────────────────────────────────────────────────────────
   Головна дія «відчуває» намір: у радіусі курсора кнопка тягнеться до нього
   на лічені пікселі й пружно повертається на місце. Що пояснює: «ось дія,
   яку ти зараз обереш». Зсув ставить `rukh.js` у `--mahnit-x/y`; СТЕЛЯ — тут
   (3px), з тієї ж причини, що в `.nahyl`: стеля лише в JS обходиться іншим
   викликом мовчки. Доданок `--t-mahnit` — у складальному правилі вище (Г33). */
.mahnit{
  --mahnit-max:3px;
  --t-mahnit:translate3d(clamp(calc(0px - var(--mahnit-max)),
                               calc(var(--mahnit-x,0px) * var(--ampl)),
                               var(--mahnit-max)),
                         clamp(calc(0px - var(--mahnit-max)),
                               calc(var(--mahnit-y,0px) * var(--ampl)),
                               var(--mahnit-max)),0);
  transition:transform var(--d-blyzko) var(--pruzhyna)}
.mahnit[data-vede]{transition:transform var(--d-mikro) var(--e-zmina)}
:root[data-ruh=min] .mahnit,
:root[data-ruh=tryvymir] .mahnit{--t-mahnit:}
@media (prefers-reduced-motion:reduce){.mahnit{--t-mahnit:;transition:none}}

/* ── ПІДЙОМ ────────────────────────────────────────────────────────────────
   Підйом = зсув угору + глибша тінь. Тінь анімувати дорого (перемальовує
   розмиття щокадру), тому тінь МІНЯЄТЬСЯ, а їде — `transform`. */
.pidiym{transition:transform var(--d-blyzko) var(--e-zmina),
                   box-shadow var(--d-blyzko) var(--e-zmina)}
.pidiym:hover{--t-pidiym:translate3d(0,calc(-2px * var(--ampl)),0);
  box-shadow:var(--tin-2)}

/* ── ПУЛЬС ЖИВОГО ──────────────────────────────────────────────────────────
   Єдиний нескінченний цикл, який ця бібліотека дозволяє: індикатор «онлайн».
   Усе інше циклічне — спінер, і в нього є власний компонент. */
.pulsuye::after{content:"";position:absolute;inset:0;border-radius:inherit;
  box-shadow:0 0 0 0 var(--akcent);
  animation:rukh-puls 2.4s var(--e-vyhid) infinite}
@keyframes rukh-puls{
  from{box-shadow:0 0 0 0 var(--akcent);opacity:.55}
  to{box-shadow:0 0 0 calc(9px * var(--ampl)) var(--akcent);opacity:0}
}
:root[data-ruh=min] .pulsuye::after,
:root[data-ruh=tryvymir] .pulsuye::after{animation:none;opacity:0}
@media (prefers-reduced-motion:reduce){.pulsuye::after{animation:none;opacity:0}}

/* ── ПЕРЕХІД МІЖ ЕКРАНАМИ ──────────────────────────────────────────────────
   View Transitions: браузер сам зшиває два стани. Спільний елемент отримує
   `view-transition-name` — і заголовок картки не зникає, а ПЕРЕЇЖДЖАЄ у
   заголовок сторінки. Це найдешевший спосіб сказати «ти там само, глибше».
   Браузер без підтримки просто перемальовує сторінку — деградація нульова. */
@media (prefers-reduced-motion:no-preference){
  :root[data-ruh=tryvymir]::view-transition-old(root),
  :root[data-ruh=tryvymir]::view-transition-new(root){animation:none}
  ::view-transition-old(root){animation:rukh-zhasannya var(--d-blyzko)
    var(--e-vyhid) both}
  ::view-transition-new(root){animation:rukh-vhid var(--d-daleko)
    var(--e-vhid) both}
}
@keyframes rukh-zhasannya{to{opacity:0}}

/* ── ЛІЧИЛЬНИК ЧИСЛА ───────────────────────────────────────────────────────
   Саме число відкручує `rukh.js` (групування розрядів CSS не вміє). Тут —
   резерв ширини: без нього рядок стрибає на кожному кадрі лічильника. */
.chyslo-bizhyt{font-variant-numeric:tabular-nums;
  transition:color var(--d-mikro) var(--e-zmina)}
.chyslo-bizhyt[data-bizhyt]{color:var(--akcent)}
