diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index 178c021f0..01156117d 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -114,6 +114,12 @@ set(ayugram_files
         ayu/utils/telegram_helpers.h
         ayu/utils/windows_utils.cpp
         ayu/utils/windows_utils.h
+        ayu/utils/taptic_engine/taptic_engine.cpp
+        ayu/utils/taptic_engine/taptic_engine.h
+        ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp
+        ayu/utils/taptic_engine/platform/taptic_engine_dummy.h
+        ayu/utils/taptic_engine/platform/taptic_engine_mac.mm
+        ayu/utils/taptic_engine/platform/taptic_engine_mac.h
         ayu/ui/ayu_logo.cpp
         ayu/ui/ayu_logo.h
         ayu/ui/utils/ayu_profile_values.cpp
diff --git a/Telegram/SourceFiles/ayu/ayu_infra.cpp b/Telegram/SourceFiles/ayu/ayu_infra.cpp
index 03bf98792..cb92fc822 100644
--- a/Telegram/SourceFiles/ayu/ayu_infra.cpp
+++ b/Telegram/SourceFiles/ayu/ayu_infra.cpp
@@ -6,12 +6,13 @@
 // Copyright @Radolyn, 2024
 #include "ayu_infra.h"
 
-#include "ayu_lang.h"
-#include "ayu_worker.h"
+#include "ayu/ayu_lang.h"
+#include "ayu/ayu_worker.h"
 #include "ayu/ayu_fonts.h"
 #include "ayu/ayu_settings.h"
 #include "ayu/data/ayu_database.h"
 #include "lang/lang_instance.h"
+#include "utils/taptic_engine/taptic_engine.h"
 
 namespace AyuInfra {
 
@@ -45,6 +46,8 @@ void init() {
 	initDatabase();
 	initFonts();
 	initWorker();
+
+	TapticEngine::init();
 }
 
 }
diff --git a/Telegram/SourceFiles/ayu/ayu_settings.cpp b/Telegram/SourceFiles/ayu/ayu_settings.cpp
index b3837ec90..a40a2de83 100644
--- a/Telegram/SourceFiles/ayu/ayu_settings.cpp
+++ b/Telegram/SourceFiles/ayu/ayu_settings.cpp
@@ -227,7 +227,7 @@ AyuGramSettings::AyuGramSettings() {
 
 	// ~ Customization
 	appIcon =
-#ifdef Q_OS_DARWIN
+#ifdef Q_OS_MAC
 		AyuAssets::DEFAULT_MACOS_ICON
 #else
 		AyuAssets::DEFAULT_ICON
diff --git a/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp b/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp
index a84e0e1d7..1a51940aa 100644
--- a/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp
+++ b/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp
@@ -34,7 +34,7 @@ void loadIcons() {
 	if (LAST_LOADED_NAME != settings->appIcon) {
 		LAST_LOADED_NAME = settings->appIcon;
 
-#ifdef Q_OS_DARWIN
+#ifdef Q_OS_MAC
 		LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app_macos.png").arg(settings->appIcon));
 #else
 		LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app.png").arg(settings->appIcon));
diff --git a/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp b/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp
index d9e5eae32..735d66eae 100644
--- a/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp
+++ b/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp
@@ -170,7 +170,6 @@ private:
 	QString _chosen;
 	QStringList _query;
 
-	bool _areOfficial = false;
 	bool _mouseSelection = false;
 	QPoint _globalMousePosition;
 
diff --git a/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp b/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp
index 3351662ac..1ce4281c3 100644
--- a/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp
+++ b/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp
@@ -34,7 +34,7 @@
 namespace AyuUi {
 
 bool needToShowItem(int state) {
-	return state == 1 || state == 2 && base::IsExtendedContextMenuModifierPressed();
+	return state == 1 || (state == 2 && base::IsExtendedContextMenuModifierPressed());
 }
 
 void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
@@ -120,7 +120,7 @@ void AddMessageDetailsAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
 	if (!containsSingleCustomEmojiPack && emojiPacks.size() > 1) {
 		const auto author = emojiPacks.front().id >> 32;
 		auto sameAuthor = true;
-		for (const auto pack : emojiPacks) {
+        for (const auto &pack : emojiPacks) {
 			if (pack.id >> 32 != author) {
 				sameAuthor = false;
 				break;
diff --git a/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp b/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp
index 8e5b566fa..6e2a2fc3f 100644
--- a/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp
+++ b/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp
@@ -21,7 +21,7 @@
 #endif
 
 const QVector<QString> icons{
-#ifdef Q_OS_DARWIN
+#ifdef Q_OS_MAC
 	AyuAssets::DEFAULT_MACOS_ICON,
 #endif
 	AyuAssets::DEFAULT_ICON,
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp
new file mode 100644
index 000000000..ee486e70b
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp
@@ -0,0 +1,23 @@
+#include "taptic_engine_dummy.h"
+
+#ifndef Q_OS_MAC
+
+namespace TapticEngine {
+namespace Impl {
+
+void init() {
+}
+
+void generateGeneric() {
+}
+
+void generateAlignment() {
+}
+
+void generateLevelChange() {
+}
+
+}
+}
+
+#endif
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h
new file mode 100644
index 000000000..d2a78b2a5
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace TapticEngine {
+namespace Impl {
+
+void init();
+void generateGeneric();
+void generateAlignment();
+void generateLevelChange();
+
+}
+}
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h
new file mode 100644
index 000000000..d2a78b2a5
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace TapticEngine {
+namespace Impl {
+
+void init();
+void generateGeneric();
+void generateAlignment();
+void generateLevelChange();
+
+}
+}
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm
new file mode 100644
index 000000000..f0c390d34
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm
@@ -0,0 +1,41 @@
+#include "taptic_engine_mac.h"
+
+#ifdef Q_OS_MAC
+
+#import <AppKit/AppKit.h>
+
+namespace TapticEngine {
+namespace Impl {
+
+NSHapticFeedbackManager *hapticFeedbackManager = nil;
+
+void init() {
+    if (@available(macOS 10.11, *)) {
+        hapticFeedbackManager = [NSHapticFeedbackManager defaultPerformer];
+    }
+}
+
+void performHapticFeedback(NSHapticFeedbackPattern pattern) {
+    if (@available(macOS 10.11, *)) {
+        if (hapticFeedbackManager) {
+            [hapticFeedbackManager performFeedbackPattern:pattern performanceTime:NSHapticFeedbackPerformanceTimeNow];
+        }
+    }
+}
+
+void generateGeneric() {
+    performHapticFeedback(NSHapticFeedbackPatternGeneric);
+}
+
+void generateAlignment() {
+    performHapticFeedback(NSHapticFeedbackPatternAlignment);
+}
+
+void generateLevelChange() {
+    performHapticFeedback(NSHapticFeedbackPatternLevelChange);
+}
+
+}
+}
+
+#endif
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp
new file mode 100644
index 000000000..7d4865413
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp
@@ -0,0 +1,27 @@
+#include "taptic_engine.h"
+
+#if defined Q_OS_MAC
+#include "ayu/utils/taptic_engine/platform/taptic_engine_mac.h"
+#else
+#include "ayu/utils/taptic_engine/platform/taptic_engine_dummy.h"
+#endif
+
+namespace TapticEngine {
+
+void init() {
+	Impl::init();
+}
+
+void generateGeneric() {
+	Impl::generateGeneric();
+}
+
+void generateAlignment() {
+	Impl::generateAlignment();
+}
+
+void generateLevelChange() {
+	Impl::generateLevelChange();
+}
+
+}
diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h
new file mode 100644
index 000000000..2534f550a
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h
@@ -0,0 +1,11 @@
+#pragma once
+
+namespace TapticEngine {
+
+void init();
+void generateGeneric();
+void generateAlignment();
+void generateLevelChange();
+// void deinit();
+
+}
diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
index 41a9ddd8d..b9522136f 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
@@ -93,6 +93,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 // AyuGram includes
 #include "ayu/ayu_settings.h"
+#include "ayu/utils/taptic_engine/taptic_engine.h"
 
 
 namespace Dialogs {
@@ -1025,6 +1026,7 @@ void Widget::setupStories() {
 			storiesToggleExplicitExpand(true);
 			_scroll->setOverscrollDefaults(0, 0);
 		} else {
+			TapticEngine::generateLevelChange();
 			_scroll->setOverscrollDefaults(
 				-st::dialogsStoriesFull.height,
 				0);
diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp
index e77526572..217da94bb 100644
--- a/Telegram/SourceFiles/history/history_inner_widget.cpp
+++ b/Telegram/SourceFiles/history/history_inner_widget.cpp
@@ -99,6 +99,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 // AyuGram includes
 #include "ayu/ui/context_menu/context_menu.h"
 #include "ayu/utils/telegram_helpers.h"
+#include "data/data_document_media.h"
 
 
 namespace {
@@ -488,6 +489,51 @@ HistoryInner::HistoryInner(
 		_scroll->scrollToY(_scroll->scrollTop() + d);
 	}, _scroll->lifetime());
 
+	_controller->window().widget()->globalForceClicks() |
+		rpl::start_with_next(
+			[=](QPoint globalPosition)
+			{
+				auto mousePos = mapFromGlobal(globalPosition);
+				auto point = _widget->clampMousePosition(mousePos);
+
+				if (!inSelectionMode() && !_emptyPainter && rect().contains(mousePos)) {
+					if (const auto view = Element::Moused()) {
+						mouseActionCancel();
+
+						const auto m = mapPointToItem(point, view);
+						const auto inside = view->pointState(m) != PointState::Outside;
+						const auto media = view->data()->media();
+						if (inside && media) {
+							if (const auto preview = media->document()) {
+								if (!preview->sticker()) {
+									if (const auto mediaView = preview->activeMediaView()) {
+										const auto previewState = Data::VideoPreviewState(mediaView.get());
+										if (!previewState.loaded()) {
+											preview->loadVideoThumbnail(view->data()->fullId());
+											preview->loadThumbnail(view->data()->fullId());
+											return;
+										}
+									}
+								}
+
+								_wasForceClickPreview = _controller->uiShow()->showMediaPreview(
+									preview->sticker() ? preview->stickerSetOrigin() : view->data()->fullId(), preview);
+							} else if (const auto previewPhoto = media->photo()) {
+								_wasForceClickPreview =
+									_controller->uiShow()->showMediaPreview(Data::FileOrigin(), previewPhoto);
+							}
+
+							if (!_wasForceClickPreview) {
+								toggleFavoriteReaction(view);
+							}
+						} else {
+							toggleFavoriteReaction(view);
+						}
+					}
+				}
+			},
+			lifetime());
+
 	setupSharingDisallowed();
 }
 
@@ -1976,6 +2022,11 @@ void HistoryInner::mouseActionFinish(
 }
 
 void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {
+	if (_wasForceClickPreview) {
+		_wasForceClickPreview = false;
+		return;
+	}
+
 	mouseActionFinish(e->globalPos(), e->button());
 	if (!rect().contains(e->pos())) {
 		leaveEvent(e);
diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h
index 5a11b2944..5edc1b61d 100644
--- a/Telegram/SourceFiles/history/history_inner_widget.h
+++ b/Telegram/SourceFiles/history/history_inner_widget.h
@@ -538,4 +538,6 @@ private:
 	int _scrollDateLastItemTop = 0;
 	ClickHandlerPtr _scrollDateLink;
 
+	bool _wasForceClickPreview = false;
+
 };
diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp
index 5dfae5a65..da76463e3 100644
--- a/Telegram/SourceFiles/intro/intro_step.cpp
+++ b/Telegram/SourceFiles/intro/intro_step.cpp
@@ -464,14 +464,7 @@ void Step::paintCover(QPainter &p, int top) {
 	st::introCoverLeft.paint(p, left, coverHeight - st::introCoverLeft.height(), width());
 	st::introCoverRight.paint(p, width() - right - st::introCoverRight.width(), coverHeight - st::introCoverRight.height(), width());
 
-	auto planeLeft = (width() - st::introCoverIcon.width()) / 2 - st::introCoverIconLeft;
 	auto planeTop = top + st::introCoverIconTop;
-	if (top < 0 && !_hasCover) {
-		auto deltaLeft = -qRound(float64(st::introPlaneWidth / st::introPlaneHeight) * top);
-//		auto deltaTop = top;
-		planeLeft += deltaLeft;
-	//	planeTop += top;
-	}
 	const auto ayuGramIcon = Ui::PixmapFromImage(AyuAssets::currentAppLogo());
 	QIcon(ayuGramIcon).paint(&p, QRect(width() / 2 - ayuGramIcon.width() / 2, planeTop - 16, ayuGramIcon.width(), st::introCoverIcon.height()));
 }
diff --git a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp
index a193bf32d..3fcabe3eb 100644
--- a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp
+++ b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp
@@ -17,6 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "base/random.h"
 #include "styles/style_chat.h"
 
+// AyuGram includes
+#include "ayu/utils/taptic_engine/taptic_engine.h"
+
+
 namespace Ui {
 namespace {
 
@@ -55,6 +59,11 @@ auto ReactionFlyAnimation::callback() {
 	return [=] {
 		if (_repaint) {
 			_repaint();
+
+			if (_minis.animating() && !_hapticExecuted) {
+				TapticEngine::generateGeneric();
+				_hapticExecuted = true;
+			}
 		}
 	};
 }
diff --git a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h
index 0ea353f3b..48e8f0688 100644
--- a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h
+++ b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h
@@ -127,6 +127,8 @@ private:
 	bool _effectOnly = false;
 	bool _valid = false;
 
+	bool _hapticExecuted = false;
+
 	mutable Parabolic _cached;
 
 };