/* ووموو — صفحه محصول: نمایشگر ماژول و پلنر */
/* توکن‌ها در tokens.css، قواعد پایه در base.css */
/* هیچ مقدار رنگ، فاصله یا شعاعی مستقیم نوشته نمی‌شود — فقط var(--...) */

/* ————————————————————————————— نمایشگر عکس */

/* ورقی، نه نواری. عکس‌ها مثل ورق‌های یک دسته کنار هم می‌ایستند و
   هرکدام باز شود پهن می‌شود. همان الگوی «کاروسل ورقی» صفحه اصلی،
   این‌بار برای عکس محصول — یک زبانِ حرکت در کل سایت، نه دو تا.

   چرا نه قابِ پهنِ قبلی: عکس‌های محصول مربع‌اند و قاب پهن با
   object-fit:cover بالا و پایینشان را می‌برید. اینجا ورقِ باز
   خودش تقریباً مربع است — همان نسبت خودِ عکس — پس چیزی بریده
   نمی‌شود. توکن‌های --gal-h و --gal-open برای همین به vw هم بند
   شده‌اند: روی موبایل هم ورق مربع می‌ماند، نه یک نوار باریکِ بلند.

   روی عکس محصول هیچ متنی نمی‌نشیند. شماره‌ها زیر دسته می‌آیند. */

/* پس‌زمینه‌ی وجه‌دار زیر همه‌ی بخش‌هایی که کارت شیشه‌ای دارند.
   روی یک رنگِ کاملاً یک‌دست، شیشه دیده نمی‌شود — چیزی پشتش نیست
   که تار شود. attachment:fixed می‌کند تا وجه‌ها از بخشی به بخش
   بعد ادامه پیدا کنند و درزِ تکرار دیده نشود. */
.gal,.studio,.buy{background-color:var(--page);background-image:var(--facet);
  background-attachment:fixed;background-size:cover;background-repeat:no-repeat}

.gal{position:relative;padding:var(--s8) 0 var(--s7)}

.gal-deck{display:flex;gap:var(--s2);
  height:var(--gal-h);
  padding-inline:clamp(var(--s4),4vw,var(--s7));
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-ms-overflow-style:none;

  /* دسته پهن‌تر از قاب است و اسکرول می‌شود، ولی هیچ نشانه‌ای
     نداشت: نوار پنهان است و آخرین ورق درست روی لبه تمام می‌شد،
     پس شبیه پایانِ فهرست دیده می‌شد نه ادامه‌دار.
     اندازه‌گیری روی محصولی با ۱۴ عکس: عرضِ قاب ۱۴۲۵ و عرضِ
     محتوا ۱۶۹۴ — یعنی سه ورق کاملاً بیرونِ دید بودند.
     محو‌شدنِ لبه همان کاری را می‌کند که برای چیپ‌های فیلتر شد.
     ورق‌ها خودشان مشکلی نداشتند: همه دقیقاً ۷۲ پیکسل‌اند. */
  -webkit-mask-image:linear-gradient(to left,transparent 0,#000 var(--s5),
    #000 calc(100% - var(--s5)),transparent 100%);
  mask-image:linear-gradient(to left,transparent 0,#000 var(--s5),
    #000 calc(100% - var(--s5)),transparent 100%);
  scroll-snap-type:x proximity;
  scroll-padding-inline:clamp(var(--s4),4vw,var(--s7))}
.gal-deck::-webkit-scrollbar{display:none}
.gal-slide{scroll-snap-align:start}

/* هر ورق یک دکمه است، نه یک div: با کیبورد هم باز می‌شود و
   صفحه‌خوان می‌داند که کلیک‌شدنی است. */
.gal-slide{position:relative;flex:0 0 var(--gal-rib);
  margin:0;padding:0;border:0;background:var(--band);
  border-radius:var(--r-card);overflow:hidden;cursor:pointer;
  isolation:isolate;
  box-shadow:inset 0 0 0 var(--hair) var(--gline);
  transition:flex-basis var(--t-slow) var(--e)}
.gal-slide.open{flex-basis:var(--gal-open);cursor:default}

/* روی دسکتاپ، موس هم همان کار کلیک را می‌کند. روی لمسی این بلوک
   اصلاً فعال نمی‌شود، وگرنه یک لمس هم باز می‌کرد هم می‌بست. */
@media (hover:hover) and (pointer:fine){
  .gal-deck:hover .gal-slide:hover{flex-basis:var(--gal-open)}
  .gal-deck:hover .gal-slide.open:not(:hover){flex-basis:var(--gal-rib)}
}

/* قاب عکس داخل ورق. علتِ وجودش در product-gallery.php نوشته شده.
   انتخابگرها عمداً دو کلاسی‌اند: استایل پیش‌فرض ووکامرس روی img
   بعد از قالب بارگذاری می‌شود و با وزن برابر برنده می‌شد. */
.gal-slide .gal-shot{position:absolute;inset:0;display:block;
  overflow:hidden;border-radius:inherit}
.gal-slide .gal-img{width:100%;height:100%;max-width:none;
  object-fit:cover;object-position:center;display:block;
  -webkit-user-drag:none;user-select:none}

.gal-slide:focus-visible{outline:1.5px solid var(--signal);outline-offset:2px}

/* شماره و شاخص‌ها — زیر دسته، نه روی عکس */
.gal-pager{display:flex;align-items:center;gap:var(--s3);
  margin-top:var(--s5);padding-inline:clamp(var(--s4),4vw,var(--s7))}

/* شاخص‌ها با تعداد عکس‌ها کم و زیاد می‌شوند، نه با عرض ثابت.
   با عرض ثابتِ ۲۴ پیکسل، محصولی با ۱۴ عکس نواری ۳۸۸ پیکسلی
   می‌ساخت که روی موبایل کل صفحه را به پهلو می‌کشید و دکمه‌ی
   منو را از کادر بیرون می‌برد. حالا نوار هرچه جا هست را
   می‌گیرد و شاخص‌ها بینشان تقسیم می‌شوند — تا سقف ۲۴ پیکسل،
   که همان اندازه‌ی قبلی است، پس روی گالری‌های کوتاه هیچ فرقی
   نمی‌کند. min-width:0 لازم است وگرنه آیتم فلکس کوچک‌تر از
   محتوایش نمی‌شود و همان سرریز برمی‌گردد. */
.gal-pager .ticks{display:flex;gap:var(--s1);flex:1 1 auto;min-width:0}
.gal-pager .tick{flex:1 1 0;min-width:6px;max-width:var(--s5);
  height:var(--hair);background:var(--gline);
  border:0;padding:0;cursor:pointer;
  transition:background var(--t-fast) var(--e),height var(--t-fast) var(--e)}
.gal-pager .tick.on{background:var(--signal);height:1.5px}

/* ————————————————————————————— سه کارت */

/* زیر عکس، در جریان صفحه — نه رویش. کارت روی محصول نمی‌نشیند:
   محصول باید کامل دیده شود، همان اصل «محصول مثل مجسمه، در نور». */
/* هر سه کارت هم‌اندازه‌اند — ارتفاعشان از محتوا نمی‌آید، ثابت است.
   محتوای بلندتر داخل خودِ کارت اسکرول می‌شود، نه اینکه کارت را
   بکشد و ردیف را نامرتب کند. */
/* auto-fit نه repeat(3): کارتِ «دانلود» وقتی فایلی ندارد اصلاً
   چاپ نمی‌شود (product-gallery.php)، پس تعداد کارت‌ها ثابت
   نیست. با ستونِ ثابتِ سه‌تایی، جای کارتِ نبوده خالی می‌ماند. */
.gal-cards{display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));
  gap:var(--s4);align-items:stretch;
  padding:0 clamp(var(--s4),4vw,var(--s7)) var(--s8)}

