Самодостаточный сниппет на чистом JavaScript (Web Audio API + DOM/CSS, без библиотек и без аудиофайлов; звук синтезируется в реальном времени). Один общий AudioContext, создаётся лениво и возобновляется на первом действии пользователя.
ОБЩИЙ ТРИГГЕР: клик по ссылке-кнопке «в корзину» — ссылке <a> с href="#order" (по нажатию она кладёт товар в корзину). Клик может прийтись по вложенному значку или тексту внутри ссылки, поэтому определяй ссылку через closest от места клика (ищи ближайший предок a[href="#order"]). Подключайся делегированием событий на document (фаза перехвата), чтобы работало и для динамически добавленных ссылок. На другие ссылки и кнопки не реагируй.
# ЧАСТЬ 1. ЗВУК.
Мягкое короткое положительное подтверждение «добавлено», из ДВУХ нот, восходящих на чистую квинту. Один звук на клик, с коротким подавлением повторов (около 100 мс).
Техника (точный ориентир):
— Две чистые СИНУСОИДЫ, без шума, без фильтров, без эха.
— Нота 1: 523 Гц (до), сразу.
— Нота 2: 784 Гц (соль — чистая квинта выше), со сдвигом примерно 80 миллисекунд.
— У каждой очень быстрая мягкая атака около 2 миллисекунд, затем плавное ЭКСПОНЕНЦИАЛЬНОЕ затухание: первая нота примерно до 0.1 секунды, вторая примерно до 0.15 секунды.
— Пиковая громкость каждой ноты примерно 0.3 (негромко, деликатно).
## ЧАСТЬ 2. ПОЛËТ.
На этот же клик запусти визуальный эффект: миниатюра товара вылетает из места клика и летит к иконке корзины. Только чистый JS и CSS (например Web Animations API element.animate или CSS-переходы), без библиотек.
1. Определи URL картинки товара так: от нажатой ссылки поднимись ВВЕРХ по дереву до карточки товара — ближайшего предка с классом js-product. Внутри этой карточки найди ПЕРВЫЙ тег <meta itemprop="image"> и возьми URL из его атрибута content (там лежит полный адрес картинки товара). Если карточка или такой мета-тег не найдены — анимацию полёта не запускай (звук всё равно должен играть).
2. Создай элемент <img> с этой картинкой: небольшой размер (примерно 200х200 пикселей), position: fixed, очень высокий z-index (поверх всего), pointer-events: none, слегка скруглённые углы. Помести его в точку клика КУРСОРА (координаты курсора в момент клика), отцентрировав относительно курсора.
3. Найди на странице целевой элемент — ссылку a[href="#opencart"] (иконка/кнопка открытия корзины) — и возьми координаты её центра. Их может быть несколько, и первая может быть скрытой (размером 0x0) — в неё лететь нельзя. Выбери первую видимую (ненулевые размеры, реально отрисована).
4. Плавно анимируй перелёт картинки от точки клика К центру цели за 500 миллисекунд (вся траектория укладывается в 500 мс). Путь должен быть НЕ прямой, а в форме буквы «L» / гиперболы: сначала картинка идёт преимущественно по ГОРИЗОНТАЛИ (почти вдоль по X, примерно до уровня корзины по горизонтали), затем плавно заворачивает и движется ВВЕРХ (по вертикали) к корзине. Переход между горизонтальным и вертикальным участком должен быть СГЛАЖЕННЫМ (как плавный изгиб гиперболы), а не резким прямым углом. Одновременно немного уменьшай картинку (scale вниз).
5. Прозрачность: почти всю дорогу картинка остаётся видимой (opacity близко к 1), а гаснет только в самом конце. Зарони ключевые точки прозрачности так: на 99% времени анимации opacity: 0.1, а в конце (100%) opacity: 0. Позиция в конце — почти у цели, совсем чуть-чуть не доходя до неё.
6. По завершении анимации удали этот элемент <img> из DOM (очистка).
Если целевой элемент a[href="#opencart"] на странице не найден — можно не запускать полёт (или дать картинке просто погаснуть на месте).
Скрипт должен работать сразу после вставки на страницу.