Template Loading Product - Tailwind

🏷️ Extraits de code HTML 📅 17/04/2026 👤 Mezgani said
Tailwind Loading Product Html Css

Template de chargement de produit Tailwind avec design élégant et moderne.

<!doctype html>
<html lang="fr">
  <head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="MEZGANI Said" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Loading Product Tailwind | AngularForAll</title>
  <!-- Tailwind CSS via CDN -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Font Awesome Icons -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
  <style>
    * { font-family: 'Inter', sans-serif; }

    /* Animation squelette */
    @keyframes skeleton-loading {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }

    .skeleton {
      background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
      background-size: 200% 100%;
      animation: skeleton-loading 1.5s ease-in-out infinite;
    }

    /* Animation spin */
    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    .animate-spin-custom {
      animation: spin 0.8s linear infinite;
    }

    /* Animation pulse */
    @keyframes pulse-custom {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.5; }
    }

    .animate-pulse-custom {
      animation: pulse-custom 1.5s ease-in-out infinite;
    }

    /* Animation fade-in */
    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(10px); }
      to { opacity: 1; transform: translateY(0); }
    }

    .fade-in {
      animation: fadeIn 0.4s ease-out forwards;
    }

    /* Animation slide */
    @keyframes slideIn {
      from { opacity: 0; transform: translateX(-20px); }
      to { opacity: 1; transform: translateX(0); }
    }

    .slide-in {
      animation: slideIn 0.3s ease-out forwards;
    }

    /* Loader progress bar animation */
    @keyframes progressFill {
      0% { width: 0%; }
      30% { width: 35%; }
      60% { width: 70%; }
      100% { width: 95%; }
    }

    .progress-animate {
      animation: progressFill 2.5s ease-in-out infinite;
    }

    /* Shimmer effect */
    .shimmer {
      position: relative;
      overflow: hidden;
    }

    .shimmer::after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
      transform: translateX(-100%);
      animation: shimmer 2s infinite;
    }

    @keyframes shimmer {
      100% { transform: translateX(100%); }
    }

    /* Custom scrollbar */
    ::-webkit-scrollbar {
      width: 6px;
      height: 6px;
    }

    ::-webkit-scrollbar-track {
      background: #f1f5f9;
      border-radius: 10px;
    }

    ::-webkit-scrollbar-thumb {
      background: #cbd5e1;
      border-radius: 10px;
    }

    ::-webkit-scrollbar-thumb:hover {
      background: #94a3b8;
    }
  </style>
</head>
<body class="bg-slate-50 min-h-screen">

<!-- ==================== LOADER OVERLAY ==================== -->
<div id="loaderOverlay" class="fixed inset-0 bg-white/90 backdrop-blur-sm z-[9999] flex items-center justify-center transition-opacity duration-300">
  <div class="text-center max-w-sm px-6">
    <!-- Spinner animé -->
    <div class="relative w-20 h-20 mx-auto mb-6">
      <div class="absolute inset-0 rounded-full border-4 border-slate-200"></div>
      <div class="absolute inset-0 rounded-full border-4 border-transparent border-t-blue-500 border-r-blue-400 animate-spin-custom"></div>
      <div class="absolute inset-2 rounded-full border-4 border-transparent border-b-indigo-400 border-l-indigo-300 animate-spin-custom" style="animation-direction: reverse; animation-duration: 1.2s;"></div>
    </div>

    <h3 class="text-xl font-bold text-slate-800 mb-2">Chargement des produits</h3>
    <p class="text-slate-500 text-sm mb-4">Préparation de votre catalogue...</p>

    <!-- Barre de progression animée -->
    <div class="w-64 h-1.5 bg-slate-200 rounded-full overflow-hidden mx-auto">
      <div class="h-full bg-gradient-to-r from-blue-500 to-indigo-500 rounded-full progress-animate"></div>
    </div>

    <!-- Étapes de chargement -->
    <div class="flex justify-between mt-6 text-xs text-slate-400">
      <span class="flex items-center gap-1"><i class="fas fa-database"></i> Fetch</span>
      <span class="flex items-center gap-1"><i class="fas fa-image"></i> Images</span>
      <span class="flex items-center gap-1"><i class="fas fa-tags"></i> Prix</span>
      <span class="flex items-center gap-1"><i class="fas fa-check-circle"></i> Prêt</span>
    </div>
  </div>
</div>

