/* klyvra motion tokens — CSS.
 * Сгенерировано из motion.js скриптом build-motion-css.mjs (motion-spec.md §16). Значения и обоснование: knowledge/motion-spec.md.
 * Подключение: <link rel="stylesheet" href="/snippets/_tokens/motion.css">
 * Правило: компоненты берут только var(--k-…); литералы ms и cubic-bezier в компонентах — дефект ревью.
 * Выход = вход × --k-exit-ratio: transition-duration: calc(var(--k-dur-base) * var(--k-exit-ratio)).
 * Лицензия: MIT, klyvra. */

:root {
  /* 1. Длительности */
  --k-dur-instant: 0ms;
  --k-dur-micro: 100ms;
  --k-dur-short: 150ms;
  --k-dur-base: 200ms;
  --k-dur-medium: 300ms;
  --k-dur-long: 400ms;
  --k-dur-page: 500ms;
  --k-dur-slow: 600ms;
  --k-dur-cinematic: 900ms;
  --k-exit-ratio: 0.75;
  --k-dur-crossfade: 150ms;            /* замена перемещения при reduce */

  /* 2. Кривые */
  --k-ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --k-ease-enter: cubic-bezier(0.05, 0.7, 0.1, 1);
  --k-ease-exit: cubic-bezier(0.3, 0, 0.8, 0.15);
  --k-ease-emphasized: linear(0, 0.003 2%, 0.013 4%, 0.03 6%, 0.056 8%, 0.093 10%, 0.146 12%, 0.222 14%, 0.341 16%, 0.52 18%, 0.636 20%, 0.706 22%, 0.773 25%, 0.84 30%, 0.883 35%, 0.912 40%, 0.951 50%, 0.973 60%, 0.987 70%, 0.997 85%, 1);
  --k-ease-linear: linear;
  --k-ease-display: cubic-bezier(0.16, 1, 0.3, 1);
  --k-ease-snap: cubic-bezier(0.45, 0, 0.55, 1);
  --k-ease-follow: cubic-bezier(0.25, 1, 0.5, 1);
  --k-ease-productive: cubic-bezier(0.2, 0, 0.38, 0.9);
  --k-ease-expressive: cubic-bezier(0.4, 0.14, 0.3, 1);

  /* 3. Пружины: linear() до покоя ±0,5 % + длительность. Для жестов и прерываемых — JS (motion.js) */
  --k-spring-snappy-dur: 210ms;   /* k 700, ζ 0.9, перелёт 0.15 % */
  --k-spring-snappy: linear(0, 0.048, 0.155, 0.287, 0.419, 0.541, 0.646, 0.734, 0.804, 0.859, 0.901, 0.932, 0.955, 0.971, 0.982, 0.99, 1);
  --k-spring-base-dur: 320ms;   /* k 300, ζ 0.9, перелёт 0.15 % */
  --k-spring-base: linear(0, 0.021, 0.074, 0.146, 0.228, 0.314, 0.399, 0.479, 0.555, 0.623, 0.684, 0.737, 0.784, 0.823, 0.857, 0.886, 0.909, 0.929, 0.945, 0.958, 0.968, 0.977, 0.983, 0.988, 0.992, 1);
  --k-spring-bouncy-dur: 340ms;   /* k 400, ζ 0.65, перелёт 6.81 % */
  --k-spring-bouncy: linear(0, 0.028, 0.099, 0.198, 0.312, 0.43, 0.546, 0.654, 0.75, 0.833, 0.902, 0.956, 0.998, 1.029, 1.049, 1.062, 1.067, 1.068, 1.065, 1.059, 1.052, 1.044, 1.036, 1.028, 1.021, 1.015, 1.009, 1);
  --k-spring-gesture-dur: 150ms;   /* k 1755, ζ 0.86, перелёт 0.5 % */
  --k-spring-gesture: linear(0, 0.116, 0.337, 0.553, 0.724, 0.844, 0.92, 0.965, 0.989, 1, 1.004, 1);
  --k-spring-effects-dur: 190ms;   /* k 1600, ζ 1, перелёт 0 % */
  --k-spring-effects: linear(0, 0.099, 0.286, 0.472, 0.626, 0.742, 0.826, 0.885, 0.925, 0.951, 0.969, 0.98, 0.987, 0.992, 1);

  /* 4. Stagger */
  --k-stagger-step: 30ms;              /* 20–50; шаг = clamp(20, (500 − d)/(N − 1), 50) */
  --k-stagger-total: 500ms;
  --k-stagger-lines: 80ms;
  --k-stagger-chars: 15ms;

  /* 5. Дистанция → длительность: d = (a + b·√(Δ/100)) × factor; clamp(100ms, …, 400ms) */
  --k-dist-a: 80ms;
  --k-dist-b: 110ms;
  --k-dur-factor: 1;                  /* 1.3 планшет, 0.6 десктоп — ниже */

  /* 6. Задержки и пороги */
  --k-delay-press-touch: 150ms;
  --k-dur-press-min: 225ms;
  --k-delay-tooltip: 500ms;
  --k-delay-tooltip-skip: 300ms;
  --k-delay-tooltip-grace: 100ms;
  --k-delay-loading: 1000ms;
  --k-dur-loading-min: 500ms;
  --k-dur-spinner: 800ms;               /* на оборот, linear */
  --k-dur-pulse: 1500ms;                /* skeleton, не меньше */
  --k-dur-shake: 320ms;
  --k-shake-amp: 6px;
  --k-shake-amp-icon: 2px;          /* иконка 24 px: ключи × ⅓ */

  /* 7. Смещения и скролл */
  --k-move: 1;                            /* множитель всех смещений; 0 при reduce */
  --k-scale-from: 0.96;                   /* появление поповера, тултипа, модалки */
  --k-press-scale: 0.97;
  --k-press-scale-icon: 0.9;              /* иконка ≤ 48 px */
  --k-scale-fade-through: 0.92;            /* вход нового экрана в fade through */
  --k-list-offset: 8px;
  --k-reveal-offset: 24px;
  --k-hover-lift: -4px;
  --k-parallax-photo: 0.1;               /* max 0.2 */
  --k-parallax-decor: 0.35;             /* 0.2–0.35, ≤ 3 слоёв, шаг k ≥ 0.1 */
  --k-marquee-speed: 60;                /* px/с; длительность = ширина группы / скорость */
  --k-draw-range: entry 25% cover 55%;   /* animation-range рисования SVG по скроллу (view()) */
  --k-reveal-range: entry 0% cover 30%;    /* animation-range reveal декора без текста (view()) */
  --k-pin-lead-range: cover 15vh cover 100vh;   /* рисование до пина: верх секции 85 % → верх окна (= GSAP scroll.pinLead) */
}