.gcard{position:relative;z-index:1;
  display:flex;flex-direction:column;gap:var(--s2);
  padding:var(--s5);
  height:clamp(190px,26vh,268px);
  transition:transform var(--t-mid) var(--e),
             border-color var(--t-fast) var(--e)}

/* حالا که پشتِ کارت عکس نیست، تنتِ نازک کافی است */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .gcard{background:var(--glass-thin);
    backdrop-filter:var(--glass-filter);
    -webkit-backdrop-filter:var(--glass-filter)}
}

/* کارت زیر موس بالا می‌آید — اندازه‌اش عوض نمی‌شود */
.gcard:hover,.gcard:focus-within{
  z-index:3;
  transform:translateY(calc(var(--s3) * -1));
  border-color:var(--signal)}

.gcard > .label{flex-shrink:0}
/* عنوان کارت پیش‌تر <h3> بود و حالا <p> است — دلیلش در
   product-gallery.php نوشته شده (ترتیب سرفصل‌های صفحه). وزن
   دستی ست می‌شود چون <p> برخلاف <h3> پررنگ نیست و بدون این
   خط ظاهر کارت‌ها عوض می‌شد. */
.gcard-t{margin:var(--s1) 0 var(--s2);font-size:var(--fs-body);
  font-weight:500;flex-shrink:0}

/* ناحیه اسکرول‌شونده. min-height:0 لازم است وگرنه آیتم فلکس
   کوتاه نمی‌شود و به‌جای اسکرول، از کارت بیرون می‌زند. */
.gcard-body{flex:1;min-height:0;
  overflow-y:auto;overscroll-behavior:contain;
  display:flex;flex-direction:column;gap:var(--s3);
  scrollbar-width:thin}
.gcard-body::-webkit-scrollbar{width:3px}
.gcard-body::-webkit-scrollbar-thumb{background:var(--gline);border-radius:var(--r-full)}
.gcard-body p{color:var(--muted);font-size:var(--fs-body-s)}
.gcard-lede{color:var(--ink)!important}
.gcard-empty{color:var(--muted);font-size:var(--fs-micro)}

/* فایل‌ها */
.gfiles{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--s1)}
.gfiles a{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  padding:var(--s2) 0;border-bottom:var(--hair) solid var(--gline);
  transition:color var(--t-fast) var(--e)}
.gfiles li:last-child a{border-bottom:0}
.gfiles a:hover{color:var(--signal)}
.gfile-n{font-size:var(--fs-body-s)}
.gfile-m{flex-shrink:0;color:var(--muted)}

/* دیتاشیت */
.gspecs{margin:0;display:flex;flex-direction:column;gap:var(--s1)}
.gspec{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  padding:var(--s1) 0;border-bottom:var(--hair) solid var(--gline)}
.gspec:last-child{border-bottom:0}
.gspec dt{font-size:var(--fs-micro);color:var(--muted)}
.gspec dd{margin:0;font-size:var(--fs-body-s);direction:ltr;
  unicode-bidi:isolate;font-variant-numeric:tabular-nums;text-align:left}

