diff --git a/static/css/skeleton.css b/static/css/skeleton.css
new file mode 100644
index 0000000..7dbaa5e
--- /dev/null
+++ b/static/css/skeleton.css
@@ -0,0 +1,64 @@
+/**
+ * Skeleton Loader for Language Transitions
+ * ==========================================
+ * Simple skeleton animation shown during HTMX content swaps
+ * Uses HTMX's built-in .htmx-swapping class
+ */
+
+/* ========================================================================
+ CONTENT FADE & SKELETON TRANSITION
+ ======================================================================== */
+
+/* Fade out content when HTMX starts swapping */
+.cv-page-content-wrapper.htmx-swapping {
+ opacity: 0.3;
+ transition: opacity 250ms ease;
+ position: relative;
+}
+
+/* Skeleton overlay appears during swap */
+.cv-page-content-wrapper.htmx-swapping::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background:
+ linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
+ background-size: 200% 100%;
+ animation: skeleton-shimmer 1.5s ease-in-out infinite;
+ border-radius: 4px;
+ pointer-events: none;
+ z-index: 1;
+}
+
+@keyframes skeleton-shimmer {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+}
+
+/* Fade in new content */
+.cv-page-content-wrapper.htmx-settling {
+ opacity: 1;
+ transition: opacity 250ms ease;
+}
+
+/* ========================================================================
+ ACCESSIBILITY
+ ======================================================================== */
+
+@media (prefers-reduced-motion: reduce) {
+ .cv-page-content-wrapper.htmx-swapping::before {
+ animation: none;
+ background: #e8e8e8;
+ }
+
+ .cv-page-content-wrapper {
+ transition: none !important;
+ }
+}
diff --git a/templates/index.html b/templates/index.html
index e05527e..7ceaab0 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -62,6 +62,7 @@
+