<!-- ==================== NAVBAR ==================== -->
<nav class="bg-white border-b border-slate-200 sticky top-0 z-40">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div class="flex justify-between items-center h-16">
      <!-- Logo -->
      <div class="flex items-center gap-2">
        <i class="fas fa-bag-shopping text-2xl text-blue-500"></i>
        <span class="text-xl font-bold text-slate-800">Shop<span class="text-blue-500">Now</span></span>
      </div>

      <!-- Navigation -->
      <div class="hidden md:flex items-center gap-8">
        <a href="#" class="text-slate-600 hover:text-blue-500 font-medium transition">Accueil</a>
        <a href="#" class="text-slate-600 hover:text-blue-500 font-medium transition">Boutique</a>
        <a href="#" class="text-slate-600 hover:text-blue-500 font-medium transition">Nouveautés</a>
        <a href="#" class="text-slate-600 hover:text-blue-500 font-medium transition">Promos</a>
      </div>

      <!-- Actions -->
      <div class="flex items-center gap-4">
        <button class="relative p-2 text-slate-600 hover:text-blue-500 transition">
          <i class="fas fa-search"></i>
        </button>
        <button class="relative p-2 text-slate-600 hover:text-blue-500 transition">
          <i class="far fa-heart"></i>
        </button>
        <button class="relative p-2 text-slate-600 hover:text-blue-500 transition">
          <i class="fas fa-shopping-cart"></i>
          <span class="absolute -top-1 -right-1 w-5 h-5 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center">2</span>
        </button>
      </div>
    </div>
  </div>
</nav>

<!-- ==================== HEADER PAGE ==================== -->
<div class="bg-white border-b border-slate-200">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
    <h1 class="text-2xl md:text-3xl font-bold text-slate-800">Tous les produits</h1>
    <div class="flex items-center gap-2 text-sm text-slate-500 mt-1">
      <a href="#" class="hover:text-blue-500 transition">Accueil</a>
      <i class="fas fa-chevron-right text-xs"></i>
      <a href="#" class="hover:text-blue-500 transition">Boutique</a>
      <i class="fas fa-chevron-right text-xs"></i>
      <span class="text-slate-700">Produits</span>
    </div>
  </div>
</div>

