/* ПРУЖИННОЕ НАЖАТИЕ — ОДНО ПРАВИЛО НА ВСЁ ПРИЛОЖЕНИЕ (10.09.2026, правка
   Сармата, п.5: «нажал — кнопка красиво сжимается и пружинит обратно», и это
   должно быть общим правилом, а не заплаткой по местам, иначе на следующей
   новой кнопке эффекта снова не будет).

   ПОЧЕМУ АНИМАЦИЯ, А НЕ :active + transition. Две причины, обе не вкусовые.
   1. Кассада. В проекте уже около двадцати своих правил вида
      `.home .tiles .tile.st-t:active{transform:translateY(1px) scale(.99)}`
      весом до (0,4,1). Обычным правилом их не перебить, не заводя !important
      в каждую строку — а !important в этом проекте не заводят принципиально
      (см. комментарии в cabinet.css). CSS-АНИМАЦИЯ бьёт любое обычное
      объявление того же свойства по правилам каскада, независимо от веса
      селектора. Поэтому пружина ложится поверх всех прежних нажатий,
      ничего не переписывая и ничего не ломая.
   2. Отпускание. У :active нет состояния «только что отпустили»: снятие
      класса просто возвращает элемент по обратному переходу. Пружинит именно
      ОТПУСКАНИЕ, и ему нужна своя кривая с перелётом — то есть отдельная
      анимация, которую и вешает spring.js на pointerup.

   ЧАСТОТА КАДРОВ. Анимируется только transform — значит анимация уходит на
   композитор и идёт с частотой дисплея (120 Гц на ProMotion), не завися от
   занятости главного потока. Это тот же приём, что просил Сармат в п.6 для
   раскрытия списка треков. `will-change:transform` в spring.js ставится ровно
   на время нажатия и снимается после: постоянный will-change держит слой на
   каждой кнопке экрана впустую.

   КРИВАЯ НАСТОЯЩАЯ, А НЕ НА ГЛАЗ. --spring — это затухающая пружина
   x(t)=e^(-6t)(cos8.5t+(6/8.5)sin8.5t), посчитанная численно и выложенная в
   linear() 33 точками (шаг 3.13% — при 420ms это 13ms, то есть в среднем полтора
   кадра на отрезок при 120 Гц; на глаз от гладкой кривой не отличается).
   Перелёт 11% от хода: ход 0.045 (scale .955→1), значит верхняя точка
   scale≈1.005 — пружинит заметно, но кнопка не «прыгает». cubic-bezier перед
   linear() — не украшение, а откат для браузеров без linear(): они не разберут
   вторую строку и оставят первую. */
:root{
  --spring:cubic-bezier(.34,1.56,.64,1);
  --spring:linear(0 0%, 0.0464 3.13%, 0.1617 6.25%, 0.3141 9.38%, 0.4788 12.5%,
    0.6376 15.63%, 0.7783 18.75%, 0.8945 21.88%, 0.9835 25%, 1.0461 28.13%,
    1.0851 31.25%, 1.1045 34.38%, 1.1087 37.5%, 1.1021 40.63%, 1.0886 43.75%,
    1.0716 46.88%, 1.0537 50%, 1.0366 53.13%, 1.0217 56.25%, 1.0096 59.38%,
    1.0004 62.5%, 0.9941 65.63%, 0.9902 68.75%, 0.9884 71.88%, 0.9882 75%,
    0.9891 78.13%, 0.9907 81.25%, 0.9925 84.38%, 0.9945 87.5%, 0.9963 90.63%,
    0.9979 93.75%, 0.9992 96.88%, 1.0001 100%);
  /* Вниз — быстро и без пружины: палец уже приехал, тут нужна отзывчивость, а
     не красота. 90ms — порог, ниже которого нажатие перестаёт читаться вовсе. */
  --spring-in:cubic-bezier(.2,0,.35,1);
  --spring-dur:420ms;
  --spring-in-dur:90ms;
  /* Ход нажатия. .955 на кнопке 48px это 2px — видно пальцем и не мельтешит на
     крупных плитках, где та же доля даёт уже 6-8px. Доля, а не пиксели, именно
     поэтому: у продукта кнопки от 22px (закрыть) до плиток во всю ширину. */
  --spring-press:.955;
}

@keyframes sp-press-in{
  from{transform:scale(1)}
  to{transform:scale(var(--spring-press))}
}
@keyframes sp-press-out{
  from{transform:scale(var(--spring-press))}
  to{transform:scale(1)}
}

/* Класс ставит spring.js — он же решает, что считать кнопкой (один список
   селекторов на всё приложение, см. ПРЕСС в spring.js). */
.sp-press{animation:sp-press-in var(--spring-in-dur) var(--spring-in) forwards}
.sp-back{animation:sp-press-out var(--spring-dur) var(--spring)}

/* Крупные поверхности жмутся мягче: на плитке во всю ширину и на карточке
   полки те же 4.5% дают 8-16px хода — это уже не нажатие, а прыжок. */
.tile.sp-press,.tile.sp-back,
.lesson-cta.sp-press,.lesson-cta.sp-back,
.hm-card.sp-press,.hm-card.sp-back,
.sp-shelf-c.sp-press,.sp-shelf-c.sp-back,
.dm-teaser.sp-press,.dm-teaser.sp-back,
.st-help.sp-press,.st-help.sp-back,
.connect-link.sp-press,.connect-link.sp-back,
.ls-item.sp-press,.ls-item.sp-back{--spring-press:.982}

/* Уважение к настройке ОС. Нажатие не исчезает совсем — остаётся мгновенная
   ступенька без пружины: обратная связь «я нажал» это не украшение, её убирать
   нельзя, а вот качание убрать надо. */
@media (prefers-reduced-motion:reduce){
  .sp-press{animation-duration:1ms}
  .sp-back{animation:none}
}
