{"id":5586,"date":"2024-10-21T18:15:17","date_gmt":"2024-10-21T18:15:17","guid":{"rendered":"https:\/\/demosites.royal-elementor-addons.com\/landing-page-business-v2\/?page_id=7"},"modified":"2026-10-20T07:39:52","modified_gmt":"2026-10-20T07:39:52","slug":"home-landing-page-business-v2","status":"publish","type":"page","link":"https:\/\/builders24.net\/zw\/","title":{"rendered":"Home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"5586\" class=\"elementor elementor-5586\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a9184b9 e-con e-atomic-element e-flexbox-base e-default-div e-a9184b9-02bcd84 \" data-id=\"a9184b9\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"a9184b9\">\n    \t\t<div class=\"elementor-element elementor-element-8f004a9 elementor-widget elementor-widget-html\" data-id=\"8f004a9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en-ZW\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>Builders24 Zimbabwe | Building Materials, Equipment &amp; Machinery, Vehicles, Home Goods and Trade Services<\/title>\r\n<meta name=\"description\" content=\"Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe. Builders24 provides construction and trade services in Zimbabwe, supplies wholesale goods to Zimbabwean businesses, and offers import, export and cross-border logistics from Zimbabwe.\">\r\n<link rel=\"canonical\" href=\"https:\/\/app.builders24.net\/\">\r\n<link rel=\"manifest\" href=\"https:\/\/app.builders24.net\/manifest.json\">\r\n<meta name=\"theme-color\" content=\"#0D1B3E\">\r\n<link rel=\"stylesheet\" href=\"https:\/\/app.builders24.net\/b24app.css\">\r\n<meta name=\"robots\" content=\"index, follow\">\r\n<meta name=\"google-site-verification\" content=\"_1nm4oHbnqeUKbFf1nsJ4N6q_9SkLiT5qV1c3Ac1wOg\">\r\n\r\n<!-- Open Graph -->\r\n<meta property=\"og:type\" content=\"website\">\r\n<meta property=\"og:site_name\" content=\"Builders24\">\r\n<meta property=\"og:title\" content=\"Builders24 Zimbabwe | Building Materials, Equipment &amp; Machinery, Vehicles, Home Goods and Trade Services\">\r\n<meta property=\"og:description\" content=\"Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe. Builders24 provides construction and trade services in Zimbabwe, supplies wholesale goods to Zimbabwean businesses, and offers import, export and cross-border logistics from Zimbabwe.\">\r\n<meta property=\"og:url\" content=\"https:\/\/app.builders24.net\/\">\r\n<meta property=\"og:image\" content=\"https:\/\/app.builders24.net\/assets\/og-image.jpg\">\r\n<meta property=\"og:locale\" content=\"en_ZA\">\r\n\r\n<!-- Twitter Card -->\r\n<meta name=\"twitter:card\" content=\"summary_large_image\">\r\n<meta name=\"twitter:title\" content=\"Builders24 Zimbabwe | Building Materials, Equipment &amp; Machinery, Vehicles, Home Goods and Trade Services\">\r\n<meta name=\"twitter:description\" content=\"Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe. Builders24 provides construction and trade services in Zimbabwe, supplies wholesale goods to Zimbabwean businesses, and offers import, export and cross-border logistics from Zimbabwe.\">\r\n<meta name=\"twitter:image\" content=\"https:\/\/app.builders24.net\/assets\/og-image.jpg\">\r\n\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Archivo:wght@400;500;600;700;800&family=Archivo+Narrow:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600&display=swap\" rel=\"stylesheet\">\r\n<link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/@tabler\/icons-webfont@latest\/tabler-icons.min.css\">\r\n\r\n<script type=\"application\/ld+json\">\r\n{\r\n  \"@context\": \"https:\/\/schema.org\",\r\n  \"@type\": \"Organization\",\r\n  \"name\": \"Builders24\",\r\n  \"url\": \"https:\/\/app.builders24.net\/\",\r\n  \"description\": \"Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe and provides construction and trade services in Zimbabwe.\",\r\n  \"areaServed\": \"Zimbabwe\"\r\n}\r\n<\/script>\r\n\r\n<style>\r\n  :root{\r\n    --navy:#0D1B3E;\r\n    --navy-2:#132352;\r\n    --navy-3:#091430;\r\n    --orange:#F0A500;\r\n    --orange-2:#CC8C00;\r\n    --grey-bg:#EEF0F3;\r\n    --grey-text:#6B7280;\r\n    --grey-light:#9CA3AF;\r\n    --sage:#E6ECDF;\r\n    --border:#E7E9EC;\r\n    --white:#FFFFFF;\r\n    --text:#0D1220;\r\n    --pad:16px;\r\n  }\r\n  *{box-sizing:border-box; margin:0; padding:0;}\r\n  body{\r\n    font-family:'Archivo Narrow', sans-serif;\r\n    background:#F3F4F6;\r\n    color:var(--text);\r\n    -webkit-font-smoothing:antialiased;\r\n  }\r\n  .app{\r\n    max-width:430px;\r\n    margin:0 auto;\r\n    background:var(--white);\r\n    overflow:hidden;\r\n    min-height:100vh;\r\n  }\r\n  \/* Desktop: genuinely full-width, not a narrow card. The page\r\n     itself stretches edge to edge; content inside is capped at\r\n     a sensible reading\/shopping width and centered, same\r\n     pattern real e-commerce sites use - full-bleed background,\r\n     contained content. Components that would otherwise stretch\r\n     to awkward proportions (deal cards, category icons) get\r\n     fixed sizing instead of pure flex-stretch. *\/\r\n  @media(min-width:900px){\r\n    .app{ max-width:100%; min-height:100vh; }\r\n    .category-row, .deals-row, .trust-bar-inner{\r\n      max-width:1200px;\r\n      margin-left:auto;\r\n      margin-right:auto;\r\n    }\r\n    .category-row{ justify-content:center; gap:36px; }\r\n    .cat-item{ width:300px; }\r\n    .cat-icon-bg{ width:300px; height:300px; border-radius:36px; }\r\n    .cat-label{ font-size:16px; }\r\n    .deals-row{ display:grid; grid-template-columns:repeat(4, 1fr); gap:18px; }\r\n    .deal-card{ flex:none; }\r\n    .hero-banner{ min-height:460px; padding:36px 44px; }\r\n    .hero-content{ max-width:50%; }\r\n    .badge-pill{ font-size:12px; padding:7px 16px; }\r\n    .hero-title{ font-size:34px; }\r\n    .hero-sub{ font-size:14px; margin-top:6px; }\r\n    .btn-orange{ font-size:14px; padding:14px 22px; margin-top:16px; }\r\n    .hero-discount-box{ padding:16px 20px; }\r\n    .renovate-banner{ min-height:340px; }\r\n    .renovate-text{ padding:36px 0 36px 40px; }\r\n    .renovate-title{ font-size:28px; }\r\n    .renovate-sub{ font-size:14px; margin-top:12px; }\r\n    .btn-navy{ font-size:13px; padding:13px 20px; margin-top:18px; }\r\n  }\r\n  a{ text-decoration:none; color:inherit; }\r\n  button{ font-family:inherit; border:none; cursor:pointer; }\r\n\r\n  \/* ===== HEADER ===== *\/\r\n  .app-header{\r\n    background:none;\r\n    margin:0;\r\n  }\r\n  .header-top{\r\n    display:flex;\r\n    align-items:flex-start;\r\n    justify-content:space-between;\r\n    margin-bottom:18px;\r\n  }\r\n  .logo-text{\r\n    font-weight:900;\r\n    font-size:20px;\r\n    letter-spacing:0.5px;\r\n    color:var(--navy);\r\n    line-height:1;\r\n  }\r\n  .logo-text .orange{ color:var(--orange); }\r\n  .logo-text sup{ font-size:9px; margin-left:1px; }\r\n  .logo-tagline{\r\n    font-size:8.5px;\r\n    font-weight:700;\r\n    letter-spacing:1.6px;\r\n    color:var(--grey-text);\r\n    margin-top:5px;\r\n  }\r\n  .header-right{\r\n    display:flex;\r\n    align-items:flex-start;\r\n    gap:14px;\r\n  }\r\n  .deliver{\r\n    display:flex;\r\n    align-items:flex-start;\r\n    gap:6px;\r\n    background:none;\r\n    border:none;\r\n    padding:0;\r\n    text-align:left;\r\n    font:inherit;\r\n    color:inherit;\r\n    cursor:pointer;\r\n  }\r\n  .deliver svg{ margin-top:2px; flex-shrink:0; }\r\n  .deliver-label{\r\n    display:block;\r\n    font-size:10.5px;\r\n    color:#AEB8CC;\r\n    font-weight:500;\r\n    margin-bottom:2px;\r\n  }\r\n  .deliver-city{\r\n    display:flex;\r\n    align-items:center;\r\n    gap:3px;\r\n    font-size:13px;\r\n    font-weight:700;\r\n    color:var(--white);\r\n    white-space:nowrap;\r\n  }\r\n  .bell-wrap{ position:relative; margin-top:2px; }\r\n  .badge{\r\n    position:absolute;\r\n    top:-7px;\r\n    right:-7px;\r\n    background:var(--orange);\r\n    color:var(--white);\r\n    font-size:9.5px;\r\n    font-weight:800;\r\n    width:16px;\r\n    height:16px;\r\n    border-radius:50%;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    border:1.5px solid var(--navy);\r\n  }\r\n  .deliver-row{ padding-bottom:12px; }\r\n  .deliver-row .deliver{ gap:7px; }\r\n  .deliver-row .deliver-city{ font-size:13.5px; }\r\n  .currency-badge{\r\n    display:flex; align-items:center; gap:2px;\r\n    background:var(--navy); border:none; border-radius:8px;\r\n    padding:6px 8px; color:#ffffff; font-size:11.5px; font-weight:700; cursor:pointer;\r\n    font-family:inherit; margin-top:2px;\r\n  }\r\n  .cart-badge-count{\r\n    position:absolute; top:-6px; right:-8px;\r\n    background:var(--orange); color:#ffffff; font-size:9.5px; font-weight:800;\r\n    min-width:16px; height:16px; border-radius:10px; display:flex; align-items:center; justify-content:center;\r\n    padding:0 3px; border:1.5px solid var(--navy);\r\n  }\r\n  .search-bar{\r\n    background:var(--white);\r\n    border-radius:16px;\r\n    padding:12px 14px;\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    box-shadow:0 6px 16px rgba(0,0,0,0.18);\r\n  }\r\n  .search-bar input{\r\n    border:none;\r\n    outline:none;\r\n    flex:1;\r\n    font-size:13px;\r\n    font-family:inherit;\r\n    color:var(--text);\r\n    background:transparent;\r\n  }\r\n  .search-bar input::placeholder{ color:#9AA1AE; }\r\n\r\n  \/* ===== QUICK ACTIONS ===== *\/\r\n  .quick-actions{\r\n    display:flex;\r\n    align-items:stretch;\r\n    padding:16px var(--pad);\r\n  }\r\n  .qa-item{\r\n    flex:1;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    text-align:center;\r\n    gap:6px;\r\n    padding:0 4px;\r\n  }\r\n  .qa-item b{\r\n    font-size:11.5px;\r\n    font-weight:700;\r\n    color:var(--text);\r\n  }\r\n  .qa-item span{\r\n    font-size:9px;\r\n    color:var(--grey-text);\r\n    font-weight:500;\r\n  }\r\n  .qa-divider{\r\n    width:1px;\r\n    background:var(--border);\r\n    margin:2px 0;\r\n  }\r\n\r\n  \/* ===== SECTION HEADER ===== *\/\r\n  .section-header{\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:space-between;\r\n    padding:0 var(--pad);\r\n    margin-bottom:14px;\r\n  }\r\n  .section-header h3{\r\n    font-size:17px;\r\n    font-weight:800;\r\n    color:var(--text);\r\n  }\r\n  .view-all{\r\n    display:flex;\r\n    align-items:center;\r\n    gap:2px;\r\n    font-size:11.5px;\r\n    font-weight:700;\r\n    color:var(--orange);\r\n    flex-shrink:0;\r\n    white-space:nowrap;\r\n  }\r\n\r\n  \/* ===== HERO BANNER ===== *\/\r\n  .hero-section{ padding:18px var(--pad); }\r\n  .hero-banner{\r\n    position:relative;\r\n    border-radius:22px;\r\n    overflow:hidden;\r\n    background:linear-gradient(100deg, var(--navy-3) 28%, #17284f 55%, #2b3f6b 100%);\r\n    min-height:260px;\r\n    padding:20px 18px;\r\n    display:flex;\r\n    flex-direction:column;\r\n    justify-content:flex-start;\r\n  }\r\n  .hero-house{\r\n    position:absolute;\r\n    inset:0;\r\n    width:100%;\r\n    height:100%;\r\n  }\r\n  .hero-fade{\r\n    position:absolute;\r\n    inset:0;\r\n    background:linear-gradient(90deg, var(--navy-3) 22%, rgba(9,20,48,0.55) 45%, rgba(9,20,48,0) 62%);\r\n  }\r\n  .hero-content{ position:relative; z-index:2; max-width:62%; }\r\n  .badge-pill{\r\n    display:inline-block;\r\n    background:var(--orange);\r\n    color:var(--white);\r\n    font-size:9.5px;\r\n    font-weight:800;\r\n    letter-spacing:0.5px;\r\n    padding:5px 11px;\r\n    border-radius:20px;\r\n    margin-bottom:10px;\r\n  }\r\n  .hero-title{\r\n    font-size:26px;\r\n    font-weight:900;\r\n    line-height:1.06;\r\n    color:var(--white);\r\n    letter-spacing:-0.3px;\r\n  }\r\n  .hero-title .orange{ color:var(--orange); display:block; }\r\n  .hero-sub{\r\n    font-size:11px;\r\n    color:#D7DCE8;\r\n    font-weight:500;\r\n    line-height:1.4;\r\n    margin-top:9px;\r\n    max-width:150px;\r\n  }\r\n  .btn-orange{\r\n    background:var(--orange);\r\n    color:var(--white);\r\n    font-size:12.5px;\r\n    font-weight:700;\r\n    padding:11px 22px;\r\n    border-radius:12px;\r\n    margin-top:14px;\r\n    box-shadow:0 6px 14px rgba(240,165,0,0.35);\r\n  }\r\n  .hero-discount-box{\r\n    position:absolute;\r\n    top:80px;\r\n    right:16px;\r\n    z-index:3;\r\n    background:rgba(9,15,32,0.88);\r\n    border:1px solid rgba(255,255,255,0.12);\r\n    border-radius:14px;\r\n    padding:12px 14px;\r\n    text-align:left;\r\n    width:104px;\r\n  }\r\n  .up-to{\r\n    display:block;\r\n    font-size:9px;\r\n    font-weight:700;\r\n    color:var(--white);\r\n    letter-spacing:0.5px;\r\n  }\r\n  .percent{\r\n    display:block;\r\n    font-size:34px;\r\n    font-weight:900;\r\n    color:var(--orange);\r\n    line-height:1.05;\r\n    margin-top:2px;\r\n  }\r\n  .pct-sign{ font-size:16px; }\r\n  .off{\r\n    display:block;\r\n    font-size:15px;\r\n    font-weight:800;\r\n    color:var(--white);\r\n    margin-top:-4px;\r\n  }\r\n  .limited{\r\n    display:block;\r\n    font-size:7.5px;\r\n    font-weight:700;\r\n    color:var(--orange);\r\n    letter-spacing:0.3px;\r\n    margin-top:6px;\r\n  }\r\n  .carousel-dots{\r\n    position:relative;\r\n    z-index:3;\r\n    display:flex;\r\n    justify-content:center;\r\n    gap:5px;\r\n    margin-top:auto;\r\n    padding-top:16px;\r\n  }\r\n  .dot{\r\n    width:6px;\r\n    height:6px;\r\n    border-radius:4px;\r\n    background:rgba(255,255,255,0.45);\r\n  }\r\n  .dot.active{\r\n    width:16px;\r\n    background:var(--orange);\r\n  }\r\n\r\n  \/* ===== CATEGORIES ===== *\/\r\n  .category-section{ padding:6px 0 22px; }\r\n  .category-row{\r\n    display:flex;\r\n    gap:16px;\r\n    padding:0 var(--pad);\r\n    overflow-x:auto;\r\n    scroll-snap-type:x proximity;\r\n    -webkit-overflow-scrolling:touch;\r\n  }\r\n  .cat-item{\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    gap:10px;\r\n    width:184px;\r\n    flex:0 0 auto;\r\n    scroll-snap-align:start;\r\n  }\r\n  .cat-icon-bg{\r\n    width:184px;\r\n    height:184px;\r\n    border-radius:28px;\r\n    background:var(--grey-bg);\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    overflow:hidden;\r\n  }\r\n  .cat-label{\r\n    font-size:13.5px;\r\n    font-weight:700;\r\n    text-align:center;\r\n    line-height:1.25;\r\n    color:var(--text);\r\n  }\r\n\r\n  \/* ===== RENOVATE BANNER ===== *\/\r\n  .renovate-section{ padding:0 var(--pad) 24px; }\r\n  .renovate-banner{\r\n    background:var(--sage);\r\n    border-radius:20px;\r\n    display:flex;\r\n    align-items:stretch;\r\n    overflow:hidden;\r\n    min-height:190px;\r\n  }\r\n  .renovate-text{\r\n    flex:1;\r\n    padding:20px 0 20px 18px;\r\n    display:flex;\r\n    flex-direction:column;\r\n    justify-content:center;\r\n    max-width:55%;\r\n  }\r\n  .renovate-eyebrow{\r\n    font-size:12px;\r\n    color:#3A4A3A;\r\n    font-weight:500;\r\n    margin-bottom:4px;\r\n  }\r\n  .renovate-title{\r\n    font-size:19px;\r\n    font-weight:800;\r\n    color:var(--navy);\r\n    line-height:1.18;\r\n  }\r\n  .renovate-title .orange{ color:var(--orange); }\r\n  .renovate-sub{\r\n    font-size:11px;\r\n    color:#5B6B5B;\r\n    font-weight:500;\r\n    line-height:1.4;\r\n    margin-top:8px;\r\n  }\r\n  .btn-navy{\r\n    background:var(--navy);\r\n    color:var(--white);\r\n    font-size:11px;\r\n    font-weight:700;\r\n    padding:11px 14px;\r\n    border-radius:11px;\r\n    margin-top:14px;\r\n    align-self:flex-start;\r\n  }\r\n  .renovate-image{\r\n    flex:1;\r\n    position:relative;\r\n    min-width:42%;\r\n    overflow:hidden;\r\n    border-radius:0 22px 22px 0;\r\n  }\r\n  .renovate-image img{\r\n    position:absolute;\r\n    inset:0;\r\n    width:100%;\r\n    height:100%;\r\n  }\r\n\r\n  \/* ===== FEATURED DEALS ===== *\/\r\n  .deals-section{ padding:4px 0 24px; }\r\n  .deals-row{\r\n    display:flex;\r\n    gap:12px;\r\n    padding:0 var(--pad) 4px;\r\n    overflow-x:auto;\r\n    scroll-snap-type:x proximity;\r\n    -webkit-overflow-scrolling:touch;\r\n  }\r\n  \/* ===== Real product cards (matches shop.html) - used by the new\r\n     \"Featured Products\" section, which replaces the old Top Picks\/deals\r\n     grid ===== *\/\r\n  .product-grid-5{ display:grid; grid-template-columns:repeat(2,1fr); gap:14px; }\r\n  @media(min-width:640px){ .product-grid-5{ grid-template-columns:repeat(3,1fr); } }\r\n  @media(min-width:1100px){ .product-grid-5{ grid-template-columns:repeat(5,1fr); } }\r\n  .product-card{\r\n    width:auto; flex:none; border:1px solid var(--border); border-radius:14px; padding:12px;\r\n    display:flex; flex-direction:column; position:relative;\r\n    transition:box-shadow .25s ease, transform .25s ease;\r\n  }\r\n  .product-card:hover{ box-shadow:0 10px 22px rgba(13,27,61,0.1); transform:translateY(-2px); }\r\n  .card-top-row{ display:flex; align-items:flex-start; justify-content:space-between; margin-bottom:6px; }\r\n  .wish-btn{ width:22px; height:22px; display:flex; align-items:center; justify-content:center; }\r\n  .wish-btn.wished svg{ fill:#E63946; stroke:#E63946; }\r\n  .featured-badge{ position:absolute; top:8px; left:8px; z-index:2; background:var(--navy); color:#ffffff; font-size:9px; font-weight:800; padding:3px 7px; border-radius:8px; }\r\n  .card-image{ width:100%; aspect-ratio:1; border-radius:10px; overflow:hidden; background:var(--grey-bg); margin-bottom:9px; }\r\n  .card-image svg{ width:100%; height:100%; }\r\n  .card-seller{ display:flex; align-items:center; gap:5px; font-size:11px; font-weight:600; color:var(--text); margin-bottom:4px; }\r\n  .card-name{ font-size:12.5px; font-weight:700; line-height:1.32; height:33px; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; margin-bottom:6px; }\r\n  .card-rating{ display:flex; align-items:center; gap:5px; margin-bottom:6px; }\r\n  .card-rating .stars{ display:inline-flex; gap:1px; }\r\n  .card-rating-count{ font-size:10.5px; color:#8A96B0; }\r\n  .card-price-row{ display:flex; align-items:baseline; gap:5px; margin-bottom:2px; flex-wrap:wrap; }\r\n  .card-price{ font-size:15px; font-weight:800; }\r\n  .card-price-strike{ font-size:9px; color:var(--grey-light); text-decoration:line-through; }\r\n  .card-secondary-prices{ font-size:9.5px; color:var(--grey-text); margin-bottom:6px; }\r\n  .card-stock{ font-size:10.5px; font-weight:600; margin-bottom:9px; }\r\n  .card-stock.in{ color:#1F9D55; }\r\n  .card-stock.out{ color:#D64545; }\r\n  .card-bottom-row{ display:flex; gap:6px; margin-top:auto; }\r\n  .qty-stepper{ display:flex; align-items:center; border:1px solid var(--border); border-radius:9px; flex:none; }\r\n  .qty-stepper button{ width:24px; height:32px; background:none; font-size:14px; font-weight:700; color:var(--navy); }\r\n  .qty-stepper span{ width:22px; text-align:center; font-size:12px; font-weight:600; }\r\n  .card-cart-btn{\r\n    background:var(--orange); color:var(--white); font-size:10.5px; font-weight:700; padding:9px 6px;\r\n    border-radius:9px; display:flex; align-items:center; justify-content:center; gap:5px; flex:1;\r\n  }\r\n  .load-more-link-btn{\r\n    display:block; text-align:center; margin:20px auto 0; background:var(--white); border:1.5px solid var(--border);\r\n    color:var(--text); font-size:13px; font-weight:700; padding:11px 28px; border-radius:9px; text-decoration:none; width:fit-content;\r\n  }\r\n\r\n  .deal-card{\r\n    flex:0 0 auto;\r\n    width:158px;\r\n    border:1px solid var(--border);\r\n    border-radius:14px;\r\n    padding:12px;\r\n    display:flex;\r\n    flex-direction:column;\r\n    scroll-snap-align:start;\r\n  }\r\n  .deal-image-wrap{\r\n    position:relative;\r\n    width:100%;\r\n    height:118px;\r\n    border-radius:10px;\r\n    overflow:hidden;\r\n    background:var(--grey-bg);\r\n    margin-bottom:9px;\r\n  }\r\n  .deal-image-wrap svg{ width:100%; height:100%; }\r\n  .discount-badge{\r\n    position:absolute;\r\n    top:6px;\r\n    left:6px;\r\n    z-index:2;\r\n    background:var(--orange);\r\n    color:var(--white);\r\n    font-size:9px;\r\n    font-weight:800;\r\n    padding:3px 7px;\r\n    border-radius:8px;\r\n  }\r\n  .deal-name{\r\n    font-size:12px;\r\n    font-weight:700;\r\n    color:var(--text);\r\n    line-height:1.3;\r\n    height:31px;\r\n    margin-bottom:6px;\r\n    overflow:hidden;\r\n    display:-webkit-box;\r\n    -webkit-line-clamp:2;\r\n    -webkit-box-orient:vertical;\r\n  }\r\n  .deal-price-row{\r\n    display:flex;\r\n    align-items:baseline;\r\n    gap:4px;\r\n    flex-wrap:wrap;\r\n    margin-bottom:7px;\r\n    row-gap:0;\r\n  }\r\n  .price{\r\n    font-size:15px;\r\n    font-weight:800;\r\n    color:var(--text);\r\n    white-space:nowrap;\r\n  }\r\n  .price sup{ font-size:9px; }\r\n  .price-unit{\r\n    font-size:8.5px;\r\n    color:var(--grey-text);\r\n    font-weight:500;\r\n  }\r\n  .price-strike{\r\n    font-size:9.5px;\r\n    color:var(--grey-light);\r\n    text-decoration:line-through;\r\n    white-space:nowrap;\r\n  }\r\n  .btn-cart{\r\n    background:var(--orange);\r\n    color:var(--white);\r\n    font-size:8.5px;\r\n    font-weight:700;\r\n    padding:7px 4px;\r\n    border-radius:8px;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    gap:4px;\r\n    white-space:nowrap;\r\n    flex:1;\r\n    min-width:0;\r\n  }\r\n  .btn-row{ display:flex; align-items:center; gap:6px; margin-top:auto; }\r\n  .btn-favorite{\r\n    flex:none;\r\n    width:28px;\r\n    height:28px;\r\n    border-radius:8px;\r\n    border:1px solid var(--border);\r\n    background:var(--white);\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n  }\r\n\r\n  \/* ---- Bottom promo cards ---- *\/\r\n  .shop-promo-grid{ display:grid; grid-template-columns:1fr; gap:14px; margin:24px var(--pad) 0; }\r\n  .shop-promo-card{ background:var(--grey-bg); border-radius:12px; padding:16px; display:flex; flex-direction:column; }\r\n  .spc-img{ width:100%; aspect-ratio:1.6; border-radius:9px; overflow:hidden; margin-bottom:12px; }\r\n  .spc-img img{ width:100%; height:100%; object-fit:cover; }\r\n  .shop-promo-card h4{ font-size:14px; font-weight:700; color:var(--navy); margin-bottom:4px; }\r\n  .shop-promo-card p{ font-size:11.5px; color:var(--grey-text); margin-bottom:10px; line-height:1.4; }\r\n  .shop-promo-card span{ font-size:12px; font-weight:700; color:var(--navy); margin-top:auto; }\r\n  @media(min-width:640px){ .shop-promo-grid{ grid-template-columns:repeat(2,1fr); } }\r\n  @media(min-width:1100px){ .shop-promo-grid{ grid-template-columns:repeat(4,1fr); } }\r\n\r\n  \/* ===== TRUST BAR ===== *\/\r\n  .trust-bar{\r\n    background:var(--navy);\r\n    padding:20px 10px;\r\n  }\r\n  .trust-bar-inner{\r\n    display:flex;\r\n  }\r\n  .trust-item{\r\n    flex:1;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    text-align:center;\r\n    gap:7px;\r\n    padding:0 4px;\r\n  }\r\n  .trust-item b{\r\n    display:block;\r\n    font-size:9.5px;\r\n    font-weight:700;\r\n    color:var(--white);\r\n    line-height:1.2;\r\n  }\r\n  .trust-item span{\r\n    display:block;\r\n    font-size:7.5px;\r\n    color:#A7B0C4;\r\n    font-weight:500;\r\n    line-height:1.3;\r\n    margin-top:3px;\r\n  }\r\n  \/* ===== LOCATION & CURRENCY MODAL ===== *\/\r\n  .modal-overlay{\r\n    position:fixed; inset:0; background:rgba(9,15,32,0.55);\r\n    display:flex; align-items:flex-end; justify-content:center;\r\n    z-index:100; opacity:0; pointer-events:none; transition:opacity .25s ease;\r\n  }\r\n  .modal-overlay.open{ opacity:1; pointer-events:auto; }\r\n  .modal-sheet{\r\n    width:100%; max-width:430px;\r\n    background:var(--white); border-radius:20px 20px 0 0;\r\n    max-height:82vh; display:flex; flex-direction:column;\r\n    transform:translateY(100%); transition:transform .3s ease;\r\n  }\r\n  .modal-overlay.open .modal-sheet{ transform:translateY(0); }\r\n  .modal-head{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px; border-bottom:1px solid var(--border); flex-shrink:0; }\r\n  .modal-head h3{ font-size:15px; font-weight:800; }\r\n  .modal-close{ width:28px; height:28px; border-radius:50%; background:var(--grey-bg); display:flex; align-items:center; justify-content:center; }\r\n  .modal-body{ overflow-y:auto; padding:16px 18px 8px; }\r\n  .modal-section-title{ font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:0.4px; color:var(--grey-text); margin:14px 0 10px; }\r\n  .modal-section-title:first-child{ margin-top:0; }\r\n  .loc-search{ width:100%; border:1px solid var(--border); border-radius:10px; padding:10px 12px; font-size:13px; outline:none; margin-bottom:4px; font-family:inherit; }\r\n  .loc-list{ display:flex; flex-direction:column; }\r\n  .loc-item{ display:flex; align-items:center; justify-content:space-between; padding:11px 4px; border-bottom:1px solid #F3F4F6; cursor:pointer; }\r\n  .loc-item:last-child{ border-bottom:none; }\r\n  .loc-item-name{ font-size:12.5px; font-weight:600; color:var(--text); }\r\n  .loc-item-country{ font-size:10.5px; color:var(--grey-text); font-weight:500; margin-top:1px; }\r\n  .loc-check{ width:18px; height:18px; border-radius:50%; border:2px solid var(--border); flex-shrink:0; }\r\n  .loc-item.selected .loc-check{ border-color:var(--orange); background:var(--orange); }\r\n  .loc-item.selected .loc-item-name{ color:var(--orange); }\r\n  .currency-grid{ display:flex; flex-wrap:wrap; gap:8px; }\r\n  .currency-chip{ border:1px solid var(--border); border-radius:10px; padding:8px 12px; font-size:11.5px; font-weight:700; color:var(--text); display:flex; align-items:center; gap:5px; cursor:pointer; }\r\n  .currency-chip .sym{ color:var(--grey-text); font-weight:500; }\r\n  .currency-chip.selected{ background:#FFF1E2; border-color:var(--orange); color:var(--orange); }\r\n  .currency-chip.selected .sym{ color:var(--orange); }\r\n  .currency-note{ font-size:9.5px; color:var(--grey-light); font-weight:500; margin-top:10px; line-height:1.4; }\r\n  .modal-foot{ padding:14px 18px 20px; border-top:1px solid var(--border); flex-shrink:0; }\r\n  .modal-apply-btn{ width:100%; background:var(--navy); color:var(--white); font-size:13px; font-weight:700; padding:13px; border-radius:12px; }\r\n\r\n  \/* ===== SPLASH SCREEN ===== *\/\r\n  #splashScreen{ position:fixed; inset:0; z-index:9999; background:#0D1B3E; display:flex; align-items:center; justify-content:center; overflow:hidden; transition:opacity 0.6s ease; }\r\n  #splashScreen.fade-out{ opacity:0; pointer-events:none; }\r\n  #splashScreen img{ width:100%; height:100%; object-fit:cover; display:block; }\r\n  body.splash-active{ overflow:hidden; }\r\n\r\n  \/* ===== NEW HERO \u2014 real replica of Builders24_Commerce_Listing design ===== *\/\r\n  .bc-hero{ position:relative; background:var(--navy); overflow:hidden; margin:0 0 0; font-family:'Archivo Narrow',sans-serif; }\r\n  .bc-hero-bg{ position:absolute; inset:0; z-index:0; }\r\n  .bc-hero-bg img{ width:100%; height:100%; object-fit:cover; }\r\n  .bc-hero-gradient{ position:absolute; inset:0; background:linear-gradient(100deg, rgba(13,27,62,0.96) 0%, rgba(13,27,62,0.78) 38%, rgba(13,27,62,0.15) 68%); }\r\n\r\n  .bc-topbar{ position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between; padding:14px var(--pad); border-bottom:1px solid rgba(255,255,255,0.15); flex-wrap:nowrap; gap:8px; }\r\n  .bc-brand{ display:flex; flex-direction:column; min-width:0; flex-shrink:0; }\r\n  .bc-brand-main{ font-family:'Archivo',sans-serif; font-weight:800; font-size:17px; color:#fff; line-height:1.1; white-space:nowrap; }\r\n  .bc-brand-sub{ font-size:9px; font-weight:700; color:#F0A500; letter-spacing:.5px; text-transform:uppercase; text-align:justify; text-align-last:justify; white-space:nowrap; width:100%; }\r\n  .bc-nav{ display:none; align-items:center; gap:26px; }\r\n  .bc-nav a{ color:#fff; font-size:13px; }\r\n  .bc-nav a.bc-nav-active{ color:#F0A500; font-weight:600; }\r\n  .bc-topbar-right{ display:flex; align-items:center; gap:8px; flex-shrink:0; }\r\n  .bc-saved{ display:none; align-items:center; gap:6px; color:#fff; font-size:13px; }\r\n  .bc-util{ display:flex; align-items:center; gap:4px; }\r\n  .bc-util-btn{ display:flex; align-items:center; gap:4px; color:#fff; font-size:12px; background:rgba(255,255,255,0.1); border-radius:7px; padding:6px 8px; cursor:pointer; position:relative; }\r\n  .bc-util-dropdown{ display:none; position:absolute; top:calc(100% + 6px); right:0; background:#fff; border-radius:10px; box-shadow:0 12px 28px rgba(13,27,62,0.25); padding:8px; min-width:180px; max-height:280px; overflow-y:auto; z-index:20; }\r\n  .bc-util-dropdown.open{ display:block; }\r\n  .bc-util-item{ padding:8px 10px; font-size:13px; color:var(--navy); border-radius:7px; cursor:pointer; display:flex; justify-content:space-between; gap:8px; }\r\n  .bc-util-item:hover{ background:var(--grey-bg); }\r\n  .bc-util-item.selected{ font-weight:700; color:var(--orange); }\r\n  .bc-login-link{ color:#fff; font-size:13px; font-weight:600; }\r\n  .bc-avatar{ width:30px; height:30px; border-radius:50%; background:#EDEFF3; display:flex; align-items:center; justify-content:center; overflow:hidden; flex-shrink:0; }\r\n  .bc-avatar img{ width:100%; height:100%; object-fit:cover; }\r\n\r\n  .bc-hero-inner{ position:relative; z-index:1; padding:32px var(--pad) 0; }\r\n  .bc-hero-title{ margin:0; font-family:'Archivo',sans-serif; font-weight:800; font-size:20px; line-height:1.2; color:#fff; }\r\n  .bc-hero-title .accent{ color:#F0A500; }\r\n  .bc-hero-sub{ margin:14px 0 0; font-size:13.5px; color:#D7DEEC; max-width:420px; }\r\n  .bc-trust-row{ display:flex; gap:18px; flex-wrap:wrap; margin-top:22px; }\r\n  .bc-trust-item{ display:flex; align-items:center; gap:8px; }\r\n  .bc-trust-item .diamond{ width:24px; height:24px; border:1.5px solid #ffffff; border-radius:6px; transform:rotate(45deg); display:flex; align-items:center; justify-content:center; flex:none; }\r\n  .bc-trust-item .diamond svg{ transform:rotate(-45deg); width:11px; height:11px; }\r\n  .bc-trust-item span{ font-size:11.5px; color:#D7DEEC; line-height:1.3; }\r\n\r\n  .bc-tabbar{ position:relative; z-index:1; margin-top:26px; padding:0 var(--pad); display:flex; gap:2px; overflow-x:auto; }\r\n  .bc-tab{ background:rgba(255,255,255,0.1); color:rgba(255,255,255,0.85); font-size:12.5px; font-weight:600; padding:12px 18px; border-radius:9px 9px 0 0; cursor:pointer; white-space:nowrap; }\r\n  .bc-tab.active{ background:var(--navy); color:#fff; }\r\n\r\n  .filter-card{ background:#ffffff; border-radius:12px; padding:18px var(--pad); margin:0 var(--pad) 20px; box-shadow:0 8px 24px rgba(13,27,62,0.15); position:relative; z-index:2; }\r\n  .filter-fields{ display:grid; grid-template-columns:1fr; gap:10px; margin-bottom:12px; }\r\n  .filter-fields label{ display:block; font-size:11.5px; color:var(--grey-text); margin-bottom:5px; }\r\n  .filter-fields select, .filter-fields input{ width:100%; box-sizing:border-box; border:1px solid var(--border); border-radius:9px; padding:11px 12px; font-size:13px; font-family:'Archivo Narrow',sans-serif; color:var(--text); background:var(--grey-bg); }\r\n  .filter-range{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }\r\n  .filter-range input{ min-width:0; }\r\n  .filter-submit-btn{ width:100%; background:#F0A500; color:var(--navy); border:none; border-radius:9px; padding:13px; font-size:13.5px; font-weight:700; font-family:'Archivo',sans-serif; }\r\n\r\n  .tab-results{ padding:6px var(--pad) 28px; }\r\n  .tab-results-head h2{ font-size:16px; font-weight:800; color:var(--navy); margin-bottom:14px; }\r\n  .tab-results-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:12px; }\r\n  .tr-card{ background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; display:block; }\r\n  .tr-card-img{ position:relative; width:100%; aspect-ratio:4\/3; background:var(--grey-bg); }\r\n  .tr-card-img img{ width:100%; height:100%; object-fit:cover; }\r\n  .tr-card-body{ padding:14px 16px 16px; }\r\n  .tr-card-title{ font-size:12.5px; color:var(--navy); margin-bottom:3px; }\r\n  .tr-card-price{ font-size:14.5px; font-weight:700; font-family:'Archivo',sans-serif; color:var(--navy); }\r\n  .tr-card-meta{ font-size:11px; color:var(--grey-text); margin-top:3px; }\r\n  .tr-empty{ grid-column:1\/-1; text-align:center; padding:30px 10px; color:var(--grey-text); font-size:13px; }\r\n  .tr-group-label{ font-size:13px; font-weight:800; color:var(--navy); margin:18px 0 10px; }\r\n  .tr-group-label:first-child{ margin-top:0; }\r\n\r\n  \/* ===== Sectors (Building Services tab content) \u2014 real, from Thomas's uploaded design, prefixed to avoid collisions ===== *\/\r\n  .sectors-section{ padding:56px var(--pad); position:relative; overflow:hidden; background:#f4f6fa; font-family:'Space Grotesk',sans-serif; }\r\n  .sectors-bg{ position:absolute; inset:0; background-image:linear-gradient(rgba(13,27,62,0.04) 1px,transparent 1px),linear-gradient(90deg,rgba(13,27,62,0.04) 1px,transparent 1px); background-size:52px 52px; pointer-events:none; }\r\n  .sectors-orb{ position:absolute; top:-120px; right:-80px; width:420px; height:420px; border-radius:50%; background:radial-gradient(circle,rgba(240,165,0,0.07) 0%,transparent 70%); pointer-events:none; }\r\n  .sectors-orb2{ position:absolute; bottom:-100px; left:-80px; width:300px; height:300px; border-radius:50%; background:radial-gradient(circle,rgba(13,27,62,0.05) 0%,transparent 70%); pointer-events:none; }\r\n  .sectors-inner{ max-width:1200px; margin:0 auto; position:relative; z-index:2; }\r\n  .sectors-label{ font-size:9px; font-weight:600; letter-spacing:3px; text-transform:uppercase; color:#F0A500; display:flex; align-items:center; gap:8px; margin-bottom:10px; }\r\n  .sectors-label:before{ content:''; display:block; width:20px; height:2px; background:#F0A500; }\r\n  .sectors-heading{ font-size:clamp(20px,4vw,30px); font-weight:600; color:#0D1B3E; line-height:1.15; margin-bottom:12px; }\r\n  .sectors-heading span{ color:#F0A500; }\r\n  .sectors-sub{ font-size:13px; color:#0D1B3E; line-height:1.7; max-width:680px; margin-bottom:32px; }\r\n  .sectors-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }\r\n  .sectors-card{ position:relative; border-radius:14px; overflow:hidden; height:220px; border:2px solid transparent; text-decoration:none; display:block; transition:border-color .3s,box-shadow .3s,transform .2s; }\r\n  .sectors-card:hover{ border-color:#F0A500; box-shadow:0 20px 40px rgba(13,27,62,0.2); transform:translateY(-3px); }\r\n  .sectors-card-img{ position:absolute; inset:0; background-size:cover; background-position:center; transition:transform .6s ease; }\r\n  .sectors-card:hover .sectors-card-img{ transform:scale(1.08); }\r\n  .sectors-card-overlay{ position:absolute; inset:0; background:linear-gradient(0deg,rgba(13,27,62,0.95) 0%,rgba(13,27,62,0.5) 50%,rgba(13,27,62,0.1) 100%); }\r\n  .sectors-card-topbar{ position:absolute; top:0; left:0; right:0; height:3px; background:#F0A500; transform:scaleX(0); transform-origin:left; transition:transform .35s ease; z-index:5; }\r\n  .sectors-card:hover .sectors-card-topbar{ transform:scaleX(1); }\r\n  .sectors-card-body{ position:absolute; bottom:0; left:0; right:0; padding:16px 14px 18px; z-index:4; }\r\n  .sectors-card-icon-wrap{ width:36px; height:36px; background:#F0A500; border-radius:9px; display:flex; align-items:center; justify-content:center; margin-bottom:10px; box-shadow:0 4px 12px rgba(240,165,0,0.4); }\r\n  .sectors-card-icon-wrap i{ font-size:17px; color:#0D1B3E; }\r\n  .sectors-card-sector{ font-size:9px; font-weight:600; letter-spacing:0.12em; text-transform:uppercase; color:#F0A500; margin-bottom:4px; opacity:.9; }\r\n  .sectors-card-title{ font-size:12px; font-weight:600; color:#ffffff; text-transform:uppercase; letter-spacing:0.04em; margin-bottom:5px; line-height:1.25; }\r\n  .sectors-card-desc{ font-size:10px; font-weight:400; color:#ffffff; line-height:1.5; margin-bottom:10px; opacity:.85; }\r\n  .sectors-card-cta{ display:inline-flex; align-items:center; gap:5px; background:#F0A500; color:#0D1B3E; font-size:9px; font-weight:600; padding:5px 10px; border-radius:5px; letter-spacing:0.06em; text-transform:uppercase; }\r\n  .sectors-card-cta i{ font-size:10px; }\r\n  .sectors-depth-badge{ position:absolute; top:12px; right:12px; background:rgba(13,27,62,0.7); border:1px solid rgba(240,165,0,0.4); border-radius:20px; padding:3px 9px; font-size:8.5px; font-weight:600; color:#F0A500; letter-spacing:0.06em; text-transform:uppercase; z-index:4; backdrop-filter:blur(4px); }\r\n  .sectors-bottom-row{ margin-top:32px; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:14px; }\r\n  .sectors-seo-text{ font-size:11px; color:#0D1B3E; line-height:1.7; max-width:700px; opacity:.7; }\r\n  .sectors-btn-all{ display:inline-flex; align-items:center; gap:8px; background:#0D1B3E; color:#ffffff; font-size:11px; font-weight:600; padding:13px 24px; text-decoration:none; letter-spacing:0.06em; text-transform:uppercase; border-radius:8px; white-space:nowrap; }\r\n  .sectors-btn-all:hover{ background:#F0A500; color:#0D1B3E; }\r\n\r\n  @media(max-width:900px){ .sectors-grid{ grid-template-columns:repeat(2,1fr); } }\r\n  @media(max-width:600px){\r\n    .sectors-section{ padding:36px var(--pad); }\r\n    .sectors-grid{ grid-template-columns:repeat(2,1fr); gap:10px; }\r\n    .sectors-card{ height:130px; border-radius:11px; }\r\n    .sectors-card-body{ padding:10px 10px 12px; }\r\n    .sectors-card-icon-wrap{ width:26px; height:26px; border-radius:7px; margin-bottom:6px; }\r\n    .sectors-card-icon-wrap i{ font-size:12px; }\r\n    .sectors-card-title{ font-size:10px; }\r\n    .sectors-card-desc,.sectors-card-cta{ display:none; }\r\n    .sectors-depth-badge{ display:none; }\r\n    .sectors-bottom-row{ flex-direction:column; align-items:flex-start; }\r\n  }\r\n\r\n  \/* Vehicle card \u2014 exact replica of vehicles.html's bl-card design *\/\r\n  .bl-card{ background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; display:flex; flex-direction:column; text-decoration:none; color:inherit; }\r\n  .bl-card-img{ position:relative; width:100%; aspect-ratio:4\/3; background:var(--grey-bg); display:flex; align-items:center; justify-content:center; overflow:hidden; }\r\n  .bl-card-img img{ width:100%; height:100%; object-fit:cover; }\r\n  .bl-card-badge{ position:absolute; top:10px; left:10px; z-index:2; background:#2B5FBF; color:#fff; font-size:11px; font-weight:600; padding:3px 9px; border-radius:6px; font-family:'Archivo',sans-serif; }\r\n  .bl-fav-btn{ position:absolute; top:8px; right:8px; z-index:2; width:28px; height:28px; border-radius:50%; background:#fff; border:1px solid var(--border); display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0; }\r\n  .bl-card-body{ padding:14px 16px 16px; display:flex; flex-direction:column; gap:4px; }\r\n  .bl-card-title{ font-size:12.5px; color:var(--navy); }\r\n  .bl-card-price{ font-size:14.5px; font-weight:700; font-family:'Archivo',sans-serif; color:var(--navy); }\r\n  .bl-card-meta{ display:flex; align-items:center; gap:10px; font-size:11px; color:var(--grey-text); margin-top:2px; }\r\n  .bl-card-flag{ display:flex; align-items:center; gap:4px; margin-left:auto; }\r\n  .bl-flag-emoji{ font-size:12px; line-height:1; }\r\n\r\n  @media(min-width:900px){\r\n    .bc-nav{ display:flex; }\r\n    .bc-saved{ display:flex; }\r\n    .bc-util{ gap:6px; }\r\n    .bc-util-btn{ gap:5px; font-size:12.5px; padding:6px 10px; }\r\n    .bc-topbar{ padding:18px 40px; }\r\n    .bc-hero-inner{ padding:56px 40px 0; max-width:640px; }\r\n    .bc-hero-title{ font-size:30px; }\r\n    .bc-hero-sub{ font-size:16px; max-width:460px; }\r\n    .bc-tabbar{ padding:0 40px; margin-top:48px; }\r\n    .bc-tab{ font-size:14px; padding:14px 26px; }\r\n    .filter-card{ position:relative; margin:0 40px -40px; width:auto; max-width:none; border-radius:0 12px 12px 12px; z-index:3; display:flex; align-items:flex-end; gap:16px; padding:24px 32px; }\r\n    .filter-fields{ flex:1; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:12px; margin-bottom:0; }\r\n    .filter-submit-btn{ width:auto; white-space:nowrap; padding:12px 28px; flex:none; }\r\n    .tab-results{ padding:6px 40px 40px; }\r\n    .tab-results-grid{ grid-template-columns:repeat(4,1fr); gap:20px; }\r\n  }\r\n\r\n  \/* ===== PROMO STRIP ===== *\/\r\n  .promo-strip{ display:flex; flex-direction:column; gap:14px; padding:0 var(--pad) 24px; }\r\n  .promo-tile{ background:#ffffff; border:1px solid var(--border); border-radius:14px; padding:16px 18px; }\r\n  .promo-tile.emergency{ background:linear-gradient(135deg,#F0A500,#CC8C00); border:none; display:flex; justify-content:space-between; align-items:center; gap:12px; color:#ffffff; }\r\n  .promo-tile.emergency .pt-title{ font-size:15px; font-weight:800; color:#ffffff; }\r\n  .promo-tile.emergency .pt-sub{ font-size:11.5px; color:rgba(255,255,255,0.9); margin-bottom:12px; }\r\n  .promo-tile.emergency button{ background:#ffffff; color:#F0A500; border:none; border-radius:8px; padding:9px 16px; font-size:12.5px; font-weight:700; }\r\n  .promo-tile .pt-photo{ position:relative; width:84px; height:70px; flex:none; border-radius:10px; overflow:hidden; background:rgba(255,255,255,0.15); }\r\n  .promo-tile .pt-photo img{ width:100%; height:100%; object-fit:cover; }\r\n  .promo-tile .pt-badge247{ position:absolute; top:5px; right:5px; width:26px; height:26px; border-radius:50%; border:1.5px solid rgba(255,255,255,0.85); background:rgba(13,27,62,0.4); display:flex; align-items:center; justify-content:center; font-size:8.5px; font-weight:800; color:#ffffff; }\r\n  .promo-tile h4{ font-size:13.5px; font-weight:700; color:var(--navy); margin:10px 0 4px; }\r\n  .promo-tile p{ font-size:11.5px; color:var(--grey-text); margin-bottom:8px; }\r\n  .promo-tile a{ font-size:12px; font-weight:700; color:var(--navy); }\r\n  @media(min-width:900px){ .promo-strip{ max-width:1200px; margin:0 auto; padding:0 40px 32px; } }\r\n\r\n  .promo-3d-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:12px; }\r\n  .promo-3d-card{\r\n    position:relative; border-radius:16px; overflow:hidden; aspect-ratio:1.15;\r\n    box-shadow:0 10px 22px rgba(13,27,62,0.2);\r\n    transition:transform .22s ease, box-shadow .22s ease;\r\n  }\r\n  .promo-3d-card:active{ transform:translateY(-2px) scale(0.98); box-shadow:0 6px 14px rgba(13,27,62,0.22); }\r\n  .promo-3d-card img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }\r\n  .p3d-gradient{ position:absolute; inset:0; background:linear-gradient(180deg, rgba(13,27,62,0) 38%, rgba(13,27,62,0.88) 100%); }\r\n  .p3d-label{ position:absolute; left:12px; right:12px; bottom:12px; z-index:2; color:#ffffff; font-size:13.5px; font-weight:800; line-height:1.25; }\r\n  @media(min-width:900px){\r\n    .promo-3d-grid{ grid-template-columns:repeat(4,1fr); }\r\n    .promo-3d-card:hover{ transform:translateY(-5px); box-shadow:0 18px 34px rgba(13,27,62,0.28); }\r\n    .p3d-label{ font-size:15px; }\r\n  }\r\n\r\n  \/* ===== TOP PICKS RENAME (reuses existing .deals-section\/.deal-card styles) ===== *\/\r\n\r\n  \/* ===== SLIDE-IN CART ===== *\/\r\n  .cart-drawer-overlay{ position:fixed; inset:0; background:rgba(9,15,32,0.5); z-index:200; opacity:0; pointer-events:none; transition:opacity .25s ease; }\r\n  .cart-drawer-overlay.open{ opacity:1; pointer-events:auto; }\r\n  .cart-drawer{ position:fixed; top:0; right:0; bottom:0; width:100%; max-width:400px; background:#fff; z-index:201; display:flex; flex-direction:column; transform:translateX(100%); transition:transform .28s ease; box-shadow:-8px 0 30px rgba(0,0,0,0.15); }\r\n  .cart-drawer-overlay.open .cart-drawer{ transform:translateX(0); }\r\n  .cd-head{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px; border-bottom:1px solid #E7E9EC; flex-shrink:0; }\r\n  .cd-head h3{ font-size:15px; font-weight:800; color:#0D1220; }\r\n  .cd-head-right{ display:flex; align-items:center; gap:10px; }\r\n  .cd-clear-btn{ font-size:11.5px; font-weight:700; color:#D64535; }\r\n  .cd-close{ width:28px; height:28px; border-radius:50%; background:#EEF0F3; display:flex; align-items:center; justify-content:center; border:none; cursor:pointer; flex-shrink:0; }\r\n  .cd-body{ flex:1; overflow-y:auto; padding:12px 18px; }\r\n  .cd-item{ display:flex; gap:12px; padding:12px 0; border-bottom:1px solid #F3F4F6; }\r\n  .cd-item:last-child{ border-bottom:none; }\r\n  .cd-thumb{ width:56px; height:56px; border-radius:9px; background:#EEF0F3; flex:none; overflow:hidden; }\r\n  .cd-thumb img{ width:100%; height:100%; object-fit:cover; }\r\n  .cd-item-name{ font-size:12.5px; font-weight:600; color:#0D1220; line-height:1.3; margin-bottom:4px; }\r\n  .cd-item-price{ font-size:12.5px; font-weight:700; color:#0D1220; }\r\n  .cd-item-qty-row{ display:flex; align-items:center; gap:8px; margin-top:6px; }\r\n  .cd-qty-btn{ width:24px; height:24px; border-radius:6px; background:#F4F6FB; border:1px solid #E3E8F0; font-size:13px; font-weight:700; color:#0D1B3E; }\r\n  .cd-qty-val{ font-size:12px; font-weight:700; min-width:16px; text-align:center; }\r\n  .cd-item-remove{ margin-left:auto; font-size:11px; font-weight:600; color:#D64535; }\r\n  .cd-empty{ text-align:center; padding:60px 20px; color:#5B6A8C; }\r\n  .cd-empty svg{ width:42px; height:42px; margin:0 auto 12px; color:#0D1B3E; }\r\n  .cd-foot{ border-top:1px solid #E7E9EC; padding:16px 18px calc(16px + env(safe-area-inset-bottom)); flex-shrink:0; }\r\n  .cd-subtotal-row{ display:flex; justify-content:space-between; font-size:14px; font-weight:700; color:#0D1220; margin-bottom:12px; }\r\n  .cd-checkout-btn{ width:100%; background:#F0A500; color:#fff; border-radius:11px; padding:13px; font-size:13.5px; font-weight:700; margin-bottom:8px; }\r\n  .cd-view-cart-btn{ width:100%; background:#fff; border:1.5px solid #0D1B3E; color:#0D1B3E; border-radius:11px; padding:11px; font-size:13px; font-weight:700; }\r\n\r\n  \/* ===== New homepage sections \u2014 reuses the page's real --navy\/--orange tokens ===== *\/\r\n  .hp-section{ padding:28px var(--pad) 0; }\r\n  .hp-section-head{ display:flex; justify-content:space-between; align-items:baseline; flex-wrap:wrap; gap:10px; margin-bottom:16px; }\r\n  .hp-section-title{ font-size:20px; font-weight:800; color:var(--navy); font-family:'Archivo',sans-serif; }\r\n  .hp-section-sub{ font-size:12.5px; color:#6b7280; margin-top:3px; }\r\n  .hp-viewall{ font-size:12.5px; font-weight:700; color:var(--orange); }\r\n  .hp-skel{ height:280px; border-radius:10px; background:linear-gradient(90deg,#eee 25%,#f5f5f5 50%,#eee 75%); background-size:200% 100%; animation:hpshimmer 1.4s infinite; grid-column:1\/-1; }\r\n  @keyframes hpshimmer{ from{background-position:200% 0;} to{background-position:-200% 0;} }\r\n\r\n  .hp-product-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:14px; }\r\n  @media(min-width:640px){ .hp-product-grid{ grid-template-columns:repeat(3,1fr); } }\r\n  @media(min-width:1000px){ .hp-product-grid{ grid-template-columns:repeat(6,1fr); } }\r\n\r\n  \/* Horizontally scrollable product rows (Shipped from USA \/ China \/ Zimbabwe) *\/\r\n  .hp-scroll-row{ display:flex; gap:14px; overflow-x:auto; scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; padding:2px 2px 12px; min-width:0; }\r\n  .hp-scroll-row > .product-card{ flex:0 0 auto; width:170px; scroll-snap-align:start; }\r\n  .hp-scroll-row > .hp-skel{ flex:1 0 100%; }\r\n  .hp-scroll-row > p{ flex:1 0 100%; }\r\n  .hp-scroll-row > .bl-card{ flex:0 0 auto; width:200px; scroll-snap-align:start; }\r\n  @media(min-width:900px){ .hp-scroll-row > .product-card{ width:200px; } .hp-scroll-row > .bl-card{ width:240px; } }\r\n  \/* Home product view switcher: Original (cards) \/ List *\/\r\n  .pv-actions{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }\r\n  .pv-switch{ display:inline-flex; border:1px solid var(--border); border-radius:10px; overflow:hidden; background:#fff; }\r\n  .pv-switch button{ min-height:32px; padding:0 12px; font-size:12.5px; font-weight:700; color:var(--navy); background:#fff; white-space:nowrap; }\r\n  .pv-switch button:active{ transform:scale(.96); }\r\n  .pv-switch button.on{ background:var(--navy); color:#fff; }\r\n  body[data-pview=\"list\"] .pv-target{ display:flex; flex-direction:column; gap:10px; overflow:visible; scroll-snap-type:none; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card{ width:auto; flex:0 0 auto; display:grid; grid-template-columns:minmax(0,1fr) 150px; column-gap:14px; row-gap:4px; align-items:center; position:relative; padding:12px; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > a{ grid-column:1; grid-row:1 \/ span 6; display:grid !important; grid-template-columns:96px minmax(0,1fr); column-gap:12px; align-items:start; min-width:0; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > a > .card-image{ grid-column:1; grid-row:1 \/ span 5; margin:0; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > a > :not(.card-image){ grid-column:2; min-width:0; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-top-row{ position:absolute; top:8px; right:8px; margin:0; z-index:2; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-price-row,\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-secondary-prices,\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-stock,\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-bottom-row{ grid-column:2; margin:0; }\r\n  body[data-pview=\"list\"] .pv-target > .product-card > .card-price-row{ margin-top:22px; }\r\n  @media(max-width:599px){\r\n    body[data-pview=\"list\"] .pv-target > .product-card{ grid-template-columns:minmax(0,1fr); }\r\n    body[data-pview=\"list\"] .pv-target > .product-card > a{ grid-row:auto; grid-template-columns:84px minmax(0,1fr); }\r\n    body[data-pview=\"list\"] .pv-target > .product-card > .card-price-row,\r\n    body[data-pview=\"list\"] .pv-target > .product-card > .card-secondary-prices,\r\n    body[data-pview=\"list\"] .pv-target > .product-card > .card-stock,\r\n    body[data-pview=\"list\"] .pv-target > .product-card > .card-bottom-row{ grid-column:1; }\r\n    body[data-pview=\"list\"] .pv-target > .product-card > .card-price-row{ margin-top:6px; }\r\n  }\r\n  .hp-category-banners{ display:grid; grid-template-columns:repeat(1,1fr); gap:14px; }\r\n  @media(min-width:700px){ .hp-category-banners{ grid-template-columns:repeat(3,1fr); } }\r\n  .hp-cat-banner{ position:relative; border-radius:8px; overflow:hidden; height:160px; cursor:pointer; }\r\n  .hp-cat-banner img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }\r\n  .hp-cat-banner-overlay{ position:absolute; inset:0; background:linear-gradient(90deg,rgba(13,27,62,0.88) 0%,rgba(13,27,62,0.15) 80%); }\r\n  .hp-cat-banner-copy{ position:relative; z-index:1; padding:18px; height:100%; display:flex; flex-direction:column; justify-content:center; gap:8px; }\r\n  .hp-cat-banner-title{ color:#fff; font-weight:800; font-size:19px; }\r\n  .hp-cat-banner-sub{ color:#dbe1f0; font-size:11.5px; max-width:75%; }\r\n  .hp-cat-banner-btn{ background:var(--orange); color:var(--navy); font-weight:700; font-size:11.5px; border:none; border-radius:6px; padding:7px 14px; width:fit-content; cursor:pointer; }\r\n\r\n  .hp-full-banner{ width:100%; display:block; border-radius:8px; }\r\n\r\n  .hp-bulk-banner{ position:relative; border-radius:8px; overflow:hidden; display:flex; flex-wrap:wrap; align-items:stretch; min-height:220px; }\r\n  .hp-bulk-bg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }\r\n  .hp-bulk-overlay{ position:absolute; inset:0; z-index:0; background:linear-gradient(90deg, rgba(13,27,62,0.92) 0%, rgba(13,27,62,0.6) 55%, rgba(13,27,62,0.25) 100%); }\r\n  .hp-bulk-copy{ padding:26px 28px; display:flex; flex-direction:column; justify-content:center; gap:10px; max-width:420px; flex:1; position:relative; z-index:1; }\r\n  .hp-bulk-title{ color:#fff; font-weight:800; font-size:22px; }\r\n  .hp-bulk-sub{ color:#c7cee6; font-size:12.5px; line-height:1.5; }\r\n  .hp-bulk-cta{ background:var(--orange); color:var(--navy); font-weight:700; font-size:12.5px; border-radius:6px; padding:9px 16px; width:fit-content; }\r\n  .hp-bulk-features{ background:var(--orange); padding:22px 24px; display:flex; flex-direction:column; justify-content:center; gap:11px; flex-shrink:0; position:relative; z-index:1; }\r\n  .hp-bulk-feature{ color:var(--navy); font-size:12px; font-weight:700; white-space:nowrap; }\r\n  .hp-mockup-hero-row{ display:flex; gap:20px; padding:28px var(--pad) 0; align-items:flex-start; }\r\n  .hp-cat-sidebar{ width:230px; flex-shrink:0; background:#fff; border:1px solid #eee; border-radius:8px; padding:14px 0; }\r\n  .hp-cat-sidebar-title{ font-weight:700; font-size:15px; color:var(--navy); padding:0 16px 10px; }\r\n  .hp-cat-row{ display:flex; align-items:center; justify-content:space-between; padding:8px 16px; cursor:pointer; }\r\n  .hp-cat-row:hover{ background:#f8f9fb; }\r\n  .hp-cat-row-left{ display:flex; align-items:center; gap:10px; font-size:13.5px; color:#333; }\r\n  .hp-cat-row-icon{ color:var(--navy); }\r\n  .hp-cat-row-chevron{ color:#bbb; font-size:13px; }\r\n  .hp-mockup-hero{ flex:1; min-width:0; position:relative; border-radius:8px; overflow:hidden; height:290px; }\r\n  .hp-mockup-hero img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }\r\n  .hp-mockup-hero-gradient{ position:absolute; inset:0; background:linear-gradient(90deg,rgba(13,27,62,0.88) 0%,rgba(13,27,62,0.55) 45%,rgba(13,27,62,0) 75%); pointer-events:none; }\r\n  .hp-mockup-hero-copy{ position:absolute; top:0; left:0; bottom:0; width:60%; padding:36px 30px; display:flex; flex-direction:column; justify-content:center; gap:14px; }\r\n  .hp-mockup-hero-eyebrow{ color:var(--orange); font-weight:700; font-size:13px; letter-spacing:1.5px; }\r\n  .hp-mockup-hero-title{ color:#fff; font-weight:800; font-size:34px; line-height:1.15; }\r\n  .hp-mockup-hero-sub{ color:#dbe1f0; font-size:14px; line-height:1.5; max-width:400px; }\r\n  .hp-mockup-hero-btn{ background:var(--orange); color:var(--navy); font-weight:700; font-size:14px; border:none; border-radius:6px; padding:11px 22px; display:inline-flex; align-items:center; gap:8px; width:fit-content; }\r\n  .hp-mockup-hero-badge{ position:absolute; top:22px; right:22px; background:var(--orange); color:var(--navy); border-radius:8px; padding:14px 16px; text-align:center; line-height:1.1; font-weight:800; }\r\n  .hp-mockup-hero-badge-top{ font-size:12px; font-weight:700; }\r\n  .hp-mockup-hero-badge-pct{ font-size:26px; }\r\n  .hp-mockup-hero-badge-off{ font-size:14px; }\r\n  .hp-mockup-hero-badge-sub{ font-size:10px; font-weight:700; margin-top:2px; }\r\n  @media(max-width:900px){ .hp-mockup-hero-row{ flex-direction:column; } .hp-cat-sidebar{ width:100%; } .hp-mockup-hero-copy{ width:80%; } }\r\n  .hp-trust-row{ background:#F0F2F6; border-radius:8px; padding:16px 24px; display:flex; justify-content:space-between; flex-wrap:wrap; gap:14px; }\r\n  .hp-trust-item{ display:flex; align-items:center; gap:10px; }\r\n  .hp-trust-item-icon{ color:var(--navy); font-size:18px; }\r\n  .hp-trust-item-title{ font-size:13px; font-weight:700; color:var(--navy); }\r\n  .hp-trust-item-sub{ font-size:11.5px; color:#777; }\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div id=\"splashScreen\">\r\n  <img decoding=\"async\" src=\"https:\/\/app.builders24.net\/assets\/splash.jpg\" alt=\"Builders24\">\r\n<\/div>\r\n<script>\r\n  \/\/ Show once per session, not on every internal navigation\/reload \u2014\r\n  \/\/ a fresh session (new tab, or app relaunched from the home screen icon) sees it again.\r\n  (function(){\r\n    var splash = document.getElementById('splashScreen');\r\n    if (sessionStorage.getItem('b24_splash_shown')) {\r\n      splash.style.display = 'none';\r\n      return;\r\n    }\r\n    document.body.classList.add('splash-active');\r\n    sessionStorage.setItem('b24_splash_shown', '1');\r\n    setTimeout(function(){\r\n      splash.classList.add('fade-out');\r\n      document.body.classList.remove('splash-active');\r\n      setTimeout(function(){ splash.style.display = 'none'; }, 650);\r\n    }, 2500);\r\n  })();\r\n<\/script>\r\n<div class=\"app\">\r\n\r\n\r\n  <!-- ================= HERO (with quote card) ================= -->\r\n  <section class=\"bc-hero\">\r\n    <div class=\"bc-hero-bg\">\r\n      <img decoding=\"async\" src=\"https:\/\/app.builders24.net\/assets\/builders24%20home.png\" alt=\"\">\r\n      <div class=\"bc-hero-gradient\"><\/div>\r\n    <\/div>\r\n\r\n    <div class=\"bc-hero-inner\">\r\n      <h1 class=\"bc-hero-title\">Builders24, Everything You Need To Build, Renovate, <span class=\"accent\">And Move Goods Across Zimbabwe<\/span><\/h1>\r\n      <p class=\"bc-hero-sub\">Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe. We provide construction, renovation and trade services in Zimbabwe, supply wholesale goods to Zimbabwean businesses, and offer import, export and cross-border logistics from Zimbabwe through Zimbabwean and international suppliers.<\/p>\r\n      <div class=\"bc-trust-row\">\r\n        <div class=\"bc-trust-item\"><span class=\"diamond\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#F0A500\" stroke-width=\"2.5\"><path d=\"M12 2l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V5z\"\/><\/svg><\/span><span>Quality<br>Guaranteed<\/span><\/div>\r\n        <div class=\"bc-trust-item\"><span class=\"diamond\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#F0A500\" stroke-width=\"2.5\"><path d=\"M12 2l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V5z\"\/><\/svg><\/span><span>Nationwide<br>Delivery<\/span><\/div>\r\n        <div class=\"bc-trust-item\"><span class=\"diamond\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#F0A500\" stroke-width=\"2.5\"><path d=\"M12 2l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V5z\"\/><\/svg><\/span><span>Trusted by<br>Pros<\/span><\/div>\r\n        <div class=\"bc-trust-item\"><span class=\"diamond\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#F0A500\" stroke-width=\"2.5\"><path d=\"M12 2l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V5z\"\/><\/svg><\/span><span>Secure<br>Payments<\/span><\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"bc-tabbar\" id=\"hero2Tabs\">\r\n      <div class=\"bc-tab active\" data-tab=\"shop\">Shop Now<\/div>\r\n      <div class=\"bc-tab\" data-tab=\"vehicles\">Browse Vehicles<\/div>\r\n      <div class=\"bc-tab\" data-tab=\"building\">Building Services<\/div>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <div class=\"filter-card\" id=\"filterCard\">\r\n    <div id=\"filterFields\" class=\"filter-fields\"><\/div>\r\n    <button type=\"button\" class=\"filter-submit-btn\" id=\"filterSubmitBtn\"><\/button>\r\n  <\/div>\r\n\r\n  <!-- ================= NEW HOMEPAGE SECTIONS ================= -->\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Today's Featured Deals<\/div>\r\n        <div class=\"hp-section-sub\">Top quality products at unbeatable prices. Limited time only.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?filter=deals\" class=\"hp-viewall\">View All Deals \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-product-grid\" id=\"featuredDealsGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <!-- ================= MOCKUP HERO + SIDEBAR (stitched in as-is) ================= -->\r\n  <div class=\"hp-mockup-hero-row\">\r\n    <div class=\"hp-cat-sidebar\" id=\"mockupCatSidebar\">\r\n      <div class=\"hp-cat-sidebar-title\">Shop by Category<\/div>\r\n    <\/div>\r\n    <div class=\"hp-mockup-hero\">\r\n      <img decoding=\"async\" src=\"https:\/\/app.builders24.net\/assets\/hero.png\" alt=\"Quality Materials for Every Project\">\r\n      <div class=\"hp-mockup-hero-gradient\"><\/div>\r\n      <div class=\"hp-mockup-hero-copy\">\r\n        <div class=\"hp-mockup-hero-eyebrow\">BUILD SMARTER<\/div>\r\n        <div class=\"hp-mockup-hero-title\">Quality Materials for Every Project<\/div>\r\n        <div class=\"hp-mockup-hero-sub\">From home renovations to large-scale builds, get the tools, materials and supplies you need \u2014 delivered across Zimbabwe.<\/div>\r\n        <a href=\"https:\/\/app.builders24.net\/retail\/shop.html\" class=\"hp-mockup-hero-btn\">Shop Now \u2192<\/a>\r\n      <\/div>\r\n      <div class=\"hp-mockup-hero-badge\">\r\n        <div class=\"hp-mockup-hero-badge-top\">UP TO<\/div>\r\n        <div class=\"hp-mockup-hero-badge-pct\">40%<\/div>\r\n        <div class=\"hp-mockup-hero-badge-off\">OFF<\/div>\r\n        <div class=\"hp-mockup-hero-badge-sub\">SELECTED ITEMS<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-trust-row\" id=\"trustRow\"><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-category-banners\" id=\"categoryBannersRow\"><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Best Sellers<\/div>\r\n        <div class=\"hp-section-sub\">Our most popular products, trusted by thousands.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?filter=bestsellers\" class=\"hp-viewall\">View All Best Sellers \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-product-grid\" id=\"bestSellersGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <img decoding=\"async\" src=\"https:\/\/app.builders24.net\/assets\/home-services.png\" alt=\"Trusted Home Services. Done Right.\" class=\"hp-full-banner\" onclick=\"location.href='https:\/\/app.builders24.net\/build\/local-services.html'\" style=\"cursor:pointer;\">\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\" id=\"shipUsaSection\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Shipped from USA<\/div>\r\n        <div class=\"hp-section-sub\">Latest arrivals shipping from the USA.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?shipped_from=usa\" class=\"hp-viewall\">View All \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-scroll-row\" id=\"shipUsaGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\" id=\"shipChinaSection\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Shipped from China<\/div>\r\n        <div class=\"hp-section-sub\">Latest arrivals shipping from China.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?shipped_from=china\" class=\"hp-viewall\">View All \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-scroll-row\" id=\"shipChinaGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\" id=\"shipSaSection\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Shipped from Zimbabwe<\/div>\r\n        <div class=\"hp-section-sub\">Latest arrivals shipping from Zimbabwe.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?shipped_from=south-africa\" class=\"hp-viewall\">View All \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-scroll-row\" id=\"shipSaGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\" id=\"vehiclesRowSection\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Latest Vehicles<\/div>\r\n        <div class=\"hp-section-sub\">The newest vehicles added to Builders24 Auto.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/auto\/vehicles\/\" class=\"hp-viewall\">View All \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-scroll-row\" id=\"vehiclesRowGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-bulk-banner\">\r\n      <img decoding=\"async\" src=\"https:\/\/app.builders24.net\/assets\/support.png\" alt=\"\" class=\"hp-bulk-bg\">\r\n      <div class=\"hp-bulk-overlay\"><\/div>\r\n      <div class=\"hp-bulk-copy\">\r\n        <div class=\"hp-bulk-title\">Building or Renovating?<\/div>\r\n        <div class=\"hp-bulk-sub\">Builders24 has a network of thousands of skilled construction services partners across Zimbabwe.<\/div>\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html\" class=\"hp-bulk-cta\">Get a Free Quote \u2192<\/a>\r\n      <\/div>\r\n      <div class=\"hp-bulk-features\">\r\n        <div class=\"hp-bulk-feature\">\ud83d\udcb2 Competitive Pricing<\/div>\r\n        <div class=\"hp-bulk-feature\">\ud83d\udce6 Volume Discounts<\/div>\r\n        <div class=\"hp-bulk-feature\">\ud83d\udc64 Dedicated Account Manager<\/div>\r\n        <div class=\"hp-bulk-feature\">\ud83d\ude9a Flexible Delivery<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"hp-section\">\r\n    <div class=\"hp-section-head\">\r\n      <div>\r\n        <div class=\"hp-section-title\">Popular Searches<\/div>\r\n        <div class=\"hp-section-sub\">Our most popular products, trusted by thousands.<\/div>\r\n      <\/div>\r\n      <a href=\"https:\/\/app.builders24.net\/retail\/shop.html?filter=popular\" class=\"hp-viewall\">View All \u2192<\/a>\r\n    <\/div>\r\n    <div class=\"hp-product-grid\" id=\"popularSearchesGrid\"><div class=\"hp-skel\"><\/div><\/div>\r\n  <\/div>\r\n\r\n  <!-- ================= BUILDING SERVICES \u2014 Sectors (real, from Thomas's uploaded design) ================= -->\r\n  <section class=\"sectors-section\" id=\"sectorsSection\" style=\"display:none;\">\r\n    <div class=\"sectors-bg\"><\/div>\r\n    <div class=\"sectors-orb\"><\/div>\r\n    <div class=\"sectors-orb2\"><\/div>\r\n    <div class=\"sectors-inner\">\r\n\r\n      <span class=\"sectors-label\">Our Sectors<\/span>\r\n      <h2 class=\"sectors-heading\">Built For Every Sector,<br><span>Across Zimbabwe<\/span><\/h2>\r\n      <p class=\"sectors-sub\">Builders24 operates across 8 sectors in Zimbabwe, delivering construction, industrial, commercial, residential, agricultural, import, export and supply services to businesses, developers, government and communities in Harare, Bulawayo, Manicaland, Midlands and every other province.<\/p>\r\n\r\n      <div class=\"sectors-grid\">\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Residential%20Construction\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1600585154340-be6161a56a0c?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Residential<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-home-2\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 01<\/div>\r\n            <div class=\"sectors-card-title\">Residential Construction<\/div>\r\n            <div class=\"sectors-card-desc\">New homes, renovations, extensions, roofing, plumbing, electrical and home improvements.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Commercial%20Construction\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1486406146926-c627a92ad1ab?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Commercial<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-building-skyscraper\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 02<\/div>\r\n            <div class=\"sectors-card-title\">Commercial Construction<\/div>\r\n            <div class=\"sectors-card-desc\">Offices, retail parks, hotels, restaurants, fit-outs and commercial developments.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Industrial%20Construction\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1581094794329-c8112a89af12?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Industrial<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-building-factory-2\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 03<\/div>\r\n            <div class=\"sectors-card-title\">Industrial Construction<\/div>\r\n            <div class=\"sectors-card-desc\">Warehouses, factories, logistics hubs, steel structures and industrial facilities.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Infrastructure%20%26%20Civil\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1477959858617-67f85cf4f1df?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Infrastructure<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-road\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 04<\/div>\r\n            <div class=\"sectors-card-title\">Infrastructure &amp; Civil<\/div>\r\n            <div class=\"sectors-card-desc\">Roads, water systems, civil engineering, drainage and public infrastructure.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Agriculture%20%26%20Agritech\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1416879595882-3373a0480b5b?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Agriculture<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-tractor\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 05<\/div>\r\n            <div class=\"sectors-card-title\">Agriculture &amp; Agritech<\/div>\r\n            <div class=\"sectors-card-desc\">Drone spraying, precision agritech, chemical supplies, harvesting and irrigation.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Import%20%26%20Sourcing\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1494412574643-ff11b0a5c1c3?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Import<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-ship\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 06<\/div>\r\n            <div class=\"sectors-card-title\">Import &amp; Sourcing<\/div>\r\n            <div class=\"sectors-card-desc\">Factory-direct procurement, freight, customs clearance and last-mile delivery across Zimbabwe.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Export%20%26%20Trade\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1568992687947-868a62a9f521?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Export<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-world\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 07<\/div>\r\n            <div class=\"sectors-card-title\">Export &amp; Trade<\/div>\r\n            <div class=\"sectors-card-desc\">Zimbabwean produce, commodities and manufactured goods exported to international buyers worldwide.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html?subcategory=Supplies%20%26%20Equipment\" class=\"sectors-card\">\r\n          <div class=\"sectors-card-img\" style=\"background-image:url('https:\/\/images.unsplash.com\/photo-1504307651254-35680f356dfd?w=700&q=80')\"><\/div>\r\n          <div class=\"sectors-card-overlay\"><\/div>\r\n          <div class=\"sectors-card-topbar\"><\/div>\r\n          <div class=\"sectors-depth-badge\">Supplies<\/div>\r\n          <div class=\"sectors-card-body\">\r\n            <div class=\"sectors-card-icon-wrap\"><i class=\"ti ti-package\"><\/i><\/div>\r\n            <div class=\"sectors-card-sector\">Sector 08<\/div>\r\n            <div class=\"sectors-card-title\">Supplies &amp; Equipment<\/div>\r\n            <div class=\"sectors-card-desc\">Machinery, tools, hardware, building materials and home goods \u2014 factory-direct B2B supply.<\/div>\r\n            <span class=\"sectors-card-cta\"><i class=\"ti ti-arrow-right\"><\/i>Explore<\/span>\r\n          <\/div>\r\n        <\/a>\r\n\r\n      <\/div>\r\n\r\n      <div class=\"sectors-bottom-row\">\r\n        <p class=\"sectors-seo-text\">Builders24 delivers construction, trade and supply services across <strong>Zimbabwe<\/strong> \u2014 serving residential homeowners, commercial developers, industrial operators, agricultural businesses, importers, exporters and B2B buyers, with cross-border logistics from Zimbabwe into the wider SADC region.<\/p>\r\n        <a href=\"https:\/\/app.builders24.net\/build\/request-quote.html\" class=\"sectors-btn-all\">Get a Quote <i class=\"ti ti-arrow-right\"><\/i><\/a>\r\n      <\/div>\r\n\r\n    <\/div>\r\n  <\/section>\r\n\r\n\r\n\r\n<\/div>\r\n\r\n<div class=\"cart-drawer-overlay\" id=\"cartDrawerOverlay\">\r\n  <div class=\"cart-drawer\">\r\n    <div class=\"cd-head\">\r\n      <h3>Your Cart<\/h3>\r\n      <div class=\"cd-head-right\">\r\n        <button class=\"cd-clear-btn\" id=\"cdClearBtn\">Clear Cart<\/button>\r\n        <button class=\"cd-close\" id=\"cdCloseBtn\" aria-label=\"Close cart\">\r\n          <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0D1220\" stroke-width=\"2.4\" stroke-linecap=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"\/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"\/><\/svg>\r\n        <\/button>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"cd-body\" id=\"cdBody\">\r\n      <div class=\"cd-empty\">Loading&hellip;<\/div>\r\n    <\/div>\r\n    <div class=\"cd-foot\" id=\"cdFoot\" style=\"display:none;\">\r\n      <div class=\"cd-subtotal-row\"><span>Subtotal<\/span><span id=\"cdSubtotal\">$0.00<\/span><\/div>\r\n      <button class=\"cd-checkout-btn\" onclick=\"location.href='https:\/\/app.builders24.net\/retail\/checkout.html'\">Checkout<\/button>\r\n      <button class=\"cd-view-cart-btn\" onclick=\"location.href='https:\/\/app.builders24.net\/retail\/cart.html'\">View Full Cart<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@supabase\/supabase-js@2\"><\/script>\r\n<script src=\"https:\/\/app.builders24.net\/guest-cart.js\"><\/script>\r\n<script src=\"https:\/\/app.builders24.net\/b24app.js\"><\/script>\r\n<script>\r\n  \/\/ ===== SLIDE-IN CART DRAWER =====\r\n  \/\/ Uses the same real getCartItemsUnified()\/products lookup as\r\n  \/\/ cart.html itself, not a separate\/duplicated data source.\r\n  function esc_cd(s){ return (s||'').toString().replace(\/[&<>\"']\/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c])); }\r\n\r\n  async function openCartDrawer(){\r\n    document.getElementById('cartDrawerOverlay').classList.add('open');\r\n    await renderCartDrawer();\r\n  }\r\n  function closeCartDrawer(){\r\n    document.getElementById('cartDrawerOverlay').classList.remove('open');\r\n  }\r\n\r\n  async function renderCartDrawer(){\r\n    const body = document.getElementById('cdBody');\r\n    const foot = document.getElementById('cdFoot');\r\n    body.innerHTML = '<div class=\"cd-empty\">Loading&hellip;<\/div>';\r\n\r\n    let items = [];\r\n    try { items = await getCartItemsUnified(); } catch (e) { items = []; }\r\n\r\n    if (!items.length) {\r\n      body.innerHTML = `\r\n        <div class=\"cd-empty\">\r\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\"\/><path d=\"M17 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\"\/><path d=\"M17 17h-11v-14h-2\"\/><path d=\"M6 5l14 1l-1 7h-13\"\/><\/svg>\r\n          <p>Your cart is empty.<\/p>\r\n        <\/div>`;\r\n      foot.style.display = 'none';\r\n      return;\r\n    }\r\n\r\n    try {\r\n      const ids = items.map(i => i.product_id);\r\n      const { data: products, error } = await sb.from('products')\r\n        .select('id,name,price,currency,images')\r\n        .in('id', ids);\r\n      if (error || !products) throw error || new Error('no products');\r\n\r\n      const byId = {};\r\n      products.forEach(p => { byId[p.id] = p; });\r\n\r\n      let subtotal = 0;\r\n      let currency = 'USD';\r\n      body.innerHTML = items.filter(i => byId[i.product_id]).map(i => {\r\n        const p = byId[i.product_id];\r\n        const img = (Array.isArray(p.images) && p.images.length) ? p.images[0] : null;\r\n        subtotal += p.price * i.quantity;\r\n        currency = p.currency || currency;\r\n        return `\r\n          <div class=\"cd-item\">\r\n            <div class=\"cd-thumb\">${img ? `<img decoding=\"async\" src=\"${esc_cd(img)}\" alt=\"\" referrerpolicy=\"no-referrer\" onerror=\"this.remove()\">` : ''}<\/div>\r\n            <div style=\"flex:1;min-width:0;\">\r\n              <div class=\"cd-item-name\">${esc_cd(p.name)}<\/div>\r\n              <div class=\"cd-item-price\">${fmtNative(p.price, p.currency)}<\/div>\r\n              <div class=\"cd-item-qty-row\">\r\n                <button class=\"cd-qty-btn\" onclick=\"cdChangeQty('${i.item_id}', ${i.quantity}, -1)\">&minus;<\/button>\r\n                <span class=\"cd-qty-val\">${i.quantity}<\/span>\r\n                <button class=\"cd-qty-btn\" onclick=\"cdChangeQty('${i.item_id}', ${i.quantity}, 1)\">+<\/button>\r\n                <button class=\"cd-item-remove\" onclick=\"cdRemoveItem('${i.item_id}')\">Remove<\/button>\r\n              <\/div>\r\n            <\/div>\r\n          <\/div>`;\r\n      }).join('');\r\n\r\n      document.getElementById('cdSubtotal').textContent = fmtNative(subtotal, currency);\r\n      foot.style.display = 'block';\r\n    } catch (e) {\r\n      body.innerHTML = '<div class=\"cd-empty\">Could not load your cart right now.<\/div>';\r\n      foot.style.display = 'none';\r\n    }\r\n  }\r\n\r\n  async function cdChangeQty(itemId, currentQty, delta){\r\n    await updateGuestCartQty(itemId, currentQty + delta);\r\n    await renderCartDrawer();\r\n  }\r\n  async function cdRemoveItem(itemId){\r\n    await removeFromGuestCart(itemId);\r\n    await renderCartDrawer();\r\n  }\r\n\r\n  document.getElementById('cartDrawerOverlay').addEventListener('click', (e) => {\r\n    if (e.target.id === 'cartDrawerOverlay') closeCartDrawer();\r\n  });\r\n  document.getElementById('cdCloseBtn').addEventListener('click', closeCartDrawer);\r\n  document.getElementById('cdClearBtn').addEventListener('click', async () => {\r\n    if (!confirm('Clear your entire cart?')) return;\r\n    await clearCart();\r\n    await renderCartDrawer();\r\n  });\r\n  document.querySelectorAll('a[href=\"\/retail\/cart.html\"]').forEach(link => {\r\n    link.addEventListener('click', (e) => {\r\n      e.preventDefault();\r\n      openCartDrawer();\r\n    });\r\n  });\r\n\r\n  function esc(s){ return (s||'').toString().replace(\/[&<>\"']\/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c])); }\r\n\r\n  \/\/ ===== LOCATION (delivery-location picker UX, unchanged) =====\r\n  const LOCATIONS = window.B24_LOCATIONS || [];\r\n  \/\/ Single real source: header.js sets window.B24_LOCATIONS (all 54\r\n  \/\/ African countries), loaded before this script now runs. Local\r\n  \/\/ duplicate array removed \u2014 this page no longer keeps its own copy.\r\n\r\n  \/\/ ===== REAL CURRENCY SYSTEM =====\r\n  \/\/ Live rates from the real currencies table - same pattern\r\n  \/\/ proven on the shop page, not the fake static table this page\r\n  \/\/ originally shipped with.\r\n  \/\/ _ratesToUsd \/ _customerCurrency \/ _currencySymbols now come\r\n  \/\/ from b24app.js (shared) instead of being redeclared here.\r\n\r\n  async function loadExchangeRates() {\r\n    if (_ratesToUsd) return _ratesToUsd;\r\n    _ratesToUsd = {};\r\n    _currencySymbols = {};\r\n    try {\r\n      const { data: codes } = await sb.from('currency_codes').select('code, symbol');\r\n      (codes || []).forEach(c => { _currencySymbols[c.code] = c.symbol; });\r\n    } catch (e) {}\r\n    try {\r\n      const { data: rates } = await sb.from('currencies').select('currency_code, rate_to_usd').eq('is_active', true);\r\n      (rates || []).forEach(r => {\r\n        if (r.currency_code && r.rate_to_usd && !(r.currency_code in _ratesToUsd)) {\r\n          _ratesToUsd[r.currency_code] = r.rate_to_usd;\r\n        }\r\n      });\r\n    } catch (e) {}\r\n    return _ratesToUsd;\r\n  }\r\n\r\n  async function getCustomerCurrency() {\r\n    if (_customerCurrency) return _customerCurrency;\r\n    try {\r\n      const { data: { session } } = await sb.auth.getSession();\r\n      _customerCurrency = 'USD'; return _customerCurrency;\r\n      if (!session) { _customerCurrency = 'USD'; return _customerCurrency; }\r\n      const { data } = await sb.from('app_users').select('preferred_currency').eq('id', session.user.id).maybeSingle();\r\n      _customerCurrency = (data && data.preferred_currency) || 'USD';\r\n    } catch (e) { _customerCurrency = 'USD'; }\r\n    return _customerCurrency;\r\n  }\r\n\r\n  async function setCustomerCurrency(code) {\r\n    return; \/* Zimbabwe localisation: USD only *\/\r\n    _customerCurrency = code;\r\n    try {\r\n      const { data: { session } } = await sb.auth.getSession();\r\n      if (session) await sb.from('app_users').update({ preferred_currency: code }).eq('id', session.user.id);\r\n    } catch (e) {}\r\n  }\r\n\r\n  \/\/ Guest location detection is now shared, site-wide, in b24app.js\r\n  \/\/ (getCustomerDefaultAddress()\/detectGuestLocation()) \u2014 this wrapper\r\n  \/\/ just applies the shared function's result to this page's own appState.\r\n  async function detectGuestLocationForPage(){\r\n    const { matchIdx, isGuest } = await detectGuestLocation();\r\n    if (matchIdx !== -1) {\r\n      appState.locationIndex = matchIdx;\r\n    }\r\n  }\r\n\r\n  async function initProfileMenu(){\r\n    const circle = document.getElementById('headerAvatarCircle');\r\n    const badge = document.querySelector('.avatar-plus-badge');\r\n    const dropdown = document.getElementById('profileDropdown');\r\n    const trigger = document.getElementById('profileMenuTrigger');\r\n\r\n    \/\/ Listener attaches unconditionally, regardless of login state \u2014 this was the bug:\r\n    \/\/ it previously lived after a guest-path \"return\", so it never ran for signed-out users.\r\n    trigger.addEventListener('click', (e) => {\r\n      e.stopPropagation();\r\n      dropdown.classList.toggle('open');\r\n    });\r\n    document.addEventListener('click', () => dropdown.classList.remove('open'));\r\n\r\n    let session = null;\r\n    try {\r\n      const { data } = await sb.auth.getSession();\r\n      session = data.session;\r\n    } catch (e) { console.error('profile menu session check failed', e); }\r\n\r\n    if (!session) {\r\n      \/\/ Guest: generic icon + plus badge, dropdown offers Login only\r\n      if (badge) badge.style.display = 'flex';\r\n      dropdown.innerHTML = `<a class=\"dropdown-item\" href=\"https:\/\/app.builders24.net\/login.html\">Login<\/a>`;\r\n      return;\r\n    }\r\n\r\n    try {\r\n      const { data: profile } = await sb.from('app_users').select('full_name, avatar_url').eq('id', session.user.id).maybeSingle();\r\n      const hasPhoto = profile && profile.avatar_url;\r\n      if (hasPhoto) {\r\n        circle.innerHTML = `<img decoding=\"async\" src=\"${esc(profile.avatar_url)}\" alt=\"Profile picture\">`;\r\n        if (badge) badge.style.display = 'none';\r\n      } else {\r\n        \/\/ Logged in but no photo uploaded yet: same generic icon + plus badge as the guest state\r\n        if (badge) badge.style.display = 'flex';\r\n      }\r\n      dropdown.innerHTML = `\r\n        <a class=\"dropdown-item\" href=\"https:\/\/app.builders24.net\/retail\/my-account.html\">My Account<\/a>\r\n        <a class=\"dropdown-item\" href=\"https:\/\/app.builders24.net\/retail\/my-profile.html\">Settings<\/a>\r\n        <div class=\"dropdown-divider\"><\/div>\r\n        <button class=\"dropdown-item danger\" id=\"signOutBtn\" type=\"button\">Logout<\/button>`;\r\n      document.getElementById('signOutBtn').addEventListener('click', async () => {\r\n        await sb.auth.signOut();\r\n        location.href = 'https:\/\/app.builders24.net\/index.html';\r\n      });\r\n    } catch (e) { console.error('profile menu init failed', e); }\r\n  }\r\n\r\n  function convertAmount(amount, fromCurrency, toCurrency) {\r\n    if (!_ratesToUsd) return amount;\r\n    const fromRate = _ratesToUsd[fromCurrency];\r\n    const toRate = _ratesToUsd[toCurrency];\r\n    if (!fromRate || !toRate) return amount;\r\n    return (amount \/ fromRate) * toRate;\r\n  }\r\n\r\n  function fmtNative(amount, currency) {\r\n    const sym = (_currencySymbols && _currencySymbols[currency]) || { USD: '$' }[currency] || (currency ? currency + ' ' : '$');\r\n    return sym + Number(amount || 0).toLocaleString('en', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\r\n  }\r\n\r\n  function fmtConverted(amount, fromCurrency, toCurrency) {\r\n    const from = fromCurrency || 'USD';\r\n    const to = toCurrency || from;\r\n    if (from === to || !_ratesToUsd) return fmtNative(amount, from);\r\n    return fmtNative(convertAmount(amount, from, to), to);\r\n  }\r\n\r\n  let appState = { locationIndex: 0, currency: 'USD' };\r\n\r\n  function formatNumber(n, decimals){\r\n    return n.toLocaleString('en-US', {minimumFractionDigits:decimals, maximumFractionDigits:decimals});\r\n  }\r\n  function renderPricesStatic(){\r\n    \/\/ Static marketing thresholds only - real product prices are\r\n    \/\/ rendered directly via fmtNative\/fmtConverted in dealCardHtml.\r\n    const sym = (_currencySymbols && _currencySymbols[appState.currency]) || '$';\r\n    document.querySelectorAll('[data-zar]').forEach(el => {\r\n      const zar = parseFloat(el.getAttribute('data-zar'));\r\n      const converted = convertAmount(zar, 'USD', appState.currency);\r\n      const decimals = ['NGN','KES','TZS','UGX','AOA','CDF','MGA','MWK'].includes(appState.currency) ? 0 : 2;\r\n      const format = el.getAttribute('data-format') || 'plain';\r\n      if (format === 'split'){\r\n        const parts = formatNumber(converted, decimals).split('.');\r\n        el.innerHTML = decimals > 0\r\n          ? `${sym}${parts[0]}<sup>${parts[1]}<\/sup>`\r\n          : `${sym}${parts[0]}`;\r\n      } else if (format === 'threshold'){\r\n        el.textContent = `${sym}${formatNumber(Math.round(converted), 0)}`;\r\n      } else if (format === 'compact-plus'){\r\n        el.textContent = `${sym}${formatNumber(Math.round(converted), 0)}+`;\r\n      } else {\r\n        el.textContent = `${sym}${formatNumber(converted, decimals)}`;\r\n      }\r\n    });\r\n    const badge = document.getElementById('currencyBadgeText');\r\n    if (badge) badge.textContent = appState.currency;\r\n  }\r\n  function updateDeliverLabel(){\r\n    const label = _customerDefaultAddressLabel || LOCATIONS[appState.locationIndex].city;\r\n    document.querySelectorAll('.deliver-city-text').forEach(el => el.textContent = label);\r\n  }\r\n\r\n  function closeUtilDropdowns(){\r\n    document.getElementById('deliverDropdown')?.classList.remove('open');\r\n    document.getElementById('currencyDropdown')?.classList.remove('open');\r\n  }\r\n  \/\/ Re-renders every product\/vehicle card currently on screen in the\r\n  \/\/ newly-selected currency \u2014 the Featured grid (loadHomeProducts) and\r\n  \/\/ whichever tab result set is active (loadShopMixedGrid for 'shop',\r\n  \/\/ otherwise the tab's own cfg.action). 'building' has no priced cards.\r\n  async function refreshAllPrices(){\r\n    renderPricesStatic();\r\n    \/\/ The home sections live in the hero-tabs IIFE below, which exposes\r\n    \/\/ window.b24RefreshHomeSections so this scope can re-render them.\r\n    const tasks = [];\r\n    if (window.b24RefreshHomeSections) tasks.push(window.b24RefreshHomeSections());\r\n    try { await Promise.all(tasks); } catch (e) { console.warn('refreshAllPrices:', e.message); }\r\n  }\r\n  \/\/ header.js's shared currency\/location modal already checks for\r\n  \/\/ window.renderPrices after a currency change and calls it if present\r\n  \/\/ \u2014 expose our more complete refresh (re-formats prices AND re-fetches\r\n  \/\/ the active product\/vehicle grid in the new currency) under that\r\n  \/\/ exact name so the existing hook actually does something.\r\n  window.renderPrices = refreshAllPrices;\r\n  function renderDeliverDropdown(){\r\n    const el = document.getElementById('deliverDropdown');\r\n    if (!el) return;\r\n    el.innerHTML = LOCATIONS.map(l => `<div class=\"bc-util-item\" data-city=\"${esc(l.city)}\" data-currency=\"${l.currency}\">${esc(l.city)}<\/div>`).join('');\r\n    el.querySelectorAll('.bc-util-item').forEach(item => {\r\n      item.addEventListener('click', async () => {\r\n        const city = item.dataset.city, currency = item.dataset.currency;\r\n        document.querySelectorAll('.deliver-city-text').forEach(t => t.textContent = city);\r\n        await setCustomerCurrency(currency);\r\n        appState.currency = currency;\r\n        const badge = document.getElementById('currencyBadgeText');\r\n        if (badge) badge.textContent = currency;\r\n        closeUtilDropdowns();\r\n        await refreshAllPrices();\r\n      });\r\n    });\r\n  }\r\n  function renderCurrencyDropdown(){\r\n    if (!_ratesToUsd) return;\r\n    const el = document.getElementById('currencyDropdown');\r\n    if (!el) return;\r\n    const codes = Object.keys(_ratesToUsd).sort();\r\n    el.innerHTML = codes.map(code => `<div class=\"bc-util-item${code === appState.currency ? ' selected' : ''}\" data-code=\"${code}\">${code}<\/div>`).join('');\r\n    el.querySelectorAll('.bc-util-item').forEach(item => {\r\n      item.addEventListener('click', async () => {\r\n        const code = item.dataset.code;\r\n        await setCustomerCurrency(code);\r\n        appState.currency = code;\r\n        const badge = document.getElementById('currencyBadgeText');\r\n        if (badge) badge.textContent = code;\r\n        closeUtilDropdowns();\r\n        renderCurrencyDropdown();\r\n        await refreshAllPrices();\r\n      });\r\n    });\r\n  }\r\n  document.addEventListener('click', closeUtilDropdowns);\r\n\r\n  \/\/ ===== REAL FEATURED PRODUCTS (matches shop.html's fixed card logic:\r\n  \/\/ shopper's selected currency shown prominently, native currency as\r\n  \/\/ small secondary note, working wishlist) =====\r\n  let _cardQty = {};\r\n  \/\/ Real product URL pattern, matching the actual .htaccess rewrite rule\r\n  \/\/ in app\/shop\/product\/ (routes \/shop\/product\/{uuid}-{slug} to\r\n  \/\/ product.php?path={uuid}-{slug}) - NOT a static product.html file.\r\n  function productUrl(p){\r\n    return 'https:\/\/app.builders24.net\/retail\/product\/' + p.slug;\r\n  }\r\n\r\n  \/\/ Real star rating \u2014 full\/half\/empty stars from a real 0-5 avg_rating.\r\n  function starsHtml(avg) {\r\n    const rating = Number(avg) || 0;\r\n    let out = '';\r\n    for (let i = 1; i <= 5; i++) {\r\n      if (rating >= i) out += '<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"#F0A500\"><path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\/><\/svg>';\r\n      else if (rating >= i - 0.5) out += '<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\"><defs><linearGradient id=\"half' + i + '\"><stop offset=\"50%\" stop-color=\"#F0A500\"\/><stop offset=\"50%\" stop-color=\"#E3E8F0\"\/><\/linearGradient><\/defs><path fill=\"url(#half' + i + ')\" d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\/><\/svg>';\r\n      else out += '<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"#E3E8F0\"><path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\/><\/svg>';\r\n    }\r\n    return '<span class=\"stars\">' + out + '<\/span>';\r\n  }\r\n\r\n  \/\/ Real rating, from whichever source actually has data: real customer\r\n  \/\/ reviews first, then the rating imported from the original source\r\n  \/\/ site. If neither exists, show nothing rather than a fake 0-star row.\r\n  function ratingRowHtml(p) {\r\n    if (p.review_count > 0) {\r\n      return `<div class=\"card-rating\">${starsHtml(p.avg_rating)}<span class=\"card-rating-count\">(${p.review_count})<\/span><\/div>`;\r\n    }\r\n    if (p.source_rating != null && p.source_rating_scale) {\r\n      const normalized = (Number(p.source_rating) \/ Number(p.source_rating_scale)) * 5;\r\n      const countLabel = p.source_review_count > 0 ? `(${p.source_review_count})` : '';\r\n      return `<div class=\"card-rating\">${starsHtml(normalized)}<span class=\"card-rating-count\">${countLabel}<\/span><\/div>`;\r\n    }\r\n    return `<div class=\"card-rating\">${starsHtml(0)}<span class=\"card-rating-count\">No reviews yet<\/span><\/div>`;\r\n  }\r\n\r\n  function productCardHtml(p, myCurrency, sellerNames){\r\n    const img = (Array.isArray(p.images) && p.images.length) ? p.images[0] : null;\r\n    const showEstimate = p.currency !== myCurrency;\r\n    const hasSale = p.sale_price && p.price && p.sale_price < p.price;\r\n    const discountPct = hasSale ? Math.round((1 - p.sale_price \/ p.price) * 100) : 0;\r\n    const displayPrice = hasSale ? p.sale_price : p.price;\r\n    const outOfStock = p.track_inventory && (p.stock_quantity || 0) <= 0;\r\n    const sellerName = sellerNames && p.org_id && sellerNames[p.org_id] ? sellerNames[p.org_id] : null;\r\n    _cardQty[p.id] = _cardQty[p.id] || 1;\r\n    return `\r\n      <div class=\"product-card\" data-product-id=\"${p.id}\">\r\n        ${hasSale ? `<span class=\"discount-badge\">-${discountPct}%<\/span>` : (p.is_featured ? `<span class=\"featured-badge\">Featured<\/span>` : '')}\r\n        <div class=\"card-top-row\" style=\"justify-content:flex-end;\"><button class=\"wish-btn\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0D1220\" stroke-width=\"1.8\"><path d=\"M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21l7.8-7.6 1-1a5.5 5.5 0 0 0 0-7.8Z\"\/><\/svg><\/button><\/div>\r\n        <a href=\"${productUrl(p)}\" style=\"display:block;\">\r\n          <div class=\"card-image\">\r\n            ${img\r\n              ? `<img decoding=\"async\" src=\"${esc(img)}\" alt=\"${esc(p.name)}\" referrerpolicy=\"no-referrer\" onerror=\"this.onerror=null;this.removeAttribute('src');this.style.background='#EEF0F3'\" style=\"width:100%;height:100%;object-fit:cover;\">`\r\n              : `<svg viewBox=\"0 0 150 150\"><rect width=\"150\" height=\"150\" fill=\"#EEF0F3\"\/><\/svg>`}\r\n          <\/div>\r\n          ${sellerName ? `<div class=\"card-seller\">${esc(sellerName)}<\/div>` : ''}\r\n          <p class=\"card-name\">${esc(p.name)}<\/p>\r\n          ${ratingRowHtml(p)}\r\n        <\/a>\r\n        <div class=\"card-price-row\">\r\n          <span class=\"card-price\">${fmtConverted(displayPrice, p.currency, myCurrency)}<\/span>\r\n          ${hasSale ? `<span class=\"card-price-strike\">${fmtConverted(p.price, p.currency, myCurrency)}<\/span>` : ''}\r\n        <\/div>\r\n        ${showEstimate ? `<div class=\"card-secondary-prices\">Listed at ${fmtNative(displayPrice, p.currency)}<\/div>` : ''}\r\n        <div class=\"card-stock ${outOfStock ? 'out' : 'in'}\">${outOfStock ? 'Out of Stock' : 'In Stock'}<\/div>\r\n        <div class=\"card-bottom-row\">\r\n          <div class=\"qty-stepper\">\r\n            <button type=\"button\" onclick=\"changeCardQty('${p.id}',-1,this)\">&minus;<\/button>\r\n            <span id=\"qty-${p.id}\">${_cardQty[p.id]}<\/span>\r\n            <button type=\"button\" onclick=\"changeCardQty('${p.id}',1,this)\">+<\/button>\r\n          <\/div>\r\n          <button class=\"card-cart-btn\" ${outOfStock ? 'disabled style=\"opacity:0.5;\"' : ''} onclick=\"event.preventDefault();handleAddToCart(event,'${p.id}',this);\">\r\n            <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ffffff\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"9\" cy=\"21\" r=\"1\"\/><circle cx=\"20\" cy=\"21\" r=\"1\"\/><path d=\"M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h9.7a2 2 0 0 0 2-1.6L23 6H6\"\/><\/svg>\r\n            Add to Cart\r\n          <\/button>\r\n        <\/div>\r\n      <\/div>`;\r\n  }\r\n\r\n  function changeCardQty(productId, delta, btn){\r\n    const newQty = Math.max(1, (_cardQty[productId] || 1) + delta);\r\n    _cardQty[productId] = newQty;\r\n    const span = document.getElementById('qty-' + productId);\r\n    if (span) span.textContent = newQty;\r\n  }\r\n\r\n  function handleAddToCart(event, productId, btn){\r\n    addToGuestCart(productId, _cardQty[productId] || 1);\r\n    const original = btn.innerHTML;\r\n    btn.textContent = 'Added \\u2713';\r\n    setTimeout(() => { btn.innerHTML = original; }, 1500);\r\n  }\r\n\r\n  \/\/ ---- Wishlist (client-side only, matches shop.html - no wishlist\r\n  \/\/ table exists in the DB yet, flagged there already) ----\r\n  const WISH_KEY = 'b24_wishlist';\r\n  function getWishlist(){ try { return JSON.parse(localStorage.getItem(WISH_KEY) || '[]'); } catch(e) { return []; } }\r\n  function setWishlist(ids){ try { localStorage.setItem(WISH_KEY, JSON.stringify(ids)); } catch(e) {} }\r\n  function toggleWish(productId, btn){\r\n    let ids = getWishlist();\r\n    const isWished = ids.includes(productId);\r\n    ids = isWished ? ids.filter(id => id !== productId) : [...ids, productId];\r\n    setWishlist(ids);\r\n    btn.classList.toggle('wished', !isWished);\r\n  }\r\n  function wireWishButtons(scopeEl){\r\n    const ids = getWishlist();\r\n    scopeEl.querySelectorAll('.product-card').forEach(card => {\r\n      const pid = card.dataset.productId;\r\n      const btn = card.querySelector('.wish-btn');\r\n      if (!btn) return;\r\n      btn.classList.toggle('wished', ids.includes(pid));\r\n      btn.onclick = (e) => { e.preventDefault(); toggleWish(pid, btn); };\r\n    });\r\n  }\r\n\r\n  \/* Front page shows only: Builders Warehouse products whose main image is hosted by us (Supabase storage), and Goo-net Exchange cars. Newest first. *\/\r\n  const HOSTED_IMG = '%\/storage\/v1\/object\/public\/%';\r\n  const ownProducts = q => q.eq('source_site', 'Builders Warehouse').ilike('images->>0', HOSTED_IMG);\r\n  const gooNetCars  = q => q.eq('source_site', 'Goo-net Exchange').ilike('images->>0', HOSTED_IMG);\r\n\r\n  async function loadHomeProducts(){\r\n    const grid = document.getElementById('homeProductsGrid');\r\n    const myCurrency = appState.currency;\r\n    try {\r\n      const { data: products, error } = await ownProducts(sb.from('products')\r\n        .select('id, name, slug, price, sale_price, currency, images, org_id, stock_quantity, track_inventory, is_featured, units_sold, created_at, avg_rating, review_count, source_rating, source_rating_scale, source_review_count')\r\n        .eq('is_published', true)\r\n        .eq('is_archived', false))\r\n        .order('created_at', { ascending: false })\r\n        .limit(30);\r\n      if (error) throw error;\r\n\r\n      if (!products || !products.length) {\r\n        grid.innerHTML = '<p style=\"font-size:12px;color:var(--grey-text);grid-column:1\/-1;\">No products available right now.<\/p>';\r\n        return;\r\n      }\r\n\r\n      let sellerNames = {};\r\n      const sellerIds = [...new Set(products.map(p => p.org_id).filter(Boolean))];\r\n      if (sellerIds.length) {\r\n        try {\r\n          const { data: sellers } = await sb.from('orgs').select('id,name').in('id', sellerIds);\r\n          (sellers || []).forEach(s => { sellerNames[s.id] = s.name; });\r\n        } catch (e) { \/* seller names are optional enrichment, non-fatal *\/ }\r\n      }\r\n\r\n      grid.innerHTML = products.map(p => productCardHtml(p, myCurrency, sellerNames)).join('');\r\n      wireWishButtons(grid);\r\n    } catch (e) {\r\n      console.warn('home products:', e.message);\r\n      grid.innerHTML = '<p style=\"font-size:12px;color:var(--grey-text);grid-column:1\/-1;\">Could not load products right now.<\/p>';\r\n    }\r\n  }\r\n\r\n  \/\/ Logs a real click against affiliate_link_clicks whenever someone\r\n  \/\/ lands here via a referral link (?ref=CODE). Fire-and-forget: this\r\n  \/\/ must never block or break page load if it fails (e.g. table\r\n  \/\/ doesn't exist yet, or the insert errors for any reason).\r\n  async function trackAffiliateClick(){\r\n    try {\r\n      const ref = new URLSearchParams(location.search).get('ref');\r\n      if (!ref) return;\r\n      await sb.from('affiliate_link_clicks').insert({\r\n        referral_code: ref,\r\n        referrer_url: document.referrer || null,\r\n      });\r\n    } catch (e) {\r\n      console.warn('affiliate click tracking:', e.message);\r\n    }\r\n  }\r\n\r\n  (async () => {\r\n    trackAffiliateClick(); \/\/ not awaited - never delays the rest of page init\r\n    const [, currency] = await Promise.all([\r\n      loadExchangeRates(),\r\n      getCustomerCurrency(),\r\n      getCustomerDefaultAddress(),\r\n    ]);\r\n    appState.currency = currency;\r\n    \/\/ The app header is not loaded on this page, so there is no deliver label or profile menu to update.\r\n    try { if (!_customerDefaultAddressLabel) await detectGuestLocationForPage(); } catch (e) {}\r\n    renderPricesStatic();\r\n  })();\r\n<\/script>\r\n<script>\r\n(function(){\r\n  const TABS = {\r\n    shop: {\r\n      resultsTitle: 'Featured Products & Vehicles',\r\n      fields: [\r\n        { id: 'tfShopCategory', label: 'Category', type: 'select-parent-categories' },\r\n        { id: 'tfShopSubcategory', label: 'Subcategory', type: 'select-sub-categories', dependsOn: 'tfShopCategory' },\r\n        { id: 'tfShopBrand', label: 'Brand', type: 'text', placeholder: 'e.g. PPC, Bosch' },\r\n        { id: 'tfShopLocation', label: 'Location', type: 'text', placeholder: 'City' },\r\n        { id: 'tfShopPrice', label: 'Price Range', type: 'range', minId: 'tfShopPriceMin', maxId: 'tfShopPriceMax' }\r\n      ],\r\n      submitLabel: 'Search Products',\r\n      action: runProductSearch\r\n    },\r\n    vehicles: {\r\n      resultsTitle: 'Vehicles',\r\n      fields: [\r\n        { id: 'tfVehicleType', label: 'Vehicle Type', type: 'select', options: [\r\n          ['', 'All Types'], ['heavy_truck', 'Trucks'], ['bus', 'Buses'], ['trailer', 'Trailers'],\r\n          ['mining_equipment', 'Machinery'], ['bakkie_van', 'Vans & Pickups']\r\n        ] },\r\n        { id: 'tfVehicleCategory', label: 'Category', type: 'select-vehicle-category' },\r\n        { id: 'tfVehicleMake', label: 'Make', type: 'text', placeholder: 'e.g. Toyota' },\r\n        { id: 'tfVehicleLocation', label: 'Location', type: 'text', placeholder: 'Country' },\r\n        { id: 'tfVehiclePrice', label: 'Price Range', type: 'range', minId: 'tfVehiclePriceMin', maxId: 'tfVehiclePriceMax' }\r\n      ],\r\n      submitLabel: 'Search Vehicles',\r\n      action: runVehicleSearch\r\n    },\r\n    building: {\r\n      resultsTitle: '',\r\n      fields: [\r\n        { id: 'tfServiceType', label: 'Service Type', type: 'select', options: [\r\n          ['construction', 'Construction'], ['local', 'Local Services'], ['quotes', 'Quotes']\r\n        ] },\r\n        { id: 'tfServiceCategory', label: 'Service Category', type: 'select-service-category', dependsOn: 'tfServiceType' },\r\n        { id: 'tfServiceSubcategory', label: 'Subcategory', type: 'text', placeholder: 'e.g. Cement & Concrete' },\r\n        { id: 'tfServiceLocation', label: 'Service Location', type: 'text', placeholder: 'Suburb, City' },\r\n        { id: 'tfServiceBudget', label: 'Budget', type: 'range', minId: 'tfServiceBudgetMin', maxId: 'tfServiceBudgetMax' }\r\n      ],\r\n      submitLabel: 'Request a Quote',\r\n      action: () => runQuoteRedirect('tfServiceCategory', 'tfServiceSubcategory', 'tfServiceLocation')\r\n    }\r\n  };\r\n\r\n  let _activeTab = 'shop';\r\n  let _productCategories = null;\r\n  let _serviceCategories = null;\r\n  let _localCategories = null;\r\n\r\n  const COUNTRY_ABBREV = {\r\n    'japan':'JP','uk':'UK','united kingdom':'UK','china':'CN','germany':'DE',\r\n    'united states':'US','usa':'US','uae':'UAE','united arab emirates':'UAE',\r\n    'india':'IN','turkey':'TR','brazil':'BR','south africa':'SA','nigeria':'NG',\r\n    'kenya':'KE','ghana':'GH','zimbabwe':'ZW','zambia':'ZM','tanzania':'TZ',\r\n    'uganda':'UG','mozambique':'MZ','angola':'AO','botswana':'BW','namibia':'NA',\r\n    'drc':'DRC','democratic republic of congo':'DRC','ethiopia':'ET',\r\n    'saudi arabia':'SA','oman':'OM'\r\n  };\r\n  const COUNTRY_TO_ISO2 = { ...COUNTRY_ABBREV, uk:'GB', 'united kingdom':'GB', uae:'AE', 'united arab emirates':'AE', drc:'CD', 'democratic republic of congo':'CD' };\r\n  function countryFlagEmoji(name){ const iso2 = COUNTRY_TO_ISO2[(name||'').trim().toLowerCase()]; if(!iso2) return '\ud83c\udf0d'; return String.fromCodePoint(...[...iso2].map(c=>127397+c.charCodeAt(0))); }\r\n  function countryAbbrev(name){ return COUNTRY_ABBREV[(name||'').trim().toLowerCase()] || (name||''); }\r\n\r\n  \/\/ Vehicle card \u2014 real replica of the bl-card design used on vehicles.html\r\n  \/\/ (Auto), not a new invented style.\r\n  \/\/ ===== New homepage sections: Featured Deals, Best Sellers, Recently\r\n  \/\/ Added, plus category banners. Real signals first (sale_price,\r\n  \/\/ is_promoted), falling back to genuinely recent real inventory when\r\n  \/\/ those are empty \u2014 never a fabricated discount or \"best seller\" claim\r\n  \/\/ on an item that isn't actually one. =====\r\n  \/\/ Top-level category of a product's category (walks parent_id), so\r\n  \/\/ \"each category\" means the main categories, loaded live from the DB.\r\n  async function ensureHomeCategories(){\r\n    if (_productCategories) return;\r\n    try {\r\n      const { data } = await sb.from('categories').select('id,name,parent_id').eq('is_active', true).order('sort_order');\r\n      _productCategories = data || [];\r\n    } catch (e) { _productCategories = []; }\r\n  }\r\n  function rootCategoryKey(catId){\r\n    if (!catId) return 'none';\r\n    const byId = {};\r\n    (_productCategories || []).forEach(c => { byId[c.id] = c; });\r\n    let cur = byId[catId];\r\n    if (!cur) return catId;\r\n    let guard = 0;\r\n    while (cur.parent_id && byId[cur.parent_id] && guard++ < 10) cur = byId[cur.parent_id];\r\n    return cur.id;\r\n  }\r\n  \/\/ rows must be newest-first. Returns up to `limit` rows, taking the newest\r\n  \/\/ of each category in turn, then the second-newest of each, and so on.\r\n  function latestPerCategory(rows, limit){\r\n    const groups = new Map();\r\n    rows.forEach(r => {\r\n      const k = rootCategoryKey(r.category_id);\r\n      if (!groups.has(k)) groups.set(k, []);\r\n      groups.get(k).push(r);\r\n    });\r\n    const lists = [...groups.values()];\r\n    const out = [];\r\n    for (let i = 0; out.length < limit; i++) {\r\n      let added = false;\r\n      for (const list of lists) {\r\n        if (list[i]) { out.push(list[i]); added = true; if (out.length >= limit) break; }\r\n      }\r\n      if (!added) break;\r\n    }\r\n    return out;\r\n  }\r\n\r\n  async function loadNewHomepageSections(){\r\n    const myCurrency = appState.currency || await getCustomerCurrency();\r\n\r\n    await ensureHomeCategories();\r\n    const COLS = 'id, name, slug, price, sale_price, currency, images, org_id, category_id, stock_quantity, track_inventory, is_featured, units_sold, created_at, avg_rating, review_count, source_rating, source_rating_scale, source_review_count';\r\n    const live = () => sb.from('products').select(COLS).eq('is_published', true).eq('is_archived', false).ilike('images->>0', HOSTED_IMG);\r\n    const [\r\n      { data: pool }, { data: usaRows }, { data: chinaRows }, { data: saRows }, { data: vehicleRows },\r\n    ] = await Promise.all([\r\n      ownProducts(sb.from('products').select(COLS).eq('is_published', true).eq('is_archived', false))\r\n        .order('created_at', { ascending: false }).limit(300),\r\n      live().or('shipped_from.ilike.*usa*,shipped_from.ilike.*united states*').order('created_at', { ascending: false }).limit(100),\r\n      live().ilike('shipped_from', '%china%').order('created_at', { ascending: false }).limit(100),\r\n      live().ilike('shipped_from', '%south africa%').order('created_at', { ascending: false }).limit(300),\r\n      gooNetCars(sb.from('vehicle_listings').select('id,slug,price,currency,year,mileage_km,location_country,condition,images,raw_make,raw_model,vehicle_models(name,vehicle_makes(name))')\r\n        .eq('is_published', true).eq('status', 'available'))\r\n        .order('created_at', { ascending: false }).limit(20),\r\n    ]);\r\n\r\n    \/\/ Newest first, rotating through categories so every category's latest\r\n    \/\/ product surfaces \u2014 nothing is pinned. Sections take consecutive slices\r\n    \/\/ of the same ordering so they never repeat each other.\r\n    const ordered = latestPerCategory(pool || [], 52);\r\n    const dealsRows = ordered.slice(0, 16);\r\n    const bestRows = ordered.slice(16, 22);\r\n    const popRows = ordered.slice(22, 52);\r\n    const usaPicked = latestPerCategory(usaRows || [], 20);\r\n    const chinaPicked = latestPerCategory(chinaRows || [], 20);\r\n    const saPicked = latestPerCategory(saRows || [], 20);\r\n\r\n    let sellerNames = {};\r\n    const allOrgIds = [...new Set([...dealsRows, ...bestRows, ...popRows, ...usaPicked, ...chinaPicked, ...saPicked].map(p => p.org_id).filter(Boolean))];\r\n    if (allOrgIds.length) {\r\n      try {\r\n        const { data: sellers } = await sb.from('orgs').select('id,name').in('id', allOrgIds);\r\n        (sellers || []).forEach(s => { sellerNames[s.id] = s.name; });\r\n      } catch (e) {}\r\n    }\r\n\r\n    const emptyMsg = '<p style=\"font-size:12px;color:#6b7280;grid-column:1\/-1;\">No products available right now.<\/p>';\r\n    const fillGrid = (id, rows) => {\r\n      const el = document.getElementById(id);\r\n      el.innerHTML = rows.length ? rows.map(p => productCardHtml(p, myCurrency, sellerNames)).join('') : emptyMsg;\r\n      wireWishButtons(el);\r\n    };\r\n    fillGrid('featuredDealsGrid', dealsRows);\r\n    fillGrid('bestSellersGrid', bestRows);\r\n    fillGrid('popularSearchesGrid', popRows);\r\n\r\n    \/\/ Shipped-from rows: horizontally scrollable; a row with no products is\r\n    \/\/ hidden rather than shown empty.\r\n    const fillShipRow = (sectionId, gridId, rows) => {\r\n      const sec = document.getElementById(sectionId);\r\n      if (!rows.length) { sec.style.display = 'none'; return; }\r\n      sec.style.display = '';\r\n      fillGrid(gridId, rows);\r\n    };\r\n    fillShipRow('shipUsaSection', 'shipUsaGrid', usaPicked);\r\n    fillShipRow('shipChinaSection', 'shipChinaGrid', chinaPicked);\r\n    fillShipRow('shipSaSection', 'shipSaGrid', saPicked);\r\n\r\n    \/\/ Latest Vehicles row \u2014 newest first, same horizontal scroll as above.\r\n    const vehSec = document.getElementById('vehiclesRowSection');\r\n    const vehEl = document.getElementById('vehiclesRowGrid');\r\n    if (vehicleRows && vehicleRows.length) {\r\n      vehSec.style.display = '';\r\n      vehEl.innerHTML = vehicleRows.map(v => vehicleCardHtml(v, myCurrency)).join('');\r\n    } else {\r\n      vehSec.style.display = 'none';\r\n    }\r\n\r\n    \/\/ Mockup hero's sidebar \u2014 deliberately curated, not every real\r\n    \/\/ category (there are 46 top-level ones). \"Used Vehicles\" isn't a\r\n    \/\/ product category at all \u2014 vehicles live in vehicle_listings, a\r\n    \/\/ separate table \u2014 so it links to the real vehicles page instead\r\n    \/\/ of a category filter.\r\n    const mockupSidebarEl = document.getElementById('mockupCatSidebar');\r\n    const CURATED_CATEGORIES = [\r\n      { label: 'Home Goods', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=home-goods' },\r\n      { label: 'Machinery', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=machinery-and-equipment' },\r\n      { label: 'Building Supplies', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=building-materials' },\r\n      { label: 'Used Vehicles', href: 'https:\/\/app.builders24.net\/auto\/vehicles\/' },\r\n      { label: 'Solar', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=solar-and-renewable-energy' },\r\n    ];\r\n    mockupSidebarEl.innerHTML = '<div class=\"hp-cat-sidebar-title\">Shop by Category<\/div>' + CURATED_CATEGORIES.map(c => `\r\n      <div class=\"hp-cat-row\" onclick=\"location.href='${c.href}'\">\r\n        <div class=\"hp-cat-row-left\"><span class=\"hp-cat-row-icon\">\u25aa<\/span>${esc(c.label)}<\/div>\r\n        <span class=\"hp-cat-row-chevron\">\u203a<\/span>\r\n      <\/div>`).join('');\r\n\r\n    \/\/ Trust row \u2014 real mockup content, 5 items exactly as designed.\r\n    const TRUST_BADGES = [\r\n      { icon: '\ud83d\udee1', title: 'Trusted Sellers', sub: 'Verified & secure' },\r\n      { icon: '\ud83d\ude9a', title: 'Fast Delivery', sub: 'Across Zimbabwe' },\r\n      { icon: '\ud83d\udd12', title: 'Secure Payments', sub: 'Multiple options' },\r\n      { icon: '\u21a9', title: 'Easy Returns', sub: '30-day policy' },\r\n      { icon: '\ud83c\udfa7', title: 'Live Support', sub: \"We're here to help\" },\r\n    ];\r\n    document.getElementById('trustRow').innerHTML = TRUST_BADGES.map(b => `\r\n      <div class=\"hp-trust-item\">\r\n        <div class=\"hp-trust-item-icon\">${b.icon}<\/div>\r\n        <div><div class=\"hp-trust-item-title\">${esc(b.title)}<\/div><div class=\"hp-trust-item-sub\">${esc(b.sub)}<\/div><\/div>\r\n      <\/div>`).join('');\r\n\r\n    \/\/ Category banners \u2014 using the real mockup's exact 3 categories\r\n    \/\/ (Tools & Hardware \/ Home & Living \/ Garden & Outdoor) and copy,\r\n    \/\/ with the real provided photo filenames.\r\n    const bannersEl = document.getElementById('categoryBannersRow');\r\n    const CATEGORY_BANNERS = [\r\n      { title: 'Tools & Hardware', sub: 'Built for professionals. Ready for your next project.', img: 'https:\/\/app.builders24.net\/assets\/tools.png', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=hardware-and-fasteners' },\r\n      { title: 'Home & Living', sub: 'Comfort, style and function for every space.', img: 'https:\/\/app.builders24.net\/assets\/style-modern-minimalist.webp', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=home-goods' },\r\n      { title: 'Garden & Outdoor', sub: 'Keep your outdoor spaces working for you.', img: 'https:\/\/app.builders24.net\/assets\/style-outdoor-living.jpg', href: 'https:\/\/app.builders24.net\/retail\/shop.html?category=landscaping-and-garden' },\r\n    ];\r\n    bannersEl.innerHTML = CATEGORY_BANNERS.map(c => `\r\n      <div class=\"hp-cat-banner\" onclick=\"location.href='${c.href}'\">\r\n        <img decoding=\"async\" src=\"${c.img}\" alt=\"${esc(c.title)}\">\r\n        <div class=\"hp-cat-banner-overlay\"><\/div>\r\n        <div class=\"hp-cat-banner-copy\">\r\n          <div class=\"hp-cat-banner-title\">${esc(c.title)}<\/div>\r\n          <div class=\"hp-cat-banner-sub\">${esc(c.sub)}<\/div>\r\n          <button class=\"hp-cat-banner-btn\">Shop Now \u2192<\/button>\r\n        <\/div>\r\n      <\/div>`).join('');\r\n  }\r\n\r\n  function vehicleCardHtml(l, myCurrency){\r\n    const img = Array.isArray(l.images) && l.images.length ? l.images[0] : null;\r\n    const title = (`${l.vehicle_models?.vehicle_makes?.name || ''} ${l.vehicle_models?.name || ''}`.trim()) || (`${l.raw_make || ''} ${l.raw_model || ''}`.trim()) || 'Vehicle';\r\n    const isNew = (l.condition || '').toLowerCase() === 'new';\r\n    const toCurrency = myCurrency || appState.currency;\r\n    const priceLabel = l.price ? fmtConverted(l.price, l.currency, toCurrency) : 'Ask For Price';\r\n    const km = l.mileage_km != null ? `${Number(l.mileage_km).toLocaleString()} km` : '0 km';\r\n    return `\r\n      <a class=\"bl-card\" href=\"https:\/\/app.builders24.net\/auto\/vehicle\/${l.slug}\">\r\n        <div class=\"bl-card-img\">\r\n          ${isNew ? `<div class=\"bl-card-badge\">Brand New<\/div>` : ''}\r\n          <button class=\"bl-fav-btn\" onclick=\"event.preventDefault();event.stopPropagation();\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#3A3F4D\" stroke-width=\"1.8\"><path d=\"M12 21s-7-4.6-9.5-9C.8 8.3 2.4 5 6 5c2 0 3.3 1 6 3.4C14.7 6 16 5 18 5c3.6 0 5.2 3.3 3.5 7-2.5 4.4-9.5 9-9.5 9z\"><\/path><\/svg><\/button>\r\n          ${img ? `<img decoding=\"async\" src=\"${esc(img)}\" alt=\"\" referrerpolicy=\"no-referrer\" onerror=\"this.remove()\">` : `<i class=\"ti ti-photo\"><\/i>`}\r\n        <\/div>\r\n        <div class=\"bl-card-body\">\r\n          <div class=\"bl-card-title\">${esc(title)}<\/div>\r\n          <div class=\"bl-card-price\">${esc(priceLabel)}<\/div>\r\n          <div class=\"bl-card-meta\">\r\n            <span>${l.year || ''}<\/span>\r\n            <span>${km}<\/span>\r\n            <span class=\"bl-card-flag\"><span class=\"bl-flag-emoji\">${countryFlagEmoji(l.location_country)}<\/span>${esc(countryAbbrev(l.location_country))}<\/span>\r\n          <\/div>\r\n        <\/div>\r\n      <\/a>`;\r\n  }\r\n\r\n  async function loadShopMixedGrid(){\r\n    const grid = document.getElementById('tabResultsGrid');\r\n    grid.innerHTML = '<div class=\"tr-empty\">Loading...<\/div>';\r\n    \/\/ Self-healing: appState.currency is set by a separate init IIFE that\r\n    \/\/ isn't guaranteed to finish before this runs \u2014 don't assume it's ready.\r\n    const myCurrency = appState.currency || await getCustomerCurrency();\r\n\r\n    const [{ data: products }, { data: vehicles }] = await Promise.all([\r\n      ownProducts(sb.from('products').select('id, name, slug, price, sale_price, currency, images, org_id, stock_quantity, track_inventory, is_featured, units_sold, created_at, avg_rating, review_count, source_rating, source_rating_scale, source_review_count')\r\n        .eq('is_published', true).eq('is_archived', false))\r\n        .order('created_at', { ascending: false }).limit(30),\r\n      gooNetCars(sb.from('vehicle_listings')\r\n        .select('id,slug,price,currency,year,mileage_km,location_country,condition,images,raw_make,raw_model,vehicle_models(name,vehicle_makes(name,vehicle_type))')\r\n        .eq('is_published', true).eq('status', 'available')).order('created_at', { ascending: false }).limit(30)\r\n    ]);\r\n\r\n    let sellerNames = {};\r\n    const sellerIds = [...new Set((products||[]).map(p => p.org_id).filter(Boolean))];\r\n    if (sellerIds.length) {\r\n      try {\r\n        const { data: sellers } = await sb.from('orgs').select('id,name').in('id', sellerIds);\r\n        (sellers || []).forEach(s => { sellerNames[s.id] = s.name; });\r\n      } catch (e) {}\r\n    }\r\n\r\n    const productCards = (products||[]).map(p => productCardHtml(p, myCurrency, sellerNames));\r\n    const vehicleCards = (vehicles||[]).map(l => vehicleCardHtml(l, myCurrency));\r\n\r\n    if (!productCards.length && !vehicleCards.length) {\r\n      grid.innerHTML = '<div class=\"tr-empty\">Nothing available right now.<\/div>';\r\n      return;\r\n    }\r\n\r\n    \/\/ Grouped, not interleaved \u2014 product cards and vehicle cards have\r\n    \/\/ different heights\/layouts and looked broken mixed row-by-row.\r\n    let html = '';\r\n    if (productCards.length) {\r\n      html += `<div class=\"tr-group-label\">Products<\/div><div class=\"tab-results-grid\">${productCards.join('')}<\/div>`;\r\n    }\r\n    if (vehicleCards.length) {\r\n      html += `<div class=\"tr-group-label\">Vehicles<\/div><div class=\"tab-results-grid\">${vehicleCards.join('')}<\/div>`;\r\n    }\r\n    grid.outerHTML = `<div id=\"tabResultsGrid\" class=\"tr-groups\">${html}<\/div>`;\r\n    wireWishButtons(document.getElementById('tabResultsGrid'));\r\n  }\r\n\r\n  const VEHICLE_CATEGORY_OPTIONS = `\r\n    <option value=\"\">All Categories<\/option>\r\n    <optgroup label=\"Transmission\">\r\n      <option value=\"transmission:automatic\">Automatic<\/option>\r\n      <option value=\"transmission:manual\">Manual<\/option>\r\n    <\/optgroup>\r\n    <optgroup label=\"Steering\">\r\n      <option value=\"steering:rhd\">RHD<\/option>\r\n      <option value=\"steering:lhd\">LHD<\/option>\r\n    <\/optgroup>\r\n    <optgroup label=\"Fuel Type\">\r\n      <option value=\"fuel_type:hybrid\">Hybrid<\/option>\r\n      <option value=\"fuel_type:electric\">Electric<\/option>\r\n      <option value=\"fuel_type:petrol\">Petrol<\/option>\r\n      <option value=\"fuel_type:diesel\">Diesel<\/option>\r\n    <\/optgroup>\r\n    <optgroup label=\"Condition\">\r\n      <option value=\"condition:new\">New<\/option>\r\n      <option value=\"condition:used\">Used<\/option>\r\n    <\/optgroup>`;\r\n\r\n  async function fieldHtml(f) {\r\n    if (f.type === 'text') {\r\n      return `<div><label>${f.label}<\/label><input type=\"text\" id=\"${f.id}\" placeholder=\"${f.placeholder||''}\"><\/div>`;\r\n    }\r\n    if (f.type === 'range') {\r\n      return `<div><label>${f.label} (${esc(appState.currency || 'USD')})<\/label><div class=\"filter-range\"><input type=\"number\" inputmode=\"decimal\" min=\"0\" step=\"any\" id=\"${f.minId}\" placeholder=\"Min\"><input type=\"number\" inputmode=\"decimal\" min=\"0\" step=\"any\" id=\"${f.maxId}\" placeholder=\"Max\"><\/div><\/div>`;\r\n    }\r\n    if (f.type === 'select') {\r\n      return `<div><label>${f.label}<\/label><select id=\"${f.id}\">${f.options.map(([v,l]) => `<option value=\"${v}\">${l}<\/option>`).join('')}<\/select><\/div>`;\r\n    }\r\n    if (f.type === 'select-vehicle-category') {\r\n      return `<div><label>${f.label}<\/label><select id=\"${f.id}\">${VEHICLE_CATEGORY_OPTIONS}<\/select><\/div>`;\r\n    }\r\n    if (f.type === 'select-parent-categories') {\r\n      if (!_productCategories) {\r\n        const { data } = await sb.from('categories').select('id,name,parent_id').eq('is_active', true).order('sort_order');\r\n        _productCategories = data || [];\r\n      }\r\n      const parents = _productCategories.filter(c => !c.parent_id);\r\n      return `<div><label>${f.label}<\/label><select id=\"${f.id}\"><option value=\"\">All Categories<\/option>${parents.map(c => `<option value=\"${c.id}\">${esc(c.name)}<\/option>`).join('')}<\/select><\/div>`;\r\n    }\r\n    if (f.type === 'select-sub-categories') {\r\n      return `<div><label>${f.label}<\/label><select id=\"${f.id}\">${subcategoryOptionsHtml('')}<\/select><\/div>`;\r\n    }\r\n    if (f.type === 'select-service-category') {\r\n      return `<div><label>${f.label}<\/label><select id=\"${f.id}\">${await serviceCategoryOptionsHtml('construction')}<\/select><\/div>`;\r\n    }\r\n    return '';\r\n  }\r\n\r\n  function subcategoryOptionsHtml(parentId) {\r\n    const subs = parentId\r\n      ? _productCategories.filter(c => c.parent_id === parentId)\r\n      : _productCategories.filter(c => c.parent_id);\r\n    return `<option value=\"\">All Subcategories<\/option>${subs.map(c => `<option value=\"${c.id}\">${esc(c.name)}<\/option>`).join('')}`;\r\n  }\r\n\r\n  async function serviceCategoryOptionsHtml(serviceType) {\r\n    if (serviceType === 'local') {\r\n      if (!_localCategories) {\r\n        const { data } = await sb.from('local_service_categories').select('id,name').order('sort_order');\r\n        _localCategories = data || [];\r\n      }\r\n      return `<option value=\"\">All Service Categories<\/option>${_localCategories.map(c => `<option value=\"${esc(c.name)}\">${esc(c.name)}<\/option>`).join('')}`;\r\n    }\r\n    \/\/ 'construction' and 'quotes' both draw from the real service_categories\r\n    \/\/ taxonomy \u2014 quote_requests.category is free text matching those same names.\r\n    if (!_serviceCategories) {\r\n      const { data } = await sb.from('service_categories').select('id,name').order('sort_order');\r\n      _serviceCategories = data || [];\r\n    }\r\n    return `<option value=\"\">All Service Categories<\/option>${_serviceCategories.map(c => `<option value=\"${esc(c.name)}\">${esc(c.name)}<\/option>`).join('')}`;\r\n  }\r\n\r\n  function wireDependentFields(cfg) {\r\n    cfg.fields.forEach(f => {\r\n      if (!f.dependsOn) return;\r\n      const parentEl = document.getElementById(f.dependsOn);\r\n      const childEl = document.getElementById(f.id);\r\n      if (!parentEl || !childEl) return;\r\n      parentEl.addEventListener('change', async () => {\r\n        if (f.type === 'select-sub-categories') {\r\n          childEl.innerHTML = subcategoryOptionsHtml(parentEl.value);\r\n        } else if (f.type === 'select-service-category') {\r\n          childEl.innerHTML = await serviceCategoryOptionsHtml(parentEl.value);\r\n        }\r\n      });\r\n    });\r\n  }\r\n\r\n  async function renderTab(tab) {\r\n    _activeTab = tab;\r\n    document.querySelectorAll('.bc-tab').forEach(t => t.classList.toggle('active', t.dataset.tab === tab));\r\n    const cfg = TABS[tab];\r\n    const fieldsEl = document.getElementById('filterFields');\r\n    try {\r\n      \/\/ Sequential, not Promise.all \u2014 dependent fields (e.g. Subcategory)\r\n      \/\/ read state that an earlier field's own fetch populates, so they\r\n      \/\/ must resolve in order, not concurrently.\r\n      const rendered = [];\r\n      for (const f of cfg.fields) { rendered.push(await fieldHtml(f)); }\r\n      fieldsEl.innerHTML = rendered.join('');\r\n      wireDependentFields(cfg);\r\n      const btn = document.getElementById('filterSubmitBtn');\r\n      btn.textContent = cfg.submitLabel;\r\n      btn.onclick = cfg.action;\r\n    } catch (e) {\r\n      console.error('[renderTab] failed to build filter fields:', e);\r\n      fieldsEl.innerHTML = '<div class=\"tr-empty\">Could not load filters \u2014 please refresh.<\/div>';\r\n      return;\r\n    }\r\n\r\n    const sectorsSection = document.getElementById('sectorsSection');\r\n    if (tab === 'building') {\r\n      \/\/ Building Services is blind-bid quote requests, not a browsable\r\n      \/\/ listing grid \u2014 no provider profiles. Show the real Sectors\r\n      \/\/ section instead.\r\n      sectorsSection.style.display = '';\r\n    } else {\r\n      sectorsSection.style.display = 'none';\r\n      \/\/ TODO (Thomas is wiring this): the inline results grid this used\r\n      \/\/ to populate (tabResults\/tabResultsGrid) was removed along with\r\n      \/\/ the old Featured Products section. Tab\/search submission should\r\n      \/\/ navigate to a separate results page instead of rendering inline\r\n      \/\/ here \u2014 cfg.action \/ loadShopMixedGrid still exist below if\r\n      \/\/ useful for that page, but nothing currently calls them from here.\r\n    }\r\n  }\r\n\r\n  document.getElementById('hero2Tabs').addEventListener('click', (e) => {\r\n    const t = e.target.closest('.bc-tab');\r\n    if (t) renderTab(t.dataset.tab);\r\n  });\r\n\r\n  \/\/ Exposed so the currency-switch handler (separate script scope, up in\r\n  \/\/ the appState\/renderPrices block) can refresh whichever tab's result\r\n  \/\/ grid is currently on screen, without duplicating TABS\/_activeTab here.\r\n  \/\/ One refresh at a time; a request made while one is running triggers a\r\n  \/\/ single follow-up run instead of piling up concurrent fetches.\r\n  let _homeRefreshing = false, _homeRefreshQueued = false;\r\n  window.b24RefreshHomeSections = async () => {\r\n    if (_homeRefreshing) { _homeRefreshQueued = true; return; }\r\n    _homeRefreshing = true;\r\n    try {\r\n      do { _homeRefreshQueued = false; await loadNewHomepageSections(); } while (_homeRefreshQueued);\r\n    } catch (e) { console.warn('home refresh:', e.message); }\r\n    _homeRefreshing = false;\r\n  };\r\n\r\n  \/\/ Price\/budget bounds are entered in the shopper's selected currency, so\r\n  \/\/ the currency code travels with them for the receiving page to interpret.\r\n  function addPriceParams(params, minId, maxId, minKey, maxKey) {\r\n    const minEl = document.getElementById(minId), maxEl = document.getElementById(maxId);\r\n    const min = minEl ? minEl.value.trim() : '', max = maxEl ? maxEl.value.trim() : '';\r\n    if (min !== '') params.set(minKey || 'min_price', min);\r\n    if (max !== '') params.set(maxKey || 'max_price', max);\r\n    if (min !== '' || max !== '') params.set('currency', appState.currency || 'USD');\r\n  }\r\n\r\n  function runProductSearch() {\r\n    const categoryId = document.getElementById('tfShopCategory').value;\r\n    const subcategoryId = document.getElementById('tfShopSubcategory').value;\r\n    const brand = document.getElementById('tfShopBrand').value.trim();\r\n    const place = document.getElementById('tfShopLocation').value.trim();\r\n    const params = new URLSearchParams();\r\n    if (subcategoryId) params.set('category', subcategoryId);\r\n    else if (categoryId) params.set('category', categoryId);\r\n    if (brand) params.set('brand', brand);\r\n    if (place) params.set('location', place);\r\n    addPriceParams(params, 'tfShopPriceMin', 'tfShopPriceMax');\r\n    location.href = 'https:\/\/app.builders24.net\/retail\/shop.html' + (params.toString() ? '?' + params.toString() : '');\r\n  }\r\n\r\n  function runVehicleSearch() {\r\n    const type = document.getElementById('tfVehicleType').value;\r\n    const category = document.getElementById('tfVehicleCategory').value;\r\n    const make = document.getElementById('tfVehicleMake').value.trim();\r\n    const place = document.getElementById('tfVehicleLocation').value.trim();\r\n    const params = new URLSearchParams();\r\n    if (type) params.set('type', type);\r\n    if (category) params.set('category', category);\r\n    if (make) params.set('make', make);\r\n    if (place) params.set('location', place);\r\n    addPriceParams(params, 'tfVehiclePriceMin', 'tfVehiclePriceMax');\r\n    location.href = 'https:\/\/app.builders24.net\/auto\/vehicles\/' + (params.toString() ? '?' + params.toString() : '');\r\n  }\r\n\r\n  function runQuoteRedirect(typeFieldId, subFieldId, addressFieldId) {\r\n    const category = document.getElementById(typeFieldId).value;\r\n    const subcategory = document.getElementById(subFieldId).value.trim();\r\n    const address = document.getElementById(addressFieldId).value.trim();\r\n    const params = new URLSearchParams();\r\n    if (category) params.set('category', category);\r\n    if (subcategory) params.set('subcategory', subcategory);\r\n    if (address) params.set('address', address);\r\n    addPriceParams(params, 'tfServiceBudgetMin', 'tfServiceBudgetMax', 'budget_min', 'budget_max');\r\n    location.href = 'https:\/\/app.builders24.net\/build\/request-quote.html' + (params.toString() ? '?' + params.toString() : '');\r\n  }\r\n\r\n  renderTab('shop');\r\n  window.b24RefreshHomeSections();\r\n})();\r\n<\/script>\r\n\r\n<script>\r\n\/\/ ---- PWA: service worker + offline queue + push + periodic sync ----\r\nif ('serviceWorker' in navigator) {\r\n  window.addEventListener('load', async () => {\r\n    try {\r\n      const reg = await navigator.serviceWorker.register('https:\/\/app.builders24.net\/sw.js');\r\n\r\n      \/\/ Periodic Background Sync (Chrome only; requires installed PWA\r\n      \/\/ with usage history \u2014 browser grants this permission itself,\r\n      \/\/ there's no user prompt to trigger).\r\n      if ('periodicSync' in reg) {\r\n        try {\r\n          const status = await navigator.permissions.query({ name: 'periodic-background-sync' });\r\n          if (status.state === 'granted') {\r\n            await reg.periodicSync.register('b24-refresh-catalog', { minInterval: 24 * 60 * 60 * 1000 });\r\n          }\r\n        } catch (e) { \/* not supported in this browser, ignore *\/ }\r\n      }\r\n    } catch (e) {\r\n      console.error('Service worker registration failed:', e);\r\n    }\r\n  });\r\n}\r\n\r\n\/\/ Background Sync: call this instead of fetch() directly when submitting\r\n\/\/ something that should survive a dropped connection (e.g. a quote request).\r\n\/\/ Usage: queueForSync(url, { method: 'POST', headers: {...}, body: ... })\r\nasync function queueForSync(url, opts) {\r\n  if (!('serviceWorker' in navigator) || !('SyncManager' in window)) {\r\n    return fetch(url, opts); \/\/ fallback: just try directly\r\n  }\r\n  const db = await new Promise((resolve, reject) => {\r\n    const req = indexedDB.open('b24-offline-queue', 1);\r\n    req.onupgradeneeded = () => req.result.createObjectStore('queue', { keyPath: 'id', autoIncrement: true });\r\n    req.onsuccess = () => resolve(req.result);\r\n    req.onerror = () => reject(req.error);\r\n  });\r\n  const tx = db.transaction('queue', 'readwrite');\r\n  tx.objectStore('queue').add({ url, method: opts.method || 'GET', headers: opts.headers || {}, body: opts.body || null });\r\n  const reg = await navigator.serviceWorker.ready;\r\n  return reg.sync.register('b24-sync-queue');\r\n}\r\n\r\n\/\/ Push Notifications: call requestPushPermission() from a user gesture\r\n\/\/ (e.g. a \"Enable notifications\" button) \u2014 do not call on page load,\r\n\/\/ browsers ignore\/penalize unsolicited permission prompts.\r\nasync function requestPushPermission(vapidPublicKey) {\r\n  if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\r\n    return null;\r\n  }\r\n  const permission = await Notification.requestPermission();\r\n  if (permission !== 'granted') return null;\r\n\r\n  const reg = await navigator.serviceWorker.ready;\r\n  const subscription = await reg.pushManager.subscribe({\r\n    userVisibleOnly: true,\r\n    applicationServerKey: vapidPublicKey\r\n  });\r\n\r\n  \/\/ Send the subscription to your backend to store against the user,\r\n  \/\/ e.g.: await sb.from('push_subscriptions').upsert({ user_id, subscription });\r\n  return subscription;\r\n}\r\n<\/script>\r\n\r\n<script>\r\n\/\/ Home product view switcher: \"Original\" (current cards) or \"List\". One choice for every product section.\r\n(function(){\r\n  var KEY='b24_home_view';\r\n  var ids=['featuredDealsGrid','bestSellersGrid','shipUsaGrid','shipChinaGrid','shipSaGrid'];\r\n  function get(){ try{ return localStorage.getItem(KEY)==='list'?'list':'original'; }catch(e){ return 'original'; } }\r\n  function set(v){ try{ localStorage.setItem(KEY,v); }catch(e){} }\r\n  function apply(v){\r\n    document.body.setAttribute('data-pview',v);\r\n    document.querySelectorAll('.pv-switch button').forEach(function(b){ var on=b.getAttribute('data-pv')===v; b.classList.toggle('on',on); b.setAttribute('aria-pressed',on); });\r\n  }\r\n  ids.forEach(function(id){\r\n    var grid=document.getElementById(id); if(!grid) return;\r\n    grid.classList.add('pv-target');\r\n    var sec=grid.closest('.hp-section'); var head=sec&&sec.querySelector('.hp-section-head'); if(!head) return;\r\n    var va=head.querySelector('.hp-viewall');\r\n    var wrap=document.createElement('div'); wrap.className='pv-actions';\r\n    wrap.innerHTML='<div class=\"pv-switch\" role=\"group\" aria-label=\"Change product view\"><button type=\"button\" data-pv=\"original\">Original<\/button><button type=\"button\" data-pv=\"list\">List<\/button><\/div>';\r\n    if(va){ head.insertBefore(wrap,va); wrap.appendChild(va); } else head.appendChild(wrap);\r\n  });\r\n  document.addEventListener('click',function(e){ var b=e.target.closest&&e.target.closest('.pv-switch button'); if(!b) return; var v=b.getAttribute('data-pv'); set(v); apply(v); });\r\n  apply(get());\r\n})();\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Builders24 Zimbabwe | Building Materials, Equipment &amp; Machinery, Vehicles, Home Goods and Trade Services Builders24, Everything You Need To Build, Renovate, And Move Goods Across Zimbabwe Builders24 Zimbabwe sells building materials, equipment and machinery, vehicles and home goods in Zimbabwe. We provide construction, renovation and trade services in Zimbabwe, supply wholesale goods to Zimbabwean businesses, and offer import, export and cross-border logistics from Zimbabwe through Zimbabwean and international suppliers. QualityGuaranteed NationwideDelivery Trusted byPros SecurePayments Shop Now Browse Vehicles Building Services Today&#8217;s Featured Deals Top quality products at unbeatable prices. Limited time only. View All Deals \u2192 Shop by Category BUILD SMARTER Quality Materials for Every Project From home renovations to large-scale builds, get the tools, materials and supplies you need \u2014 delivered across Zimbabwe. Shop Now \u2192 UP TO 40% OFF SELECTED ITEMS Best Sellers Our most popular products, trusted by thousands. View All Best Sellers \u2192 Shipped from USA Latest arrivals shipping from the USA. View All \u2192 Shipped from China Latest arrivals shipping from China. View All \u2192 Shipped from Zimbabwe Latest arrivals shipping from Zimbabwe. View All \u2192 Latest Vehicles The newest vehicles added to Builders24 Auto. View All \u2192 Building or Renovating? Builders24 has a network of thousands of skilled construction services partners across Zimbabwe. Get a Free Quote \u2192 \ud83d\udcb2 Competitive Pricing \ud83d\udce6 Volume Discounts \ud83d\udc64 Dedicated Account Manager \ud83d\ude9a Flexible Delivery Popular Searches Our most popular products, trusted by thousands. View All \u2192 Our Sectors Built For Every Sector,Across Zimbabwe Builders24 operates across 8 sectors in Zimbabwe, delivering construction, industrial, commercial, residential, agricultural, import, export and supply services to businesses, developers, government and communities in Harare, Bulawayo, Manicaland, Midlands and every other province. Residential Sector 01 Residential Construction New homes, renovations, extensions, roofing, plumbing, electrical and home improvements. Explore Commercial Sector 02 Commercial Construction Offices, retail parks, hotels, restaurants, fit-outs and commercial developments. Explore Industrial Sector 03 Industrial Construction Warehouses, factories, logistics hubs, steel structures and industrial facilities. Explore Infrastructure Sector 04 Infrastructure &amp; Civil Roads, water systems, civil engineering, drainage and public infrastructure. Explore Agriculture Sector 05 Agriculture &amp; Agritech Drone spraying, precision agritech, chemical supplies, harvesting and irrigation. Explore Import Sector 06 Import &amp; Sourcing Factory-direct procurement, freight, customs clearance and last-mile delivery across Zimbabwe. Explore Export Sector 07 Export &amp; Trade Zimbabwean produce, commodities and manufactured goods exported to international buyers worldwide. Explore Supplies Sector 08 Supplies &amp; Equipment Machinery, tools, hardware, building materials and home goods \u2014 factory-direct B2B supply. Explore Builders24 delivers construction, trade and supply services across Zimbabwe \u2014 serving residential homeowners, commercial developers, industrial operators, agricultural businesses, importers, exporters and B2B buyers, with cross-border logistics from Zimbabwe into the wider SADC region. Get a Quote Your Cart Clear Cart Loading&hellip; Subtotal$0.00 Checkout View Full Cart<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-5586","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/pages\/5586","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/comments?post=5586"}],"version-history":[{"count":45,"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/pages\/5586\/revisions"}],"predecessor-version":[{"id":153411,"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/pages\/5586\/revisions\/153411"}],"wp:attachment":[{"href":"https:\/\/builders24.net\/zw\/wp-json\/wp\/v2\/media?parent=5586"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}