.gsheet{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  margin-top:var(--s2);padding:var(--s3) var(--s4);
  border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  font-size:var(--fs-body-s);
  transition:border-color var(--t-fast) var(--e),color var(--t-fast) var(--e)}
.gsheet:hover{border-color:var(--signal);color:var(--signal)}

@media (max-width:900px){
  /* attachment:fixed روی موبایل هر اسکرول را دوباره رنگ می‌زند */
  .gal,.studio,.buy{background-attachment:scroll}

  .gal{padding:var(--s6) 0 var(--s5)}
  .gal-deck{gap:var(--s1)}

  /* کارت‌ها یک نوار افقی قابل‌کشیدن می‌شوند */
  .gal-cards{grid-template-columns:none;
    display:flex;gap:var(--s3);
    overflow-x:auto;scroll-snap-type:x proximity;
    padding:0 clamp(var(--s4),4vw,var(--s7)) var(--s7)}
  .gcard{flex:0 0 min(300px,82vw);scroll-snap-align:start;
    height:clamp(180px,32vh,240px)}
  .gcard:hover,.gcard:focus-within{transform:none}
}


/* ————————————————————————————— سرصفحه */

.studio{position:relative;background:var(--page)}

.studio-head{padding:var(--s10) clamp(var(--s5),5vw,var(--s9)) var(--s6)}
/* وقتی کاروسل بالای صفحه هست، فاصله‌ی زیر هدر ثابت را خودش می‌دهد */
.gal + .studio .studio-head{padding-top:var(--s7)}
.studio-head h1{margin:var(--s4) 0 0;font-size:clamp(38px,6vw,88px);line-height:1}
.studio-lede{color:var(--muted);margin-top:var(--s4);max-width:52ch}


/* ————————————————————————————— نمایشگر ماژول */

/* همان لایه‌بندی انتخابگر صفحه اصلی: نوار افقی، دایره بزرگ،
   ماژول شناور وسط. محصول در کادر نیست — کادر پشتش نور است. */
.mv{position:relative;
  min-height:88vh;
  min-height:88svh;
  overflow:hidden;isolation:isolate}

.mv::before{content:"";position:absolute;inset:calc(50% - var(--band-h) / 2) 0 auto 0;
  height:var(--band-h);background:var(--band);z-index:1}

/* دایره بزرگ — عنصر واقعی است تا قوس‌ها شعاعش را بخوانند */
.mv-circle{position:absolute;top:50%;left:50%;
  width:var(--circle-sel);aspect-ratio:1;border-radius:50%;
  background:var(--circle);transform:translate(-50%,-50%);z-index:2;
  pointer-events:none}

/* نیم‌دایره‌های کناری — ماژول قبلی و بعدی */
.mv-win{position:absolute;top:50%;transform:translateY(-50%);z-index:5;
  width:clamp(88px,12vw,168px);height:clamp(200px,26vw,340px);
  background:var(--win);border:0;padding:0;cursor:pointer;
  display:grid;place-items:center;overflow:hidden;
  transition:width var(--t-mid) var(--e)}
.mv-win.l{left:0;border-radius:0 var(--r-full) var(--r-full) 0}
.mv-win.r{right:0;border-radius:var(--r-full) 0 0 var(--r-full)}
.mv-win canvas{position:absolute;inset:0;width:100%;height:100%;opacity:.85}
.mv-win .label{position:relative;z-index:2;opacity:0;transition:opacity var(--t-fast) var(--e)}
.mv-win:hover .label{opacity:1}
.mv-win:hover{width:clamp(96px,13vw,184px)}

/* ماژول مرکزی. pointer-events فقط روی خود کانواس برمی‌گردد،
   وگرنه این جعبه کل بخش را می‌گیرد و کلیک دکمه‌ها را می‌بلعد. */
.mv-stage{position:absolute;inset:0;z-index:6;display:grid;place-items:center;
  pointer-events:none}
/* pan-y یعنی اسکرول عمودی صفحه آزاد می‌ماند و فقط کشیدن افقی
   ماژول را می‌چرخاند */
#mv-main{width:min(68vh,74vw);height:min(68vh,74vw);
  display:block;cursor:grab;touch-action:pan-y;pointer-events:auto;
  transition:opacity var(--t-mid) var(--e),transform var(--t-mid) var(--e)}
#mv-main.grabbing{cursor:grabbing}
#mv-main.swap{opacity:0;transform:scale(.94)}

.mv-hint{position:absolute;top:var(--s6);left:50%;transform:translateX(-50%);opacity:.5}

/* یادداشت مدل — دیگر خطا نیست: شکل ماژول از روی ابعادش ساخته شده
   و همین‌جا گفته می‌شود که چرا. پس رنگش خنثی است، نه هشدار. */
.mv-err{position:absolute;bottom:var(--s5);left:50%;transform:translateX(-50%);
  color:var(--muted);max-width:52ch;text-align:center;letter-spacing:0;
  text-transform:none;direction:rtl;line-height:1.7;
  padding:var(--s2) var(--s4);border-radius:var(--r-card);
  background:var(--glass-thin)}

.mv-note{position:absolute;z-index:12;top:var(--s6);
  inset-inline-start:clamp(var(--s5),5vw,var(--s9));color:var(--signal);opacity:.7}

