-
{icon}
+ {/* Use animate-pulse for celebration; bounce easing reads dated and
+ the lift is the moment, not the bounce. */}
+
{icon}
{title}
diff --git a/src/components/admin/userDetail/SyncTab.tsx b/src/components/admin/userDetail/SyncTab.tsx
index c543966..2721c1e 100644
--- a/src/components/admin/userDetail/SyncTab.tsx
+++ b/src/components/admin/userDetail/SyncTab.tsx
@@ -186,7 +186,7 @@ export function SyncTab({
disabled={actionLoading}
className="flex flex-col items-center justify-center gap-2 rounded-xl border border-accent-500/30 bg-accent-500/10 p-4 text-accent-400 transition-all hover:bg-accent-500/20 disabled:opacity-50"
>
-
+
{t('admin.users.detail.sync.fromPanel')}
@@ -196,7 +196,7 @@ export function SyncTab({
disabled={actionLoading}
className="flex flex-col items-center justify-center gap-2 rounded-xl border border-accent-500/30 bg-accent-500/10 p-4 text-accent-400 transition-all hover:bg-accent-500/20 disabled:opacity-50"
>
-
+
{t('admin.users.detail.sync.toPanel')}
diff --git a/src/components/broadcasts/BroadcastPreview.tsx b/src/components/broadcasts/BroadcastPreview.tsx
index 0971bba..8cd0d55 100644
--- a/src/components/broadcasts/BroadcastPreview.tsx
+++ b/src/components/broadcasts/BroadcastPreview.tsx
@@ -106,13 +106,13 @@ function wrap(frame: Frame, key: number): ReactNode {
return
{frame.children};
case 'code':
return (
-
+
{frame.children}
);
case 'pre':
return (
-
+
{frame.children}
);
@@ -190,7 +190,7 @@ export function TelegramPreview({
if (!open) return null;
return createPortal(
${t('admin.broadcasts.previewEmpty', '— пусто —')}`;
return createPortal(
- {/* Fill bar */}
+ {/* Fill bar — scaleX (compositor) instead of width (layout reflow).
+ Use top-left origin so fill grows left→right same as width. */}
{/* Gradient fill */}
diff --git a/src/components/layout/AppShell/AppHeader.tsx b/src/components/layout/AppShell/AppHeader.tsx
index 3cac5df..4dba295 100644
--- a/src/components/layout/AppShell/AppHeader.tsx
+++ b/src/components/layout/AppShell/AppHeader.tsx
@@ -310,7 +310,10 @@ export function AppHeader({
style={{ top: headerHeight }}
>
{/* Backdrop */}
-
setMobileMenuOpen(false)} />
+
setMobileMenuOpen(false)}
+ />
{/* Menu content */}
(
({ className, ...props }, ref) => (
diff --git a/src/components/primitives/Sheet/Sheet.tsx b/src/components/primitives/Sheet/Sheet.tsx
index 33cd6de..fe9d95b 100644
--- a/src/components/primitives/Sheet/Sheet.tsx
+++ b/src/components/primitives/Sheet/Sheet.tsx
@@ -91,7 +91,7 @@ export const SheetOverlay = forwardRef(
({ className, ...props }, ref) => (
diff --git a/src/components/tickets/MessageMediaGrid.tsx b/src/components/tickets/MessageMediaGrid.tsx
index 7ccb1c0..267454c 100644
--- a/src/components/tickets/MessageMediaGrid.tsx
+++ b/src/components/tickets/MessageMediaGrid.tsx
@@ -116,7 +116,7 @@ export function MessageMediaGrid({
loading="lazy"
/>
{isLastVisible && (
-
+
+{hiddenCount}
)}
@@ -172,7 +172,7 @@ export function MessageMediaGrid({
photoItems[fullscreenIndex] &&
createPortal(
-
+
{fullscreenIndex + 1} / {photoItems.length}
>
diff --git a/src/components/ui/Sheet.tsx b/src/components/ui/Sheet.tsx
index 486a165..07c6b88 100644
--- a/src/components/ui/Sheet.tsx
+++ b/src/components/ui/Sheet.tsx
@@ -333,7 +333,7 @@ export function Sheet({
>
{/* Backdrop */}
@@ -388,5 +388,5 @@ export function Sheet({
// Light theme styles applied via CSS
// Add to globals.css:
-// .light .sheet-backdrop { @apply bg-black/40; }
+// .light .sheet-backdrop { @apply bg-dark-950/40; }
// .light .sheet-container { @apply bg-champagne-100; }
diff --git a/src/pages/AdminBanSystem.tsx b/src/pages/AdminBanSystem.tsx
index 16cfc3e..2925d39 100644
--- a/src/pages/AdminBanSystem.tsx
+++ b/src/pages/AdminBanSystem.tsx
@@ -1535,7 +1535,7 @@ export default function AdminBanSystem() {
{/* User Detail Modal */}
{selectedUser && (
setSelectedUser(null)}
>
setDeleteConfirm(null)}
aria-hidden="true"
/>
diff --git a/src/pages/AdminLandingStats.tsx b/src/pages/AdminLandingStats.tsx
index 8ca3cf4..6a3fd5b 100644
--- a/src/pages/AdminLandingStats.tsx
+++ b/src/pages/AdminLandingStats.tsx
@@ -419,7 +419,7 @@ export default function AdminLandingStats() {
{t('admin.landings.stats.revenue')}
-
{stats.total_gifts}
+
{stats.total_gifts}
{t('admin.landings.stats.giftPurchases')}
diff --git a/src/pages/AdminPolicies.tsx b/src/pages/AdminPolicies.tsx
index f01d622..b3ecd7f 100644
--- a/src/pages/AdminPolicies.tsx
+++ b/src/pages/AdminPolicies.tsx
@@ -449,7 +449,7 @@ export default function AdminPolicies() {
{deleteConfirm !== null && (
setDeleteConfirm(null)}
aria-hidden="true"
/>
diff --git a/src/pages/AdminPromoGroups.tsx b/src/pages/AdminPromoGroups.tsx
index d231b28..3c81e8e 100644
--- a/src/pages/AdminPromoGroups.tsx
+++ b/src/pages/AdminPromoGroups.tsx
@@ -221,7 +221,7 @@ export default function AdminPromoGroups() {
{deleteConfirm && (
setDeleteConfirm(null)}
aria-hidden="true"
/>
diff --git a/src/pages/AdminRoles.tsx b/src/pages/AdminRoles.tsx
index ca7113c..f0dbf23 100644
--- a/src/pages/AdminRoles.tsx
+++ b/src/pages/AdminRoles.tsx
@@ -248,7 +248,7 @@ export default function AdminRoles() {
{deleteConfirm !== null && (
setDeleteConfirm(null)}
aria-hidden="true"
/>
diff --git a/src/pages/AdminTickets.tsx b/src/pages/AdminTickets.tsx
index d6ae44c..c1703b1 100644
--- a/src/pages/AdminTickets.tsx
+++ b/src/pages/AdminTickets.tsx
@@ -591,7 +591,7 @@ export default function AdminTickets() {
)}
{att.uploading && (
-
+
)}
diff --git a/src/pages/Contests.tsx b/src/pages/Contests.tsx
index af65891..fee4aaa 100644
--- a/src/pages/Contests.tsx
+++ b/src/pages/Contests.tsx
@@ -98,7 +98,7 @@ export default function Contests() {
{/* Game Modal */}
{selectedContest && (
-
+
e.stopPropagation()}
diff --git a/src/pages/Polls.tsx b/src/pages/Polls.tsx
index 8d3049e..7a44de8 100644
--- a/src/pages/Polls.tsx
+++ b/src/pages/Polls.tsx
@@ -139,7 +139,7 @@ export default function Polls() {
{selectedPoll && (
diff --git a/src/pages/ReferralNetwork/components/NetworkFilters.tsx b/src/pages/ReferralNetwork/components/NetworkFilters.tsx
index 13c3139..94c53d3 100644
--- a/src/pages/ReferralNetwork/components/NetworkFilters.tsx
+++ b/src/pages/ReferralNetwork/components/NetworkFilters.tsx
@@ -171,7 +171,7 @@ export function NetworkFilters({ data, className }: NetworkFiltersProps) {
{/* Mobile: full-screen overlay */}
{isOpen && (
-
setIsOpen(false)} />
+
setIsOpen(false)} />
diff --git a/src/pages/Support.tsx b/src/pages/Support.tsx
index 11146d4..f5900e7 100644
--- a/src/pages/Support.tsx
+++ b/src/pages/Support.tsx
@@ -346,7 +346,7 @@ export default function Support() {
)}
{att.uploading && (
-
+
)}
diff --git a/src/pages/TelegramCallback.tsx b/src/pages/TelegramCallback.tsx
index 981327e..3a11a00 100644
--- a/src/pages/TelegramCallback.tsx
+++ b/src/pages/TelegramCallback.tsx
@@ -80,7 +80,7 @@ export default function TelegramCallback() {
return (
-
+
{t('auth.authenticating')}
{t('common.loading')}
diff --git a/src/pages/VerifyEmail.tsx b/src/pages/VerifyEmail.tsx
index e7d473c..cfd6f71 100644
--- a/src/pages/VerifyEmail.tsx
+++ b/src/pages/VerifyEmail.tsx
@@ -75,7 +75,7 @@ export default function VerifyEmail() {
{status === 'loading' && (
-
+
{t('emailVerification.verifying')}
@@ -95,7 +95,7 @@ export default function VerifyEmail() {
{t('emailVerification.redirecting', 'Redirecting to dashboard...')}
)}