/* linear() нет (Chrome < 113, Firefox < 112, Safari < 17.2) → cubic-bezier */
@supports not (transition-timing-function: linear(0, 1)) {
  :root {
    --k-ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
    --k-spring-snappy: var(--k-ease-standard);
    --k-spring-base: var(--k-ease-standard);
    --k-spring-gesture: var(--k-ease-standard);
    --k-spring-effects: var(--k-ease-standard);
    --k-spring-bouncy: cubic-bezier(0.34, 1.4, 0.64, 1);
  }
}

/* Платформенный множитель дистанции (02 §2.2): планшет ×1.3, десктоп ×0.6 */
@media (min-width: 768px) and (pointer: coarse) { :root { --k-dur-factor: 1.3; } }
@media (min-width: 1024px) and (pointer: fine) { :root { --k-dur-factor: 0.6; } }

/* Reduced motion: перемещения → 0, длинные длительности → кроссфейд 150 мс, stagger → 0, отскок → ζ = 1.
 * Источник правды — системная настройка; переключатель сайта ставит html[data-motion="full"|"reduce"] (08 §2). */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) {
    --k-move: 0;
    --k-scale-from: 1;
    --k-press-scale: 1;
    --k-press-scale-icon: 1;
    --k-scale-fade-through: 1;
    --k-list-offset: 0px;
    --k-reveal-offset: 0px;
    --k-hover-lift: 0px;
    --k-shake-amp: 0px;
    --k-shake-amp-icon: 0px;
    --k-dur-medium: var(--k-dur-crossfade);
    --k-dur-long: var(--k-dur-crossfade);
    --k-dur-page: var(--k-dur-crossfade);
    --k-dur-slow: var(--k-dur-crossfade);
    --k-dur-cinematic: var(--k-dur-crossfade);
    --k-stagger-step: 0ms;
    --k-stagger-lines: 0ms;
    --k-stagger-chars: 0ms;
    --k-spring-bouncy: var(--k-spring-effects);
    --k-spring-bouncy-dur: var(--k-spring-effects-dur);
    --k-dur-spinner: 1600ms;
  }
}
:root[data-motion="reduce"] {
  --k-move: 0;
  --k-scale-from: 1;
  --k-press-scale: 1;
  --k-press-scale-icon: 1;
  --k-scale-fade-through: 1;
  --k-list-offset: 0px;
  --k-reveal-offset: 0px;
  --k-hover-lift: 0px;
  --k-shake-amp: 0px;
  --k-shake-amp-icon: 0px;
  --k-dur-medium: var(--k-dur-crossfade);
  --k-dur-long: var(--k-dur-crossfade);
  --k-dur-page: var(--k-dur-crossfade);
  --k-dur-slow: var(--k-dur-crossfade);
  --k-dur-cinematic: var(--k-dur-crossfade);
  --k-stagger-step: 0ms;
  --k-stagger-lines: 0ms;
  --k-stagger-chars: 0ms;
  --k-spring-bouncy: var(--k-spring-effects);
  --k-spring-bouncy-dur: var(--k-spring-effects-dur);
  --k-dur-spinner: 1600ms;
}

/* View Transitions при reduce (§11): снимки old/new — кроссфейд 150 мс без задержки. Полёт общих элементов
 * снимает компонент: при reduce у элементов нет view-transition-name (02 §7.4), group без анимации не ставить. */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"])::view-transition-old(*),
  :root:not([data-motion="full"])::view-transition-new(*) { animation-duration: var(--k-dur-crossfade); animation-delay: 0s; }
}
:root[data-motion="reduce"]::view-transition-old(*),
:root[data-motion="reduce"]::view-transition-new(*) { animation-duration: var(--k-dur-crossfade); animation-delay: 0s; }