/* کد ماژول — لاتین، پس مستقیم ltr */
.mv-name{position:absolute;z-index:10;bottom:var(--s8);
  inset-inline-start:clamp(var(--s5),5vw,var(--s9));margin:0;
  font-size:clamp(28px,4.4vw,64px);line-height:.95;
  direction:ltr;unicode-bidi:isolate;
  transition:opacity var(--t-mid) var(--e),transform var(--t-mid) var(--e)}
.mv-name.swap{opacity:0;transform:translateX(calc(var(--s5) * -1))}

/* ناوبری شماره‌ای */
.mv-pager{position:absolute;z-index:10;bottom:var(--s8);
  inset-inline-end:clamp(var(--s5),5vw,var(--s9));
  display:flex;align-items:center;gap:var(--s3)}
.mv-pager .ticks{display:flex;gap:var(--s1)}
.mv-pager .tick{width:var(--s5);height:var(--hair);background:var(--gline);
  transition:background var(--t-fast) var(--e),height var(--t-fast) var(--e)}
.mv-pager .tick.on{background:var(--signal);height:1.5px}


/* ————————————————————————————— قوس‌ها */

/* یک SVG تمام‌بخش، هم‌مرکز با دایره بزرگ. چپ ماژول، راست رنگ.
   pointer-events روی خود svg بسته است تا کادرش جلوی درگ را نگیرد. */
.mv .arcs{position:absolute;inset:0;width:100%;height:100%;z-index:8;
  overflow:visible;pointer-events:none}
.mv .arcs .item{pointer-events:auto;cursor:pointer}
.mv .arcs .curve{stroke:var(--gline);fill:none;stroke-width:.9}
.mv .arcs .cap{fill:var(--muted);font-family:var(--fa);font-size:var(--fs-micro);letter-spacing:.22em}
.mv .arcs .lbl{fill:var(--muted);font-family:var(--fa);font-size:var(--fs-body-s);
  transition:fill var(--t-fast) var(--e),font-size var(--t-mid) var(--e)}
.mv .arcs .dot{stroke:var(--gline);stroke-width:.9;cursor:pointer;
  transform-box:fill-box;transform-origin:center;
  transition:transform var(--t-mid) var(--e),stroke var(--t-fast) var(--e)}

.mv .arcs .l .item:hover .dot{transform:scale(1.9) translateX(6px);stroke:var(--ink)}
.mv .arcs .r .item:hover .dot{transform:scale(1.9) translateX(-6px);stroke:var(--ink)}
.mv .arcs .item:hover .lbl{fill:var(--ink);font-size:var(--fs-body)}

.mv .arcs .item.on .dot{stroke:var(--signal);stroke-width:1.6;transform:scale(1.3)}
.mv .arcs .item.on .lbl{fill:var(--ink)}
.mv .arcs .l .item.on:hover .dot{transform:scale(1.95) translateX(6px)}
.mv .arcs .r .item.on:hover .dot{transform:scale(1.95) translateX(-6px)}


/* ————————————————————————————— کارت ماژول */

/* کارت زیر نمایشگر می‌نشیند، نه رویش — مدل سه‌بعدی باید کامل و
   بدون چیزی جلویش دیده شود. یک نوار افقی است، نه ستون: زیرِ یک
   نمایشگرِ پهن، ستونِ باریک وسط صفحه بی‌جا می‌افتد. */
.mv-card{position:relative;z-index:1;
  margin:var(--s6) auto var(--s8);width:var(--card-w);
  padding:var(--s4) var(--s5);
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s4);
  transition:transform var(--t-mid) var(--e),opacity var(--t-fast) var(--e)}
.mv-card.swap{transform:translateY(var(--s4));opacity:0}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .mv-card{background:var(--glass-thin);
    backdrop-filter:var(--glass-filter);
    -webkit-backdrop-filter:var(--glass-filter)}
}
.mv-card-t{margin:var(--s1) 0 var(--s2);direction:ltr;unicode-bidi:isolate}
.mv-card-l{color:var(--muted);font-size:var(--fs-micro);flex-basis:100%;order:3}
/* خط جداکننده برای چیدمان ستونی بود؛ در نوار افقی جایی ندارد */
.mv-hr{display:none}
/* هر عدد یک قرصِ جدا — در یک ردیف، نه سطرهای پشت‌سرهم */
.mv-card .rowv{display:inline-flex;gap:var(--s1);align-items:baseline;width:auto;
  padding:var(--s1) var(--s3);border:var(--hair) solid var(--gline);
  border-radius:var(--r-full)}
.mv-card .rowv span{font-size:var(--fs-micro);color:var(--muted)}
.mv-card .rowv b{font-weight:400;font-size:var(--fs-body-s);direction:ltr;
  unicode-bidi:isolate;font-variant-numeric:tabular-nums}
.mv-go{display:block;text-align:center;flex-basis:100%;order:5;margin-top:var(--s2);width:100%}

/* ردیف انتخاب ماژول/رنگ داخل کارت — جایگزین قوس‌ها زیر ۱۱۵۰px */
.mv .card-picker,.mv-card .card-picker{display:none}
@media (max-width:1150px){
  .mv-card .card-picker{display:flex;flex-direction:column;gap:var(--s3);
    flex-basis:100%;order:4;margin:0}
  .mv-card .picker-row{display:flex;gap:var(--s2);flex-wrap:wrap}
  .mv-card .pchip{display:inline-flex;align-items:center;gap:var(--s2);cursor:pointer;
    background:none;border:var(--hair) solid var(--gline);border-radius:var(--r-full);
    color:var(--muted);font-family:var(--fa);font-size:var(--fs-micro);
    padding:var(--s2) var(--s4);min-height:36px;
    transition:border-color var(--t-fast) var(--e),color var(--t-fast) var(--e)}
  .mv-card .pchip.on{border-color:var(--signal);color:var(--ink)}
  .mv-card .pchip-color i{width:var(--s3);height:var(--s3);border-radius:50%;
    background:var(--sw);display:block;border:var(--hair) solid var(--gline)}
}

