diff --git a/src/components/Elements/MainModal/components/SidebarSkeleton.jsx b/src/components/Elements/MainModal/components/SidebarSkeleton.jsx
new file mode 100644
index 00000000..8ad81f86
--- /dev/null
+++ b/src/components/Elements/MainModal/components/SidebarSkeleton.jsx
@@ -0,0 +1,50 @@
+import { TAB_TYPES } from '../constants/tabConfig';
+
+// Tab-specific configurations with exact divider positions
+const TAB_CONFIGS = {
+ [TAB_TYPES.SETTINGS]: {
+ itemCount: 16, // Excluding experimental
+ dividerPositions: [10, 12], // After Weather, Language
+ textWidths: [80, 100, 70, 90, 85, 75, 80, 95, 90, 75, 85, 90, 85, 80, 70, 95], // Fixed widths in pixels
+ },
+ [TAB_TYPES.DISCOVER]: {
+ itemCount: 5,
+ dividerPositions: [0], // After "All"
+ textWidths: [60, 95, 95, 110, 90], // Fixed widths
+ },
+ [TAB_TYPES.LIBRARY]: {
+ itemCount: 0, // Library doesn't show sidebar
+ dividerPositions: [],
+ textWidths: [],
+ },
+};
+
+const SidebarSkeleton = ({ currentTab = TAB_TYPES.SETTINGS }) => {
+ const config = TAB_CONFIGS[currentTab] || TAB_CONFIGS[TAB_TYPES.SETTINGS];
+
+ // Library tab doesn't show sidebar
+ if (config.itemCount === 0) {
+ return null;
+ }
+
+ return (
+
+ {Array.from({ length: config.itemCount }).map((_, index) => {
+ const hasDivider = config.dividerPositions.includes(index);
+ const textWidth = config.textWidths[index] || 80;
+
+ return (
+
+ );
+ })}
+
+ );
+};
+
+export default SidebarSkeleton;
diff --git a/src/components/Elements/MainModal/scss/modules/_sidebar.scss b/src/components/Elements/MainModal/scss/modules/_sidebar.scss
index b412c06c..25756c0f 100644
--- a/src/components/Elements/MainModal/scss/modules/_sidebar.scss
+++ b/src/components/Elements/MainModal/scss/modules/_sidebar.scss
@@ -74,3 +74,54 @@
margin-left: 0 !important;
margin-right: 0 !important;
}
+
+// Sidebar skeleton loader
+.sidebarSkeleton {
+ padding: 0.5rem 0.2rem;
+
+ .skeletonItem {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem;
+ margin: 0.2rem;
+ pointer-events: none;
+
+ .iconPlaceholder {
+ width: 17px;
+ height: 17px;
+ border-radius: 6px;
+ margin-left: 20px;
+ margin-right: 20px;
+ flex-shrink: 0;
+
+ @include themed {
+ background: t($modal-sidebarActive);
+ }
+ }
+
+ .textPlaceholder {
+ height: 18px;
+ border-radius: 6px;
+
+ @include themed {
+ background: t($modal-sidebarActive);
+ }
+ }
+ }
+
+ .skeletonDivider {
+ @include themed {
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent 0%,
+ t($modal-sidebarActive) 20%,
+ t($modal-sidebarActive) 80%,
+ transparent 100%
+ );
+ margin: 0.5rem 1.75rem;
+ border: none;
+ opacity: 0.6;
+ }
+ }
+}
diff --git a/src/scss/index.scss b/src/scss/index.scss
index a1fccaa0..49719b81 100644
--- a/src/scss/index.scss
+++ b/src/scss/index.scss
@@ -210,7 +210,7 @@ body {
width: 100%;
background: linear-gradient(-90deg, #efefef 0%, #ccc 50%, #efefef 100%);
background-size: 400% 400%;
- animation: pulse 1.2s ease-in-out infinite;
+ animation: pulse 0.8s ease-in-out infinite;
@keyframes pulse {
0% {
@@ -230,7 +230,7 @@ body {
width: 100%;
background: linear-gradient(-90deg, #000 0%, rgb(83 83 83) 50%, #000 100%);
background-size: 400% 400%;
- animation: pulse 1.2s ease-in-out infinite;
+ animation: pulse 0.8s ease-in-out infinite;
@keyframes pulse {
0% {