<!doctype html>
<html lang="id">
  <head>
    <meta charset="UTF-8" />
    
    <!-- Favicons -->
    <link rel="icon" type="image/x-icon" href="/favicon_best_ksjshoptek.ico" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon_best_ksjshoptek_32x32.png" />
    
    <!-- Essential Meta Tags -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="KSJSHOPTEK - Grosir Perkakas dan Hardware Toko Bangunan. Supplier perkakas lengkap: gembok, kunci pintu, kran sanitary, kawat, obeng, tang, dan perkakas lainnya." />
    <meta name="keywords" content="grosir perkakas, ksjshopbangunan, ksjshopmlg, KSJSHOPTEK, ksjshoptek, ksjshop, grosirkuncipintu, grosirperkakas, krantermurah, kuncipintu termurah, grosir proyek, kulakkan toko bangunan, supplier toko bangunan, hardware toko bangunan, gembok murah, kunci pintu, kran sanitary, kawat, obeng, tang, perkakas rumah tangga, aksesoris kamar mandi, handel pintu, engsel, baut sekrup, alat pertukangan, supplier hardware, isco, toho, maxtech, bosch, powertools, sanitary, ysk, vpr, viper, aigo, erdos, igm, amico, alinco, gembok isco, kunci toho, kran ysk, obeng bosch, tang maxtech" />
    <meta name="author" content="KSJSHOPTEK" />
    <meta name="theme-color" content="#3b82f6" />
    
    <!-- Open Graph Meta Tags -->
    <meta property="og:title" content="KSJSHOPTEK - Grosir Perkakas & Hardware Toko Bangunan" />
    <meta property="og:description" content="Supplier perkakas lengkap untuk toko bangunan. Grosir gembok, kunci pintu, kran sanitary, kawat, obeng, tang brand ISCO, TOHO, MAXTECH, BOSCH, YSK, VPR dan lainnya dengan harga terbaik." />
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://ksjshopbangunan.com/" />
    <meta property="og:image" content="https://ksjshopbangunan.com/logo/ksjshop-logo.png" />
    <meta property="og:site_name" content="KSJSHOPTEK" />
    
    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="KSJSHOPTEK - Grosir Perkakas & Hardware Toko Bangunan" />
    <meta name="twitter:description" content="Supplier perkakas lengkap untuk toko bangunan. Grosir gembok, kunci pintu, kran sanitary brand ISCO, TOHO, MAXTECH, BOSCH, YSK, VPR dan lainnya." />
    
    <!-- Performance: Critical Resource Hints -->
    <link rel="dns-prefetch" href="//gvqzlfkdofvlfimzouov.supabase.co" />
    <link rel="dns-prefetch" href="//fonts.googleapis.com" />
    <link rel="dns-prefetch" href="//fonts.gstatic.com" />
    <link rel="dns-prefetch" href="//maps.googleapis.com" />
    <link rel="dns-prefetch" href="//www.google.com" />
    
    <!-- Preconnect to critical origins -->
    <link rel="preconnect" href="https://gvqzlfkdofvlfimzouov.supabase.co" crossorigin />
    <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    
    <!-- Prefetch critical API endpoints - Backend URL tetap tidak diubah -->
    <link rel="dns-prefetch" href="//kasirkirania-production.up.railway.app" />
    <link rel="preconnect" href="https://kasirkirania-production.up.railway.app" crossorigin />
    
    <!-- ✅ CRITICAL: Inline critical CSS for above-the-fold content -->
    <style>
      /* Font face declaration for immediate use */
      @font-face {
        font-family: 'Inter';
        font-style: normal;
        font-weight: 400;
        font-display: swap;
        src: url('https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2') format('woff2');
        unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
      }
      
      /* Critical loading styles */
      #root {
        min-height: 100vh;
      }
      
      .loading-spinner {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 100vh;
        background-color: #f8fafc;
      }
      
      .spinner {
        animation: spin 1s linear infinite;
        border: 3px solid #e2e8f0;
        border-top: 3px solid #3b82f6;
        border-radius: 50%;
        width: 40px;
        height: 40px;
      }
      
      @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
      
      /* Critical above-the-fold styles */
      body {
        margin: 0;
        padding: 0;
        font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
          'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
          sans-serif;
        font-feature-settings: 'cv11', 'ss01';
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        background-color: #f9fafb;
        color: #1f2937;
        line-height: 1.6;
      }
      
      /* Loading animation */
      .animate-pulse {
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      @keyframes pulse {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.5; }
      }
      
      /* Critical utility classes */
      .bg-gray-50 { background-color: #f9fafb; }
      .bg-gray-100 { background-color: #f3f4f6; }
      .bg-gray-200 { background-color: #e5e7eb; }
      .bg-white { background-color: #ffffff; }
      .rounded-2xl { border-radius: 1rem; }
      .shadow-lg { 
        box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); 
      }
      
      /* Critical carousel styles */
      .carousel-container {
        position: relative;
        width: 100%;
        max-width: 1200px;
        margin: 0 auto;
        background: #f3f4f6;
        border-radius: 1rem;
        overflow: hidden;
      }
      
      .carousel-image {
        width: 100%;
        height: 400px;
        -o-object-fit: cover;
           object-fit: cover;
        display: block;
      }
      
      @media (max-width: 640px) {
        .carousel-image {
          height: 200px;
        }
      }
      
      /* Critical category grid styles */
      .category-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
        gap: 0.75rem;
        padding: 1rem;
        background: white;
        border-radius: 1rem;
        box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
      }
      
      @media (min-width: 640px) {
        .category-grid {
          grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
          gap: 1rem;
          padding: 1.5rem;
        }
      }
      
      .category-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 0.75rem;
        background: #f9fafb;
        border: 1px solid #e5e7eb;
        border-radius: 0.75rem;
        transition: all 0.2s ease;
        text-decoration: none;
        color: inherit;
        min-height: 100px;
      }
      
      .category-item:hover {
        background: white;
        border-color: #3b82f6;
        transform: translateY(-2px);
        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
      }
      
      .category-icon {
        width: 48px;
        height: 48px;
        border-radius: 50%;
        background: white;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 0.5rem;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }
      
      .category-name {
        font-size: 0.75rem;
        font-weight: 600;
        text-align: center;
        color: #1f2937;
        line-height: 1.2;
      }
      
      @media (min-width: 640px) {
        .category-icon {
          width: 56px;
          height: 56px;
        }
        .category-name {
          font-size: 0.875rem;
        }
      }
      
      /* Critical product card styles */
      .product-card {
        background: white;
        border-radius: 1rem;
        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        overflow: hidden;
        transition: all 0.3s ease;
        border: 1px solid #e5e7eb;
      }
      
      .product-card:hover {
        transform: translateY(-4px);
        box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
      }
      
      .product-image {
        width: 100%;
        height: 200px;
        -o-object-fit: cover;
           object-fit: cover;
        background: #f3f4f6;
        display: block;
      }
      
      .product-info {
        padding: 1rem;
      }
      
      .product-price {
        font-size: 1.25rem;
        font-weight: 600;
        color: #3b82f6;
        margin-bottom: 0.5rem;
      }
      
      .product-title {
        font-size: 0.875rem;
        font-weight: 500;
        color: #1f2937;
        line-height: 1.4;
        margin-bottom: 0.5rem;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
      }
      
      /* Critical button styles */
      .btn-primary {
        background: #3b82f6;
        color: white;
        padding: 0.75rem 1rem;
        border: none;
        border-radius: 0.5rem;
        cursor: pointer;
        font-weight: 500;
        transition: all 0.2s ease;
        width: 100%;
        font-size: 0.875rem;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.5rem;
      }
      
      .btn-primary:hover {
        background: #2563eb;
        transform: translateY(-1px);
      }
      
      .btn-secondary {
        background: #fbbf24;
        color: #1f2937;
        padding: 0.75rem 1rem;
        border: none;
        border-radius: 0.5rem;
        cursor: pointer;
        font-weight: 500;
        transition: all 0.2s ease;
        width: 100%;
        font-size: 0.875rem;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.5rem;
      }
      
      .btn-secondary:hover {
        background: #f59e0b;
        transform: translateY(-1px);
      }
      
      /* Critical layout styles */
      .container {
        max-width: 1200px;
        margin: 0 auto;
        padding: 0 1rem;
      }
      
      @media (min-width: 640px) {
        .container {
          padding: 0 1.5rem;
        }
      }
      
      @media (min-width: 1024px) {
        .container {
          padding: 0 2rem;
        }
      }
      
      .grid {
        display: grid;
        gap: 1rem;
      }
      
      .grid-2 {
        grid-template-columns: repeat(2, 1fr);
      }
      
      .grid-3 {
        grid-template-columns: repeat(3, 1fr);
      }
      
      .grid-4 {
        grid-template-columns: repeat(4, 1fr);
      }
      
      .grid-5 {
        grid-template-columns: repeat(5, 1fr);
      }
      
      @media (max-width: 640px) {
        .grid-3 {
          grid-template-columns: repeat(2, 1fr);
        }
        .grid-4 {
          grid-template-columns: repeat(2, 1fr);
        }
        .grid-5 {
          grid-template-columns: repeat(2, 1fr);
        }
      }
      
      /* Critical skeleton loading styles */
      .skeleton-carousel {
        width: 100%;
        height: 400px;
        background: #e5e7eb;
        border-radius: 1rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      @media (max-width: 640px) {
        .skeleton-carousel {
          height: 200px;
        }
      }
      
      .skeleton-category {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 0.75rem;
        background: #f3f4f6;
        border-radius: 0.75rem;
        min-height: 100px;
      }
      
      .skeleton-category-icon {
        width: 48px;
        height: 48px;
        border-radius: 50%;
        background: #e5e7eb;
        margin-bottom: 0.5rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      .skeleton-category-name {
        width: 60px;
        height: 12px;
        background: #e5e7eb;
        border-radius: 0.25rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      .skeleton-product {
        background: white;
        border-radius: 1rem;
        overflow: hidden;
        border: 1px solid #e5e7eb;
      }
      
      .skeleton-product-image {
        width: 100%;
        height: 200px;
        background: #e5e7eb;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      .skeleton-product-info {
        padding: 1rem;
      }
      
      .skeleton-product-title {
        width: 100%;
        height: 16px;
        background: #e5e7eb;
        border-radius: 0.25rem;
        margin-bottom: 0.5rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      .skeleton-product-price {
        width: 80px;
        height: 20px;
        background: #e5e7eb;
        border-radius: 0.25rem;
        margin-bottom: 0.5rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      .skeleton-product-button {
        width: 100%;
        height: 44px;
        background: #e5e7eb;
        border-radius: 0.5rem;
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      
      /* Hide elements until fully loaded */
      .lazy-content {
        opacity: 0;
        transition: opacity 0.3s ease;
      }
      
      .lazy-content.loaded {
        opacity: 1;
      }
      
      /* Critical header styles */
      .header {
        background: #fff;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        position: sticky;
        top: 0;
        z-index: 1000;
        border-bottom: 1px solid #e5e7eb;
      }
      
      .nav-container {
        max-width: 1200px;
        margin: 0 auto;
        padding: 0 1rem;
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 64px;
      }
      
      .logo {
        font-size: 1.5rem;
        font-weight: 700;
        color: #3b82f6;
      }
      
      /* Critical responsive utilities */
      .aspect-square {
        aspect-ratio: 1 / 1;
      }
      
      .aspect-video {
        aspect-ratio: 16 / 9;
      }
      
      .object-cover {
        -o-object-fit: cover;
           object-fit: cover;
      }
      
      .object-center {
        -o-object-position: center;
           object-position: center;
      }
      
      /* Critical text utilities */
      .text-center { text-align: center; }
      .text-sm { font-size: 0.875rem; }
      .text-base { font-size: 1rem; }
      .text-lg { font-size: 1.125rem; }
      .text-xl { font-size: 1.25rem; }
      .text-2xl { font-size: 1.5rem; }
      .font-medium { font-weight: 500; }
      .font-semibold { font-weight: 600; }
      .font-bold { font-weight: 700; }
      
      /* Critical spacing utilities */
      .p-4 { padding: 1rem; }
      .p-6 { padding: 1.5rem; }
      .px-4 { padding-left: 1rem; padding-right: 1rem; }
      .py-4 { padding-top: 1rem; padding-bottom: 1rem; }
      .m-4 { margin: 1rem; }
      .mb-4 { margin-bottom: 1rem; }
      .mb-6 { margin-bottom: 1.5rem; }
      .mb-8 { margin-bottom: 2rem; }
      
      /* Critical color utilities */
      .text-gray-600 { color: #6b7280; }
      .text-gray-900 { color: #1f2937; }
      .text-blue-600 { color: #2563eb; }
      
      /* Critical responsive visibility */
      @media (max-width: 640px) {
        .hidden-mobile { display: none; }
      }
      
      @media (min-width: 641px) {
        .hidden-desktop { display: none; }
      }
      
      /* Critical layout utilities */
      .flex { display: flex; }
      .grid { display: grid; }
      .block { display: block; }
      .inline-block { display: inline-block; }
      .hidden { display: none; }
      
      /* Critical positioning */
      .relative { position: relative; }
      .absolute { position: absolute; }
      .fixed { position: fixed; }
      .sticky { position: sticky; }
      
      /* Critical sizing */
      .w-full { width: 100%; }
      .h-full { height: 100%; }
      .min-h-screen { min-height: 100vh; }
      .max-w-7xl { max-width: 80rem; }
      .mx-auto { margin-left: auto; margin-right: auto; }
      
      /* Critical background */
      .bg-white { background-color: #ffffff; }
      .bg-gray-50 { background-color: #f9fafb; }
      .bg-blue-600 { background-color: #2563eb; }
      
      /* Critical border */
      .border { border-width: 1px; }
      .rounded-lg { border-radius: 0.5rem; }
      .rounded-xl { border-radius: 0.75rem; }
      
      /* Critical shadow */
      .shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); }
      
      /* Critical z-index */
      .z-10 { z-index: 10; }
      .z-50 { z-index: 50; }
    </style>
    
    <!-- Resource hints for critical resources -->
    <!-- Vite will auto-generate modulepreload links during build -->
    
    <!-- ✅ ULTRA-AGGRESSIVE: Inline critical CSS and defer non-critical with JavaScript -->
    <script>
      // Inline critical CSS loading with aggressive optimization
      (function() {
        var css = document.createElement('link');
        css.rel = 'stylesheet';
        css.href = '/assets/main.css';
        css.media = 'print';
        css.onload = function() {
          this.media = 'all';
        };
        document.head.appendChild(css);
        
        // Load Google Fonts with same technique
        var fonts = document.createElement('link');
        fonts.rel = 'stylesheet';
        fonts.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap';
        fonts.media = 'print';
        fonts.onload = function() {
          this.media = 'all';
        };
        document.head.appendChild(fonts);
      })();
    </script>
    
    <!-- Fallback for users with JavaScript disabled -->
    <noscript>
      <link rel="stylesheet" href="/assets/main.css">
      <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap">
    </noscript>
    

    
    <!-- ✅ PRECONNECT TO API DOMAIN -->
    <link rel="preconnect" href="https://api.ksjshopbangunan.com" />
    <link rel="dns-prefetch" href="https://api.ksjshopbangunan.com" />
    
    <!-- ✅ PRECONNECT TO SUPABASE FOR IMAGES -->
    <link rel="preconnect" href="https://gvqzlfkdofvlfimzouov.supabase.co" />
    <link rel="dns-prefetch" href="https://gvqzlfkdofvlfimzouov.supabase.co" />
    
    <title>KSJSHOPTEK - Grosir Perkakas & Hardware Toko Bangunan | Supplier Perkakas</title>
    
    <!-- Schema.org structured data -->
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Store",
      "name": "KSJSHOPTEK",
      "alternateName": ["KSJSHOP", "KSJSHOPMLG", "KSJSHOPBANGUNAN", "GROSIRKUNCIPINTU", "GROSIRPERKAKAS", "KRANTERMURAH"],
      "description": "Grosir Perkakas dan Hardware Toko Bangunan. Supplier perkakas lengkap untuk kebutuhan toko bangunan dan rumah tangga.",
      "url": "https://ksjshopbangunan.com",
      "telephone": "+62857-5528-2807",
      "image": "https://ksjshopbangunan.com/logo/ksjshop-logo.png",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "Jl. Kapi Minda No.Raya 10a 20, Keduyo, Mangliawan",
        "addressLocality": "Kec. Pakis, Kabupaten Malang",
        "addressRegion": "Jawa Timur",
        "postalCode": "65154",
        "addressCountry": "ID"
      },
      "geo": {
        "@type": "GeoCoordinates",
        "latitude": "-7.9638",
        "longitude": "112.6638"
      },
      "openingHours": "Mo-Su 08:00-17:00",
      "priceRange": "$$",
      "paymentAccepted": ["Cash", "Credit Card", "Bank Transfer"],
      "currenciesAccepted": "IDR"
    }
    </script>
    <script type="module" crossorigin src="/assets/index-BTT0PVsq.js"></script>
    <link rel="modulepreload" crossorigin href="/js/react-core-C_YVPeIs.js">
    <link rel="modulepreload" crossorigin href="/js/vendor-BAuKwsxN.js">
    <link rel="stylesheet" crossorigin href="/css/index-BybA36ST.css">
  </head>
  <body>
    <!-- Initial loading state to prevent blank screen -->
    <div id="root">
      <div class="loading-spinner">
        <div class="spinner"></div>
      </div>
    </div>
    
    <!-- Main application script -->
    
    <!-- Performance monitoring and optimization -->
    <script>
      // Early optimization: Preload critical API endpoints
      if ('requestIdleCallback' in window) {
        requestIdleCallback(() => {
          // Preload critical API endpoints
          const apiBase = 'https://kasirkirania-production.up.railway.app';
          const criticalEndpoints = [
            '/web/main-banners',
            '/web/kategori-produk'
          ];
          
          criticalEndpoints.forEach(endpoint => {
            fetch(apiBase + endpoint, { 
              method: 'GET',
              priority: 'high'
            }).catch(() => {}); // Silent fail for preload
          });
        });
      }
      
      // Performance monitoring
      window.addEventListener('load', function() {
        if ('performance' in window && 'getEntriesByType' in performance) {
          const navigation = performance.getEntriesByType('navigation')[0];
          if (navigation) {
            console.log('Page Load Time:', navigation.loadEventEnd - navigation.loadEventStart, 'ms');
            
            // Send performance data to analytics (optional)
            if (navigation.loadEventEnd - navigation.loadEventStart > 5000) {
              console.warn('Slow page load detected:', navigation.loadEventEnd - navigation.loadEventStart, 'ms');
            }
          }
        }
      });
      
      // Lazy load images with intersection observer
      if ('IntersectionObserver' in window) {
        const imageObserver = new IntersectionObserver((entries, observer) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              const img = entry.target;
              img.src = img.dataset.src;
              img.classList.remove('lazy');
              observer.unobserve(img);
            }
          });
        });
        
        document.addEventListener('DOMContentLoaded', () => {
          const lazyImages = document.querySelectorAll('img[data-src]');
          lazyImages.forEach(img => imageObserver.observe(img));
        });
      }
      
      // Prefetch next page content on hover
      let prefetchTimeouts = new Map();
      document.addEventListener('mouseover', (e) => {
        if (e.target.tagName === 'A' && e.target.href && !e.target.href.includes('#')) {
          const href = e.target.href;
          const timeout = setTimeout(() => {
            const link = document.createElement('link');
            link.rel = 'prefetch';
            link.href = href;
            document.head.appendChild(link);
          }, 200); // 200ms delay to avoid prefetching on quick hovers
          
          prefetchTimeouts.set(href, timeout);
        }
      });
      
      document.addEventListener('mouseout', (e) => {
        if (e.target.tagName === 'A' && e.target.href) {
          const timeout = prefetchTimeouts.get(e.target.href);
          if (timeout) {
            clearTimeout(timeout);
            prefetchTimeouts.delete(e.target.href);
          }
        }
      });
    </script>
  </body>
</html>