/* بدون WebGL: کانواس‌ها می‌روند، پیام و کارت می‌مانند */
.mv.no-gl #mv-main,.mv.no-gl .mv-win canvas{display:none}

@media (max-width:1150px){
  .mv .arcs{display:none}
}
@media (max-width:900px){
  .mv{min-height:auto;height:min(62vh,500px)}
  .mv-name,.mv-hint{display:none}
  .mv-pager{bottom:auto;top:var(--s5);inset-inline-end:50%;transform:translateX(50%)}
  #mv-main{width:min(52vh,80vw);height:min(52vh,80vw)}

  /* کارت همان‌جا زیر نمایشگر می‌ماند، فقط باریک‌تر */
  .mv-card{margin:var(--s5) auto var(--s7);width:min(560px,92vw)}
}


/* ————————————————————————————— پلنر */

.planner{position:relative;background:var(--page);
  padding:var(--s9) clamp(var(--s5),5vw,var(--s9)) var(--s10)}

.pl-head{margin-bottom:var(--s7);position:relative}
.pl-head h2{margin-top:var(--s4);font-size:var(--fs-title)}
.pl-lede{color:var(--muted);margin-top:var(--s3);max-width:48ch}

/* کلید نما — روبه‌رو یا سه‌بعدی. همان قاب کلید تیره/روشن هدر. */
.pl-views{display:inline-flex;margin-top:var(--s5);
  border:var(--hair) solid var(--gline);border-radius:var(--r-full);overflow:hidden}
.vbtn{background:none;border:0;cursor:pointer;
  font-family:var(--fa);font-size:var(--fs-micro);letter-spacing:.1em;
  color:var(--muted);padding:var(--s2) var(--s5);min-height:36px;
  transition:color var(--t-fast) var(--e),background var(--t-fast) var(--e)}
.vbtn:hover{color:var(--ink)}
.vbtn.on{color:var(--ink);background:var(--band)}
.vbtn[hidden]{display:none}

/* سه ستون: ابزار — شبکه — خروجی. شبکه بزرگ‌ترین است. */
.pl-body{display:grid;gap:var(--s6);
  grid-template-columns:minmax(180px,220px) 1fr minmax(220px,268px);
  align-items:start}

.pl-block + .pl-block{margin-top:var(--s6)}
.pl-block > .label{display:block;margin-bottom:var(--s3)}


/* پالت ماژول */

.palette{display:flex;flex-wrap:wrap;gap:var(--s2)}
.chip{display:flex;flex-direction:column;align-items:center;gap:var(--s2);
  background:none;cursor:pointer;
  border:var(--hair) solid var(--gline);border-radius:var(--r-card);
  padding:var(--s3);min-width:var(--s9);
  transition:border-color var(--t-fast) var(--e),background var(--t-fast) var(--e)}
.chip:hover{border-color:var(--ink)}
.chip.on{border-color:var(--signal);background:var(--band)}
.chip.on .label{color:var(--ink)}

/* شمایل ماژول — از ماتریس cells ساخته می‌شود، نه از آیکن آماده */
.chip-art{display:grid;gap:var(--s1)}
.chip-art i{display:block;width:var(--s3);height:var(--s3)}
.chip-art .f{background:var(--muted)}
.chip-art .e{background:none}
.chip.on .chip-art .f{background:var(--ink)}
/* ماژولی که در جنسِ انتخاب‌شده تولید نمی‌شود — خاموش، نه پنهان */
.chip.off{opacity:.3;cursor:not-allowed}
.chip.off:hover{border-color:var(--gline)}


/* جنس — قدم اول، و تنها انتخابی که روی کل ترکیب است.
   عمداً بزرگ‌تر و ستونی است، نه هم‌شکل قوس رنگ: این یک تصمیم
   است، آن یک قلم‌مو. */

.mats{display:flex;flex-direction:column;gap:var(--s2)}
.mat{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  cursor:pointer;text-align:start;
  background:none;border:var(--hair) solid var(--gline);border-radius:var(--r-card);
  color:var(--muted);font-family:var(--fa);font-size:var(--fs-body-s);
  padding:var(--s3) var(--s4);min-height:44px;
  transition:border-color var(--t-fast) var(--e),color var(--t-fast) var(--e),
    background var(--t-fast) var(--e)}
.mat:hover{border-color:var(--ink)}
.mat.on{border-color:var(--signal);background:var(--band);color:var(--ink)}
.mat-c{color:var(--muted);white-space:nowrap}
.mat.on .mat-c{color:var(--ink)}


/* رنگ */

.swatches{display:flex;flex-wrap:wrap;gap:var(--s2)}
.swatch{display:inline-flex;align-items:center;gap:var(--s2);cursor:pointer;
  background:none;border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  color:var(--muted);font-family:var(--fa);font-size:var(--fs-micro);
  padding:var(--s2) var(--s4);min-height:36px;
  transition:border-color var(--t-fast) var(--e),color var(--t-fast) var(--e)}
