<?php
/**
* The main template file - Ultra Performance + Beautiful Categories
* @package Kahuna
*/
get_header(); ?>
<div id="container" class="<?php echo kahuna_get_layout_class(); ?>">
<main id="main" role="main" class="main">
<?php cryout_before_content_hook(); ?>
<?php
// ── Pre-fetch all data before any HTML output ──
$cats = get_terms(array(
'taxonomy' => 'product_cat',
'hide_empty' => true,
'parent' => 0,
'number' => 12,
'orderby' => 'count',
'order' => 'DESC',
));
$q = new WP_Query(array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'no_found_rows' => true,
'update_post_term_cache' => true,
'meta_query' => array(array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '=',
)),
));
$cat_icons = array(
'ابزار دیجیتال' => array('icon'=>'📱','bg'=>'#fff0f2','color'=>'#c0223a','border'=>'#ffc8d0','grd'=>'linear-gradient(135deg,#ff6b8a,#ef4056)'),
'خانه و آشپزخانه' => array('icon'=>'🏠','bg'=>'#e8f4ff','color'=>'#1557a0','border'=>'#b0d4ff','grd'=>'linear-gradient(135deg,#4da6ff,#1a78c2)'),
'زیبایی و بهداشت' => array('icon'=>'💄','bg'=>'#fff0fa','color'=>'#a01060','border'=>'#ffb0e0','grd'=>'linear-gradient(135deg,#ff80c8,#e040a0)'),
'سفر و تفریح' => array('icon'=>'🎒','bg'=>'#fff8e6','color'=>'#8a5500','border'=>'#ffd060','grd'=>'linear-gradient(135deg,#ffc040,#e09000)'),
'کودک و نوجوان' => array('icon'=>'🧸','bg'=>'#f3eeff','color'=>'#5c30a0','border'=>'#cbb0ff','grd'=>'linear-gradient(135deg,#a06ae0,#7040c0)'),
'لوازم خودرو' => array('icon'=>'🚗','bg'=>'#edfaf5','color'=>'#0a6e43','border'=>'#9fe8c8','grd'=>'linear-gradient(135deg,#40d090,#00a060)'),
'لوازم جانبی' => array('icon'=>'🔌','bg'=>'#e8fbff','color'=>'#0a6e7e','border'=>'#80e4f4','grd'=>'linear-gradient(135deg,#40d8f0,#0098b0)'),
'سیستم هوشمند' => array('icon'=>'💡','bg'=>'#fff5ee','color'=>'#904010','border'=>'#ffbf90','grd'=>'linear-gradient(135deg,#ff9050,#e06020)'),
'پوشاک' => array('icon'=>'👗','bg'=>'#fdf0ff','color'=>'#800090','border'=>'#e0a0ff','grd'=>'linear-gradient(135deg,#d060f0,#a020c0)'),
'ورزش' => array('icon'=>'🏃','bg'=>'#f0fff8','color'=>'#006840','border'=>'#80e8b0','grd'=>'linear-gradient(135deg,#40e880,#00b858)'),
);
$cart_url = wc_get_cart_url();
$ajax_url = admin_url('admin-ajax.php');
// Pre-process products
$products_data = array();
if ($q->have_posts()) {
$badges = ['پرفروش','جدید','تخفیف'];
$b_cls = ['bg-best','bg-new','bg-hot'];
$cnt = 0;
while ($q->have_posts()) {
$q->the_post();
$product = wc_get_product(get_the_ID());
if (!$product) continue;
$pid = get_the_ID();
$cnt++;
$img_id = $product->get_image_id();
$img_sm = $img_id ? wp_get_attachment_image_url($img_id, 'woocommerce_thumbnail') : wc_placeholder_img_src();
$img_lg = $img_id ? wp_get_attachment_image_url($img_id, 'woocommerce_single') : wc_placeholder_img_src();
$raw_desc = $product->get_short_description() ?: $product->get_description();
$desc_full = wp_trim_words(strip_tags($raw_desc), 30, '...');
$reg = (float)$product->get_regular_price();
$sale_p = (float)$product->get_price();
$on_sale = $product->is_on_sale();
$disc = ($on_sale && $reg > 0) ? round((($reg - $sale_p) / $reg) * 100) : 0;
$stock = $product->get_stock_quantity();
if ($stock !== null && $stock <= 0) continue;
$s_label = $s_class = '';
if ($stock !== null) {
if ($stock < 10) { $s_label = "فقط {$stock} عدد!"; $s_class = 's-low'; }
else { $s_label = "{$stock} موجود"; $s_class = 's-ok'; }
}
$p_terms = get_the_terms($pid, 'product_cat');
$cat_slugs = ($p_terms && !is_wp_error($p_terms)) ? implode(' ', wp_list_pluck($p_terms, 'slug')) : '';
$rating = $product->get_average_rating();
$stars = str_repeat('★', min(5, max(0, round($rating)))) . str_repeat('☆', 5 - min(5, max(0, round($rating))));
$nonce = wp_create_nonce('add_to_cart_nonce_' . $pid);
$bi = ($cnt - 1) % 3;
$products_data[] = compact('pid','cnt','img_sm','img_lg','desc_full','reg','sale_p','on_sale','disc','stock','s_label','s_class','cat_slugs','rating','stars','nonce','bi','badges','b_cls');
}
wp_reset_postdata();
}
$total_products = count($products_data);
?>
<style>
/* ============================================================
CRITICAL CSS — paint-blocking minimum
============================================================ */
:root{
--p:#ef4056;--p-d:#d63447;--p-l:#fff0f2;
--ok:#00a049;--ok-l:#edfaf5;
--dark:#1e2235;--mid:#81858b;
--border:#e8e8f0;--bg:#f4f5fa;--white:#fff;
--text:#3f4064;--r:14px;--r-sm:8px;
--sh:0 2px 12px rgba(30,34,53,.07);
--sh-h:0 10px 32px rgba(30,34,53,.16);
--t:all .22s cubic-bezier(.4,0,.2,1);
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{-webkit-tap-highlight-color:transparent}
.shop-wrap{background:var(--bg);font-family:'Vazirmatn','Tahoma',sans-serif;direction:rtl;min-height:100vh}
/* ============================================================
★ CATEGORIES — Hero redesign
============================================================ */
/* Sticky wrapper */
.cats-sticky{
position:sticky;top:0;z-index:300;
background:var(--white);
box-shadow:0 2px 16px rgba(30,34,53,.10);
}
/* Top label bar */
.cats-label{
display:flex;align-items:center;justify-content:space-between;
padding:10px 16px 0;
max-width:1180px;margin:0 auto;
}
.cats-label-txt{
font-size:11px;font-weight:700;color:var(--mid);
letter-spacing:.5px;text-transform:uppercase;
}
.cats-see-all{
font-size:11px;font-weight:700;color:var(--p);
text-decoration:none;
display:flex;align-items:center;gap:3px;
}
/* Scrollable row */
.cats-row{
display:flex;align-items:stretch;gap:10px;
padding:10px 16px 14px;
overflow-x:auto;scrollbar-width:none;
-webkit-overflow-scrolling:touch;
max-width:1180px;margin:0 auto;
}
.cats-row::-webkit-scrollbar{display:none}
/* ── ALL chip ── */
.cat-all{
display:inline-flex;flex-direction:column;
align-items:center;justify-content:center;
gap:4px;
flex-shrink:0;
min-width:68px;padding:10px 14px;
border-radius:16px;
background:var(--p);
color:#fff;
border:2.5px solid var(--p-d);
cursor:pointer;
transition:var(--t);
user-select:none;
box-shadow:0 4px 14px rgba(239,64,86,.35);
position:relative;overflow:hidden;
}
.cat-all::after{
content:'';position:absolute;inset:0;
background:linear-gradient(135deg,rgba(255,255,255,.18),transparent);
pointer-events:none;
}
.cat-all:hover{transform:translateY(-3px);box-shadow:0 8px 22px rgba(239,64,86,.45)}
.cat-all.active{box-shadow:0 4px 20px rgba(239,64,86,.55);transform:scale(.97)}
.cat-all .c-icon{font-size:22px;line-height:1}
.cat-all .c-name{font-size:10.5px;font-weight:800;white-space:nowrap}
.cat-all .c-cnt{
font-size:9px;font-weight:700;
background:rgba(255,255,255,.25);
padding:1px 6px;border-radius:20px;
}
/* ── Individual category chip ── */
.cat-chip{
display:inline-flex;flex-direction:column;
align-items:center;justify-content:center;
gap:5px;
flex-shrink:0;
min-width:72px;padding:10px 12px;
border-radius:16px;
cursor:pointer;
transition:var(--t);
user-select:none;
border:2px solid transparent;
position:relative;overflow:hidden;
text-decoration:none;
}
.cat-chip::before{
content:'';
position:absolute;inset:0;
background:linear-gradient(135deg,rgba(255,255,255,.55),rgba(255,255,255,.15));
pointer-events:none;border-radius:14px;
}
.cat-chip:hover{transform:translateY(-3px);filter:brightness(.95)}
.cat-chip.active{
transform:translateY(-2px) scale(.98);
filter:brightness(.92) saturate(1.2);
box-shadow:0 6px 18px rgba(0,0,0,.18);
}
.cat-chip .c-icon{
font-size:24px;line-height:1;
transition:transform .3s cubic-bezier(.34,1.56,.64,1);
}
.cat-chip:hover .c-icon{transform:scale(1.2) rotate(-5deg)}
.cat-chip .c-name{
font-size:10.5px;font-weight:700;
white-space:nowrap;
position:relative;z-index:1;
}
.cat-chip .c-cnt{
font-size:9px;font-weight:700;
background:rgba(0,0,0,.1);
padding:1px 7px;border-radius:20px;
position:relative;z-index:1;
}
/* Active indicator dot */
.cat-chip.active::after,
.cat-all.active::after{
content:'';
position:absolute;
bottom:4px;left:50%;
transform:translateX(-50%);
width:5px;height:5px;
border-radius:50%;
background:rgba(0,0,0,.25);
}
.cat-all.active::after{background:rgba(255,255,255,.6)}
/* Scroll fade edges */
.cats-sticky::before,
.cats-sticky::after{
content:'';position:absolute;top:0;bottom:0;
width:28px;pointer-events:none;z-index:2;
transition:opacity .2s;
}
.cats-sticky::before{
right:0;
background:linear-gradient(to right,transparent,var(--white));
}
.cats-sticky::after{
left:0;
background:linear-gradient(to left,transparent,var(--white));
}
/* ── Pill divider between all and cats ── */
.cats-divider{
width:1.5px;height:44px;
background:var(--border);
flex-shrink:0;align-self:center;
border-radius:2px;
}
/* ============================================================
PRODUCTS SECTION
============================================================ */
.products-wrap{max-width:1180px;margin:0 auto;padding:16px 14px 50px}
.products-top{
display:flex;align-items:center;justify-content:space-between;
margin-bottom:16px;flex-wrap:wrap;gap:8px;
}
.products-top h1{font-size:18px;font-weight:800;color:var(--dark)}
.p-count{
background:var(--white);border:1px solid var(--border);
border-radius:20px;padding:5px 14px;
font-size:12px;color:var(--mid);font-weight:600;
transition:var(--t);
}
/* ============================================================
GRID
============================================================ */
.p-grid{
display:grid;
grid-template-columns:repeat(2,1fr);
gap:12px;
/* GPU hint */
contain:layout style;
}
@media(min-width:600px){.p-grid{grid-template-columns:repeat(3,1fr)}}
@media(min-width:960px){.p-grid{grid-template-columns:repeat(4,1fr);gap:16px}}
@media(min-width:1200px){.p-grid{grid-template-columns:repeat(5,1fr)}}
/* ============================================================
PRODUCT CARD
============================================================ */
.p-card{
background:var(--white);border-radius:var(--r);
overflow:hidden;box-shadow:var(--sh);
transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;
position:relative;
will-change:transform;
contain:layout style paint;
animation:fadeUp .4s ease both;
}
.p-card:hover{box-shadow:var(--sh-h);transform:translateY(-4px)}
@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
/* Image */
.p-img-box{
position:relative;aspect-ratio:1;overflow:hidden;
background:#f4f4f8;cursor:pointer;
}
.p-img-box img{
width:100%;height:100%;object-fit:cover;
transition:transform .4s ease;display:block;
}
.p-card:hover .p-img-box img{transform:scale(1.07)}
.img-ov{
position:absolute;inset:0;
background:rgba(20,24,40,.4);
display:flex;align-items:center;justify-content:center;
opacity:0;transition:opacity .22s;
}
.p-card:hover .img-ov{opacity:1}
.ov-btn{
background:var(--white);color:var(--dark);border:none;
padding:8px 16px;border-radius:30px;
font-size:12px;font-weight:700;cursor:pointer;
transform:translateY(10px);transition:var(--t);
display:flex;align-items:center;gap:5px;
font-family:'Vazirmatn','Tahoma',sans-serif;
}
.p-card:hover .ov-btn{transform:translateY(0)}
.ov-btn:hover{background:var(--p);color:#fff}
/* Badges */
.p-badge{
position:absolute;top:8px;right:8px;
padding:3px 9px;border-radius:20px;
font-size:10px;font-weight:800;color:#fff;z-index:3;
}
.bg-best{background:linear-gradient(135deg,#00c272,#009956)}
.bg-new{background:linear-gradient(135deg,#19bfd3,#0e9ab0)}
.bg-hot{background:linear-gradient(135deg,#ff7b00,#e05a00)}
.disc-c{
position:absolute;top:8px;left:8px;
width:36px;height:36px;background:var(--p);
color:#fff;border-radius:50%;
display:flex;align-items:center;justify-content:center;
font-size:10px;font-weight:800;z-index:3;
box-shadow:0 2px 8px rgba(239,64,86,.4);
animation:pc 2s ease infinite;
}
@keyframes pc{0%,100%{box-shadow:0 2px 8px rgba(239,64,86,.4)}50%{box-shadow:0 2px 18px rgba(239,64,86,.7)}}
.stk-tag{
position:absolute;bottom:8px;left:8px;
padding:3px 8px;border-radius:20px;
font-size:9.5px;font-weight:700;color:#fff;z-index:3;
}
.s-ok{background:rgba(0,160,73,.85)}
.s-low{background:rgba(239,64,86,.92);animation:bk .9s ease infinite alternate}
@keyframes bk{from{opacity:.8}to{opacity:1;transform:scale(1.04)}}
/* Body */
.p-body{padding:12px}
.p-title{
font-size:13px;font-weight:600;color:var(--text);
line-height:1.55;
display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
min-height:40px;margin-bottom:8px;text-decoration:none;
}
.p-title:hover{color:var(--p)}
.p-rating{display:flex;align-items:center;gap:4px;margin-bottom:8px}
.stars{color:#ffc107;font-size:11px;letter-spacing:1px}
.rating-n{font-size:11px;color:var(--mid)}
.p-price-box{margin-bottom:10px}
.p-orig{font-size:11px;color:var(--mid);text-decoration:line-through;display:block;line-height:1.5}
.p-curr{display:flex;align-items:baseline;gap:4px;font-size:15px;font-weight:800;color:var(--dark)}
.p-curr .tmn{font-size:11px;font-weight:500;color:var(--mid)}
.p-sale .p-curr{color:var(--p)}
/* Qty */
.qty-row{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.qty-lbl{font-size:11px;color:var(--mid);flex-shrink:0}
.qty-box{
display:flex;align-items:center;
border:1.5px solid var(--border);border-radius:var(--r-sm);
overflow:hidden;background:var(--white);flex:1;
}
.q-btn{
width:32px;height:32px;background:var(--bg);border:none;
font-size:18px;font-weight:700;color:var(--text);cursor:pointer;
display:flex;align-items:center;justify-content:center;
transition:var(--t);flex-shrink:0;user-select:none;
}
.q-btn:hover{background:var(--p);color:#fff}
.q-btn:active{transform:scale(.88)}
.q-val{flex:1;text-align:center;font-size:14px;font-weight:800;color:var(--dark);transition:transform .12s}
/* Cart button */
.btn-cart{
width:100%;padding:11px;border:none;border-radius:var(--r-sm);
background:var(--p);color:#fff;font-size:13px;font-weight:700;
cursor:pointer;position:relative;overflow:hidden;transition:var(--t);
display:flex;align-items:center;justify-content:center;gap:7px;
font-family:'Vazirmatn','Tahoma',sans-serif;
}
.btn-cart:hover:not(:disabled){background:var(--p-d);transform:translateY(-1px)}
.btn-cart:active:not(:disabled){transform:scale(.97)}
.btn-cart:disabled{cursor:not-allowed}
.btn-cart.st-loading{background:#a0a0b0;pointer-events:none}
.btn-cart.st-success{background:var(--ok);pointer-events:none}
.btn-cart.st-error{background:#e04060}
.btn-spin{
width:15px;height:15px;border:2px solid rgba(255,255,255,.35);
border-top-color:#fff;border-radius:50%;
animation:spin .7s linear infinite;flex-shrink:0;
}
@keyframes spin{to{transform:rotate(360deg)}}
.ripple{
position:absolute;border-radius:50%;
background:rgba(255,255,255,.3);
transform:scale(0);animation:rpl .55s ease-out forwards;
pointer-events:none;
}
@keyframes rpl{to{transform:scale(4.5);opacity:0}}
.chk-hint{
display:none;margin-top:8px;
background:var(--ok-l);border:1px solid #9fe8c8;
border-radius:var(--r-sm);padding:8px 12px;
font-size:11.5px;font-weight:600;color:#0a6e43;
text-align:center;animation:fadeUp .25s ease;
}
.chk-hint.show{display:block}
.chk-hint a{color:#0a6e43;font-weight:800;text-decoration:underline}
/* ============================================================
QUICK VIEW MODAL
============================================================ */
.qv-bd{
position:fixed;inset:0;background:rgba(10,12,26,.6);
z-index:9000;opacity:0;pointer-events:none;
transition:opacity .25s;backdrop-filter:blur(5px);
-webkit-backdrop-filter:blur(5px);
}
.qv-bd.open{opacity:1;pointer-events:all}
.qv-modal{
position:fixed;bottom:0;left:0;right:0;
background:var(--white);border-radius:22px 22px 0 0;
z-index:9001;max-height:92vh;overflow-y:auto;
transform:translateY(100%);
transition:transform .32s cubic-bezier(.32,0,.15,1);
padding:0 0 30px;scrollbar-width:thin;
}
.qv-modal.open{transform:translateY(0)}
@media(min-width:768px){
.qv-modal{
bottom:auto;top:50%;left:50%;right:auto;
width:90%;max-width:700px;border-radius:var(--r);
transform:translate(-50%,-42%);opacity:0;max-height:88vh;
transition:transform .3s cubic-bezier(.32,0,.15,1),opacity .3s;
}
.qv-modal.open{transform:translate(-50%,-50%);opacity:1}
}
.qv-handle{width:40px;height:4px;background:#ddd;border-radius:4px;margin:12px auto 0}
.qv-close{
position:absolute;top:12px;left:16px;width:34px;height:34px;
border-radius:50%;background:var(--bg);border:none;
font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;
color:var(--mid);transition:var(--t);z-index:2;
}
.qv-close:hover{background:#f0d0d4;color:var(--p)}
.qv-inner{padding:0 18px 10px}
.qv-img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:var(--r);margin-bottom:14px;background:#f4f4f8;display:block}
.qv-title{font-size:16px;font-weight:800;color:var(--dark);margin-bottom:8px;line-height:1.5}
.qv-desc{font-size:13px;color:var(--mid);line-height:1.7;margin-bottom:14px}
.qv-price-row{display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.qv-curr{font-size:20px;font-weight:800;color:var(--dark)}
.qv-curr.sale{color:var(--p)}
.qv-orig{font-size:13px;color:var(--mid);text-decoration:line-through}
.qv-disc{background:var(--p-l);color:var(--p);padding:3px 10px;border-radius:20px;font-size:12px;font-weight:700}
.qv-qty-row{display:flex;align-items:center;gap:12px;margin-bottom:16px}
.qv-qty-box{display:flex;align-items:center;border:2px solid var(--border);border-radius:10px;overflow:hidden}
.qv-qty-box .q-btn{width:38px;height:38px}
.qv-qty-box .q-val{min-width:46px;font-size:16px}
.qv-acts{display:flex;gap:10px}
.qv-view{
flex:0 0 auto;padding:12px 18px;border:2px solid var(--border);
border-radius:var(--r-sm);background:var(--white);color:var(--text);
font-size:13px;font-weight:700;cursor:pointer;text-decoration:none;
display:inline-flex;align-items:center;gap:6px;transition:var(--t);
font-family:'Vazirmatn','Tahoma',sans-serif;
}
.qv-view:hover{border-color:var(--p);color:var(--p)}
.qv-btn-cart{
flex:1;padding:12px;border:none;border-radius:var(--r-sm);
background:var(--p);color:#fff;font-size:14px;font-weight:800;
cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;
transition:var(--t);position:relative;overflow:hidden;
font-family:'Vazirmatn','Tahoma',sans-serif;
}
.qv-btn-cart:hover{background:var(--p-d)}
.qv-btn-cart.st-success{background:var(--ok);pointer-events:none}
.qv-btn-cart.st-loading{background:#a0a0b0;pointer-events:none}
/* ============================================================
TOAST
============================================================ */
.g-toast{
position:fixed;top:16px;left:50%;
transform:translateX(-50%) translateY(-90px);
background:var(--ok);color:#fff;
padding:11px 22px;border-radius:30px;
box-shadow:0 6px 24px rgba(0,160,73,.38);
z-index:99999;font-size:13px;font-weight:700;
display:flex;align-items:center;gap:8px;
transition:transform .35s cubic-bezier(.34,1.56,.64,1);
pointer-events:none;white-space:nowrap;max-width:90vw;
}
.g-toast.show{transform:translateX(-50%) translateY(0)}
.g-toast.t-err{background:#e04060;box-shadow:0 6px 24px rgba(224,64,96,.38)}
/* ============================================================
SUPPORT SECTION
============================================================ */
.sup-sec{background:linear-gradient(135deg,#fff9fa,#f0f8ff);border-top:1px solid var(--border);padding:32px 16px}
.sup-in{max-width:680px;margin:0 auto;text-align:center}
.sup-in h2{font-size:17px;font-weight:800;color:var(--dark);margin-bottom:7px}
.sup-in p{font-size:13px;color:var(--mid);margin-bottom:18px}
.sup-feats{display:flex;justify-content:center;flex-wrap:wrap;gap:8px;margin-bottom:20px}
.sup-feat{display:inline-flex;align-items:center;gap:5px;padding:6px 13px;border-radius:20px;font-size:12px;font-weight:600}
.sup-feat:nth-child(1){background:#edfaf5;color:#0a6e43}
.sup-feat:nth-child(2){background:#e8f4ff;color:#1557a0}
.sup-feat:nth-child(3){background:#fff8e6;color:#8a5500}
.sup-feat:nth-child(4){background:#f3eeff;color:#5c30a0}
.sup-btns{display:flex;justify-content:center;gap:12px;flex-wrap:wrap}
.sup-btn{
display:inline-flex;align-items:center;gap:9px;
padding:12px 22px;border-radius:12px;text-decoration:none;
color:#fff;font-size:13px;font-weight:700;
transition:var(--t);box-shadow:0 3px 12px rgba(0,0,0,.14);
}
.sup-btn:hover{transform:translateY(-2px);box-shadow:0 7px 20px rgba(0,0,0,.2)}
.wa{background:linear-gradient(135deg,#25d366,#18a850)}
.tg{background:linear-gradient(135deg,#0088cc,#006ab0)}
/* ============================================================
RESPONSIVE TWEAKS
============================================================ */
@media(max-width:380px){
.p-body{padding:9px}
.p-title{font-size:12px}
.p-curr{font-size:13px}
.btn-cart{font-size:11.5px;padding:9px}
.cat-chip,.cat-all{min-width:60px;padding:8px 10px}
.cat-chip .c-icon,.cat-all .c-icon{font-size:20px}
}
@media(max-width:320px){
.cats-row{gap:7px;padding:8px 12px 12px}
}
</style>
<!-- TOAST -->
<div class="g-toast" id="gToast">
<span id="tIcon">✅</span>
<span id="tTxt">محصول به سبد اضافه شد</span>
</div>
<!-- QUICK VIEW MODAL -->
<div class="qv-bd" id="qvBd" onclick="closeQV()"></div>
<div class="qv-modal" id="qvModal" role="dialog" aria-modal="true">
<div class="qv-handle"></div>
<button class="qv-close" onclick="closeQV()">✕</button>
<div class="qv-inner" id="qvInner"></div>
</div>
<div class="shop-wrap">
<!-- ============================================================
★ CATEGORIES BAR
============================================================ -->
<nav class="cats-sticky" id="catNav" aria-label="دستهبندی محصولات">
<div class="cats-label">
<span class="cats-label-txt">📂 دستهبندیها</span>
<a href="#shopSection" class="cats-see-all">مشاهده همه ←</a>
</div>
<div class="cats-row" id="catsRow">
<!-- ALL button -->
<button class="cat-all active" data-cat="all" onclick="filterP('all',this)">
<span class="c-icon">🛍️</span>
<span class="c-name">همه</span>
<span class="c-cnt"><?php echo $total_products; ?></span>
</button>
<div class="cats-divider"></div>
<?php
if ($cats && !is_wp_error($cats)):
foreach ($cats as $i => $cat):
$info = $cat_icons[$cat->name] ?? array('icon'=>'📦','bg'=>'#f4f4f8','color'=>'#555','border'=>'#ddd','grd'=>'linear-gradient(135deg,#888,#555)');
$slug = esc_attr($cat->slug);
$style = "background:{$info['bg']};color:{$info['color']};border-color:{$info['border']}";
?>
<button class="cat-chip"
data-cat="<?php echo $slug; ?>"
style="<?php echo $style; ?>"
onclick="filterP('<?php echo $slug; ?>',this)">
<span class="c-icon"><?php echo $info['icon']; ?></span>
<span class="c-name"><?php echo esc_html($cat->name); ?></span>
<span class="c-cnt"><?php echo $cat->count; ?></span>
</button>
<?php
endforeach;
endif;
?>
</div>
</nav>
<!-- ============================================================
PRODUCTS
============================================================ -->
<section id="shopSection">
<div class="products-wrap">
<div class="products-top">
<h1>🏪 فروشگاه منزل هوشمند</h1>
<span class="p-count" id="pCount"><?php echo $total_products; ?> محصول</span>
</div>
<div class="p-grid" id="pGrid">
<?php foreach ($products_data as $pd): extract($pd); ?>
<div class="p-card"
data-cats="<?php echo esc_attr($cat_slugs); ?>"
data-pid="<?php echo $pid; ?>"
style="animation-delay:<?php echo min($cnt * .05, .65); ?>s">
<!-- IMAGE -->
<div class="p-img-box"
onclick="openQV(<?php echo $pid; ?>,'<?php echo esc_js(get_the_title($pid)); ?>','<?php echo esc_js($img_lg); ?>','<?php echo esc_js($desc_full); ?>',<?php echo $sale_p; ?>,<?php echo $reg; ?>,<?php echo (int)$on_sale; ?>,<?php echo $disc; ?>,<?php echo $stock ?: 999; ?>,'<?php echo esc_js(get_permalink($pid)); ?>','<?php echo esc_js($nonce); ?>')">
<img src="<?php echo esc_url($img_sm); ?>"
alt="<?php echo esc_attr(get_the_title($pid)); ?>"
loading="lazy" decoding="async"
width="300" height="300">
<div class="img-ov">
<button class="ov-btn"><span>🔍</span> مشاهده سریع</button>
</div>
<span class="p-badge <?php echo $b_cls[$bi]; ?>"><?php echo $badges[$bi]; ?></span>
<?php if ($disc > 0): ?><span class="disc-c"><?php echo $disc; ?>٪</span><?php endif; ?>
<?php if ($s_label): ?><span class="stk-tag <?php echo $s_class; ?>"><?php echo $s_label; ?></span><?php endif; ?>
</div>
<!-- BODY -->
<div class="p-body">
<a href="<?php echo get_permalink($pid); ?>" class="p-title">
<?php echo esc_html(wp_trim_words(get_the_title($pid), 7, '...')); ?>
</a>
<div class="p-rating">
<span class="stars"><?php echo $stars; ?></span>
<?php if ($rating > 0): ?><span class="rating-n">(<?php echo $rating; ?>)</span><?php endif; ?>
</div>
<div class="p-price-box <?php echo $on_sale ? 'p-sale' : ''; ?>">
<?php if ($on_sale && $reg): ?><span class="p-orig"><?php echo number_format($reg); ?> تومان</span><?php endif; ?>
<span class="p-curr"><?php echo number_format($sale_p); ?><span class="tmn">تومان</span></span>
</div>
<div class="qty-row">
<span class="qty-lbl">تعداد:</span>
<div class="qty-box">
<button class="q-btn" onclick="qC(<?php echo $pid; ?>,-1)" aria-label="کم">−</button>
<span class="q-val" id="qv-<?php echo $pid; ?>">1</span>
<button class="q-btn" onclick="qC(<?php echo $pid; ?>,1,<?php echo $stock ?: 99; ?>)" aria-label="زیاد">+</button>
</div>
</div>
<button class="btn-cart"
id="bc-<?php echo $pid; ?>"
data-pid="<?php echo $pid; ?>"
data-nonce="<?php echo $nonce; ?>"
onclick="aC(this,<?php echo $pid; ?>)">
<span>🛒</span><span>افزودن به سبد</span>
</button>
<div class="chk-hint" id="ch-<?php echo $pid; ?>">
🎉 عالی! <a href="<?php echo esc_url($cart_url); ?>">تکمیل خرید ←</a>
</div>
</div>
</div>
<?php endforeach; ?>
<?php if (empty($products_data)): ?>
<p style="grid-column:1/-1;text-align:center;padding:50px;color:var(--mid)">محصولی یافت نشد!</p>
<?php endif; ?>
</div><!-- /#pGrid -->
</div>
</section>
<!-- SUPPORT -->
<section class="sup-sec">
<div class="sup-in">
<h2>📞 پشتیبانی و راهنمایی</h2>
<p>تیم ما آماده پاسخگویی ۲۴ ساعته است</p>
<div class="sup-feats">
<span class="sup-feat">✅ پرداخت درب منزل</span>
<span class="sup-feat">✅ تضمین کیفیت</span>
<span class="sup-feat">✅ پشتیبانی ۲۴ ساعته</span>
<span class="sup-feat">✅ مرجوع آسان</span>
</div>
<div class="sup-btns">
<a href="https://wa.me/989194218570" class="sup-btn wa" target="_blank" rel="noopener">📱 واتساپ: 09194218570</a>
<a href="https://t.me/+989194218570" class="sup-btn tg" target="_blank" rel="noopener">💬 تلگرام: 09194218570</a>
</div>
</div>
</section>
</div>
<!-- ============================================================
JAVASCRIPT — deferred, minimal
============================================================ -->
<script>
!function(){
'use strict';
/* ── Config ── */
var AJAX='<?php echo esc_js($ajax_url); ?>';
var CART_URL='<?php echo esc_js($cart_url); ?>';
var qMap={};
/* ── Qty ── */
function qC(pid,d,max){
var v=(qMap[pid]||1)+d;
if(v<1)v=1; if(max&&v>max)v=max;
qMap[pid]=v;
var el=document.getElementById('qv-'+pid);
if(el){
el.textContent=v;
el.style.transform='scale(1.3)';
el.style.transition='transform .12s';
setTimeout(function(){el.style.transform='scale(1)'},120);
}
var mel=document.getElementById('mqv-'+pid);
if(mel)mel.textContent=v;
}
window.qC=qC;
/* ── Toast ── */
var _tt;
function toast(msg,err){
var t=document.getElementById('gToast');
var ic=document.getElementById('tIcon');
var tx=document.getElementById('tTxt');
t.classList.remove('show','t-err');
if(err)t.classList.add('t-err');
ic.textContent=err?'❌':'✅';
tx.textContent=msg;
void t.offsetWidth;
t.classList.add('show');
clearTimeout(_tt);
_tt=setTimeout(function(){t.classList.remove('show')},3200);
}
/* ── Ripple ── */
function ripple(btn,e){
var r=document.createElement('span');
var rc=btn.getBoundingClientRect();
var sz=Math.max(rc.width,rc.height);
r.className='ripple';
r.style.cssText='width:'+sz+'px;height:'+sz+'px;left:'+(e.clientX-rc.left-sz/2)+'px;top:'+(e.clientY-rc.top-sz/2)+'px';
btn.appendChild(r);
setTimeout(function(){r.remove()},560);
}
/* ── Core add-to-cart ── */
function doATC(pid,qty,btn,hintId,isModal){
if(!btn)return;
btn.classList.add('st-loading');
btn.disabled=true;
btn.innerHTML='<span class="btn-spin"></span><span>در حال افزودن...</span>';
var body=new URLSearchParams();
body.append('action','woocommerce_add_to_cart');
body.append('product_id',pid);
body.append('quantity',qty);
body.append('nonce',btn.dataset.nonce||'');
fetch(AJAX,{
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body:body.toString(),
credentials:'same-origin'
})
.then(function(r){return r.text()})
.then(function(){
btn.classList.remove('st-loading');
btn.disabled=false;
btn.classList.add('st-success');
btn.innerHTML=(isModal?'':'<span>✅</span><span>')+'اضافه شد!'+(isModal?'':'</span>');
toast('محصول به سبد اضافه شد 🎉');
if(hintId){var h=document.getElementById(hintId);if(h)h.classList.add('show')}
document.body.dispatchEvent(new CustomEvent('wc_fragment_refresh'));
document.body.dispatchEvent(new CustomEvent('added_to_cart'));
setTimeout(function(){
btn.classList.remove('st-success');
btn.innerHTML=isModal?'🛒 افزودن به سبد':'<span>🛒</span><span>افزودن به سبد</span>';
btn.disabled=false;
},4000);
})
.catch(function(){
btn.classList.remove('st-loading');
btn.disabled=false;
btn.classList.add('st-error');
btn.innerHTML='<span>❌</span><span>خطا! دوباره امتحان</span>';
toast('خطا در افزودن به سبد!',true);
setTimeout(function(){
btn.classList.remove('st-error');
btn.innerHTML='<span>🛒</span><span>افزودن به سبد</span>';
},3500);
});
}
function aC(btn,pid){ripple(btn,event);doATC(pid,qMap[pid]||1,btn,'ch-'+pid,false)}
window.aC=aC;
/* ── Category filter ── */
function filterP(slug,chip){
document.querySelectorAll('.cat-chip,.cat-all').forEach(function(c){c.classList.remove('active')});
chip.classList.add('active');
var cards=document.querySelectorAll('.p-card'),vis=0;
cards.forEach(function(c){
var show=slug==='all'||c.dataset.cats.split(' ').indexOf(slug)!==-1;
c.style.display=show?'':'none';
if(show)vis++;
});
var el=document.getElementById('pCount');
if(el)el.textContent=vis+' محصول';
var sec=document.getElementById('shopSection');
if(sec)sec.scrollIntoView({behavior:'smooth',block:'start'});
}
window.filterP=filterP;
/* ── Quick View Modal ── */
var _qvPid=null;
function numF(n){return parseInt(n).toLocaleString('fa-IR')}
function escH(s){return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"')}
function openQV(pid,title,img,desc,price,reg,onSale,disc,maxStock,link,nonce){
_qvPid=pid;
var priceHtml='';
if(onSale&®){
priceHtml='<span class="qv-orig">'+numF(reg)+' تومان</span><span class="qv-curr sale">'+numF(price)+' تومان</span>';
if(disc>0)priceHtml+='<span class="qv-disc">−'+disc+'٪</span>';
}else{
priceHtml='<span class="qv-curr">'+numF(price)+' تومان</span>';
}
var cq=qMap[pid]||1;
document.getElementById('qvInner').innerHTML=
'<img class="qv-img" src="'+img+'" alt="'+escH(title)+'" loading="lazy">'+
'<h2 class="qv-title">'+escH(title)+'</h2>'+
'<p class="qv-desc">'+escH(desc||'محصول با کیفیت عالی')+'</p>'+
'<div class="qv-price-row">'+priceHtml+'</div>'+
'<div class="qv-qty-row"><span style="font-size:13px;color:var(--mid)">تعداد:</span>'+
'<div class="qv-qty-box">'+
'<button class="q-btn" onclick="qC('+pid+',-1)">−</button>'+
'<span class="q-val" id="mqv-'+pid+'">'+cq+'</span>'+
'<button class="q-btn" onclick="qC('+pid+',1,'+maxStock+')">+</button>'+
'</div></div>'+
'<div class="qv-acts">'+
'<a href="'+link+'" class="qv-view" target="_blank">🔗 صفحه محصول</a>'+
'<button class="qv-btn-cart" id="qvcb" data-pid="'+pid+'" data-nonce="'+nonce+'" onclick="qvATC(this)">🛒 افزودن به سبد</button>'+
'</div>';
document.getElementById('qvBd').classList.add('open');
document.getElementById('qvModal').classList.add('open');
document.body.style.overflow='hidden';
}
window.openQV=openQV;
function closeQV(){
document.getElementById('qvBd').classList.remove('open');
document.getElementById('qvModal').classList.remove('open');
document.body.style.overflow='';
_qvPid=null;
}
window.closeQV=closeQV;
function qvATC(btn){
ripple(btn,event);
var pid=parseInt(btn.dataset.pid);
doATC(pid,qMap[pid]||1,btn,'ch-'+pid,true);
}
window.qvATC=qvATC;
document.addEventListener('keydown',function(e){if(e.key==='Escape')closeQV()});
/* ── Cats scroll fade ── */
(function(){
var row=document.getElementById('catsRow');
if(!row)return;
var nav=document.getElementById('catNav');
row.addEventListener('scroll',function(){
var atEnd=row.scrollLeft+row.clientWidth>=row.scrollWidth-10;
var atStart=row.scrollLeft<=10;
nav.style.setProperty('--fade-r',atEnd?'0':'1');
nav.style.setProperty('--fade-l',atStart?'0':'1');
});
})();
}();
</script>
<?php
/* ── AJAX handler ── */
if (!function_exists('custom_atc_ajax')) {
function custom_atc_ajax() {
$pid = absint($_POST['product_id'] ?? 0);
$qty = max(1, absint($_POST['quantity'] ?? 1));
if (!$pid) { wp_send_json_error(); }
$ok = WC()->cart->add_to_cart($pid, $qty);
if ($ok) { WC_AJAX::get_refreshed_fragments(); }
else { wp_send_json_error(array('message' => 'error')); }
}
add_action('wp_ajax_woocommerce_add_to_cart', 'custom_atc_ajax');
add_action('wp_ajax_nopriv_woocommerce_add_to_cart', 'custom_atc_ajax');
}
?>
<?php cryout_after_content_hook(); ?>
</main>
<?php kahuna_get_sidebar(); ?>
</div>
<?php get_footer(); ?>