<!-- ==================== CONTENU PRINCIPAL ==================== -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
  <div class="flex flex-col lg:flex-row gap-8">

    <!-- ========== SIDEBAR FILTRES ========== -->
    <div class="lg:w-1/4">

      <!-- Filtres Skeleton (affiché pendant chargement) -->
      <div id="filtersSkeleton" class="space-y-5">
        <!-- Catégories Skeleton -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <div class="skeleton h-5 w-24 rounded-lg mb-4"></div>
          <div class="space-y-3">
            <div class="skeleton h-10 w-full rounded-lg"></div>
            <div class="skeleton h-10 w-full rounded-lg"></div>
            <div class="skeleton h-10 w-full rounded-lg"></div>
            <div class="skeleton h-10 w-full rounded-lg"></div>
          </div>
        </div>

        <!-- Marques Skeleton -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <div class="skeleton h-5 w-20 rounded-lg mb-4"></div>
          <div class="space-y-3">
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 flex-1 rounded"></div>
            </div>
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 flex-1 rounded"></div>
            </div>
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 flex-1 rounded"></div>
            </div>
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 flex-1 rounded"></div>
            </div>
          </div>
        </div>

        <!-- Prix Skeleton -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <div class="skeleton h-5 w-16 rounded-lg mb-4"></div>
          <div class="skeleton h-2 w-full rounded-full mb-3"></div>
          <div class="flex justify-between">
            <div class="skeleton h-3 w-10 rounded"></div>
            <div class="skeleton h-3 w-12 rounded"></div>
          </div>
        </div>

        <!-- Note Skeleton -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <div class="skeleton h-5 w-24 rounded-lg mb-4"></div>
          <div class="space-y-3">
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 w-20 rounded"></div>
              <div class="skeleton h-4 w-8 rounded ml-auto"></div>
            </div>
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 w-20 rounded"></div>
              <div class="skeleton h-4 w-8 rounded ml-auto"></div>
            </div>
            <div class="flex items-center gap-2">
              <div class="skeleton w-5 h-5 rounded"></div>
              <div class="skeleton h-4 w-20 rounded"></div>
              <div class="skeleton h-4 w-8 rounded ml-auto"></div>
            </div>
          </div>
        </div>
      </div>

      <!-- Filtres Réels (cachés initialement) -->
      <div id="filtersReal" class="hidden space-y-5 slide-in">
        <!-- Catégories -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <h3 class="font-bold text-slate-800 mb-4">Catégories</h3>
          <div class="space-y-2">
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500" checked>
              <span class="text-slate-700 group-hover:text-blue-500 transition">Électronique</span>
              <span class="ml-auto text-sm text-slate-400">(24)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Mode</span>
              <span class="ml-auto text-sm text-slate-400">(18)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Maison</span>
              <span class="ml-auto text-sm text-slate-400">(15)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Sports</span>
              <span class="ml-auto text-sm text-slate-400">(12)</span>
            </label>
          </div>
        </div>

        <!-- Marques -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <h3 class="font-bold text-slate-800 mb-4">Marques</h3>
          <div class="space-y-2">
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Apple</span>
              <span class="ml-auto text-sm text-slate-400">(8)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Samsung</span>
              <span class="ml-auto text-sm text-slate-400">(12)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Nike</span>
              <span class="ml-auto text-sm text-slate-400">(6)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer group">
              <input type="checkbox" class="w-5 h-5 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
              <span class="text-slate-700 group-hover:text-blue-500 transition">Adidas</span>
              <span class="ml-auto text-sm text-slate-400">(5)</span>
            </label>
          </div>
        </div>

        <!-- Prix -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <h3 class="font-bold text-slate-800 mb-4">Prix</h3>
          <input type="range" class="w-full accent-blue-500" min="0" max="1000" value="500">
          <div class="flex justify-between mt-2">
            <span class="text-sm text-slate-500">0€</span>
            <span class="text-sm text-slate-500">1000€</span>
          </div>
        </div>

        <!-- Note -->
        <div class="bg-white rounded-2xl p-5 border border-slate-200 shadow-sm">
          <h3 class="font-bold text-slate-800 mb-4">Note minimum</h3>
          <div class="space-y-2">
            <label class="flex items-center gap-3 cursor-pointer">
              <input type="radio" name="rating" class="w-5 h-5 text-blue-500 focus:ring-blue-500">
              <span class="text-yellow-400">★★★★★</span>
              <span class="ml-auto text-sm text-slate-400">(156)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer">
              <input type="radio" name="rating" class="w-5 h-5 text-blue-500 focus:ring-blue-500">
              <span class="text-yellow-400">★★★★</span><span class="text-slate-300">★</span>
              <span class="ml-auto text-sm text-slate-400">(89)</span>
            </label>
            <label class="flex items-center gap-3 cursor-pointer">
              <input type="radio" name="rating" class="w-5 h-5 text-blue-500 focus:ring-blue-500" checked>
              <span class="text-yellow-400">★★★</span><span class="text-slate-300">★★</span>
              <span class="ml-auto text-sm text-slate-400">(234)</span>
            </label>
          </div>
        </div>
      </div>
    </div>

    <!-- ========== ZONE PRODUITS ========== -->
    <div class="lg:w-3/4">

      <!-- Barre de tri et résultats -->
      <div class="flex flex-wrap items-center justify-between gap-4 mb-6">
        <div id="resultCount">
          <div class="skeleton h-5 w-32 rounded-lg"></div>
        </div>
        <div id="sortSelect">
          <div class="skeleton h-10 w-44 rounded-lg"></div>
        </div>
      </div>

      <!-- Grille de produits Skeleton -->
      <div id="productsSkeleton" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
        <!-- 9 cartes skeleton -->
        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden sm:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden sm:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden sm:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden lg:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden lg:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>

        <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hidden lg:block">
          <div class="skeleton h-44 w-full rounded-xl mb-4 shimmer"></div>
          <div class="skeleton h-4 w-20 rounded mb-2"></div>
          <div class="skeleton h-5 w-full rounded mb-1"></div>
          <div class="skeleton h-4 w-3/4 rounded mb-3"></div>
          <div class="flex gap-2 mb-3">
            <div class="skeleton h-6 w-16 rounded"></div>
            <div class="skeleton h-6 w-12 rounded"></div>
          </div>
          <div class="skeleton h-10 w-full rounded-lg"></div>
        </div>
      </div>

      <!-- Grille de produits Réels (cachée initialement) -->
      <div id="productsReal" class="hidden grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5"></div>

      <!-- Pagination Skeleton -->
      <div id="paginationSkeleton" class="flex justify-center gap-2 mt-8">
        <div class="skeleton w-10 h-10 rounded-lg"></div>
        <div class="skeleton w-10 h-10 rounded-lg"></div>
        <div class="skeleton w-10 h-10 rounded-lg bg-blue-100"></div>
        <div class="skeleton w-10 h-10 rounded-lg"></div>
        <div class="skeleton w-10 h-10 rounded-lg"></div>
      </div>

      <!-- Pagination Réelle (cachée initialement) -->
      <div id="paginationReal" class="hidden">
        <nav class="flex justify-center mt-8">
          <ul class="flex gap-2">
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg border border-slate-200 text-slate-400 hover:bg-slate-50 transition"><i class="fas fa-chevron-left"></i></a></li>
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg bg-blue-500 text-white font-medium">1</a></li>
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50 transition">2</a></li>
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50 transition">3</a></li>
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50 transition">4</a></li>
            <li><a href="#" class="w-10 h-10 flex items-center justify-center rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50 transition"><i class="fas fa-chevron-right"></i></a></li>
          </ul>
        </nav>
      </div>
    </div>
  </div>
