/* ─────────────────────────────────────────────────────────────
   Кнопки: эффект «волна по тексту» при наведении.
   Перенесён с боевого сайта (там это btn-hover-txt-liquid-x):
   каждая буква гаснет, уезжая влево, мгновенно перескакивает вправо
   и возвращается на место. Задержка по индексу буквы даёт волну.
   ───────────────────────────────────────────────────────────── */
@keyframes btnLiquidX {
  50%  { opacity: 0; transform: translateX(-0.3em); }
  51%  { opacity: 0; transform: translateX(0.3em); }
  100% { opacity: 1; transform: translateX(0); }
}

.btn-liquid .chars { display: inline-block; }
/* Слово — единый блок: перенос возможен только между словами */
.btn-liquid .word { display: inline-block; white-space: nowrap; }

.btn-liquid .char {
  display: inline-block;
  white-space: pre;   /* сохраняем пробелы между словами */
  will-change: transform, opacity;
}

.btn-liquid:hover .char,
.btn-liquid:focus-visible .char {
  animation: btnLiquidX 0.6s calc(var(--i, 0) * 0.03s) cubic-bezier(0.23, 1, 0.32, 1) both;
}

/* ─────────────────────────────────────────────────────────────
   Иконка перелетает на противоположную сторону.

   В разметке две копии: настоящая остаётся в потоке (держит ширину
   кнопки неизменной), копия-«призрак» лежит абсолютно на другом краю.
   Обрезки нет нигде — иконки только гаснут и проявляются,
   а текст съезжает на освободившееся место.
   Величину сдвига (--icon-shift) считает скрипт по ширине иконки.
   ───────────────────────────────────────────────────────────── */
.has-icon-swap { position: relative; }

.btn-icon {
  display: inline-flex;
  align-items: center;
  flex: none;
  transition: opacity 0.26s ease,
              transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Отступ до текста зависит от стороны. --icon-gap проставляет скрипт. */
.btn-icon--at-start { margin-right: var(--icon-gap, 8px); }
.btn-icon--at-end   { margin-left:  var(--icon-gap, 8px); }

/* Призрак не занимает места в потоке */
.btn-icon--ghost {
  position: absolute;
  top: 50%;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}
.btn-icon--ghost.btn-icon--at-start { left: var(--pad-l, 0px);  transform: translate(-10px, -50%); }
.btn-icon--ghost.btn-icon--at-end   { right: var(--pad-r, 0px); transform: translate(10px, -50%); }

/* Наведение: настоящая уходит, призрак приходит, текст сдвигается */
.has-icon-swap:hover .btn-icon--real,
.has-icon-swap:focus-visible .btn-icon--real { opacity: 0; }

.has-icon-swap:hover .btn-icon--real.btn-icon--at-end,
.has-icon-swap:focus-visible .btn-icon--real.btn-icon--at-end { transform: translateX(10px); }
.has-icon-swap:hover .btn-icon--real.btn-icon--at-start,
.has-icon-swap:focus-visible .btn-icon--real.btn-icon--at-start { transform: translateX(-10px); }

.has-icon-swap:hover .btn-icon--ghost,
.has-icon-swap:focus-visible .btn-icon--ghost {
  opacity: 1;
  transform: translate(0, -50%);
}

.has-icon-swap .chars {
  transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.has-icon-swap:hover .chars,
.has-icon-swap:focus-visible .chars {
  transform: translateX(var(--icon-shift, 0px));
}

/* Уважаем системную настройку «уменьшить движение» */
@media (prefers-reduced-motion: reduce) {
  .btn-liquid:hover .char,
  .btn-liquid:focus-visible .char { animation: none; }
  .btn-icon,
  .has-icon-swap .chars { transition: none; }
}