.swatch:hover{border-color:var(--ink)}
.swatch.on{border-color:var(--signal);color:var(--ink)}
/* رنگی که این ماژول ندارد — خاموش، نه پنهان: کاربر می‌بیند که
   وجود دارد ولی برای این ماژول نیست. */
.swatch.off{opacity:.32;cursor:not-allowed}
.swatch.off:hover{border-color:var(--gline)}
.swatch i{display:block;width:var(--s3);height:var(--s3);border-radius:50%;
  background:var(--sw);border:var(--hair) solid var(--gline)}
.swatch-all{color:var(--muted)}

.pl-cnote{color:var(--muted);font-size:var(--fs-micro);margin-top:var(--s3);line-height:1.7}


/* ترکیب‌های آماده */

.presets{display:flex;flex-wrap:wrap;gap:var(--s2)}
.preset{background:none;cursor:pointer;
  border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  color:var(--muted);font-family:var(--fa);font-size:var(--fs-body-s);
  padding:var(--s2) var(--s5);min-height:36px;
  transition:border-color var(--t-fast) var(--e),color var(--t-fast) var(--e)}
.preset:hover{border-color:var(--ink);color:var(--ink)}


/* شبکه */

.pl-stage{position:relative;display:flex;flex-direction:column;align-items:center;
  gap:var(--s4)}

/* قاب شبکه — جا برای خط‌های اندازه در چپ و پایین باز می‌کند */
.grid-wrap{position:relative;direction:ltr;
  padding:0 0 var(--s7) var(--s8)}
.grid-wrap[hidden]{display:none}

/* نمای روبه‌رو یک نقشه فنی است، پس چپ‌به‌راست خوانده می‌شود —
   ستون ۰ سمت چپ، همان‌جا که جاوااسکریپت قطعه را می‌گذارد. */
.grid{position:relative;direction:ltr;display:grid;gap:0;
  border:var(--hair) solid var(--gline);border-radius:var(--r-card);
  background:var(--band);overflow:hidden}

/* خط‌های اندازه — همان زبان نقشه: خط نازک، سر تیک، عدد لاتین */
.dims{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible;z-index:5}
.dims .dl{stroke:var(--muted);stroke-width:1;opacity:.75}
.dims .dt{fill:var(--muted);font-family:var(--fa);font-size:var(--fs-micro);
  letter-spacing:.1em;dominant-baseline:middle}

.cell{width:var(--cell);height:var(--cell);background:none;cursor:pointer;
  border:var(--hair) dashed var(--wire);
  transition:background var(--t-fast) var(--e)}
.cell.ok{background:var(--circle)}
.cell.bad{border-color:var(--signal)}

/* قطعه چیده‌شده. رنگش از داده می‌آید (--pc) و در هر دو حالت
   تیره و روشن یکی است — رنگ محصول است، نه رنگ رابط. */
.piece{position:absolute;padding:0;background:none;border:0;cursor:pointer;
  z-index:2;transition:filter var(--t-fast) var(--e)}
.piece .pfill{position:absolute;display:block;background:var(--pc);
  border-radius:var(--r-card);border:var(--hair) solid var(--gline)}
.piece:hover{filter:brightness(1.08)}
.piece.on{z-index:3}
.piece.on .pfill{outline:1.5px solid var(--signal);outline-offset:calc(var(--hair) * -2)}

.pcode{position:absolute;inset-inline-start:var(--s2);top:var(--s2);z-index:2;
  font-family:var(--fa);font-size:var(--fs-micro);letter-spacing:.12em;
  direction:ltr;color:var(--muted);pointer-events:none}
.piece.on .pcode{color:var(--signal)}

.pdel{position:absolute;inset-inline-end:var(--s2);top:var(--s2);z-index:3;
  display:grid;place-items:center;width:var(--s5);height:var(--s5);
  border-radius:50%;background:var(--signal);color:var(--on-signal);
  font-size:var(--fs-body);line-height:1;cursor:pointer}

/* نمای سه‌بعدی — همان ترکیب، در فضا */

.scene{position:relative;width:100%;
  aspect-ratio:4 / 3;max-height:min(72vh,620px);
  border:var(--hair) solid var(--gline);border-radius:var(--r-card);
  background:var(--band);overflow:hidden;isolation:isolate}
.scene[hidden]{display:none}

/* نور پشت ترکیب — همان دایره‌ی هویت، نه یک رنگ تخت */
.scene::before{content:"";position:absolute;top:50%;left:50%;
  width:min(96%,70vh);aspect-ratio:1;border-radius:50%;
  background:var(--circle);transform:translate(-50%,-50%);z-index:0}

#planner-3d{position:absolute;inset:0;z-index:1;
  width:100%;height:100%;display:block;cursor:grab;touch-action:pan-y}
#planner-3d.grabbing{cursor:grabbing}

.scene-pins{position:absolute;inset:0;z-index:2;pointer-events:none}
.pin{position:absolute;transform:translate(-50%,calc(-100% - var(--s3)));
  white-space:nowrap;color:var(--ink);
  background:var(--glass-solid);border:var(--hair) solid var(--signal);
  border-radius:var(--r-full);padding:var(--s1) var(--s3);
  letter-spacing:.1em;direction:rtl;text-transform:none}