</div>

<!-- ==================== BOUTONS DÉMO ==================== -->
<div class="fixed bottom-5 right-5 z-50 flex gap-3">
  <button id="showLoadingBtn" class="bg-white border border-slate-200 rounded-xl px-5 py-3 font-semibold text-slate-700 shadow-lg hover:shadow-xl hover:bg-slate-50 transition-all flex items-center gap-2">
    <i class="fas fa-spinner"></i> Simuler chargement
  </button>
  <button id="showLoadedBtn" class="bg-blue-500 rounded-xl px-5 py-3 font-semibold text-white shadow-lg hover:shadow-xl hover:bg-blue-600 transition-all flex items-center gap-2">
    <i class="fas fa-check-circle"></i> Afficher produits
  </button>
</div>

<script>
  (function() {
    'use strict';

    // Éléments DOM
    const loaderOverlay = document.getElementById('loaderOverlay');
    const filtersSkeleton = document.getElementById('filtersSkeleton');
    const filtersReal = document.getElementById('filtersReal');
    const productsSkeleton = document.getElementById('productsSkeleton');
    const productsReal = document.getElementById('productsReal');
    const paginationSkeleton = document.getElementById('paginationSkeleton');
    const paginationReal = document.getElementById('paginationReal');
    const resultCount = document.getElementById('resultCount');
    const sortSelect = document.getElementById('sortSelect');

    // Données produits
    const products = [
      { id: 1, name: 'Écouteurs Sans Fil Pro', category: 'Électronique', price: 89.99, oldPrice: 129.99, rating: 4.8, reviews: 234, badge: 'sale', icon: 'fa-headphones' },
      { id: 2, name: 'Montre Connectée Sport', category: 'Électronique', price: 199.99, oldPrice: null, rating: 4.9, reviews: 156, badge: 'new', icon: 'fa-clock' },
      { id: 3, name: 'Sac à Dos Urbain', category: 'Mode', price: 59.99, oldPrice: 79.99, rating: 4.7, reviews: 89, badge: 'sale', icon: 'fa-bag-shopping' },
      { id: 4, name: 'Enceinte Bluetooth Portable', category: 'Électronique', price: 49.99, oldPrice: null, rating: 4.6, reviews: 312, badge: null, icon: 'fa-speaker' },
      { id: 5, name: 'Baskets Running Air', category: 'Sports', price: 129.99, oldPrice: 159.99, rating: 4.8, reviews: 178, badge: 'sale', icon: 'fa-shoe-prints' },
      { id: 6, name: 'Lampe de Bureau LED', category: 'Maison', price: 34.99, oldPrice: null, rating: 4.5, reviews: 67, badge: null, icon: 'fa-lightbulb' },
      { id: 7, name: 'Gourde Isotherme', category: 'Sports', price: 24.99, oldPrice: 34.99, rating: 4.7, reviews: 145, badge: 'sale', icon: 'fa-flask' },
      { id: 8, name: 'Chargeur Rapide USB-C', category: 'Électronique', price: 29.99, oldPrice: null, rating: 4.8, reviews: 423, badge: null, icon: 'fa-bolt' },
      { id: 9, name: 'T-shirt Premium Coton', category: 'Mode', price: 29.99, oldPrice: 39.99, rating: 4.4, reviews: 98, badge: 'sale', icon: 'fa-shirt' }
    ];

    // Générer étoiles
    function getStars(rating) {
      const full = Math.floor(rating);
      const half = rating % 1 >= 0.5;
      let stars = '';
      for (let i = 0; i < full; i++) stars += '★';
      if (half) stars += '½';
      while (stars.length < 5) stars += '☆';
      return stars;
    }

    // Afficher produits
    function renderProducts() {
      let html = '';
      products.forEach(p => {
        const badge = p.badge === 'sale' ? '<span class="absolute top-3 left-3 bg-red-500 text-white text-xs font-bold px-2 py-1 rounded-full">-30%</span>' :
                     p.badge === 'new' ? '<span class="absolute top-3 left-3 bg-green-500 text-white text-xs font-bold px-2 py-1 rounded-full">Nouveau</span>' : '';

        html += `
          <div class="bg-white rounded-xl p-4 border border-slate-200 shadow-sm hover:shadow-lg hover:-translate-y-1 transition-all duration-300 fade-in relative overflow-hidden">
            ${badge}
            <div class="h-44 bg-gradient-to-br from-slate-100 to-slate-50 rounded-xl mb-4 flex items-center justify-center">
              <i class="fas ${p.icon} text-5xl text-blue-400"></i>
            </div>
            <span class="text-xs uppercase tracking-wider text-slate-400">${p.category}</span>
            <h3 class="font-bold text-slate-800 mt-1 line-clamp-2">${p.name}</h3>
            <div class="flex items-center gap-2 mt-1">
              <span class="text-yellow-400 text-sm">${getStars(p.rating)}</span>
              <span class="text-xs text-slate-400">(${p.reviews})</span>
            </div>
            <div class="flex items-center gap-2 mt-2">
              <span class="text-xl font-bold text-slate-800">${p.price.toFixed(2)}€</span>
              ${p.oldPrice ? `<span class="text-sm text-slate-400 line-through">${p.oldPrice.toFixed(2)}€</span>` : ''}
            </div>
            <button class="w-full mt-4 bg-slate-800 hover:bg-blue-500 text-white font-semibold py-2.5 rounded-lg transition-all duration-200 flex items-center justify-center gap-2">
              <i class="fas fa-cart-plus"></i> Ajouter
            </button>
          </div>
        `;
      });
      productsReal.innerHTML = html;
    }

    // Afficher compteur
    function renderResultCount() {
      resultCount.innerHTML = `<span class="text-slate-500"><i class="fas fa-grid-2 mr-2"></i>${products.length} produits trouvés</span>`;
    }

    // Afficher select tri
    function renderSortSelect() {
      sortSelect.innerHTML = `
        <select class="bg-white border border-slate-200 rounded-lg px-4 py-2.5 text-slate-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
          <option selected>Trier par : Popularité</option>
          <option>Prix : croissant</option>
          <option>Prix : décroissant</option>
          <option>Nouveautés</option>
          <option>Meilleures ventes</option>
        </select>
      `;
    }

    // Mode loading
    function showLoading() {
      loaderOverlay.style.display = 'flex';
      filtersSkeleton.style.display = 'block';
      filtersReal.style.display = 'none';
      productsSkeleton.style.display = 'grid';
      productsReal.style.display = 'none';
      paginationSkeleton.style.display = 'flex';
      paginationReal.style.display = 'none';

      resultCount.innerHTML = '<div class="skeleton h-5 w-32 rounded-lg"></div>';
      sortSelect.innerHTML = '<div class="skeleton h-10 w-44 rounded-lg"></div>';
    }

    // Mode loaded
    function showLoaded() {
      loaderOverlay.style.display = 'none';
      filtersSkeleton.style.display = 'none';
      filtersReal.style.display = 'block';
      productsSkeleton.style.display = 'none';
      productsReal.style.display = 'grid';
      paginationSkeleton.style.display = 'none';
      paginationReal.style.display = 'block';

      renderProducts();
      renderResultCount();
      renderSortSelect();
    }

    // Boutons
    document.getElementById('showLoadingBtn').addEventListener('click', showLoading);
    document.getElementById('showLoadedBtn').addEventListener('click', showLoaded);

    // Auto-load après 2.5s
    window.addEventListener('load', () => {
      setTimeout(showLoaded, 2500);
    });

    // Init
    showLoading();
  })();
</script>

</body>
</html>