/*
  Всё, что существует только под курсором.

  Отдельным файлом не ради порядка: он подключён с
  `media="(hover: hover) and (pointer: fine)"`, а таблицу, чей media-запрос не
  совпал, браузер не считает блокирующей отрисовку. На телефоне — то есть у
  всей платной аудитории — эти полтора килобайта уходят из критического пути
  целиком и не стоят ни миллисекунды до первого экрана. На десктопе файл
  блокирует, но там LCP 0.33 с и запас четырёхкратный.

  Порядок подключения важен: файл идёт после `styles.v4.css`, поэтому правила
  для reduce лежат здесь же, внизу, — иначе они проигрывали бы по порядку.
*/

/* Главная кнопка. Свечение и блик — два готовых градиента на ::after и
   ::before; покадрово меняются только opacity и translate, ни одного
   box-shadow. `overflow: hidden` держит блик внутри скругления. */
.btn-primary { position: relative; overflow: hidden; isolation: isolate; }
.btn-primary::before, .btn-primary::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: -1;
}
.btn-primary::after {
  background: radial-gradient(120% 160% at 50% 130%, rgba(255, 255, 255, .55), transparent 62%);
  opacity: 0; transition: opacity .2s ease;
}
.btn-primary::before {
  background: linear-gradient(100deg, transparent 42%, rgba(255, 255, 255, .5) 50%, transparent 58%);
  translate: -120% 0; opacity: 0;
}
.btn-primary:hover { translate: 0 -2px; }
.btn-primary:hover::after { opacity: 1; }
.btn-primary:hover::before { animation: sheen .6s ease-out; }
.btn-primary:hover .btn-arrow { translate: 3px 0; }

/* Вторичное: подчёркивание выезжает слева, сам элемент не двигается. */
.btn-ghost, .sticky-alt { position: relative; }
.btn-ghost::after, .sticky-alt::after {
  content: ""; position: absolute; left: 22px; right: 22px; bottom: 12px;
  height: 1px; background: currentColor; opacity: .7;
  scale: 0 1; transform-origin: left center;
  transition: scale .22s ease;
}
.sticky-alt::after { left: 6px; right: 6px; bottom: 8px; }
.btn-ghost:hover::after, .sticky-alt:hover::after { scale: 1 1; }
.btn-ghost:hover, .sticky-alt:hover { color: var(--text); }

/* Карточки: подъём на три пикселя и посветлевшая граница. */
.gstep:hover, .card:hover, .card-fact:hover {
  translate: 0 -3px;
  border-color: var(--dim);
}
/* Пятно света под курсором. Координаты приходят из одного делегированного
   `pointermove`, класс висит ровно на одной карточке за раз. Градиент
   статичен — меняется только точка, то есть перерисовка фона одного
   элемента, без размытия и без слоя на каждую карточку. */
.is-lit {
  background-image: radial-gradient(200px circle at var(--mx, 50%) var(--my, 50%),
    rgba(245, 165, 94, .11), transparent 68%);
}

.cells:hover ~ .code-hint .copy-ic, .code-hint:hover .copy-ic { animation: wobble .3s ease; }

@media (prefers-reduced-motion: reduce) {

  /* Остаются цвет и прозрачность; ничего не едет и не масштабируется. */
  .btn-primary:hover, .gstep:hover, .card:hover, .card-fact:hover { translate: none; }
  .btn:active, .btn-ghost:active, .sticky-alt:active,
  .gstep:active, .card:active, .card-fact:active { scale: none; }
  .btn-primary:hover::before { animation: none; }
  .btn-primary:hover .btn-arrow { translate: none; }
  .btn-ghost:hover::after, .sticky-alt:hover::after { scale: 1 1; }
  .is-lit { background-image: none; }
}

.btn-primary:hover { background: color-mix(in srgb, var(--accent) 88%, #fff); transform: translateY(-1px); }
.btn-ghost:hover { border-color: var(--dim); background: var(--surface); }

.tg-alt:hover { color: var(--text); border-bottom-color: var(--dim); }
.seg-btn:hover { color: var(--text); }
.lang:hover .lang-flag { opacity: 1; filter: saturate(1); }