.scene-hint{position:absolute;z-index:2;bottom:var(--s4);left:50%;
  transform:translateX(-50%);opacity:.45;pointer-events:none}

.scene-reset{position:absolute;z-index:3;top:var(--s4);
  inset-inline-end:var(--s4);cursor:pointer;
  background:none;border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  color:var(--muted);padding:var(--s1) var(--s4);min-height:32px;
  transition:color var(--t-fast) var(--e),border-color var(--t-fast) var(--e)}
.scene-reset:hover{color:var(--ink);border-color:var(--ink)}

.grid[hidden]{display:none}

/* پیام قاعده — به زبان ساده، نه خطای قرمز */
.pl-msg{min-height:var(--s5);color:var(--muted);font-size:var(--fs-body-s);
  opacity:0;transition:opacity var(--t-fast) var(--e)}
.pl-msg.show{opacity:1}


/* خروجی */

.pl-out{padding:var(--s5)}
.readout{margin-top:var(--s4)}
.ro{display:flex;justify-content:space-between;align-items:baseline;padding:var(--s2) 0;
  border-bottom:var(--hair) solid var(--gline)}
.ro:last-child{border-bottom:0}
.ro b{font-weight:400;font-size:var(--fs-body-s);direction:ltr;
  unicode-bidi:isolate;font-variant-numeric:tabular-nums}

.pl-acts{display:flex;flex-direction:column;gap:var(--s2);margin-top:var(--s5)}
.btn.ghost{background:none;color:var(--muted);border:var(--hair) solid var(--gline)}
.btn.ghost:hover{background:none;color:var(--ink);border-color:var(--ink)}

.pl-note{margin-top:var(--s4);color:var(--signal);opacity:.7}

/* نتیجه‌ی سبد، کنار خودِ دکمه. محو نمی‌شود تا کاربر حتماً ببیندش. */
.pl-cart-msg{margin-top:var(--s3);font-size:var(--fs-body-s);
  color:var(--muted);line-height:1.7}
.pl-cart-msg[hidden]{display:none}
.pl-cart-msg.bad{color:var(--signal)}


/* ————————————————————————————— خرید */

/* همان پهنای کارت ماژول — کارت‌ها زیر هم می‌آیند و باید یک
   اندازه باشند، وگرنه ستون صفحه پله‌پله می‌شود. */
.buy{padding:var(--s6) clamp(var(--s5),5vw,var(--s9)) var(--s9)}
.buy-inner{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s3) var(--s4);padding:var(--s4) var(--s5);
  width:var(--card-w);max-width:100%;margin-inline:auto}
.buy-price{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap}
.buy-price b{font-weight:400;font-size:var(--fs-card);direction:ltr;
  unicode-bidi:isolate;margin:0}
/* هر مبلغ یک تکه‌ی به‌هم‌چسبیده — وگرنه «تومان» از عددش جدا
   می‌افتد و بازه‌ی قیمت سه سطر می‌شود */
.buy-price bdi{unicode-bidi:isolate;white-space:nowrap}

.buy-inner form.cart{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s3);margin:0;width:100%}
.buy-inner .quantity input{width:var(--s8);text-align:center;
  font-family:var(--fa);font-size:var(--fs-body-s);color:var(--ink);
  background:none;border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  padding:var(--s2) var(--s3)}

/* انتخابگرها با وزنِ بیشتر نوشته شده‌اند: شیوه‌نامه‌ی خودِ ووکامرس
   بعد از قالب بارگذاری می‌شود و با وزن برابر برنده می‌شد — دکمه‌ی
   بنفشِ پیش‌فرضش از همین‌جا می‌آمد. */
.buy .buy-inner button[type="submit"],
.buy .buy-inner button.button{border:0;border-radius:var(--r-full);
  background:var(--ink);color:var(--page);padding:var(--s3) var(--s5);
  font-family:var(--fa);font-size:var(--fs-body-s);font-weight:400;
  cursor:pointer;text-transform:none;
  transition:background var(--t-fast) var(--e),color var(--t-fast) var(--e)}
.buy .buy-inner button[type="submit"]:hover,
.buy .buy-inner button.button:hover{background:var(--signal);color:var(--on-signal)}
.buy .buy-inner button.button:disabled{opacity:.4;cursor:not-allowed}

/* رنگ در فرم خرید محصول غیرمدولار. جنس select خودِ ووکامرس را
   دارد؛ این یکی را قالب می‌گذارد چون رنگ variation نیست. */
.buy-color{display:flex;align-items:center;gap:var(--s2)}
.buy-color select,
.buy-inner form.cart select{font-family:var(--fa);font-size:var(--fs-body-s);
  color:var(--ink);background:none;
  border:var(--hair) solid var(--gline);border-radius:var(--r-full);
  padding:var(--s2) var(--s3);cursor:pointer}
.buy-color select:hover,
.buy-inner form.cart select:hover{border-color:var(--ink)}
/* فرم محصول متغیر ووکامرس یک جدول است: هر ویژگی یک سطر، با
   برچسب در یک سلول و select در سلول بعدی. آن جدول در یک کارتِ
   باریک سه سطرِ نامرتب می‌شد. اینجا با display:contents از حالت
   جدولی درمی‌آید و همه در یک ردیف می‌نشینند. */
.buy-inner form.variations_form{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s3);width:100%;margin:0}
.buy-inner .variations{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s3);margin:0;width:auto;border:0;background:none}
.buy-inner .variations tbody{display:contents}
.buy-inner .variations tr{display:flex;align-items:center;gap:var(--s2)}
.buy-inner .variations td,
.buy-inner .variations th{display:block;padding:0;border:0;background:none}
.buy-inner .variations label{margin:0;font-size:var(--fs-micro);color:var(--muted)}
/* «پاک کردن» — لینکِ بازنشانیِ ووکامرس — اصلاً نمی‌آید.
   قاعده‌ی قبلی فقط وقتی پنهانش می‌کرد که ووکامرس خودش
   visibility:hidden روی عنصر بگذارد، یعنی وقتی هیچ جنسی انتخاب
   نشده باشد. ولی این محصول اولین جنسش را خودکار انتخاب می‌کند،
   پس آن حالت هیچ‌وقت پیش نمی‌آید و لینک همیشه دیده می‌شد
   (اندازه‌گیری: visibility:visible، بدون هیچ style درون‌خطی).
   با یک محورِ variation، «پاک کردن» تنها کاری که می‌کند
   برگرداندن کاربر به حالتِ «هیچ‌کدام» است — یعنی از یک وضعیتِ
   معتبر به وضعیتی که باید دوباره از آن بیرون بیاید. تا وقتی
   محور دوم اضافه نشده، جایی ندارد.
   :hover قبلی هم رنگ تأکیدی می‌گرفت، که طبق قواعد پروژه فقط سه
   جا مجاز است و این یکی‌شان نبود. */
.buy-inner .reset_variations{display:none}
.buy-inner .woocommerce-variation-price{width:100%;margin:0}
.buy-inner .woocommerce-variation-price .price{font-size:var(--fs-body);color:var(--ink)}
.buy-inner .woocommerce-variation-add-to-cart{display:flex;flex-wrap:wrap;
  align-items:center;gap:var(--s3);width:100%;margin:0}


/* ————————————————————————————— موبایل */

@media (max-width:1000px){
  .pl-body{grid-template-columns:1fr;gap:var(--s6)}
  .pl-side{display:grid;grid-template-columns:1fr;gap:var(--s5)}
  .pl-block + .pl-block{margin-top:0}

  /* پالت روی موبایل یک نوار افقی است تا شبکه بالا بماند */
  .palette{flex-wrap:nowrap;overflow-x:auto;padding-bottom:var(--s2);
    scroll-snap-type:x proximity}
  .chip{flex:0 0 auto;scroll-snap-align:start}

  /* شبکه از عرض صفحه بیرون نزند */
  .pl-stage{overflow-x:auto;align-items:flex-start}
}

@media (max-width:640px){
  .studio-head{padding-top:var(--s9)}
  .planner{padding-top:var(--s7)}
}


/* ————————————————————————————————————————————————————————————
   مشخصات فنی — جدول سرور-ساید زیر استودیو
   ———————————————————————————————————————————————————————————— */

.specs{padding:var(--s8) clamp(var(--s4),5vw,var(--s9)) var(--s7)}

.specs-inner{
  max-width:62ch;margin-inline:auto;
  padding:var(--s6) clamp(var(--s4),4vw,var(--s6));
  border-radius:var(--r-card)
}

.specs-t{
  font-size:var(--fs-card);font-weight:500;
  margin:0 0 var(--s5)
}

.spec-table{
  width:100%;border-collapse:collapse;
  font-size:var(--fs-body);line-height:1.7
}

.spec-table th,
.spec-table td{
  padding:var(--s3) 0;
  text-align:start;vertical-align:top;
  border-bottom:var(--hair) solid var(--wire)
}

.spec-table tr:last-child th,
.spec-table tr:last-child td{border-bottom:0}

.spec-table th{
  width:42%;font-weight:400;color:var(--muted);
  padding-inline-end:var(--s4)
}

.spec-table td{color:var(--ink)}

/* عدد فنی لاتین می‌ماند، حتی وسط جمله راست‌چین */
.spec-table td.mono{direction:ltr;text-align:right;unicode-bidi:isolate}

@media (max-width:640px){
  .specs{padding-top:var(--s7)}
  .spec-table th{width:46%}
}

/* ————————————————————————————— اعلان‌های ووکامرس

   «جنس را انتخاب کن»، «به سبد اضافه شد» و مانند این‌ها. مارک‌آپش
   از خودِ ووکامرس می‌آید، پس فقط رنگ و فاصله‌ی قالب رویش می‌نشیند.
   خطا با --signal مشخص می‌شود؛ همان تنها رنگ تأکیدی سایت. */

.wc-notices{padding:var(--s5) clamp(var(--s5),5vw,var(--s9)) 0}
.wc-notices:empty{display:none}

.wc-notices .woocommerce-message,
.wc-notices .woocommerce-error,
.wc-notices .woocommerce-info{
  margin:0 0 var(--s3);padding:var(--s4) var(--s5);
  list-style:none;
  border:var(--hair) solid var(--gline);border-radius:var(--r-card);
  background:var(--glass-solid);
  color:var(--ink);font-size:var(--fs-body-s);line-height:1.7}

.wc-notices .woocommerce-error{border-color:var(--signal)}
.wc-notices .woocommerce-error li{margin:0}

/* دکمه‌ی «مشاهده سبد» که ووکامرس داخل اعلان می‌گذارد */
.wc-notices a{color:var(--ink);text-decoration:underline;
  text-underline-offset:3px}
.wc-notices a:hover{color:var(--ink)}
