/* ══ kit/base.css ══════════════════════════════════════════════════════
 * پایهٔ مشترک — اندازه و قلمِ همهٔ کنترل‌ها. هیچ مؤلفه‌ای اینجا ساخته نمی‌شود.
 *
 * تکه‌ای از کیت. سرور هر پنج طبقه را به همین ترتیب به‌هم می‌چسباند و روی
 * /primitives.css سرو می‌کند، پس ترتیبِ طبقه‌ها همان ترتیبِ آبشار است:
 * base → atoms → molecules → blocks → tail.  (tools/kit-css.js)
 */

/* ══ primitives.css — اجزای پایهٔ مشترکِ رابط ═══════════════════════════════════
 *
 * چرا این فایل هست
 *   اندازه‌گیریِ ۱۴۰۵/۰۶/۱۹: دکمه در ۵۹ فایل از ۶۸ استایل‌شیت جداگانه تعریف شده
 *   بود (≈۳۰۰ نامِ کلاس)، چیپ در ۵۰، فیلد در ۵۰، مودال در ۲۶ — و `.btn-primary`
 *   با همان نام و همان دستور در دو فایل. هیچ خانه‌ای برای جزءِ پایه نبود، پس هر
 *   صفحه از نو می‌ساخت و هر اصلاحِ کنتراست/لمس نُه فایل می‌خورد.
 *
 * قاعده
 *   ۱) فقط از توکن‌های theme.css (که از design-tokens.json ساخته می‌شود). هیچ
 *      رنگ و اندازهٔ خامی اینجا نیست؛ به همین دلیل ویرایشِ اطلس همه‌جا می‌نشیند.
 *   ۲) همهٔ کلاس‌ها با پیشوندِ `mb-` تا با کلاس‌های موجودِ صفحه‌ها (`.btn`، `.card`،
 *      `.field` که در ده‌ها فایل هست) برخورد نکند. صفحه‌ای که مهاجرت می‌کند به
 *      این نام‌ها می‌رود و قاعده‌های محلی‌اش را حذف می‌کند؛ صفحه‌ای که هنوز
 *      مهاجرت نکرده ذره‌ای عوض نمی‌شود.
 *   ۳) فقط ویژگی‌های منطقی (inline-start/end)؛ این رابط راست‌به‌چپ است.
 *   ۴) «لمس یک حالت است، نه یک گوشی»: زیرِ ۱۰۲۴px کفِ ۴۴px و متنِ ورودی ۱۶px —
 *      یک‌بار همین‌جا، نه در ۴۶ فایل.
 *   ۵) این فایل مثلِ theme.css به هر صفحه تزریق می‌شود (justime-ui.js)، پس
 *      نباید هیچ گزینشگرِ بی‌پیشوندی داشته باشد — جز :focus-visible که عمداً
 *      سراسری است (بندِ ۷).
 */
/* ── ۱) اندازهٔ پایه و فونت ────────────────────────────────────────────────── */
.mb-btn, .mb-chip, .mb-field, .mb-seg, .mb-card, .mb-toast, .mb-empty, .mb-modal {
  font-family: var(--font);
  letter-spacing: 0;               /* خطِ عربی می‌چسبد؛ tracking پیوند را می‌بُرد */
  box-sizing: border-box;
}

/* اجزای درونی هم border-box‌اند — و این خط از سرِ احتیاط نیست، یک باگِ
   اندازه‌گیری‌شده را می‌بندد. تا امروز border-box را از قاعدهٔ سراسریِ
   `*` در nav.css قرض می‌گرفتیم، ولی سرور فقط theme.css/primitives.css/
   ui-kit.js را به هر صفحه تزریق می‌کند؛ nav.css را هر صفحه خودش لینک
   می‌کند و هشت صفحه (اطلس، لاگین، لندینگ، ویترین، فاکتورِ عمومی، صفحهٔ
   عمومیِ سازمان، pay-sim، celebrate) لینکش نمی‌کنند. آن‌جا
   `.mb-input{inline-size:100%}` به content-box می‌خورد و ورودی دقیقاً
   ۲۶ پیکسل (۲×۱۲ پدینگ + ۲×۱ کادر) از ظرفش پهن‌تر می‌شد؛ در ردیفِ فیلدهای
   اطلس با gapِ ۸ یعنی ۱۸ پیکسل هم‌پوشانیِ ورودی‌های همسایه. اندازه‌گیری:
   ظرف ۱۹۷٫۶ / ورودی ۲۲۳٫۶.  */
.mb-input, .mb-select, .mb-textarea, .mb-seg__btn, .mb-modal__box, .mb-table--wrap, .mb-dot { box-sizing: border-box; }

/* آواتار و قابِ آیکون هم همین‌جا، و به همان دلیلِ اندازه‌گیری‌شدهٔ بالا:
   ‎.mb-avatar--swatch‎ یک حلقهٔ ۱٫۵ پیکسلی دارد و ‎.mb-avatar--xs‎ دقیقاً
   ۲۰ پیکسل است، پس روی همان هشت صفحهٔ بی‌nav.css سواچ ۲۳ پیکسل درمی‌آمد و
   با بقیهٔ صفحه‌ها هم‌اندازه نبود — و لوگوی سازمان، یکی از مصرف‌کننده‌های
   همین سواچ، دقیقاً روی صفحهٔ عمومیِ سازمان است که در آن فهرست است.
   روی صفحه‌هایی که nav.css دارند این خط بی‌اثر است (قاعدهٔ `*` از قبل). */
.mb-avatar, .mb-iconbox { box-sizing: border-box; }

/* ══ قلابِ مشترکِ لحن ══════════════════════════════════════════════════════════
 *
 * تا امروز هر مؤلفه لحن را خودش رنگ می‌کرد: دکمه یک بلوک برای ok داشت، چیپ یک
 * بلوکِ دیگر، قاب و نوارِ پیشرفت و یادداشت هم هرکدام یکی. نتیجه این بود که هر
 * واریانتِ تازه (کادرِ رنگی، سایهٔ رنگی، گرادیانِ لحن‌دار) باید شش بار نوشته
 * می‌شد — و همین بود که نوشتنش را گران و کپی‌کردن را ارزان می‌کرد.
 *
 * حالا کلاسِ لحن فقط *متغیر می‌گذارد* و رنگ‌آمیزی را قاعدهٔ خودِ مؤلفه از همان
 * متغیر می‌خوانَد. یک واریانتِ تازه یک خط است، نه شش خط:
 *
 *     .mb-frame--glow { box-shadow: 0 8px 20px color-mix(in srgb, var(--mb-tone) 28%, transparent); }
 *
 * پیش‌فرض با ‎:where()‎ نوشته شده (وزنِ صفر) تا هر کلاسِ لحن ‎(0,1,0)‎ رویش
 * بنشیند. عمداً در base است: باید پیش از هر قاعدهٔ نقاشیِ هر طبقه‌ای بیاید.
 *
 * این‌ها *ظاهر* نمی‌دهند، فقط متغیر — پس بودنشان در base نقضِ طبقه‌بندی نیست.
 */
:where(.mb-btn, .mb-chip, .mb-card, .mb-note, .mb-empty, .mb-frame, .mb-iconbox,
       .mb-avatar, .mb-dot, .mb-status, .mb-progress, .mb-wait, .mb-sk,
       .mb-input, .mb-select, .mb-textarea, .mb-check, .mb-drop,
       .mb-seg__btn, .mb-toast, .mb-stat, .mb-hint) {
  --mb-tone: var(--accent);
  --mb-tone-ink: var(--accent-text);
  --mb-tone-soft: var(--accent-soft);
  --mb-grad-from: var(--accent);
  --mb-grad-to: var(--accent-2);
}

.mb-chip--ok, .mb-card--ok, .mb-note--ok, .mb-empty--ok, .mb-frame--ok,
.mb-iconbox--ok, .mb-avatar--ok, .mb-dot--ok, .mb-status--ok, .mb-progress--ok,
.mb-wait--ok, .mb-input--ok, .mb-select--ok, .mb-textarea--ok, .mb-check--ok,
.mb-seg__btn--ok, .mb-toast--ok, .mb-stat--ok {
  --mb-tone: var(--ok); --mb-tone-ink: var(--ok-text); --mb-tone-soft: var(--ok-soft);
  --mb-grad-from: var(--ok-text); --mb-grad-to: var(--ok);
}
.mb-chip--warn, .mb-card--warn, .mb-note--warn, .mb-empty--warn, .mb-frame--warn,
.mb-iconbox--warn, .mb-avatar--warn, .mb-dot--warn, .mb-status--warn, .mb-progress--warn,
.mb-wait--warn, .mb-input--warn, .mb-select--warn, .mb-textarea--warn, .mb-check--warn,
.mb-seg__btn--warn, .mb-toast--warn, .mb-stat--warn {
  --mb-tone: var(--warn); --mb-tone-ink: var(--warn-text); --mb-tone-soft: var(--warn-soft);
  --mb-grad-from: var(--warn-text); --mb-grad-to: var(--warn);
}
.mb-btn--danger, .mb-chip--danger, .mb-card--danger, .mb-note--danger, .mb-empty--danger, .mb-frame--danger,
.mb-iconbox--danger, .mb-avatar--danger, .mb-dot--danger, .mb-status--danger, .mb-progress--danger,
.mb-wait--danger, .mb-input--danger, .mb-select--danger, .mb-textarea--danger, .mb-check--danger,
.mb-seg__btn--danger, .mb-toast--danger, .mb-stat--danger {
  --mb-tone: var(--danger); --mb-tone-ink: var(--danger-text); --mb-tone-soft: var(--danger-soft);
  --mb-grad-from: var(--danger-text); --mb-grad-to: var(--danger);
}
.mb-chip--info, .mb-card--info, .mb-note--info, .mb-empty--info, .mb-frame--info,
.mb-iconbox--info, .mb-avatar--info, .mb-dot--info, .mb-status--info, .mb-progress--info,
.mb-wait--info, .mb-input--info, .mb-select--info, .mb-textarea--info, .mb-check--info,
.mb-seg__btn--info, .mb-toast--info, .mb-stat--info {
  --mb-tone: var(--info); --mb-tone-ink: var(--info-text); --mb-tone-soft: var(--info-soft);
  --mb-grad-from: var(--info-text); --mb-grad-to: var(--info);
}
.mb-chip--muted, .mb-card--muted, .mb-note--muted, .mb-empty--muted, .mb-frame--muted,
.mb-iconbox--muted, .mb-avatar--muted, .mb-dot--muted, .mb-status--muted, .mb-progress--muted,
.mb-wait--muted, .mb-input--muted, .mb-select--muted, .mb-textarea--muted, .mb-check--muted,
.mb-seg__btn--muted, .mb-toast--muted, .mb-stat--muted {
  --mb-tone: var(--muted); --mb-tone-ink: var(--text-2); --mb-tone-soft: var(--surface-3);
  --mb-grad-from: var(--text-2); --mb-grad-to: var(--muted);
}
.mb-chip--imp, .mb-card--imp, .mb-note--imp, .mb-empty--imp, .mb-frame--imp,
.mb-iconbox--imp, .mb-avatar--imp, .mb-dot--imp, .mb-status--imp, .mb-progress--imp,
.mb-wait--imp, .mb-input--imp, .mb-check--imp, .mb-seg__btn--imp, .mb-toast--imp, .mb-stat--imp {
  --mb-tone: var(--imp); --mb-tone-ink: var(--imp-text); --mb-tone-soft: var(--imp-soft);
  --mb-grad-from: var(--imp-text); --mb-grad-to: var(--imp);
}

/* رنگِ داده‌محور لحن نیست: نقشِ کاربر، رنگِ برند، رنگِ سلولِ جدول. JS جفتِ
   واقعی را می‌نویسد و کیت حدس نمی‌زند — همان چیزی که هشت گرادیانِ درختِ
   دسته‌بندی و ۲۳ گرادیانِ نقش را بدونِ تغییرِ رنگ بازتولید می‌کند. */
.mb-chip--tint, .mb-frame--tint, .mb-iconbox--tint, .mb-avatar--tint, .mb-dot--tint, .mb-check--tint,
.mb-progress--tint, .mb-card--tint {
  --mb-tone: var(--mb-c, var(--accent));
  --mb-tone-ink: var(--mb-c-ink, var(--accent-text));
  --mb-tone-soft: var(--mb-c-soft, var(--accent-soft));
  --mb-grad-from: var(--mb-c-ink, var(--accent-text));
  --mb-grad-to: var(--mb-c, var(--accent));
}


/* ── ۲) دکمه ────────────────────────────────────────────────────────────────
 * یک مرجع و چند حالت، از روی داده: ui/kit/components/button.json.
 * هر حالت فقط ویژگی‌هایی را که با مرجع فرق دارد «اختصاصی» اعلام می‌کند؛ بقیه
 * «عمومی»اند و از مرجع می‌خوانند. مرجع را عوض کنی، همهٔ حالت‌های وصل و هر
 * جایی که دکمه استفاده شده با هم عوض می‌شوند. ویرایش از /ui-kit یا همان فایل؛
 * بلوکِ زیر را `node tools/kit-components.js` می‌سازد.
 */
/* @kit:mb-btn:begin — ساخته‌شده از ui/kit/components/*.json؛ اینجا را دستی ویرایش نکنید، از /ui-kit یا همان فایل. */
.mb-btn {
  --btn-r: var(--r-md);
  --btn-bw: 1px;
  --btn-bs: solid;
  --btn-h: var(--ctl-h-md);
  --btn-px: var(--ctl-px-md);
  --btn-fs: var(--fs-ctl);
  --btn-fw: var(--fw-medium);
  --btn-gap: var(--sp-2);
  --btn-icon: var(--icon-sm);
  --btn-bg: var(--surface);
  --btn-bc: var(--border);
  --btn-fg: var(--text);
  --btn-sh: none;
  --btn-bg-h: var(--surface-2);
  --btn-bc-h: var(--border-strong);
  --btn-fg-h: var(--btn-fg);
  --btn-bg-a: var(--surface-3);
}
.mb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--btn-gap);
  min-height: var(--btn-h);
  padding-block: 0;
  padding-inline: var(--btn-px);
  border: var(--btn-bw) var(--btn-bs) var(--btn-bc);
  border-radius: var(--btn-r);
  background: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: var(--btn-sh);
  font-size: var(--btn-fs);
  font-weight: var(--btn-fw);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.mb-btn:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn:active {
  background: var(--btn-bg-a);
}
.mb-btn svg {
  width: var(--btn-icon);
  height: var(--btn-icon);
  flex: none;
}
/* ریز — تنها اندازهٔ دومِ برنامه: ردیفِ جدول، نوارِ ابزارِ فشرده، کنارِ کنترل‌های ریز. ‎--xs‎ و ‎--dense‎ و ‎--lg‎ به همین یا به «عادی» تا شدند. ۱۴۰۵/۰۷/۰۷ (طرحِ مالک): ریزِ عادی سبک و خاکستری است (دکمه‌های داخلِ ردیف)؛ پیش از لحن‌ها می‌آید تا اصلی/خطر/ساده وزن و مرکبِ خودشان را نگه دارند. */
.mb-btn--sm {
  --btn-h: var(--ctl-h-sm);
  --btn-px: var(--ctl-px-sm);
  --btn-fs: var(--fs-ctl-sm);
  --btn-r: var(--r-sm);
  --btn-icon: var(--icon-xs);
  --btn-fw: var(--fw-regular);
  --btn-fg: var(--text-2);
  min-height: var(--btn-h);
  padding-inline: var(--btn-px);
  font-size: var(--btn-fs);
  border-radius: var(--btn-r);
  font-weight: var(--btn-fw);
  color: var(--btn-fg);
}
.mb-btn--sm svg {
  width: var(--btn-icon);
  height: var(--btn-icon);
}
/* خطر — تنها لحنی که مانده. به‌تنهایی «دومِ خطر» است؛ با ‎--primary‎ توپُرِ قرمز، با ‎--ghost‎ سادهٔ خطر. ‎--ok‎/‎--info‎/‎--warn‎/‎--accent‎ حذف شدند: روی دکمه معنا اضافه نمی‌کردند و فقط شکلِ تازه می‌ساختند. ۱۴۰۵/۰۷/۰۷ (طرحِ مالک): «دومِ خطر» خط‌دار است — زمینهٔ سطح، کادر و مرکبِ قرمز؛ زیرِ اشاره‌گر ته‌رنگِ قرمز. */
.mb-btn--danger {
  --btn-bg: var(--surface);
  --btn-bc: color-mix(in srgb, var(--danger) 32%, var(--border));
  --btn-fg: var(--danger-text);
  --btn-bg-h: var(--danger-soft);
  --btn-bg-a: color-mix(in srgb, var(--danger-soft) 80%, var(--danger));
  --btn-bc-h: color-mix(in srgb, var(--danger) 45%, var(--border));
  --btn-fw: var(--fw-medium);
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
  font-weight: var(--btn-fw);
}
.mb-btn--danger:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn--danger:active {
  background: var(--btn-bg-a);
}
/* ساده — پلهٔ سوم: بی‌زمینه و بی‌کادر — نوارِ ابزار، آیکون‌ها، «انصراف». */
.mb-btn--ghost {
  --btn-bg: transparent;
  --btn-bc: transparent;
  --btn-fg: var(--text-2);
  --btn-bg-h: var(--surface-2);
  --btn-fg-h: var(--text);
  --btn-bg-a: var(--btn-bg-h);
  --btn-bc-h: transparent;
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
}
.mb-btn--ghost:hover {
  background: var(--btn-bg-h);
  color: var(--btn-fg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn--ghost:active {
  background: var(--btn-bg-a);
}
/* اصلی — پلهٔ اول: پُرِ مرکب (سیاه در روشن، روشن در تاریک) — طرحِ Claude Design، تصمیمِ مالک ۱۴۰۵/۰۷/۱۱. در هر گروهِ دیداری حداکثر یکی — اگر همه اصلی باشند، هیچ‌کدام اصلی نیست. ‎--grad‎ و ‎--solid‎ هر دو به همین رسیدند. */
.mb-btn--primary {
  --btn-bg: color-mix(in srgb, var(--text) 90%, var(--surface));
  --btn-bc: color-mix(in srgb, var(--text) 90%, var(--surface));
  --btn-fg: var(--surface);
  --btn-bg-h: var(--text);
  --btn-bc-h: var(--text);
  --btn-bg-a: var(--text);
  --btn-fw: var(--fw-semibold);
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
  font-weight: var(--btn-fw);
}
.mb-btn--primary:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn--primary:active {
  background: var(--btn-bg-a);
}
/* سادهٔ خطر — ترکیب است نه حالتِ تازه: در استراحت خنثی، زیرِ نشانگر قرمز رو می‌شود. آیکونِ حذف در ردیفِ جدول. */
.mb-btn--ghost.mb-btn--danger {
  --btn-bg: transparent;
  --btn-bc: transparent;
  --btn-fg: var(--text-2);
  --btn-bg-h: var(--mb-tone-soft);
  --btn-bc-h: transparent;
  --btn-fg-h: var(--mb-tone-ink);
  --btn-bg-a: var(--btn-bg-h);
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
}
.mb-btn--ghost.mb-btn--danger:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
  color: var(--btn-fg-h);
}
.mb-btn--ghost.mb-btn--danger:active {
  background: var(--btn-bg-a);
}
/* اصلیِ خطر — تأییدِ نهاییِ حذف. زمینه «مرکبِ» لحن است نه خودِ لحن — قرمزِ روشن با متنِ سفید کنتراستِ کافی نداشت. جانشینِ ‎--danger.--solid‎ِ قدیم. */
.mb-btn--primary.mb-btn--danger {
  --btn-bg: var(--mb-tone-ink);
  --btn-bc: transparent;
  --btn-fg: var(--on-accent);
  --btn-bg-h: color-mix(in srgb, var(--mb-tone-ink) 88%, var(--text));
  --btn-bc-h: transparent;
  --btn-bg-a: var(--btn-bg-h);
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
}
.mb-btn--primary.mb-btn--danger:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn--primary.mb-btn--danger:active {
  background: var(--btn-bg-a);
}
/* روی سطحِ رنگی — استثنا، نه پله: وقتی دکمه روی سطحِ رنگی می‌نشیند و متنِ خنثی گم می‌شود. */
.mb-btn--on-solid {
  --btn-bg: color-mix(in srgb, var(--on-accent) 14%, transparent);
  --btn-bc: color-mix(in srgb, var(--on-accent) 45%, transparent);
  --btn-fg: var(--on-accent);
  --btn-bg-h: color-mix(in srgb, var(--on-accent) 30%, transparent);
  --btn-bc-h: color-mix(in srgb, var(--on-accent) 60%, transparent);
  --btn-bg-a: color-mix(in srgb, var(--on-accent) 36%, transparent);
  background: var(--btn-bg);
  border-color: var(--btn-bc);
  color: var(--btn-fg);
}
.mb-btn--on-solid:hover {
  background: var(--btn-bg-h);
  border-color: var(--btn-bc-h);
}
.mb-btn--on-solid:active {
  background: var(--btn-bg-a);
}
/* افزودن — فقط و فقط برای «افزودن/جدید». کادرِ خط‌چین یعنی «اینجا هنوز چیزی نیست». */
.mb-btn--dashed {
  --btn-bs: dashed;
  border-style: var(--btn-bs);
}
/* فقط آیکون — پهنا خودبه‌خود برابرِ ارتفاع است، پس با هر اندازه‌ای مربع می‌ماند. */
.mb-btn--icon {
  --btn-px: 0;
  padding-inline: var(--btn-px);
  inline-size: var(--btn-h);
  min-inline-size: var(--btn-h);
}
/* آیکون × sm — فقط برای وزنِ (۰,۲,۰)؛ عرض همان ارتفاعِ اندازه است. بدونش عرضِ دستیِ یک صفحه بر عرضِ کیت برنده می‌شد. */
.mb-btn--icon.mb-btn--sm {
  inline-size: var(--btn-h);
  min-inline-size: var(--btn-h);
}
/* تمام‌عرض — فقط چیدمان است، نه ظاهر؛ ویژگیِ قابلِ‌تنظیمی ندارد. */
.mb-btn--block {
  display: flex;
  inline-size: 100%;
}
/* @kit:mb-btn:end */

/* رفتارِ دکمه، نه ظاهرش: غیرفعال، فشرده‌شده، و لمسیِ بی‌نشانگر. این‌ها
   ویژگیِ قابلِ‌تنظیم نیستند و عمداً بعد از بلوکِ ساخته‌شده می‌آیند — همان
   ترتیبی که پیش از این داشتند. */
.mb-btn:disabled, .mb-btn[aria-disabled="true"] {
  opacity: .55; cursor: not-allowed; pointer-events: none;
}
/* اصلیِ غیرفعال خاکستریِ پُر است، نه بنفشِ کم‌رنگ (طرحِ مالک، ۱۴۰۵/۰۷/۰۷): «هنوز
   نمی‌شود» باید با «می‌شود» اشتباه گرفته نشود. */
.mb-btn--primary:disabled, .mb-btn--primary[aria-disabled="true"] {
  --btn-bg: var(--border); --btn-bc: var(--border); --btn-fg: var(--muted);
  opacity: 1;
}
/* «صفحهٔ جاری» در صفحه‌بندی (طرحِ مالک، ۱۴۰۵/۰۷/۰۷): مرکبی پُر، نه رنگِ برند —
   رنگِ برند مالِ «اقدامِ اصلی» است و صفحهٔ جاری اقدام نیست، جای است. */
.mb-btn[aria-current="page"] {
  --btn-bg: var(--text); --btn-bc: var(--text); --btn-fg: var(--surface);
  --btn-bg-h: var(--text); --btn-bc-h: var(--text); --btn-fg-h: var(--surface);
  background: var(--btn-bg); border-color: var(--btn-bc); color: var(--btn-fg);
}
/* بی‌نشانگر: سادهٔ خطر رنگش را از اول نشان می‌دهد، چون hover ندارد. */
@media (hover: none) {
  .mb-btn--ghost.mb-btn--danger { color: var(--danger-text); }
}
.mb-btn[aria-pressed="true"]:where(:not(.mb-btn--primary, .mb-btn--danger, .mb-btn--on-solid)) {
  background: var(--surface-3);
  border-color: var(--border-strong);
}

/* ── ۳) چیپ / نشان ──────────────────────────────────────────────────────────
   حالت هرگز فقط با رنگ گفته نمی‌شود: چیپِ وضعیت همیشه برچسبِ متنی دارد
   (WCAG 1.4.1). رنگِ متن همیشه نسخهٔ -text است، نه رنگِ خام — همان اشتباهی
   که در ۹ فایل نسبتِ ۴٫۲۴ می‌داد. */
.mb-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: 24px;
  padding-block: 2px;
  padding-inline: var(--sp-2);
  /* گوشهٔ فشرده (۶)، نه کپسول — طرحِ Claude Design، مبنای اطلس از ۱۴۰۵/۰۷/۱۲.
     کپسول فقط برای «نشانِ وضعیت» است: ‎--pill‎ پایین‌تر. */
  border-radius: var(--r-sm);
  background: var(--surface-3);
  color: var(--text-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.4;
  white-space: nowrap;
  vertical-align: middle;
}

.mb-chip svg { width: var(--icon-2xs); height: var(--icon-2xs); flex: none; }

/* چیپی که خودش دکمه است (‎<button class="mb-chip …">‎، مثلِ «+N» یا فیلتر):
   کادرِ پیش‌فرضِ مرورگر (۲px outset) و قلمِ سیستمیِ دکمه را نمی‌گیرد. وزنِ
   ‎:where‎ صفر است، پس کادرِ ‎--outline/--dashed‎ و hoverِ ‎--btn‎ بر آن می‌نشیند. */
.mb-chip:where(button) { border: 1px solid transparent; font-family: inherit; }

/* نشانِ وضعیت (مستقل، مثلِ والد، تجمیعی، فقط مشاهده…): کپسول و نیمه‌پررنگ —
   همان تمایزی که طرح میانِ «برچسبِ داده» (گوشهٔ ۶) و «وضعیت» (کپسول) می‌گذارد. */
.mb-chip--pill {
  min-height: 26px; padding-inline: 10px; border-radius: var(--r-pill);
  background: var(--border-soft); color: var(--text); font-weight: var(--fw-semibold);
}

.mb-chip--accent { background: var(--accent-soft); color: var(--accent-text); }

.mb-chip--ok     { background: var(--ok-soft);     color: var(--ok-text); }

.mb-chip--warn   { background: var(--warn-soft);   color: var(--warn-text); }

.mb-chip--danger { background: var(--danger-soft); color: var(--danger-text); }

.mb-chip--info   { background: var(--info-soft);   color: var(--info-text); }

.mb-chip--imp    { background: var(--imp-soft);    color: var(--imp-text); }

.mb-chip--muted  { background: var(--surface-3);   color: var(--muted); }

.mb-chip--outline { background: transparent; border: 1px solid var(--border); }

/* گرادیانِ تأکید — هم‌نامِ .mb-iconbox--grad. (دکمه دیگر گرادیان ندارد.) */
.mb-chip--grad, /* گرادیانِ تأکید — هم‌نامِ .mb-frame--grad. (دکمه دیگر گرادیان ندارد.) */
.mb-chip--grad { background: var(--grad-accent); color: var(--on-accent); }

/* چین‌دار: «می‌شود اضافه‌اش کرد» (برچسبِ پیشنهادی، جای خالیِ فیلتر). */
.mb-chip--dashed { background: transparent; border: 1px dashed var(--border-strong); }

/* کادر/چین‌دار × لحن، صریح: تک‌کلاس‌ها هم‌وزن‌اند و تا امروز فقط ترتیبِ فایل
   می‌گفت ‎--ok --outline‎ زمینه دارد یا نه. ترکیب (۰,۲,۰) هر ترتیبی را می‌بَرد:
   زمینه شفاف، کادر رنگِ لحن، مرکب نسخهٔ -text. */
.mb-chip--outline:is(.mb-chip--accent, .mb-chip--ok, .mb-chip--warn, .mb-chip--danger, .mb-chip--info),
.mb-chip--dashed:is(.mb-chip--accent, .mb-chip--ok, .mb-chip--warn, .mb-chip--danger, .mb-chip--info) { background: transparent; }

.mb-chip--outline.mb-chip--accent, .mb-chip--dashed.mb-chip--accent { border-color: var(--accent); color: var(--accent-text); }

.mb-chip--outline.mb-chip--ok,     .mb-chip--dashed.mb-chip--ok     { border-color: var(--ok);     color: var(--ok-text); }

.mb-chip--outline.mb-chip--warn,   .mb-chip--dashed.mb-chip--warn   { border-color: var(--warn);   color: var(--warn-text); }

.mb-chip--outline.mb-chip--danger, .mb-chip--dashed.mb-chip--danger { border-color: var(--danger); color: var(--danger-text); }

.mb-chip--outline.mb-chip--info,   .mb-chip--dashed.mb-chip--info   { border-color: var(--info);   color: var(--info-text); }

/* چیپِ فیلترِ خط‌دار در حالِ استراحت (طرحِ مالک، ۱۴۰۵/۰۷/۰۷): کادرِ خنثی و مرکبِ لحن؛
   لحن فقط وقتی کادر و زمینه می‌گیرد که فشرده شود (‎[aria-pressed="true"]‎ پایین‌تر). */
.mb-chip--btn.mb-chip--outline:is(.mb-chip--accent, .mb-chip--ok, .mb-chip--warn, .mb-chip--danger, .mb-chip--info):not([aria-pressed="true"]) { border-color: var(--border); }

/* شمارندهٔ داخلِ چیپ (مثلاً «۱۲») */
.mb-chip__n {
  display: inline-block;
  min-inline-size: 1.6em;
  padding-inline: .35em;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, currentColor 14%, transparent);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* پُریِ توپُر — دکمه این محور را ندارد؛ آنجا «اصلی» یک پله است نه یک پُری.
   کیت تا امروز برای چیپ فقط soft/outline/dashed/grad داشت و هیچ پُریِ توپُری،
   پس دو تبِ برنامه (ارتباطات و هاب) شمارنده‌شان را دست‌ساز و با دو رنگِ
   متفاوت ساختند. ‎.mb-chip__n‎ جایشان نبود: زمینه‌اش color-mix(currentColor
   14%) است و مستقل روی تب یک لکهٔ کم‌رنگ می‌شود، نه یک نشانِ خوانا.
   زمینهٔ لحنِ توپُر نسخهٔ ‎-text‎ِ رنگ است نه خودِ رنگ‌مایه — دقیقاً همان
   تصمیمِ بندِ ۲ برای دکمه: سفید روی ‎--ok‎ زیرِ کفِ کنتراست می‌افتد.
   ترکیب (۰,۲,۰) نوشته شده تا ترتیبِ کلاس‌ها در HTML بی‌اثر باشد. */
.mb-chip--solid { background: var(--accent); color: var(--on-accent); border-color: transparent; }

.mb-chip--solid.mb-chip--accent { background: var(--accent); }

.mb-chip--solid.mb-chip--ok     { background: var(--ok-text); }

.mb-chip--solid.mb-chip--warn   { background: var(--warn-text); }

.mb-chip--solid.mb-chip--danger { background: var(--danger-text); }

.mb-chip--solid.mb-chip--info   { background: var(--info-text); }

.mb-chip--solid.mb-chip--imp    { background: var(--imp-text); }

.mb-chip--solid.mb-chip--muted  { background: var(--muted); }

/* شمارندهٔ مستقل (روی تب)، نه ‎.mb-chip__n‎ که داخلِ چیپ است: قرصِ گرد با کفِ
   عرض، تا ۹ و ۱۰ ردیف را جابه‌جا نکنند. کفِ ۲۴ِ چیپ اینجا معنا ندارد — این
   نشان است، نه هدفِ لمس (استثنایش در بلوکِ ≤۱۰۲۴ صریح نوشته شده). */
.mb-chip--count { border-radius: var(--r-pill); min-inline-size: 18px; min-height: 18px; padding-inline: var(--sp-1-5); justify-content: center; font-size: var(--fs-xs); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; }

/* چیپی که رنگش *داده* است نه لحن: نوعِ پرداخت، دستهٔ ممیزی، نقشِ کاربر.
   همان الگویی که ‎.mb-dot‎ با ‎--mb-dot-c‎ دارد — یک متغیر که صفحه درجا
   می‌نشانَد، هم زمینه هم مرکب. سه کپیِ زنده سه فرمولِ جدا داشتند (پرداخت‌ها
   با ‎--c‎ و ۱۲٪، ممیزی با ۱۲ جفت متغیرِ دستی، مدیریت با ۶ کلاسِ نقش)؛ با این
   هوک، نوعِ تازه دیگر CSS نمی‌خواهد. پیش‌فرض امن است: بی‌متغیر، چیپِ تأکید.

   ⚠ مرکب هرگز خودِ رنگ‌مایهٔ خام نیست — همان قاعدهٔ سرِ همین بند و همان
   تصمیمی که ‎--solid‎ با نسخهٔ ‎-text‎ گرفت. با رنگِ خام، «نقدی»ِ هشدار روی
   ته‌رنگِ خودش ۱٫۹۶ و «کارت‌به‌کارت»ِ خوب ۲٫۲۷ می‌داد (کفِ AA برای متنِ ۱۲
   پیکسلی ۴٫۵ است). ولی متغیر را نمی‌شود به «حتماً نسخهٔ ‎-text‎ را بده»
   سپرد؛ رنگ *داده* است و از دیتابیس می‌آید. پس مرکب را خودِ کیت از همان
   رنگ‌مایه می‌سازد: ۴۵٪ رنگ‌مایه + ۵۵٪ ‎--text‎. جهتش با تم می‌چرخد (در
   روشنی تیره‌تر، در تاریکی روشن‌تر) و اندازه‌گیریِ بدترین حالت روی ۱۰
   رنگ‌مایه — از زردِ لیمویی تا سرمه‌ای — در هر دو تم ≥۵٫۰ شد.
   ‎--mb-chip-ink‎ درِ پشتی است برای صفحه‌ای که *واقعاً* جفتِ ‎-text‎ دارد. */
.mb-chip--tint {
  background: color-mix(in srgb, var(--mb-chip-c, var(--accent)) 12%, var(--surface));
  color: var(--mb-chip-ink, color-mix(in srgb, var(--mb-chip-c, var(--accent)) 45%, var(--text)));
}

.mb-chip--tint .mb-dot { --mb-dot-c: var(--mb-chip-c, var(--accent)); }

/* چیپِ روی یک سطحِ توپُرِ رنگی (بنرِ «به‌جای کاربر»، نوارِ خطای سراسری):
   زمینه‌اش پرده‌ای از مرکبِ خودِ میزبان است نه ‎--surface-3‎، وگرنه روی بنر
   یک وصلهٔ خاکستری می‌شود. آخرِ خانواده است تا بر هر لحنی بنشیند. */
.mb-chip--on-solid { background: color-mix(in srgb, currentColor 22%, transparent); color: inherit; }

.mb-input,
.mb-select,
.mb-textarea {
  inline-size: 100%;
  min-height: var(--ctl-h-md);
  padding-block: 0;
  padding-inline: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-ctl);
  line-height: 1.4;
  letter-spacing: 0;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.mb-textarea { min-height: calc(var(--ctl-h-md) * 2.4); padding-block: var(--sp-2); resize: vertical; line-height: var(--lh-md); }

.mb-input::placeholder, .mb-textarea::placeholder { color: var(--faint); }

.mb-input:hover, .mb-select:hover, .mb-textarea:hover { border-color: var(--border-strong); }

.mb-input:focus, .mb-select:focus, .mb-textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
  outline: none;                   /* فوکوسِ فیلد با حلقهٔ نرمِ خودش گفته می‌شود؛ بندِ ۷ روی بقیه است */
}

/* ⚠ background-color، نه سرنامِ background: سرنام ‎background-image‎ را هم صفر
   می‌کند و سلکتِ غیرفعال پیکانش را کامل از دست می‌داد (ویزاردِ ورودِ CSV،
   ستون‌های قفل‌شده). همان تله‌ای که ‎--soft‎ هم خورد. */
.mb-input:disabled, .mb-select:disabled, .mb-textarea:disabled { background-color: var(--surface-3); color: var(--muted); cursor: not-allowed; }

/* فقط‌خواندنی با غیرفعال یکی نیست و نباید یک‌شکل دیده شود: مقدارش معنا دارد،
   انتخاب و کپی می‌شود، و فقط *این* کاربر اجازهٔ تغییرش را ندارد — مثلِ «هزینهٔ
   حملِ تأییدشده» در فاکتور، که فروشنده باید ببیند ولی حسابدار می‌نویسد. پس
   سطحِ آرام و مرکبِ خوانا، نه خاکستریِ «اینجا چیزی نیست». تا امروز هر صفحه
   خودش این حالت را از نو می‌ساخت (و هر بار با رنگِ خامِ خودش). */
.mb-input[readonly], .mb-textarea[readonly] {
  background: var(--surface-2);
  color: var(--text-2);
  cursor: default;
}

.mb-input[readonly]:hover, .mb-textarea[readonly]:hover { border-color: var(--border); }

/* «این فیلد خطا دارد» باید از هر لحن و هر حالتِ دیگری بالاتر بنشیند: با وزنِ
   (۰،۲،۰) و جای قبلی‌اش، ‎.mb-input--soft:hover/:focus‎ (هم‌وزن ولی پایین‌تر)
   کادرِ قرمز را برمی‌داشت و صفحهٔ ورود عملاً خطا را نشان نمی‌داد. ‎:where()‎
   وزن اضافه نمی‌کند، پس ‎:is()‎ روی خودِ عنصر تکرار می‌شود تا (۰،۳،۰) شود. */
.mb-input[aria-invalid="true"]:is(.mb-input), .mb-select[aria-invalid="true"]:is(.mb-select), .mb-textarea[aria-invalid="true"]:is(.mb-textarea),
.mb-input[aria-invalid="true"]:is(.mb-input):is(:hover, :focus), .mb-select[aria-invalid="true"]:is(.mb-select):is(:hover, :focus), .mb-textarea[aria-invalid="true"]:is(.mb-textarea):is(:hover, :focus) {
  border-color: var(--danger);
}

.mb-input[aria-invalid="true"]:is(.mb-input):focus, .mb-select[aria-invalid="true"]:is(.mb-select):focus, .mb-textarea[aria-invalid="true"]:is(.mb-textarea):focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 18%, transparent);
}

/* سلکت: پیکانِ خودمان، سمتِ inline-end (در RTL یعنی چپ) — ویژگیِ منطقی. */
.mb-select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: calc(var(--sp-3) + var(--icon-sm) + var(--sp-2));
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left var(--sp-3) center;
  background-size: var(--icon-sm);
}

[dir="ltr"] .mb-select { background-position: right var(--sp-3) center; }

/* جزیرهٔ LTR (کد، شماره، URL): جداسازیِ دوسویه روی خودِ محتوا، نه روی سلول/سرستون */
.mb-input--ltr { direction: ltr; unicode-bidi: isolate; text-align: start; font-family: var(--font-mono); font-size: var(--fs-sm); }

/* مبلغ: جزیرهٔ LTR، چسبیده به لبهٔ inline-end (در RTL یعنی راست، هم‌راستا با
   بقیهٔ ورودی‌ها)، با ارقامِ هم‌عرض تا عدد هنگامِ تایپ نلرزد. رفتارش —
   ارقامِ فارسی و جداکنندهٔ هزارگان حینِ تایپ — در ui-kit.js است:
   `MB.moneyInput(el)`. ظاهر و رفتار با هم می‌آیند، وگرنه هر صفحه یکی از آن دو
   را از قلم می‌اندازد. */
.mb-input--money {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: end;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* کدِ ماشینیِ وسط‌چین — خواهرِ ‎--ltr‎ است، نه رقیبش: آن جزیرهٔ لاتینِ
   سرچسب است (کد، URL) و این جزیره‌ای که کاربر *حرف‌به‌حرف* می‌خواندش
   (کدِ رنگ، رمزِ یک‌بارمصرف، سال/ماه/روز). سه کپیِ زنده هر کدام فونتش را
   جدا انتخاب کرده بودند. بعد از ‎--ltr‎ می‌آید تا ترازِ وسط برنده باشد. */
.mb-input--code {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: center;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ── ۴-الف) نردبانِ اندازهٔ کنترل ────────────────────────────────────────────
   دکمه سه پله دارد (--xs / --sm / پیش‌فرض / --lg)، ولی کنترلِ فرم تا امروز
   *یک* قد داشت: ‎--ctl-h-md‎. هر صفحه‌ای که کنترلی در یک ردیفِ فشرده لازم
   داشت — نوارِ ابزارِ جدول، جدولِ تصمیمِ ویزاردِ CSV، نوارِ انتخاب، گرهِ
   تقسیمِ انبار — ۲۸ پیکسل را با دست از نو ساخت، هر بار با پدینگ و فونتِ
   خودش (۱۲ کپیِ زنده، از ۵px‌×۸ تا ۷×۱۰). دلیلِ بیرون‌ماندنشان از کیت
   ظاهر نبود، *اندازه* بود. ‎ui/warehouse-splitter.css‎ گواهِ ماجراست: همین
   ۲۸ را از توکن‌های خودِ کیت (‎--ctl-h-sm‎/‎--ctl-px-sm‎) ساخته، چون کیت
   نمی‌داد. پس این واریانت چیزی خرج نمی‌کند که کیت از قبل نداشته باشد.
   ⚠ ترتیب مهم است: کفِ لمسیِ بلوکِ ≤۱۰۲۴ پایین‌ترِ فایل است و هم‌وزن، پس
   روی موبایل همین پله هم به ۴۴ می‌رسد — عمدی، و آنجا صریح نوشته شده. */
.mb-input--sm, .mb-select--sm, .mb-textarea--sm {
  min-height: var(--ctl-h-sm);
  padding-inline: var(--ctl-px-sm);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
}

/* پیکانِ سلکت هم با کنترل کوچک می‌شود، وگرنه در ۲۸ پیکسل متن را می‌خورد. */
.mb-select--sm {
  padding-inline-end: calc(var(--ctl-px-sm) + var(--icon-xs) + var(--sp-1));
  background-size: var(--icon-xs);
  background-position: left var(--ctl-px-sm) center;
}

[dir="ltr"] .mb-select--sm { background-position: right var(--ctl-px-sm) center; }

.mb-textarea--sm { min-height: calc(var(--ctl-h-sm) * 2.4); padding-block: var(--sp-1-5); }

/* سرِ دیگرِ همان نردبان. دو صفحهٔ عمومیِ «اولین برخورد» (ورود و صفحهٔ فرود)
   عمداً در *هر* عرضی ۴۴ و ۱۶ را می‌خواهند، نه فقط زیرِ ۱۰۲۴: سافاریِ iOS
   روی ورودیِ کمتر از ۱۶ کلِ صفحه را زوم می‌کند. تا امروز این استدلال در
   CSSِ هر صفحه از نو نوشته می‌شد؛ حالا یک بار، اینجا. */
.mb-input--lg, .mb-select--lg, .mb-textarea--lg {
  min-height: var(--ctl-h-touch);
  padding-inline: var(--ctl-px-lg);
  font-size: var(--fs-lg);
}

.mb-textarea--lg { min-height: calc(var(--ctl-h-touch) * 2.4); padding-block: var(--sp-3); }

/* زمینهٔ نرم: کنترل روی یک سطحِ آرام می‌نشیند و *هنگامِ فوکوس* بالا می‌آید و
   سفید می‌شود. شش صفحه مستقل همین دو-حالتی را از نو اختراع کردند — یک
   تصمیمِ طراحیِ واقعی و تکراری (فرمی که مثلِ شش جعبهٔ سفیدِ روی هم دیده
   نشود)، نه یک سلیقهٔ یک‌باره. ولی چون شش قاعدهٔ جدا بود، دریفت کرد: سه‌تا
   ‎--info-soft‎ (ته‌رنگِ آبی) و سه‌تا ‎--surface-2‎ (خنثی).
   ⚠ تصمیم: ‎--surface-2‎ — یعنی صفحهٔ ورود و صفحهٔ فرود ته‌رنگِ آبی‌شان را
   آگاهانه از دست می‌دهند تا «زمینهٔ نرم» در کلِ برنامه یک چیز باشد.

   ⚠ ‎background-color‎ نوشته شده نه ‎background‎: سرنامِ کوتاه ‎background-image‎
   را هم صفر می‌کند و پیکانِ ‎.mb-select‎ (که ‎appearance:none‎ است) کلاً محو
   می‌شد — سلکتی بی هیچ نشانه‌ای که بازشدنی است. ‎--sm‎ چند خط بالاتر از قبل
   همین درس را با ‎background-size/position‎ِ تک‌نام رعایت کرده بود. */
.mb-input--soft, .mb-select--soft, .mb-textarea--soft {
  background-color: var(--surface-2);
  border-color: transparent;
}

.mb-input--soft:hover, .mb-select--soft:hover, .mb-textarea--soft:hover { border-color: var(--border); }

/* ⚠ رنگِ کادرِ فوکوس اینجا دوباره گفته می‌شود چون قاعدهٔ ‎:hover‎ بالا هم‌وزنِ
   ‎.mb-input:focus‎ِ پایه است ولی ۱۰۰ خط پایین‌ترش؛ بی این خط، فیلدِ نرمِ
   فوکوس‌دار زیرِ نشانگر کادرِ خنثی می‌گرفت و فقط هالهٔ فوکوس می‌ماند —
   یک حالتِ فوکوسِ نیمه‌کشیده. */
.mb-input--soft:focus, .mb-select--soft:focus, .mb-textarea--soft:focus {
  background-color: var(--surface);
  border-color: var(--accent);
}

/* ویندوز در «کنتراستِ بالا» سایه و ‎box-shadow‎ را دور می‌ریزد — یعنی حلقهٔ نرمِ
   فوکوسِ کنترل‌ها و کارت‌ها آنجا اصلاً دیده نمی‌شود. صفحه‌های ورود/ارتباطات
   پیش از مهاجرت هرکدام یک ‎outline‎ِ دستی برای همین داشتند؛ حالا یک‌بار اینجا. */
@media (forced-colors: active) {
  :where(.mb-input, .mb-select, .mb-textarea):focus,
  :where(.mb-btn, .mb-seg__btn, .mb-card--link, .mb-chip[tabindex], .mb-menu__item, .mb-tabs__tab):focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }
}

/* ── ۶) کارت، حالتِ خالی، توست ─────────────────────────────────────────────
   کارت ارتفاع می‌گیرد (سطح)، نه سایه — سایه فقط برای چیزی که واقعاً روی محتوا
   شناور است (منو، مودال). در تمِ تیره سایه روی #0d0f13 تقریباً دیده نمی‌شود. */
.mb-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
}

.mb-card--flat { border-color: var(--border-soft); }

/* ارتفاع سه پله دارد: --flat (بی‌سایه، کادرِ کم‌رنگ) < --low < --raised.
   --low پلهٔ *رایجِ* مخزن است — از ۸۱ کارت، ۲۰تا --shadow-sm داشتند و فقط
   ۹تا --shadow. --raised عمداً عوض نشد: ده جا (برند، ارز) همان سایهٔ
   پررنگ‌تر را آگاهانه خواسته‌اند. */
.mb-card--low { box-shadow: var(--shadow-sm); }

.mb-card--raised { box-shadow: var(--shadow); }

/* پلهٔ پایینِ همان نردبان: کارتی که در یک فهرست/گرید *تکرار* می‌شود. رایج‌ترین
   کارتِ مخزن نه پیش‌فرض است نه --lg، همین پدینگِ ۱۰–۱۴ است — دوازده کارتِ
   زنده، هرکدام با عددِ خودش. گردی عوض نمی‌شود (۱۲ از قبل اکثریت بود)، فقط
   پدینگ. پیش از --lg آمده تا اگر هر دو نوشته شد، «بزرگ» حرفِ آخر را بزند. */
.mb-card--dense { padding: var(--sp-3) var(--sp-4); }

/* کارتِ بزرگ — «بخش»ِ یک صفحه، نه یک آیتمِ فهرست. ۱۸ کارت پدینگِ --sp-5
   داشتند؛ کیت تا امروز فقط اندازهٔ کوچک را داشت. گردی همان سطح (--r-lg) است. */
.mb-card--lg { padding: var(--sp-5); }

/* پلهٔ چهارمِ ارتفاع، بالاتر از --raised: کارتی که *تنها* روی زمینهٔ صفحه
   شناور است (پنلِ ورود روی صفحهٔ گرادیانی)، نه یکی از اعضای یک فهرست.
   ⚠ ضعیف‌ترینِ این دسته: فقط دو مصرف‌کنندهٔ ساکن دارد. */
.mb-card--float { box-shadow: var(--shadow-lg); }

/* زمینه: کارت نردبانِ ارتفاع و نردبانِ اندازه داشت، ولی هیچ پیچِ *سطح* —
   پس هر صفحه‌ای که «این کارت یادداشت است / ارثی است / پارک‌شده است» را
   می‌گفت، خودش زمینه و کادر را از نو اعلام می‌کرد. دو تا از آن اعلام‌ها
   رنگِ خام بودند (‎#dbe3ef‎ و ‎#fde68a‎ در product-taxonomy-admin.js) یعنی در
   تمِ تیره برنمی‌گشتند — یک باگِ زنده که همین واریانت می‌بنددش.
   لحن برای کارت یعنی *زمینه*، نه متن: متنِ داخلِ کارت رنگ نمی‌گیرد. */
.mb-card--sunken { background: var(--surface-2); }

.mb-card--info   { background: var(--info-soft);   border-color: color-mix(in srgb, var(--info) 35%, var(--border)); }

.mb-card--ok     { background: var(--ok-soft);     border-color: color-mix(in srgb, var(--ok) 35%, var(--border)); }

.mb-card--warn   { background: var(--warn-soft);   border-color: color-mix(in srgb, var(--warn) 35%, var(--border)); }

.mb-card--danger { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }

.mb-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-block-end: var(--sp-3);
}

.mb-card__title { margin: 0; font-size: var(--fs-xl); font-weight: var(--fw-semibold); line-height: var(--lh-xl); }

/* پاورقیِ کارت — همان نوارِ ‎.mb-modal__foot‎ است که نیمهٔ کارتی‌اش هرگز ساخته
   نشد، پس چهار صفحه از نو ساختندش (همان کادرِ بالایی + همان ته‌رنگ + همان
   space-between). حاشیهٔ منفی پدینگِ کارت را پس می‌گیرد تا نوار به لبه برسد؛
   چون پدینگ سه پله دارد، هر پله حاشیهٔ خودش را می‌خواهد.
   ⚠ پاورقیِ کارت و پاورقیِ مودال یک چیزند — اینجا عوض شد، آنجا را هم ببینید. */
.mb-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin: var(--sp-4) calc(var(--sp-4) * -1) calc(var(--sp-4) * -1);
  padding: var(--sp-2) var(--sp-4);
  border-block-start: 1px solid var(--border-soft);
  background: var(--surface-2);
}

.mb-card--dense > .mb-card__foot { margin: var(--sp-3) calc(var(--sp-4) * -1) calc(var(--sp-3) * -1); }

.mb-card--lg > .mb-card__foot { margin: var(--sp-5) calc(var(--sp-5) * -1) calc(var(--sp-5) * -1); padding-inline: var(--sp-5); }

/* بی‌پدینگ: پیش‌شرطِ همان پاورقی، و خانهٔ کارتی که تصویرِ بنر یا جدول یا نوار
   باید تا لبهٔ گِردش برسد. امروز هر کارتِ تصویردار این را با ‎overflow:hidden‎ +
   ‎padding:0‎ِ خودش جعل می‌کند. بعد از --dense/--lg آمده تا صفرِ پدینگ برنده باشد. */
.mb-card--flush { padding: 0; overflow: hidden; }

.mb-card--flush > .mb-card__foot { margin: 0; }

/* کارتِ کلیک‌شدنی. ۳۶ قاعدهٔ صفحه‌ای همین سه خط را دست‌ساز دارند — بازنشاندنِ
   نشانگر و زیرخط، یک ترکیبِ transition، و hoverی که سایه را یک پله بالا
   می‌برد و کارت را ۱ تا ۳ پیکسل بلند می‌کند. یک رفتار با سه عددِ دلبخواهی.
   ⚠ یک حفرهٔ دسترس‌پذیری را هم می‌بندد: بندِ ۷ حلقهٔ فوکوس را فقط به
   ‎.mb-card[tabindex]‎ می‌دهد، پس هر ‎<a class="…-card">‎ِ مخزن تا امروز بی‌حلقه
   بود؛ این کلاس به همان فهرستِ ‎:where()‎ اضافه شد، نه با قاعده‌ای دوم. */
.mb-card--link {
  display: block;
  cursor: pointer;
  text-decoration: none;
  color: var(--text);
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.mb-card--link:hover {
  box-shadow: var(--shadow);
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}

.mb-card--link:active { transform: none; }

/* انتخاب‌شده: کارتی که *گزینه* است (رادیوی پنهان، aria-checked) یا مقصدِ
   جاری است. ‎:is()‎ وزنِ بزرگ‌ترین آرگومانش را می‌گیرد — هر پنج (۰,۱,۰)‌اند،
   پس وزنِ قاعده (۰,۲,۰) و از hover بالاتر.
   رادیو باید *داخلِ* کارت باشد (کارت یک ‎<label>‎ است)، نه خواهرِ قبلی‌اش:
   قانونِ ۵ِ اساس‌نامه گزینشگرِ بی‌پیشوند را در این فایل ممنوع می‌کند، و
   ‎label > input‎ همان الگویی است که برچسب را هم خودبه‌خود درست می‌کند. */
.mb-card--link:is(.is-on, [aria-checked="true"], [aria-selected="true"], [aria-current="page"], [aria-current="true"]),
.mb-card--link:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* ── ۶-الف) نوارِ رنگیِ لبهٔ بالا ────────────────────────────────────────────
   «یک خطِ ۳ پیکسلیِ رنگی روی لبهٔ بالا» در دستِ‌کم نُه شیوه‌نامهٔ صفحه از نو
   ساخته شده، هر بار با همان ‎::before‎ِ مطلق و همان ‎overflow:hidden‎ِ میزبان.
   عمداً کلاسِ *مستقل* است و نه ‎.mb-card--rule‎: یکی رویِ آمارک لازمش دارد،
   یکی روی یک ‎<section>‎ِ ساده، یکی روی هیرو. رنگ از یک متغیر می‌آید — همان
   کاری که ‎--mb-dot-c‎ برای نقطه می‌کند — تا صفحه‌ای که رنگِ هر ردیف را از
   داده می‌گیرد، متغیر بنشانَد نه اینکه کادر را بازنویسی کند.
   ⚠ ‎overflow:hidden‎ را به میزبان تحمیل می‌کند؛ روی ظرفی که منوی شناور دارد
   نگذاریدش. */
.mb-topline { position: relative; overflow: hidden; }

.mb-topline::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: var(--mb-topline, var(--grad-accent));
}

.mb-topline--ok     { --mb-topline: var(--ok); }

.mb-topline--warn   { --mb-topline: var(--warn); }

.mb-topline--info   { --mb-topline: var(--info); }

.mb-topline--danger { --mb-topline: var(--danger); }

.mb-topline--accent { --mb-topline: var(--accent); }

/* ── ۶-پ) کلید (روشن/خاموش) ─────────────────────────────────────────────────
   پنج پیاده‌سازیِ مستقل از همین یک چیز در مخزن بود (`.switch`+`.slider`،
   `.imp-switch`+`.imp-slider`، `.pl-switch`+`.pl-switch-track`، `.sf-toggle`،
   `.iv-toggle`). پایهٔ این یکی `.pl-switch` است، چون تنها یکی بود که هر چهار
   چیزِ لازم را داشت: دستگیرهٔ راست‌به‌چپ‌آگاه، حلقهٔ فوکوس، حالتِ غیرفعال، و
   ورودیِ پنهان‌ولی‌قابلِ‌دسترس.

   ترتیب در DOM عمدی و اجباری است: **برچسب، بعد ورودی، بعد ریل**.
     • برچسبِ اول یعنی در ردیفِ RTL متن سمتِ راست و کلید سمتِ چپ می‌نشیند —
       قاعده‌ای که db/__tests__/switch-label-order.test.js نگهبانش است.
     • ورودی باید بی‌واسطه پیش از ریل باشد، وگرنه `input:checked + track` کار
       نمی‌کند. `row-reverse` این را حل نمی‌کند: ظاهر را برمی‌گرداند ولی
       ترتیبِ Tab و صفحه‌خوان را وارونه می‌کند.

   <label class="mb-switch">
     <span class="mb-switch__label">نمایش کد</span>
     <input type="checkbox">
     <span class="mb-switch__track"></span>
   </label>                                                                   */
.mb-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--ctl-h-sm);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  font-size: var(--fs-sm);
  color: var(--text-2);
}

/* از دید پنهان، ولی برای صفحه‌خوان و صفحه‌کلید سرِ جایش — نه display:none */
.mb-switch input {
  position: absolute;
  opacity: 0;
  inline-size: 1px;
  block-size: 1px;
  pointer-events: none;
}

.mb-switch__track {
  position: relative;
  flex: 0 0 auto;
  inline-size: 34px;
  block-size: 19px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  border: 1px solid var(--border);
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.mb-switch__track::after {
  content: "";
  position: absolute;
  inset-block-start: 2px;
  inset-inline-start: 2px;
  inline-size: 13px;
  block-size: 13px;
  border-radius: var(--r-pill);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-fast) var(--ease);
}

.mb-switch input:checked + .mb-switch__track {
  background: var(--accent);
  border-color: var(--accent);
}

/* روشن یعنی دستگیره به سمتِ *پایانِ* منطقی می‌رود؛ transform همیشه فیزیکی است،
   پس علامتش باید با جهت عوض شود. جزیرهٔ LTR با [dir="ltr"] گفته می‌شود، همان
   قراردادی که .mb-select در همین فایل دارد — :dir() گزینشگرِ بی‌پیشوند است و
   بندِ ۵ اساس‌نامه آن را در این فایل نمی‌پذیرد. */
.mb-switch input:checked + .mb-switch__track::after { transform: translateX(-15px); }

[dir="ltr"] .mb-switch input:checked + .mb-switch__track::after { transform: translateX(15px); }

.mb-switch:hover .mb-switch__track { border-color: var(--accent); }

.mb-switch input:focus-visible + .mb-switch__track {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.mb-switch input:disabled + .mb-switch__track { opacity: .5; }

/* پلهٔ ریز — برای نوارِ ابزار، جایی که چند کلید کنارِ هم می‌نشینند و پلهٔ
   پایه ردیف را می‌شکند. این پله *ساخته شد* چون نبودش یک بار گران تمام شد:
   کتابخانه ناچار شده بود کلیدِ پایه را با `transform: scale(.65)` کوچک کند —
   دست‌بردن در ظاهرِ جزءِ کیت از CSSِ صفحه (بندِ ۹-ب) — و حاصلش حوزهٔ کلیکِ
   ۲۲×۱۲ پیکسل بود. اندازه‌ها با همان حسابِ پله‌ی پایه در می‌آیند، نه با
   مقیاس: جابه‌جاییِ دستگیره = عرضِ ریل − عرضِ دستگیره − دو برابرِ فاصله. */
.mb-switch--sm { gap: var(--sp-1); font-size: var(--fs-xs); }
.mb-switch--sm .mb-switch__track { inline-size: 26px; block-size: 15px; }
.mb-switch--sm .mb-switch__track::after { inline-size: 11px; block-size: 11px; }
.mb-switch--sm input:checked + .mb-switch__track::after { transform: translateX(-11px); }
[dir="ltr"] .mb-switch--sm input:checked + .mb-switch__track::after { transform: translateX(11px); }

/* ردیفِ تنظیم: برچسب (و توضیحش) سمتِ راست، کلید لبهٔ چپ، کلِ عرض. همان
   «تیک‌باکسِ جمله‌ای» که در مودال‌ها تنها می‌ماند — ولی حالا یک کلید است و جمله
   می‌تواند بشکند، چون ‎nowrap‎ِ پایه برای برچسبِ کوتاهِ نوارِ ابزار بود.
     <label class="mb-switch mb-switch--block">
       <span class="mb-switch__label">وضعیتِ پرداخت<span class="mb-switch__desc">پرداخت‌شده و مانده</span></span>
       <input type="checkbox"><span class="mb-switch__track"></span>
     </label> */
.mb-switch--block {
  display: flex;
  inline-size: 100%;
  justify-content: space-between;
  gap: var(--sp-4);
  white-space: normal;
  font-size: var(--fs-md);
  color: var(--text);
}

.mb-switch--block .mb-switch__label { min-inline-size: 0; line-height: 1.5; }

.mb-switch__desc {
  display: block;
  margin-block-start: 2px;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.6;
}

.mb-switch:has(input:disabled) { cursor: not-allowed; color: var(--muted); }

/* ── ۶-ث) قابِ آیکون ─────────────────────────────────────────────────────────
   «یک مربعِ گردِ رنگی با آیکون وسطش» سی بار در این مخزن از نو ساخته شده بود —
   با اندازه‌های ۱۹، ۲۰، ۲۸، ۳۰، ۳۴، ۳۶، ۳۸، ۴۲، ۴۴، ۴۶، ۵۰، ۵۲، ۵۶، ۶۴ و ۷۶
   پیکسل. این تنوع تصمیم نبود، تصادف بود: هر صفحه عددی زد که آن روز خوب به نظر
   رسید. پنج پله جای همه‌شان را می‌گیرد.

   <span class="mb-iconbox mb-iconbox--lg mb-iconbox--ok">…svg…</span>

   لحن پس‌زمینهٔ کم‌رنگ + مرکبِ هم‌خانواده می‌دهد، نه فقط رنگِ متن: آیکونِ
   بی‌زمینه روی سطحِ تیره و روشن یکسان دیده نمی‌شود. `--plain` برای جایی است
   که قاب فقط اندازه می‌دهد و رنگ از بیرون می‌آید.

   ‎.mb-stat__icon‎ همین قاب است با نامِ جایگاهش — یک تعریف، دو نام. تا امروز
   بلوکِ کپی‌شده‌ای داشت که *بعد از* لحن‌های قاب می‌آمد، پس
   ‎.mb-stat__icon.mb-frame--ok‎ زمینهٔ لحن را به کپی می‌باخت. */
/* ── ۶-ث) قابِ آیکون ─────────────────────────────────────────────────────────
   «یک مربعِ گردِ رنگی با آیکون وسطش» سی بار در این مخزن از نو ساخته شده بود —
   با اندازه‌های ۱۹، ۲۰، ۲۸، ۳۰، ۳۴، ۳۶، ۳۸، ۴۲، ۴۴، ۴۶، ۵۰، ۵۲، ۵۶، ۶۴ و ۷۶
   پیکسل. این تنوع تصمیم نبود، تصادف بود: هر صفحه عددی زد که آن روز خوب به نظر
   رسید. پنج پله جای همه‌شان را می‌گیرد.

   <span class="mb-iconbox mb-iconbox--lg mb-iconbox--ok">…svg…</span>

   لحن پس‌زمینهٔ کم‌رنگ + مرکبِ هم‌خانواده می‌دهد، نه فقط رنگِ متن: آیکونِ
   بی‌زمینه روی سطحِ تیره و روشن یکسان دیده نمی‌شود. `--plain` برای جایی است
   که قاب فقط اندازه می‌دهد و رنگ از بیرون می‌آید.

   ‎.mb-stat__icon‎ همین قاب است با نامِ جایگاهش — یک تعریف، دو نام. تا امروز
   بلوکِ کپی‌شده‌ای داشت که *بعد از* لحن‌های قاب می‌آمد، پس
   ‎.mb-stat__icon.mb-iconbox--ok‎ زمینهٔ لحن را به کپی می‌باخت. */
.mb-iconbox, .mb-frame, .mb-stat__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  inline-size: var(--sp-10);
  block-size: var(--sp-10);
  border-radius: var(--r-md);
  background: var(--accent-soft);
  color: var(--accent-text);
}

.mb-iconbox svg, .mb-stat__icon svg, .mb-frame svg { inline-size: var(--icon-md); block-size: var(--icon-md); }

.mb-iconbox--xs, .mb-frame--xs { inline-size: var(--sp-5); block-size: var(--sp-5); border-radius: var(--r-sm); }

.mb-iconbox--xs svg, .mb-frame--xs svg { inline-size: var(--icon-sm); block-size: var(--icon-sm); }

.mb-iconbox--sm, .mb-frame--sm { inline-size: var(--sp-8); block-size: var(--sp-8); border-radius: var(--r-sm); }

.mb-iconbox--sm svg, .mb-frame--sm svg { inline-size: var(--icon-sm); block-size: var(--icon-sm); }

.mb-iconbox--lg, .mb-frame--lg { inline-size: var(--sp-12); block-size: var(--sp-12); border-radius: var(--r-md); }

.mb-iconbox--lg svg, .mb-frame--lg svg { inline-size: var(--icon-lg); block-size: var(--icon-lg); }

.mb-iconbox--xl, .mb-frame--xl { inline-size: var(--sp-16); block-size: var(--sp-16); border-radius: var(--r-lg); font-size: var(--fs-3xl); }

.mb-iconbox--xl svg, .mb-frame--xl svg { inline-size: calc(var(--icon-lg) * 1.4); block-size: calc(var(--icon-lg) * 1.4); }

/* پلهٔ ۸۰ — هم‌قدِ .mb-avatar--2xl، تا دو قاب یک نردبان داشته باشند. */
.mb-iconbox--2xl, /* پلهٔ ۸۰ — هم‌قدِ .mb-avatar--2xl، تا دو قاب یک نردبان داشته باشند. */
.mb-frame--2xl { inline-size: var(--sp-20); block-size: var(--sp-20); border-radius: var(--r-lg); font-size: var(--fs-4xl); }

.mb-iconbox--2xl svg, .mb-frame--2xl svg { inline-size: calc(var(--icon-lg) * 1.8); block-size: calc(var(--icon-lg) * 1.8); }

/* شکل بعد از اندازه: پله‌ها گردیِ خودشان را می‌نشانند و هم‌وزن‌اند، پس ترتیب
   باید شکلِ خواسته‌شده را برنده کند. */

.mb-iconbox--round, .mb-frame--round { border-radius: var(--r-pill); }

/* لحن‌های قاب با آواتار یکی‌اند و پایینِ بخشِ آواتار تعریف شده‌اند (۶-ج) —
   آن‌جا، نه این‌جا: پایهٔ .mb-avatar هم زمینه می‌نشاند و هم‌وزن است، پس
   قاعدهٔ مشترک باید بعد از *هر دو* پایه بیاید. */
/* ── ۶-ج) آواتار ────────────────────────────────────────────────────────────
   شانزده پیاده‌سازی با هشت اندازه (۳۴ · ۳۶ · ۴۰ · ۴۴ · ۴۸ · ۵۲ · ۶۲ · ۸۰) و
   دو شکل (دایره / گوشه‌گرد). همان داستانِ قابِ آیکون: اندازه‌ها تصمیم نبودند.

   یک عنصر، دو محتوا — تصویر یا حرفِ اول:
     <span class="mb-avatar mb-avatar--lg"><img src=…></span>
     <span class="mb-avatar mb-avatar--lg">ع</span>

   حرفِ اول وقتی تصویر نیست: پس‌زمینهٔ کم‌رنگ + مرکبِ هم‌خانواده، نه خاکستریِ
   بی‌معنا — چون در فهرستِ کاربران همین حرف تنها چیزی است که یک نفر را از
   دیگری جدا می‌کند. */
.mb-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  inline-size: var(--sp-10);
  block-size: var(--sp-10);
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  line-height: 1;
  user-select: none;
}

/* تصویر تمامِ قاب را می‌گیرد و کِش نمی‌آید — عکسِ پروفایل معمولاً مربع نیست. */
.mb-avatar img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }

.mb-avatar--xs { inline-size: var(--sp-5); block-size: var(--sp-5); font-size: var(--fs-xs); }

.mb-avatar--sm { inline-size: var(--sp-8); block-size: var(--sp-8); font-size: var(--fs-sm); }

.mb-avatar--lg { inline-size: var(--sp-12); block-size: var(--sp-12); font-size: var(--fs-lg); }

.mb-avatar--xl { inline-size: var(--sp-16); block-size: var(--sp-16); font-size: var(--fs-2xl); }

.mb-avatar--2xl { inline-size: var(--sp-20); block-size: var(--sp-20); font-size: var(--fs-3xl); }

/* گوشه‌گرد به‌جای دایره: برای سازمان و برند، که نشانشان مربع است نه چهره.
   ‎--round‎ هم‌واژه با .mb-frame--round است (برای آواتار همان پیش‌فرض). */
/* گوشه‌گرد به‌جای دایره: برای سازمان و برند، که نشانشان مربع است نه چهره.
   ‎--round‎ هم‌واژه با .mb-iconbox--round است (برای آواتار همان پیش‌فرض). */
.mb-avatar--rounded { border-radius: var(--r-md); }

.mb-avatar--rounded:is(.mb-avatar--xs, .mb-avatar--sm) { border-radius: var(--r-sm); }

.mb-avatar--rounded:is(.mb-avatar--xl, .mb-avatar--2xl) { border-radius: var(--r-lg); }

.mb-avatar--round { border-radius: var(--r-pill); }

/* حلقهٔ جداکننده: وقتی چند قاب کنارِ هم (یا روی هم) می‌نشینند و محتوایشان
   خودش رنگ یا تصویر است — سواچِ رنگِ برند، لوگوی سازمان‌های یک ردیف. بدونِ
   حلقه، دو رنگِ روشنِ همسایه یکی دیده می‌شوند. دو کپیِ زنده حرف‌به‌حرف همین
   دو خط را دارند و هر دو نامشان «dot» است در حالی که ۲۰–۲۲ پیکسل‌اند —
   یعنی خانه‌شان ‎.mb-dot‎ (کفِ ۷، سقفِ ۱۳) نبود، ‎.mb-avatar--xs‎ بود. */
.mb-avatar--swatch { border: 1.5px solid var(--surface); box-shadow: 0 0 0 1px var(--border); }

/* لحن‌های مشترکِ قابِ آیکون و آواتار — مقدار یکی است، پس قاعده هم یکی.
   بعد از پایهٔ هر دو (و .mb-stat__icon) آمده‌اند؛ بالاتر، پایهٔ آواتار
   هم‌وزن بود و زمینهٔ لحن را پاک می‌کرد. ‎--accent‎ همان پیش‌فرض است با نامِ
   صریح، تا انتخابگرِ لحنِ اطلس گزینهٔ خالی نداشته باشد. */

.mb-iconbox--accent, .mb-avatar--accent, .mb-frame--accent { background: var(--accent-soft); color: var(--accent-text); }

.mb-iconbox--ok,     .mb-avatar--ok, .mb-frame--ok { background: var(--ok-soft);     color: var(--ok-text); }

.mb-iconbox--warn,   .mb-avatar--warn, .mb-frame--warn { background: var(--warn-soft);   color: var(--warn-text); }

.mb-iconbox--danger, .mb-avatar--danger, .mb-frame--danger { background: var(--danger-soft); color: var(--danger-text); }

.mb-iconbox--info,   .mb-avatar--info, .mb-frame--info { background: var(--info-soft);   color: var(--info-text); }

.mb-iconbox--muted,  .mb-avatar--muted, .mb-frame--muted { background: var(--surface-3);   color: var(--text-2); }

/* لحنِ گرادیانی — برای آواتار پیش‌فرضِ *واقعیِ* این برنامه است، نه یک تزئین:
   از ۱۶ آواتارِ مخزن، هفت‌تا همین گرادیانِ تأکید را داشتند. */

.mb-iconbox--grad,  .mb-avatar--grad, .mb-frame--grad { background: var(--grad-accent); color: var(--on-accent); }

/* لحنِ داده‌محور (رنگی که از داده می‌آید، نه از نقش): رنگِ شاخهٔ ریشه در درختِ
   محصول. JS سه متغیرِ ‎--mb-c / --mb-c-ink / --mb-c-soft‎ را می‌نشاند و base
   آن‌ها را به لحن وصل می‌کند؛ این‌جا فقط نقاشی‌اش است. ‎--solid‎ همان لحن را
   پُر می‌کند — نشانِ سطحِ اول؛ بی‌آن کم‌رنگ است — نشانِ سطحِ دوم. */
.mb-iconbox--tint, .mb-avatar--tint { background: var(--mb-tone-soft); color: var(--mb-tone-ink); }
.mb-iconbox--solid, .mb-avatar--solid { background: var(--mb-tone); color: var(--on-accent); }

/* ── رنگِ داده: هفت خانواده (‎.mb-hue-0…6‎) ──────────────────────────────────
   رنگی که از *داده* می‌آید، نه از نقش: هر شاخهٔ ریشه در درختِ محصول به ترتیبِ
   ریشه‌ها یکی از این هفت را می‌گیرد (TaxonomyTree.hueIdx → hueClass). کلاس را روی
   ظرف یا خودِ جزء بگذارید؛ هر جزءِ ‎--tint‎ِ داخلش — چیپ، آواتار، قاب، نقطه، تیک —
   همان رنگ را می‌خواند. همه از نسخهٔ ‎-text‎ِ لحن‌های تم‌اند، پس در تمِ تاریک
   خودشان روشن‌تر می‌شوند. ترتیب همان طرحِ Claude Design است:
   سبزآبی، بنفش، نارنجی، قرمز، نیلی، آبی، صورتی. */
.mb-hue-0 { --mb-hue: var(--ok-text); }
.mb-hue-1 { --mb-hue: var(--accent-2); }
.mb-hue-2 { --mb-hue: color-mix(in srgb, var(--warn-text) 55%, var(--danger-text)); }
.mb-hue-3 { --mb-hue: var(--danger-text); }
.mb-hue-4 { --mb-hue: var(--accent-text); }
.mb-hue-5 { --mb-hue: var(--info-text); }
.mb-hue-6 { --mb-hue: color-mix(in srgb, var(--imp-text) 55%, var(--danger-text)); }
/* وزنِ صفر: میزبانی که خودش ‎--mb-c*‎ را می‌نشاند (گروهِ درخت، پیش‌نمایشِ کشو) برنده است. */
:where(.mb-hue-0, .mb-hue-1, .mb-hue-2, .mb-hue-3, .mb-hue-4, .mb-hue-5, .mb-hue-6) {
  --mb-c: var(--mb-hue);
  --mb-c-ink: var(--mb-hue);
  --mb-c-soft: color-mix(in srgb, var(--mb-hue) 11%, var(--surface));
  --mb-chip-c: var(--mb-hue);
}

/* قاب فقط اندازه می‌دهد؛ رنگ از بیرون می‌آید (مثلاً کارتی که خودش تمِ رنگی دارد) */
.mb-iconbox--plain,  .mb-avatar--plain, /* قاب فقط اندازه می‌دهد؛ رنگ از بیرون می‌آید (مثلاً کارتی که خودش تمِ رنگی دارد) */
.mb-frame--plain { background: transparent; color: inherit; }

/* ── ۶-چ) نقطهٔ وضعیت ────────────────────────────────────────────────────────
   سی‌ویک پیاده‌سازی در ۱۸ فایل، و همه یک چیز بودند: دایرهٔ ۷ تا ۱۳ پیکسلی که
   رنگش حال را می‌گوید. تفاوتشان تصمیم نبود — هرکس عددِ خودش را زده بود.

   دو چیز از دلِ همان ۳۱ تا بیرون آمد و اینجا ماند، چون هر کدام یک‌بار درست
   حل شده بودند و ۳۰ بارِ دیگر نه:

   ۱) `flex: 0 0 auto`. فقط `.perm-dot` این را داشت، با کامنتِ «بدونِ این، فلکس
      نقطه را به بیضی می‌کشد». درست بود — و بقیه که داخلِ یک ردیفِ فلکس با
      متنِ بلند می‌نشستند، بیضی می‌شدند. حالا در پایه است.

   ۲) رنگ از `--mb-dot-c` می‌آید، نه مستقیم از `background`. چون نیمی از این
      نقطه‌ها رنگشان داده‌محور است (JS روی خودِ عنصر `--c` می‌نشاند: رنگِ
      دسته، رنگِ کاربر، رنگِ گزینه). با یک هوکِ نام‌دار هم لحنِ ثابت کار می‌کند
      هم رنگِ دلخواه — و هالهٔ `--ring` خودش از همان یک متغیر خوانده می‌شود، پس
      دیگر لازم نیست رنگ دو جا نوشته شود.

     <i class="mb-dot mb-dot--ok mb-dot--ring"></i>
     <i class="mb-dot" style="--mb-dot-c:#6b8"></i>          رنگِ داده‌محور
     <i class="mb-dot mb-dot--hollow" ...>  →  .is-on  پُر می‌شود
*/
.mb-dot {
  display: inline-block;
  /* نقطه باید نقطه بماند: در ردیفِ فلکس، فلکس آن را به بیضی می‌کشد. */
  flex: 0 0 auto;
  inline-size: 10px;
  block-size: 10px;
  border-radius: var(--r-pill);
  background: var(--mb-dot-c, var(--muted));
  vertical-align: middle;
}

.mb-dot--xs { inline-size: 7px; block-size: 7px; }

.mb-dot--sm { inline-size: 8px; block-size: 8px; }

.mb-dot--lg { inline-size: 13px; block-size: 13px; }

/* کلیدِ افسانه (legend) گاهی مربعِ گردگوشه است نه دایره — چون کنارِ نمودار
   باید هم‌شکلِ خودِ ناحیهٔ نمودار باشد، نه هم‌شکلِ نقطهٔ وضعیت. */
.mb-dot--square { border-radius: var(--r-sm); }

.mb-dot--ok     { --mb-dot-c: var(--ok); }

.mb-dot--warn   { --mb-dot-c: var(--warn); }

.mb-dot--danger { --mb-dot-c: var(--danger); }

.mb-dot--info   { --mb-dot-c: var(--info); }

.mb-dot--accent { --mb-dot-c: var(--accent); }

.mb-dot--muted  { --mb-dot-c: var(--muted); }

/* رنگِ داده‌محور — همان ‎--mb-c‎ که آواتار و چیپِ ‎--tint‎ می‌خوانند. */
.mb-dot--tint   { --mb-dot-c: var(--mb-tone); }

/* «خاموش» یعنی هست ولی فعال نیست — خاکستریِ پررنگ، نه نامرئی. */
.mb-dot--off    { --mb-dot-c: var(--border-strong); }

/* رنگ را از متنِ میزبان می‌گیرد: داخلِ یک خطِ وضعیت که خودش لحن دارد. */
.mb-dot--current { --mb-dot-c: currentColor; }

/* هاله: نقطه را روی زمینهٔ شلوغ پیدا می‌کند، بی‌آنکه بزرگ‌ترش کند. */
.mb-dot--ring { box-shadow: 0 0 0 3px color-mix(in srgb, var(--mb-dot-c, var(--muted)) 18%, transparent); }

/* توخالی: «جای این هست ولی روشن نیست» — حالتِ خاموشِ یک دسترسی یا یک ستون.
   پُرشدنش با `.is-on` است، همان کلاسی که JS امروز هم می‌نشاند. */
.mb-dot--hollow {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--border-strong);
}

.mb-dot--hollow.is-on {
  background: var(--mb-dot-c, var(--accent));
  box-shadow: inset 0 0 0 1.5px var(--mb-dot-c, var(--accent));
}

/* سواچ: نقطه‌ای که *خودش* داده است (رنگِ گزینه)، پس کادرِ نازک می‌خواهد تا
   رنگِ روشن روی زمینهٔ روشن گم نشود. */
.mb-dot--swatch { box-shadow: inset 0 0 0 1px var(--border); }

/* ── ۶-ح) نقشهٔ روزها (heatmap) ──────────────────────────────────────────────
   یک خانه برای هر روز، هفت ردیف (شنبه تا جمعه)، هر ستون یک هفته — همان کارتِ
   «مصرف»ِ گیت‌هاب. اولین مصرف‌کننده: نمای «بکاپِ شبانه» در نوارِ بالا (auth.js).
   جهت از میزبان می‌آید: در صفحهٔ راست‌به‌چپ قدیمی‌ترین ستون سمتِ راست است.

   لحن‌ها همان پنج لحنِ کیت‌اند، به‌علاوهٔ دو شکلِ *توخالی* برای «باید می‌بود و
   نیست» — رنگ تنها حاملِ معنا نیست (WCAG 1.4.1): «انجام نشد» کادرِ خطر است نه
   پُرِ خطر، پس از «ناموفق» بی‌رنگ‌بینی هم جدا می‌شود.

     <div class="mb-heat">
       <span class="mb-heat__cell mb-heat__cell--blank"></span>   جای خالیِ پیش از روزِ اول
       <span class="mb-heat__cell mb-heat__cell--ok" tabindex="0" data-tip="…"></span>
       <span class="mb-heat__cell mb-heat__cell--danger mb-heat__cell--flag"></span>
     </div>

   اندازه از ‎--mb-heat-cell‎ / ‎--mb-heat-gap‎ می‌آید؛ میزبان می‌تواند عوضشان کند.
   خانه بیرون از ‎.mb-heat‎ هم کار می‌کند (کلیدِ افسانه کنارِ متن) — پیش‌فرضِ ۱۲ پیکسل. */
.mb-heat {
  --mb-heat-cell: 12px;
  --mb-heat-gap: 3px;
  display: inline-grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(7, var(--mb-heat-cell));
  grid-auto-columns: var(--mb-heat-cell);
  gap: var(--mb-heat-gap);
}

.mb-heat--lg { --mb-heat-cell: 15px; --mb-heat-gap: 4px; }

.mb-heat__cell {
  position: relative;
  display: block;
  inline-size: var(--mb-heat-cell, 12px);
  block-size: var(--mb-heat-cell, 12px);
  /* نصفِ پلهٔ کوچک: با --r-sm (۶) خانهٔ ۱۲–۱۵ پیکسلی دایره می‌شد، نه مربع. */
  border-radius: calc(var(--r-sm) / 2);
  background: var(--mb-heat-c, var(--surface-3));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 6%, transparent);
}

.mb-heat__cell--ok     { --mb-heat-c: var(--ok); }

.mb-heat__cell--warn   { --mb-heat-c: var(--warn); }

.mb-heat__cell--danger { --mb-heat-c: var(--danger); }

.mb-heat__cell--info   { --mb-heat-c: var(--info); }

/* «بی‌داده»: هنوز چیزی نبود که بشود سنجید — همان پیش‌فرض، با نامِ صریح. */
.mb-heat__cell--empty  { --mb-heat-c: var(--surface-3); }

/* توخالی: «باید می‌بود و نیست». با لحن جفت می‌شود (‎--danger‎ = انجام نشد،
   ‎--info‎ = هنوز وقتش نگذشته). */
.mb-heat__cell--hollow {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--mb-heat-c, var(--border-strong));
}

/* جای خالیِ پیش از روزِ اول، تا ستون‌ها با روزِ هفته جفت بمانند. */
.mb-heat__cell--blank { visibility: hidden; }

/* پرچم: یک نکتهٔ فرعی روی همان روز (مثلاً «عکسِ سرور تازه نبود») — نقطهٔ
   کوچکِ هشدار در گوشه، نه رنگِ دوم برای کلِ خانه. */
.mb-heat__cell--flag::after {
  content: "";
  position: absolute;
  inset-block-start: -2px;
  inset-inline-end: -2px;
  inline-size: 5px;
  block-size: 5px;
  border-radius: var(--r-pill);
  background: var(--warn);
  box-shadow: 0 0 0 1px var(--surface);
}

.mb-heat__cell[tabindex]:hover,
.mb-heat__cell[tabindex]:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; }

/* ── ۶-خ) حبابِ راهنما (hover) ───────────────────────────────────────────────
   ⚠ نامش عمداً `hint` است نه `tip`: `ui/mb-tip.css` از قبل `.mbtip` را دارد —
   حبابِ *سنجاق‌شونده*ی روشن با موتورِ خودش (`mb-tip.js`)، که ۵ صفحه لینکش
   می‌کنند. دو چیزِ متفاوت‌اند، و دو نامی که یک فاصله فرق دارند (`mb-tip` و
   `mbtip`) تله بود. این یکی حبابِ گذرای hover است؛ آن یکی کارتِ معرفیِ
   کلیک‌شونده که متنش انتخاب‌شدنی است.
   حبابِ تیره‌ای که کنارِ چیزی باز می‌شود. چهار پیاده‌سازی واقعی داشت و هر چهار
   یک شکل بودند: سطحِ تیره، مرکبِ روشن، گردی، بیشینهٔ عرض، و یک نوک.

   حباب همیشه تیره است، در هر دو تم — چون روی محتوای صفحه می‌نشیند و باید
   «جدا» دیده شود، نه هم‌رنگِ چیزی که رویش است.

   جای‌گذاری کارِ JS است، نه CSS: `position` و `inset` را میزبان می‌دهد
   (`--fixed` برای وقتی که از یک ظرفِ اسکرول‌دار بیرون می‌زند).

     <div class="mb-tip mb-tip--fixed is-on" style="inset-inline-start:…">…</div>
*/
.mb-hint {
  position: absolute;
  z-index: var(--z-tip);
  inline-size: max-content;
  max-inline-size: 300px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--d-border-strong);
  border-radius: var(--r-md);
  background: var(--d-surface-3);
  color: var(--on-dark);
  font-size: var(--fs-xs);
  line-height: var(--lh-md);
  box-shadow: var(--shadow-lg);
  /* نوکِ حباب از رویدادِ ماوس بی‌خبر است و نباید جلوی کلیک را بگیرد. */
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-fast) var(--ease), visibility var(--dur-fast) var(--ease);
}

.mb-hint.is-on { opacity: 1; visibility: visible; }

/* بیرونِ ظرفِ اسکرول‌دار: مختصات را JS از viewport می‌دهد. */
.mb-hint--fixed { position: fixed; }

.mb-hint--wide { max-inline-size: 440px; }

/* حبابی که خودش کلیک‌پذیر است (دکمه یا پیوند دارد). */
.mb-hint--interactive { pointer-events: auto; }

/* نوک: پیش‌فرض زیرِ حباب (یعنی حباب *بالای* هدف است). */
.mb-hint::after {
  content: "";
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: var(--mb-hint-arrow, 14px);
  border: var(--sp-1-5) solid transparent;
  border-block-start-color: var(--d-surface-3);
}

/* حباب زیرِ هدف نشسته، پس نوک باید بالا برود و برگردد. */
.mb-hint--below::after {
  inset-block-start: auto;
  inset-block-end: 100%;
  border-block-start-color: transparent;
  border-block-end-color: var(--d-surface-3);
}

.mb-hint--noarrow::after { display: none; }

/* ── ۶-خ‌ب) متنِ توضیحیِ ثابت ────────────────────────────────────────────────
   ⚠ با ‎.mb-hint‎ی که همین بالاست اشتباه نشود: آن حبابِ تیرهٔ روی‌اشاره است.
   این یک خطِ متنِ ثابت است که زیرِ فیلد یا پنل می‌نشیند و همیشه دیده می‌شود.
   از ۳۶ موردی که ممیزی «راهنما» نامیده بود، ۲۶ تا اصلاً حباب نبودند —
   همین متن بودند. کیت تنها ‎.mb-field__hint‎ را داشت، و آن *کلاسِ عنصرِ فیلد*
   است؛ پس هر توضیحی که بیرونِ فیلد بود (زیرِ پنل، بالای فرم، داخلِ مودال) از
   نو ساخته شد: بیست کپیِ زنده با هفت اندازه (۱۱ · ۱۱٫۵ · ۱۲ · ۱۲٫۵ · ۱۳ ·
   ‎.78rem‎ · ‎.84rem‎)، سه‌تا با رنگِ خامِ ‎#94a3b8‎/‎#64748b‎ که در تمِ تیره
   می‌شکند، و شش‌تا زیرِ کفِ ۱۲ پیکسلِ خودِ پروژه.
   ‎.mb-field__hint‎ عمداً دست‌نخورده ماند (خطِ زیرِ فیلد، همان ۱٫۵): تغییرش
   ظاهرِ هر فیلدِ زندهٔ مخزن را جابه‌جا می‌کرد. اینجا ‎--lh-base‎ است چون این
   یکی جمله است، نه برچسب. */
.mb-note {
  display: block;
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: var(--lh-base);
}

.mb-note--md     { font-size: var(--fs-sm); }

.mb-note--faint  { color: var(--faint); }

.mb-note--center { text-align: center; }

/* لحن روی خودِ متن — تا لحنِ بی‌جعبه هم معنا داشته باشد و کلاسِ ‎mb-‎ی که کیت
   نمی‌شناسد از آب درنیاید. */
.mb-note--ok     { color: var(--ok-text); }

.mb-note--warn   { color: var(--warn-text); }

.mb-note--info   { color: var(--info-text); }

.mb-note--danger { color: var(--danger-text); }

/* جعبهٔ توضیح: همان متن، ولی وقتی *باید* دیده شود (هشدارِ نقشِ کاربر، قفلِ
   نوعِ ستون). دو کپیِ زنده همین را جدا ساخته بودند — یکی کهربایی، یکی آبی. */
/* ۱۴۰۵/۰۷/۰۷ (طرحِ مالک): بی‌کادر — زمینهٔ ته‌رنگی خودش قاب است؛ کادرِ شفاف قد را ثابت نگه می‌دارد. */
.mb-note--callout { padding: var(--sp-2) var(--sp-3); border-radius: var(--r-lg); border: 1px solid transparent; background: var(--surface-2); }

.mb-note--callout.mb-note--warn   { background: var(--warn-soft);   color: var(--warn-text); }

.mb-note--callout.mb-note--info   { background: var(--info-soft);   color: var(--info-text); }

.mb-note--callout.mb-note--danger { background: var(--danger-soft); color: var(--danger-text); }

.mb-note--callout.mb-note--ok     { background: var(--ok-soft);     color: var(--ok-text); }

/* ── ۶-ز) نوارِ پیشرفت ──────────────────────────────────────────────────────
   ⚠ این خانواده در ممیزی چهار عضو داشت، ولی **فقط یکی واقعاً نوارِ پیشرفت
   بود**. بقیه هم‌نام بودند نه هم‌جنس: `.ch-progress` و `.sh-exit-progress`
   کارت‌اند (پنل + پدینگ + کادر) و `.tk-check-progress` یک خطِ متن است («۳ از
   ۵»). پس اینجا کپی‌ای برای برداشتن نبود — یک جزءِ پایه‌ای بود که **نداشتیم**
   و هرکس لازمش می‌شد از نو می‌ساخت. */
.mb-progress {
  display: block;
  inline-size: 100%;
  block-size: var(--sp-1);
  border-radius: var(--r-pill);
  background: var(--border);
  overflow: hidden;
}
/* `display: block` بالا بر `[hidden]`ِ مرورگر می‌چربید: نوارِ «در حالِ جستجو»ی
   پنجرهٔ الگوها با hidden هم همیشه می‌دوید (مالک، ۱۴۰۵/۰۷/۰۷). */
.mb-progress[hidden] { display: none; }

.mb-progress--lg { block-size: var(--sp-2); }

/* پلهٔ سوم (۴ / ۸ / ۱۲): نوارِ «پیشرفتِ راه‌اندازی» که خودش قهرمانِ کارت است،
   نه یک خطِ کناری. نوارِ واقعیِ صفحهٔ خانهٔ شرکت ۱۲ پیکسل است و با کیتِ
   دیروز باید ارتفاعش را از CSSِ صفحه می‌نوشت — یعنی همان بازنویسیِ ظاهرِ
   کیت که قدغن است. */
.mb-progress--xl { block-size: var(--sp-3); }

.mb-progress__fill {
  display: block;
  block-size: 100%;
  inline-size: 0;
  border-radius: inherit;
  background: var(--accent);
  transition: inline-size var(--dur-normal) var(--ease);
}

.mb-progress--ok     .mb-progress__fill { background: var(--ok); }

.mb-progress--warn   .mb-progress__fill { background: var(--warn); }

.mb-progress--danger .mb-progress__fill { background: var(--danger); }

.mb-progress--info   .mb-progress__fill { background: var(--info); }

/* «متوقف/بایگانی»: پیشرفت هست ولی دیگر جلو نمی‌رود. */
.mb-progress--muted  .mb-progress__fill { background: var(--muted); }

/* پُرشدنِ گرادیانی — هم‌واژه با ‎.mb-chip--grad‎. بعد از
   لحن‌ها آمده: هم‌وزن‌اند (۰,۲,۰) و اگر هر دو نوشته شد، گرادیان برنده است. */
.mb-progress--grad .mb-progress__fill { background: var(--grad-accent); }

/* «نمی‌دانیم چقدر مانده» — نوار می‌رود و برمی‌گردد، بی‌آنکه عددی ادعا کند. */
.mb-progress--indeterminate .mb-progress__fill { inline-size: 40%; animation: mbProgress 1.1s var(--ease) infinite; }

/* ── ۶-ژ) اسلایدر ───────────────────────────────────────────────────────────
   ⚠ مثلِ نوارِ پیشرفت: «۳ اسلایدر» شمرده شده بود ولی فقط **یکی**
   `input[type=range]` بود. `.cur-chart-range` یک چیپِ بازهٔ تاریخ است و
   `.pl-fltpop-range` جفتِ ورودیِ «از/تا». باز هم جزئی که نبود، نه کپی‌ای که
   بود.

   جهت همیشه `ltr` است: بیشترِ کاربرها کمینه را سمتِ چپ انتظار دارند، و
   `accent-color` رنگِ دسته و ریل را با یک خط به تم می‌دهد. */
.mb-range {
  inline-size: 100%;
  accent-color: var(--accent);
  direction: ltr;
  cursor: pointer;
  /* کفِ لمسی: دستهٔ باریک روی گوشی گرفتنی نیست. */
  min-block-size: var(--sp-6);
}

.mb-range:disabled { opacity: .5; cursor: not-allowed; }

/* عدد: جزیرهٔ LTR (منها و اعشار سرِ جای خودشان) و در آن جزیره «start» یعنی لبهٔ چپ —
   همان «انتهای» جدولِ راست‌به‌چپ. با موتورِ جدول (table-engine-common.css، بندِ ۳) یکی است. */
.mb-num { direction: ltr; text-align: start; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
/* عددِ درشت: جمعِ نهایی، قیمتِ اصلی، پله‌های زنجیرهٔ قیمت. دو پله بس است؛ طرح‌ها
   ۱۴ و ۱۶ و ۱۷ را inline می‌نوشتند. */
.mb-num--lg { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.mb-num--xl { font-size: var(--fs-xl); font-weight: var(--fw-bold); }

.mb-ltr { direction: ltr; unicode-bidi: isolate; display: inline-block; }

/* ── چیپ ──────────────────────────────────────────────────────────────────── */

/* دو پلهٔ اندازه که نبودنشان ۹۰ نشانِ دست‌ساز را ساخت: اندازه‌گیری نشان داد
   آن ۹۰تا سه خوشه‌اند، نه ۹۰ طرح. */
.mb-chip--xs { min-height: 18px; padding-block: 0; padding-inline: var(--sp-1-5); gap: var(--sp-1); }
.mb-chip--lg { min-height: var(--ctl-h-sm); padding-inline: var(--ctl-px-sm); gap: var(--sp-1-5); }
.mb-chip--glass {
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(8px); box-shadow: var(--shadow-sm); border-color: transparent;
}
/* بی‌ظرف: همان «نقطه + متن» که تا امروز هر صفحه خودش می‌ساخت. */
.mb-chip--bare {
  background: transparent; border-color: transparent;
  padding-inline: 0; padding-block: 0; min-height: 0; min-block-size: 1.5em;
  gap: var(--sp-1-5); font-weight: var(--fw-medium); line-height: 1.5; white-space: normal;
}
/* چیپِ کلیک‌شونده — هرگز `button.mb-chip`: وزنِ (۰,۱,۱) کادرِ --outline/--dashed
   را می‌کشد و چیپِ فیلترِ خاموش بی‌کادر می‌شود. */
.mb-chip--btn {
  cursor: pointer; font-family: inherit;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.mb-chip--btn:where(:not(.mb-chip--solid, .mb-chip--grad, .mb-chip--tint, .mb-chip--on-solid)):hover {
  border-color: var(--mb-tone); color: var(--mb-tone-ink);
}
/* «فشرده» ظاهرِ ثابت نمی‌دهد؛ پُریِ خودِ چیپ را پررنگ می‌کند. پس چیپِ تأکیدی
   نرم روشن می‌شود و چیپِ توپُرِ خطر، توپُرتر — دو شدت، بدونِ محورِ دوم. */
.mb-chip--btn[aria-pressed="true"] { background: var(--mb-tone-soft); border-color: var(--mb-tone); color: var(--mb-tone-ink); }
.mb-chip--btn.mb-chip--solid[aria-pressed="true"] { background: var(--mb-tone); color: var(--on-accent); }
/* اسلاتِ ✕ — هندسه مالِ چیپ است، ظاهرِ دکمه مالِ .mb-btn--icon.mb-btn--sm */
.mb-chip--dismissible { padding-inline: var(--sp-2) var(--sp-1); }
.mb-chip__x { display: inline-grid; place-items: center; flex: none; margin-inline-start: var(--sp-0-5); }

/* ── کارت / سطح ───────────────────────────────────────────────────────────── */

.mb-card--sm { padding: var(--sp-2) var(--sp-3); }   /* فقط پدینگ؛ شعاع نردبانِ خودش را دارد */
.mb-card--sunken-2 { background: var(--surface-3); border-color: var(--border-soft); }
.mb-card--dashed { border-style: dashed; border-color: var(--border-strong); }
.mb-card--glass { background: color-mix(in srgb, var(--surface) 86%, transparent); backdrop-filter: blur(18px) saturate(1.3); }
/* سطحِ لحن‌دار: سه لحنی که کیت نداشت و ۳۷ جای مخزن دستی ساخته بودند. عمداً
   فقط زمینه و کادر — رنگِ *متن* کارِ یادداشت است نه کارت. */
.mb-card--accent, .mb-card--imp, .mb-card--muted {
  background: var(--mb-tone-soft);
  border-color: color-mix(in srgb, var(--mb-tone) 35%, var(--border));
}
/* گرادیانِ ملایمِ سطح؛ با لحن ترکیب می‌شود چون هر شستِ زنده‌ای لحن دارد. */
.mb-card--grad { background: linear-gradient(180deg, var(--surface), var(--mb-tone-soft)); }
.mb-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.mb-card__foot { display: flex; align-items: center; gap: var(--sp-2); }

/* ── یادداشت ──────────────────────────────────────────────────────────────── */

.mb-note--lg { font-size: var(--fs-md); line-height: var(--lh-md); }
.mb-note--callout.mb-note--lg { padding: var(--sp-3) var(--sp-4); }
.mb-note--accent { color: var(--accent-text); }
.mb-note--imp { color: var(--imp-text); }
.mb-note--muted { color: var(--muted); }
.mb-note--callout:is(.mb-note--accent, .mb-note--imp, .mb-note--muted) {
  background: var(--mb-tone-soft);
  color: var(--mb-tone-ink);
}
.mb-note--callout.mb-note--outline { background: color-mix(in srgb, var(--surface) 67%, transparent);
  border-color: color-mix(in srgb, var(--mb-tone) 24%, var(--border)); }
.mb-note--callout.mb-note--dashed { border-style: dashed; border-color: var(--border); background: var(--surface-2); }
/* ردیفِ «آیکون + متن + کنش» — تنها دلیلی که ۲۰ جعبهٔ پیامِ رنگی دستی ساخته
   شدند. عمداً `--row` نه `--icon`: `--icon` جای دیگر یعنی «فقط آیکون». */
.mb-note--row { display: flex; align-items: flex-start; gap: var(--sp-2); flex-wrap: wrap; }
.mb-note--row.mb-note--center { align-items: center; }
.mb-note__icon { flex: 0 0 auto; inline-size: var(--icon-sm); block-size: var(--icon-sm); margin-block-start: var(--sp-0-5); }
.mb-note__body { flex: 1 1 200px; min-inline-size: 200px; }
.mb-note__title { display: block; font-weight: var(--fw-semibold); margin-block-end: var(--sp-0-5); }
.mb-note__actions { flex: 0 0 auto; display: flex; gap: var(--sp-2); margin-inline-start: auto; }
/* نوارِ رنگیِ لبه — `--edge`، چون `--bar` نامِ یک مؤلفهٔ دیگر است. */
.mb-note--edge { border-inline-start: 3px solid var(--mb-tone); padding-inline-start: var(--sp-3); }

/* ── کنترلِ فرم ───────────────────────────────────────────────────────────── */

/* بی‌ظرف تا وقتی دست نخورده: ویرایشِ درجا. */
.mb-input--ghost, .mb-select--ghost, .mb-textarea--ghost {
  background-color: transparent; border-color: transparent; padding-inline: var(--sp-1);
}
.mb-input--ghost:hover, .mb-select--ghost:hover, .mb-textarea--ghost:hover { background-color: var(--surface-2); border-color: transparent; }
.mb-input--ghost:focus, .mb-select--ghost:focus, .mb-textarea--ghost:focus { background-color: var(--surface); border-color: var(--mb-tone); }
.mb-input--dashed, .mb-select--dashed, .mb-textarea--dashed { border-style: dashed; }
.mb-input--ghost:is([readonly], :disabled) { background-color: transparent; }
/* لحنِ اعتبارسنجیِ غیرِ خطا (تأییدشده / هشدار / اطلاع) — تا امروز فقط
   aria-invalid بود و بقیه دستی. */
.mb-input--ok, .mb-input--warn, .mb-input--info,
.mb-select--ok, .mb-select--warn, .mb-select--info {
  border-color: var(--mb-tone);
  background-color: color-mix(in srgb, var(--mb-tone) 10%, var(--surface));
}
.mb-input--ok:focus, .mb-input--warn:focus, .mb-input--info:focus {
  border-color: var(--mb-tone);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mb-tone) 18%, transparent);
}
/* جای آیکونِ پیشوند/پسوند — تا امروز هر صفحه عددِ خودش را می‌نوشت
   (۳۴px اینجا، ۳۲ آنجا) و آیکون روی متن می‌افتاد. */
.mb-input--lead  { padding-inline-start: calc(var(--sp-3) + var(--icon-sm) + var(--sp-2)); }
.mb-input--trail { padding-inline-end:   calc(var(--sp-3) + var(--icon-sm) + var(--sp-2)); }
/* محتوای دوسویه (جست‌وجو: هم کد، هم نامِ فارسی): هر مقدار جهتش را از نخستین
   حرفِ قویِ خودش می‌گیرد — «0703-XJ-77CP» چپ‌به‌راست و درست‌ترتیب، فارسی
   راست‌به‌چپ — ولی خودِ جعبه هم‌جهتِ میزبان می‌ماند، پس جای ‎--lead/--trail‎ و
   آیکون جابه‌جا نمی‌شود. جهتِ جعبه را MB.holdDir از Ctrl+Shift نگه می‌دارد. */
.mb-input--bidi  { unicode-bidi: plaintext; }
/* عددِ بی‌فلش: پیکان‌های مرورگر در ورودیِ مقدار فقط اشتباهِ کلیک می‌سازند. */
.mb-input--nospin { appearance: textfield; -moz-appearance: textfield; font-variant-numeric: tabular-nums; }
.mb-input--nospin::-webkit-outer-spin-button,
.mb-input--nospin::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* «مقادیرِ مختلف» — ویرایشِ گروهی: چند کالا انتخاب شده‌اند و این فیلد در آن‌ها
   یک مقدار نیست. حالت است نه لحن، پس ‎.is-mixed‎ (همان نامی که درختِ گروه‌بندی
   برای چک‌باکسِ نیمه‌پر دارد) و ‎MB.mixed(el, …)‎ می‌گذاردش و placeholder را
   «مقادیرِ مختلف (n)» می‌کند. ظاهر همان واژگانی است که سرگروهِ جدولِ انبار
   ‎(.pl-group-edit-btn.is-mixed)‎ از قبل ساخته بود و مالک پذیرفته بود: کادرِ
   خط‌چین + خط‌خطیِ مورب = «یک مقدار نیست»، بی‌آنکه جای متن را بگیرد.
   background-image، نه سرنامِ background — سلکت پیکانش را از همان لایه دارد و
   پایین‌تر هر دو لایه را با هم می‌گیرد. خطا (aria-invalid، ‎(۰،۳،۰)‎) همچنان برنده است. */
.mb-input.is-mixed, .mb-select.is-mixed, .mb-textarea.is-mixed {
  --mb-mixed-hatch: repeating-linear-gradient(135deg, color-mix(in srgb, var(--warn) 10%, transparent) 0 6px, transparent 6px 12px);
  border-style: dashed;
  border-color: color-mix(in srgb, var(--warn) 55%, var(--border));
  background-image: var(--mb-mixed-hatch);
  color: var(--warn-text);
}
.mb-input.is-mixed::placeholder, .mb-textarea.is-mixed::placeholder { color: var(--warn-text); }
.mb-input.is-mixed:hover, .mb-select.is-mixed:hover, .mb-textarea.is-mixed:hover { border-color: var(--warn); }
.mb-input.is-mixed:focus, .mb-select.is-mixed:focus, .mb-textarea.is-mixed:focus { border-color: var(--accent); }

/* «ارثی / خودی» — مقدارِ یک ردیف که یا از پیش‌فرضِ کلِ سند می‌آید یا روی همین
   ردیف دست خورده. حالت است نه لحن، پس ‎.is-inherited‎/‎.is-own‎. ظاهر همان است
   که کادرِ تخفیفِ ردیفِ فاکتور از ۱۴۰۵/۰۶/۲۴ داشت و مالک پذیرفته بود — تا
   ۱۴۰۵/۰۷/۱۹ که «افزایش قیمت فاکتور» هم همین را خواست و جای ماندنِ آن در CSSِ
   یک صفحه دیگر نبود:
     • ارثی → عددِ پیش‌فرض placeholder است (کادر واقعاً خالی است)، پررنگ و به
       رنگِ اکسنت: «تصمیمِ کلِ سند»
     • خودی → مقدارِ واقعی، رنگِ هشدار و کادرِ کمی هشداری: «این ردیف دست‌خورده»
   «۰» هم مقدارِ خودی است، پس نارنجی می‌شود و پیداست که عمدی است. */
.mb-input.is-inherited::placeholder { color: var(--accent-text); opacity: 1; font-weight: 700; }
.mb-input.is-own {
  color: var(--warn-text);
  font-weight: 700;
  border-color: color-mix(in srgb, var(--warn) 45%, var(--border));
}
.mb-select.is-mixed {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"), var(--mb-mixed-hatch);
  background-repeat: no-repeat, repeat;
  background-position: left var(--sp-3) center, 0 0;
  background-size: var(--icon-sm), auto;
}
[dir="ltr"] .mb-select.is-mixed { background-position: right var(--sp-3) center, 0 0; }

/* چک‌باکس — کیت اصلاً نداشت، فقط کلید داشت. همین یک کمبود ۴۰ اعلانِ دستی با
   پنج اندازه و شش رنگ ساخت. */
.mb-check {
  inline-size: var(--icon-sm); block-size: var(--icon-sm); margin: 0; flex: 0 0 auto;
  accent-color: var(--mb-tone); cursor: pointer;
}
.mb-check--lg { inline-size: var(--icon-md); block-size: var(--icon-md); }
.mb-check:disabled { cursor: not-allowed; opacity: .5; }
.mb-check-row { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--ctl-h-sm); cursor: pointer; }

/* ناحیهٔ رهاکردنِ فایل. */
.mb-drop {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: var(--sp-1-5); padding: var(--sp-4);
  border: 1px dashed var(--border-strong); border-radius: var(--r-lg);
  background: var(--surface-2); color: var(--text-2); font-size: var(--fs-sm);
  text-align: center; cursor: pointer;
}
.mb-drop > input[type="file"] { position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; }
.mb-drop:hover, .mb-drop[data-dragging] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-text); }

/* هدفِ رهاکردنِ فایل روی یک جزءِ دیگر — کاشیِ برند و چیپِ برند در /library (فقط تیمِ سازنده).
   صفحه فقط ویژگیِ ‎data-dragging‎ را می‌نشاند؛ ظاهرش همان زبانِ ‎.mb-drop[data-dragging]‎ است
   (کادر و زمینهٔ تأکید) به‌علاوهٔ یک خطِ‌چینِ بیرونی تا حتی روی کارتِ پُرتصویر هم دیده شود.
   بعد از ‎.mb-card--link:hover‎ و لحنِ چیپ آمده تا در برابرشان برنده باشد. */
.mb-card[data-dragging], .mb-chip[data-dragging] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-text);
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
}

/* ── قاب: آیکون، آواتار، لوگو، بندانگشتی — یک مرجع ────────────────────────── */

/* `.mb-frame` نامِ تازهٔ همان قاب است؛ `.mb-iconbox`/`.mb-avatar` الیاس می‌مانند
   تا ۳۰۰ جای موجود دست نخورَد. تفاوتشان فقط یک گزینه بود (گردی)، نه یک طرح. */
.mb-frame--round { border-radius: var(--r-pill); }
/* بریدن یا جاکردن: لوگوی برند نباید بریده شود، عکسِ محصول باید. */
.mb-frame:where(img), .mb-frame img, .mb-iconbox img, .mb-avatar img, .mb-avatar:where(img) { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
.mb-frame--contain:where(img), .mb-frame--contain img,
.mb-avatar--contain:where(img), .mb-avatar--contain img { object-fit: contain; }
.mb-frame--cutout { border: 3px solid var(--surface); box-shadow: var(--shadow); }
.mb-frame--sep { border: 2px solid var(--surface); }       /* پشتهٔ هم‌پوشان */
.mb-frame--float { box-shadow: var(--shadow); }
.mb-frame--dashed { background: none; border: 1px dashed var(--border-strong); color: var(--faint); }
.mb-frame--dashed[data-dragging] { border: 2px dashed var(--accent); background: var(--accent-soft); color: var(--accent-text); }
.mb-frame--empty { background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface-3) 100%); color: var(--faint); }
.mb-frame--fluid { inline-size: 100%; aspect-ratio: 1; block-size: auto; }
.mb-frame--fill { inline-size: 100%; block-size: 100%; border-radius: inherit; }
.mb-frame--stale { opacity: .5; filter: grayscale(.4); }
/* انتخاب‌شونده: حالت، حالت است — نه یک کلاسِ ظاهری. */
.mb-frame--selectable { cursor: pointer; border: 2px solid transparent; padding: 0; background: var(--surface); }
.mb-frame--selectable:is([aria-pressed="true"], [aria-selected="true"]) { border-color: var(--accent); }

/* ── انتظار: یک حلقه، چند حالت ────────────────────────────────────────────── */

/* ممیزی ۱۸ حلقه در ۱۵ فایل پیدا کرد، با قطرهای ۱۳/۱۴/۱۸/۲۲/۲۸/۳۰/۳۴/۳۶/۳۸ و
   دو سرعتِ ۰٫۷ و ۰٫۸ ثانیه — و هیچ‌کدام از این تفاوت‌ها تصمیم نبود. حالا یک
   حلقه با چهار پله، و پله‌ها از توکنِ کنترل می‌آیند نه از عددِ آزاد.
   حالت‌های واقعیِ انتظار سه‌تا بیشتر نیست و محورش «کجا» است:
     داخلِ کنترل → --xs   ·   داخلِ ناحیه → پیش‌فرض/--lg   ·   روی محتوا → --over
   و محورِ دوم «چقدر می‌دانیم»: نامعیّن → همین حلقه، معیّن → .mb-progress. */
.mb-wait {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-4); color: var(--muted); font-size: var(--fs-sm);
}
/* ستونی: متنِ چندخطی هم باید وسط بماند — ‎align-items‎ خطِ شکسته را
   وسط نمی‌کند، فقط خودِ جعبه را. */
.mb-wait--stack { flex-direction: column; text-align: center; }
.mb-wait--inline { display: inline-flex; padding: 0; vertical-align: -2px; }
/* روی محتوایی که هست و دارد تازه می‌شود — پرده می‌اندازد، جایش را نمی‌گیرد. */
.mb-wait--over {
  position: absolute; inset: 0; z-index: var(--mb-wait-z, 4);
  padding: 0; flex-direction: column; border-radius: inherit;
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  backdrop-filter: blur(1px); pointer-events: none;
}
.mb-wait--over-block { pointer-events: auto; }
.mb-wait__spin {
  flex: none;
  inline-size: var(--mb-wait-d, var(--ctl-h-sm)); block-size: var(--mb-wait-d, var(--ctl-h-sm));
  border: var(--mb-wait-w, 3px) solid color-mix(in srgb, var(--mb-tone) 22%, transparent);
  border-block-start-color: var(--mb-tone);
  border-radius: var(--r-pill);
  animation: mb-load-spin .8s linear infinite;
  will-change: transform;
}
/* پله فقط قطرِ حلقه را عوض می‌کند؛ پدینگ محورِ جداگانه‌ای است (--inline). */
.mb-wait--xs { --mb-wait-d: var(--icon-xs); --mb-wait-w: 2px; }
.mb-wait--sm { --mb-wait-d: var(--icon-lg); --mb-wait-w: 2.5px; padding: var(--sp-4) var(--sp-3); }
.mb-wait--lg { --mb-wait-d: var(--ctl-h-md); padding: var(--sp-16) var(--sp-5); font-size: var(--fs-md); }
/* روی سطحِ توپُرِ رنگی، حلقهٔ تأکیدی دیده نمی‌شود. */
.mb-wait--on-solid { --mb-tone: var(--on-accent); color: var(--on-accent); }
.mb-wait--on-dark { --mb-tone: var(--on-dark); color: var(--on-dark); }

/* ── شکلِ شبح (اسکلت) ─────────────────────────────────────────────────────
   از ui/loading.css آمد، بی‌تغییر و با همان ترتیبِ منبع. شبح یک پایه است:
   مستطیلی که درخشش می‌گیرد. تا وقتی در فایلِ دیگری بود، اطلس نمی‌توانست
   فرض کند هست — و همین بود که هر صفحه شبحِ خودش را می‌ساخت.
   ‎.mb-sk-wrap--inherit‎ عمداً آخرین قاعده می‌ماند: هم‌وزنِ ‎--<kind>‎ است. */
@keyframes mb-load-spin { to { transform: rotate(360deg); } }

/* ── اسکلتِ محتوا (MBLoading.skeleton) ────────────────────────────────────
 * شبحِ خودِ چیدمان، نه یک اسپینرِ بی‌شکل. دو قاعده‌ای که رعایتشان مهم است:
 *
 * ۱) اندازه‌ها باید به محتوای واقعی نزدیک باشند، وگرنه لحظهٔ جایگزینی یک پرشِ
 *    بزرگ می‌شود و همان چیزی که می‌خواستیم جلویش را بگیریم اتفاق می‌افتد.
 * ۲) عرضِ خط‌ها عمداً یکسان نیست (در JS با i % n ساخته می‌شود): ستونِ کاملاً
 *    تراز، مصنوعی و «در حالِ بارگذاری‌نبودن» به نظر می‌رسد.
 *
 * جهتِ درخشش با logical properties نوشته شده تا در RTL از راست بیاید.
 */
.mb-sk {
  position: relative;
  overflow: hidden;
  background: var(--border-light);
  border-radius: var(--r-sm);
}

.mb-sk::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--surface) 72%, transparent), transparent);
  animation: mb-sk-shimmer 1.25s ease-in-out infinite;
}

[dir="rtl"] .mb-sk::after, body[dir="rtl"] .mb-sk::after { animation-name: mb-sk-shimmer-rtl; }

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

@keyframes mb-sk-shimmer-rtl { 0% { transform: translateX(100%); } 100% { transform: translateX(-100%); } }

/* کاربری که «حرکتِ کمتر» را در سیستم‌عاملش خواسته، شبحِ ثابت می‌بیند — نه
   اینکه لودینگ را از دست بدهد. */
@media (prefers-reduced-motion: reduce) {
  .mb-sk::after { animation: none; opacity: .5; }
}

.mb-sk-line { height: 12px; }

.mb-sk-line--sm { height: 9px; }

.mb-sk-pill { display: inline-block; width: 54px; height: 18px; border-radius: var(--r-pill); }

.mb-sk-avatar { flex: none; width: 36px; height: 36px; border-radius: var(--r-pill); }

.mb-sk-input { height: 34px; border-radius: var(--r-md); }

.mb-sk-wrap { display: block; }

/* cards — شبکهٔ کارتِ محصول. auto-fill تا با هر عرضی همان تعدادی ستون بدهد
   که شبکهٔ واقعی می‌دهد. */
.mb-sk-wrap--cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(168px, 100%), 1fr));
  gap: 14px;
}

.mb-sk-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 10px;
}

/* ارتفاعِ عکس از همان متغیرِ کارتِ واقعی می‌آید (--card-image-height در
   library.css) تا لحظهٔ جایگزینی، ارتفاع نپرد. جایی که آن متغیر نیست،
   نسبتِ ۱:۱ پس‌افتِ معقولی است. */
.mb-sk-card__img {
  width: 100%; border-radius: var(--r-md); margin-block-end: 10px;
  height: var(--card-image-height, 150px);
}

.mb-sk-card__body { display: flex; flex-direction: column; gap: 7px; }

.mb-sk-card__pills { display: flex; gap: var(--sp-1-5); margin-block-start: 3px; }

/* rows — ردیف‌های جدول */
.mb-sk-wrap--rows { display: flex; flex-direction: column; gap: 1px; }

.mb-sk-row {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 13px var(--sp-3);
  border-block-end: 1px solid var(--border-light);
}

/* list — فهرستِ آیتم‌دار */
.mb-sk-wrap--list { display: flex; flex-direction: column; gap: var(--sp-0-5); }

.mb-sk-list-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px var(--sp-3);
  border-block-end: 1px solid var(--border-light);
}

.mb-sk-list-item__lines { display: flex; flex-direction: column; gap: 7px; flex: 1; }

/* text / form / tiles */
.mb-sk-wrap--text { display: flex; flex-direction: column; gap: 10px; padding: var(--sp-1) 0; }

.mb-sk-wrap--form { display: flex; flex-direction: column; gap: 14px; }

.mb-sk-field { display: flex; flex-direction: column; gap: 7px; }

.mb-sk-wrap--tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
  gap: var(--sp-3);
}

.mb-sk-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ── قابِ گوشی ──────────────────────────────────────────────────────────────
   این بلوک روی ۵۶۰ بود — یک مرزِ سومِ اختراعی که در هیچ فایلِ دیگری نیست.
   کارش «چیدمانِ گوشی» است (کارت‌ها باریک‌تر، ستون‌های اضافیِ ردیف حذف)، و
   مرزِ چیدمانِ گوشی در این پروژه ۶۴۰ است. بینِ ۵۶۰ و ۶۴۰ شبح حالا هم دقیقاً
   همان تعدادی ستون می‌دهد که شبکهٔ واقعی می‌دهد — که اصلاً هدفِ اسکلت است. */
@media (max-width: 640px) {
  .mb-sk-wrap--cards { grid-template-columns: repeat(auto-fill, minmax(min(132px, 100%), 1fr)); gap: 10px; }
  /* ردیفِ جدول روی موبایل جا ندارد چهار ستون نشان دهد؛ دو ستونِ اول کافی است
     تا حس «جدولی در راه است» منتقل شود. */
  .mb-sk-row > :nth-child(n + 3) { display: none; }
  .mb-sk-row { gap: var(--sp-3); }
}

/* ناحیه‌ای که خودش grid/flex است، چیدمانش را خودش دارد: ظرفِ شبح باید کنار
   برود تا بچه‌هایش مستقیم در همان چیدمان بنشینند. بدونِ این، کلِ شبح یک خانهٔ
   آن grid می‌شود و در یک ستون جمع می‌شود — یعنی جای چیزی را نشان می‌دهد که
   آنجا ظاهر نخواهد شد.
   عمداً آخرِ فایل: هم‌وزنِ .mb-sk-wrap--<kind> است، پس فقط ترتیبِ نوشتن
   تعیین می‌کند کدام برنده شود. */
.mb-sk-wrap--inherit { display: contents; }

/* ── آیتمِ یک مجموعهٔ هم‌سطح ───────────────────────────────────────────────
 *
 * سه جا در این کیت «یک آیتم در یک ردیف/فهرست از هم‌ترازها» ساخته می‌شد و هر
 * سه از نو نوشته شده بودند: دکمهٔ سگمنت، آیتمِ منو، و گامِ ویزارد. از ۱۷
 * اعلانِ هرکدام، ۱۳تا یکی بود — و هر سه ارتفاعِ ۲۸ داشتند، به سه شکلِ
 * مختلفِ نوشتن: calc(--ctl-h-md - 8) و --ctl-h-sm و --ctl-h-sm. آن اختلاف
 * تصمیم نبود، تصادفِ سه نویسنده در سه روز بود.
 *
 * پس تعریف یکی شد و نام‌ها سه‌تا ماندند (هیچ مارک‌آپی عوض نشد). آنچه پایین
 * می‌ماند فقط چهار تفاوتِ *واقعی* است: شکلِ گوشه، پدینگِ افقی، اندازهٔ قلم،
 * و رنگِ استراحت.
 *
 * ظرف‌ها عمداً یکی نشدند و نباید بشوند: سگمنت یک ریلِ بسته است (کادر +
 * زمینه)، منو یک سطحِ شناور (سایه + لایه + اسکرول)، و ردیفِ گام هیچ سطحی
 * ندارد. کارشان هم فرق دارد: سگمنت یکی از چندتا را *انتخاب* می‌کند و همان
 * لحظه چیزی عوض می‌شود؛ منو یک *کنش* را اجرا می‌کند و بسته می‌شود (و
 * معمولاً هیچ آیتمی «روشن» نیست)؛ گام *می‌گوید کجای یک دنباله‌ای* و حالتِ
 * سومی دارد که آن دو ندارند: گامِ گذشته.
 */
/* زبانه (‎.mb-tabs__tab‎) چهارمینِ همین خانواده است: یکی از چند هم‌تراز، که
   تفاوت‌هایش (خطِ زیرین به‌جای سطح، پدینگِ پهن‌تر) در molecules می‌نشیند. */
.mb-item, .mb-seg__btn, .mb-menu__item, .mb-step, .mb-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--ctl-h-sm);
  padding-block: var(--sp-1);
  padding-inline: var(--sp-2);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-2);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
/* محورهای همین آیتم — همان واژگانِ همیشگی، نه اختراعِ تازه. */
.mb-item--block { display: flex; inline-size: 100%; text-align: start; }
.mb-item--center { justify-content: center; }
.mb-item--lg { font-size: var(--fs-md); }
.mb-item--wide { padding-inline: var(--sp-3); }

/* ══ kit/molecules.css ══════════════════════════════════════════════════════
 * ترکیب‌ها — از پایه‌ها ساخته می‌شوند. حق ندارند ظاهرِ پایه‌ای را که داخلشان است دوباره اعلام کنند؛ فقط جای‌گذاری.
 *
 * تکه‌ای از کیت. سرور هر پنج طبقه را به همین ترتیب به‌هم می‌چسباند و روی
 * /primitives.css سرو می‌کند، پس ترتیبِ طبقه‌ها همان ترتیبِ آبشار است:
 * base → atoms → molecules → blocks → tail.  (tools/kit-css.js)
 */

/* ── ۴) فیلد ────────────────────────────────────────────────────────────────
   برچسب بالای کنترل، راهنما و خطا زیرش. ورودی/سلکت/تکست‌اریا هم‌قد با دکمه
   (--ctl-h-md) تا در یک نوارِ ابزار ۰ پیکسل اختلافِ ارتفاع داشته باشند. */
.mb-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-inline-size: 0;
}

.mb-field__label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-2);
  line-height: 1.5;
}

.mb-field__label[data-required]::after { content: " *"; color: var(--danger-text); }

/* نامِ دوم (انگلیسی) — داخلِ برچسب، درست پس از نامِ فارسی (۱۴۰۵/۰۷/۱۳، فیلترهای کاتالوگ):
   «رنگ Color». ریز و کم‌رنگ تا نامِ فارسی اصل بماند؛ جزیرهٔ ltr تا «IP rating (IP)»
   پرانتزش را جابه‌جا نگیرد. کنارِ نامِ فارسی می‌نشیند، نه لبهٔ دیگرِ خط — آن‌جا جای
   کنشِ ‎.mb-field__head‎ است و نامِ انگلیسیِ دور از برچسب مالِ دکمه خوانده می‌شد. */
.mb-field__label:has(> .mb-field__sub) { display: flex; align-items: baseline; gap: var(--sp-2); min-inline-size: 0; }

.mb-field__sub {
  flex: 0 1 auto;
  min-inline-size: 0;
  direction: ltr;
  unicode-bidi: isolate;
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* سرِ فیلد: برچسب + یک کنشِ کوچک در همان خط (ویرایشِ تنظیمات، …). دکمهٔ آیکونِ ریز
   (‎--ctl-h-sm‎) از خطِ برچسب بلندتر است؛ حاشیهٔ منفی قدِ خط را نگه می‌دارد تا کنترلِ
   این فیلد با فیلدهای بی‌کنش هم‌تراز بماند. کنش با موس فقط روی فیلدِ خودش پیدا می‌شود
   (ستونی از ده چرخ‌دندهٔ همیشه‌پیدا شلوغ است)؛ با صفحه‌کلید، با منوی باز، و روی صفحهٔ
   لمسی همیشه. */
.mb-field__head { display: flex; align-items: center; gap: var(--sp-1); min-inline-size: 0; }

.mb-field__head > .mb-field__label { flex: 1 1 auto; min-inline-size: 0; }

.mb-field__head > .mb-btn--icon {
  flex: none;
  margin-block: calc((var(--fs-sm) * 1.5 - var(--btn-h)) / 2);
}

@media (hover: hover) {
  .mb-field:not(:hover):not(:focus-within) > .mb-field__head > .mb-btn--icon:not([aria-expanded="true"]) { opacity: 0; }
}

.mb-field__hint  { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }

.mb-field__error { font-size: var(--fs-xs); color: var(--danger-text); line-height: 1.5; }

/* برچسب *کنارِ* کنترل، بی‌قاب و بی‌عنوان — آینهٔ ‎.mb-group--stack‎.
   ‎.mb-field‎ فقط ستونی است و تنها چیدمانِ ردیفیِ کیت داخلِ ‎.mb-group__body‎
   زندگی می‌کند، یعنی باید کنترل را در یک جعبهٔ تنظیماتِ عنوان‌دار بپیچی و دو
   پهنای ثابت را بپذیری. نوارِ ابزار، نوارِ انتخاب و ته‌جدول نه جعبه دارند نه
   عنوان — برای همین نُه صفحه ‎flex + gap + نوشکنِ برچسب‎ را دست‌ساز نوشتند.
   اینجا هیچ پهنای ثابتی نیست؛ همین فرقش با ‎--bare‎ است. */
.mb-field--inline {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.mb-field--inline > .mb-field__label { flex: 0 0 auto; white-space: nowrap; }

.mb-field--inline > :is(.mb-input, .mb-select, .mb-textarea, .mb-seg, .mb-switch) {
  flex: 1 1 auto; inline-size: auto; min-inline-size: 0;
}

/* راهنما و خطا فرزندِ مستقیمِ همین فیلد‌اند، پس در حالتِ ردیفی بی این خط
   می‌شدند عضوِ سومِ همان ردیف و کنترل را له می‌کردند. ردیفی‌بودن چیدمانِ
   «برچسب↔کنترل» است، نه دستورِ «همه‌چیز در یک خط»: پیام سطرِ خودش را
   می‌گیرد (‎flex-wrap‎ بالا فقط برای همین است؛ با دو عضو هیچ‌وقت نمی‌شکند). */
.mb-field--inline > :is(.mb-field__hint, .mb-field__error) { flex: 1 0 100%; }

/* «مقادیرِ مختلف» در سطحِ فیلد — برای کنترلی که placeholder ندارد (کلید، چک‌باکس،
   سگمنتِ غیرِ سه‌حالته). نشانِ کوچکی کنارِ برچسب، با همان واژگانِ ‎.is-mixed‎ِ
   ورودی (خط‌چین + خط‌خطیِ مورب). ‎MB.mixed(fieldEl, {count, values})‎ خودش
   می‌سازدش و ‎.is-mixed‎ را روی فیلد می‌گذارد؛ مارک‌آپِ دستی هم همین است:
     <label class="mb-field__label">رنگ <span class="mb-field__mixed">مقادیرِ مختلف (۳)</span></label> */
.mb-field__mixed {
  display: inline-block;
  margin-inline-start: var(--sp-1-5);
  padding-inline: var(--sp-1-5);
  border: 1px dashed color-mix(in srgb, var(--warn) 55%, var(--border));
  border-radius: var(--r-sm);
  background-image: repeating-linear-gradient(135deg, color-mix(in srgb, var(--warn) 10%, transparent) 0 6px, transparent 6px 12px);
  color: var(--warn-text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  vertical-align: baseline;
}

/* ── ۴-ب) گروهِ تنظیمات ─────────────────────────────────────────────────────
   «یک کادر با یک سرِ کوچک و چند ردیفِ برچسب↔کنترل» — پنلِ تنظیمات، فیلترِ
   کنارِ جدول، تنظیم‌های سندِ فاکتور، پروفایل، ستون‌ها. تا امروز هر صفحه خودش
   می‌ساختش و هر بار یک چیز از قلم می‌افتاد؛ چیزی که از همه بیشتر از قلم
   می‌افتاد این بود:

     برچسب *بالای* کنترل + عرضِ کنترل از محتوایش = هیچ دو کنترلی هم‌لبه نیست.

   این جزء دو محورِ عمودی تضمین می‌کند — لبهٔ برچسب‌ها و لبهٔ کنترل‌ها — و هر
   ردیفی که داخلش بیفتد خودبه‌خود روی همان دو خط می‌نشیند. دو محور «تنظیم»اند،
   نه عددِ ثابت، و روی همان ظرف عوض می‌شوند:

     <section class="mb-group" style="--mb-group-label: 9rem; --mb-group-ctl: 14rem">
       <h3 class="mb-group__title">تخفیف و مالیات</h3>
       <div class="mb-group__body">
         <div class="mb-field"><label class="mb-field__label">…</label><input class="mb-input"></div>
         …
       </div>
       <p class="mb-group__note">یک خط توضیح، اگر لازم بود.</p>
     </section>

   ردیف همان `.mb-field`ِ خودِ کیت است — جزءِ تازه‌ای ساخته نشد، فقط *چیده* شد.
   زیرِ ۶۴۰ خودش ستونی می‌شود (پایینِ همین فایل)، چون دو محور در ۳۲۶ پیکسل
   بدونِ شکستنِ کفِ لمسی جا نمی‌شود. */
.mb-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  min-inline-size: 0;
}

.mb-group[hidden] { display: none; }

.mb-group__title {
  margin: 0;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--muted);
  line-height: 1.6;
}

.mb-group__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-inline-size: 0;
}

.mb-group__body .mb-field {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-3);
}

.mb-group__body .mb-field__label {
  flex: 0 0 var(--mb-group-label, 7rem);
  min-inline-size: 0;
  line-height: 1.35;
}

/* یک پهنا برای هر کنترلِ گروه — همین است که ستونِ دومِ عمودی را می‌سازد. */
.mb-group__body .mb-field > .mb-input,
.mb-group__body .mb-field > .mb-select,
.mb-group__body .mb-field > .mb-textarea,
.mb-group__body .mb-field > .mb-seg,
.mb-group__body .mb-field > .mb-bar,
.mb-group__body .mb-field > .mb-switch {
  flex: 0 1 var(--mb-group-ctl, 11.5rem);
  inline-size: var(--mb-group-ctl, 11.5rem);
  min-inline-size: 0;
}

/* دکمه‌های سگمنت ریل را نصف‌نصف پر می‌کنند؛ وگرنه ریلِ هم‌عرض با دکمه‌های
   چسبیده به یک لبه، باز هم ناهم‌تراز دیده می‌شود. */
.mb-group__body .mb-seg__btn { flex: 1 1 0; min-inline-size: 0; padding-inline: var(--sp-2); }

/* دو کنترل در یک ردیف (مثلاً جهت + گام): نوار همان پهنای مشترک را دارد و
   بچه‌هایش داخلش تقسیم می‌شوند. */
.mb-group__body .mb-bar > .mb-seg { flex: 0 0 auto; inline-size: auto; }

.mb-group__body .mb-bar > .mb-input { flex: 1 1 0; inline-size: 0; }

.mb-group__note {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.6;
}

.mb-group__note:empty { display: none; }

/* بی‌کادر: وقتی خودِ صفحه از قبل قاب دارد و کادرِ دوم یعنی جعبه‌در‌جعبه. */
/* ‎--bare‎ نامِ هم‌واژه با بقیهٔ کیت است («بی‌قاب»)؛ ‎--flat‎ نام‌مستعارِ همیشگی —
   در کارت ‎--flat‎ یعنی «بی‌سایه» و این دو نباید با هم اشتباه شوند. */
.mb-group--flat, .mb-group--bare { border-color: transparent; background: transparent; padding: 0; }

/* برچسب بالای کنترل — همان حالتی که زیرِ ۶۴۰ خودکار می‌شود، ولی به‌خواست. */
.mb-group--stack .mb-field { flex-direction: column; align-items: stretch; gap: var(--sp-1); }

.mb-group--stack .mb-field__label { flex: 0 0 auto; }

.mb-group--stack .mb-field > .mb-input,
.mb-group--stack .mb-field > .mb-select,
.mb-group--stack .mb-field > .mb-textarea,
.mb-group--stack .mb-field > .mb-seg,
.mb-group--stack .mb-field > .mb-bar,
.mb-group--stack .mb-field > .mb-switch { flex: 0 0 auto; inline-size: 100%; }

/* ── ۴-ب) ستون‌های فیلدِ هم‌تراز ──────────────────────────────────────────────
   چند .mb-field کنارِ هم که *سه ردیفِ مشترک* دارند: برچسب / کنترل / محتوا.
   هر ردیف ارتفاعِ بلندترین ستونش را می‌گیرد، پس برچسب‌ها یک خط، کنترل‌ها یک
   خط، و جعبه‌های محتوا هم‌قد می‌شوند — مهم نیست متنِ هر ستون چند خط باشد.

   از «تنظیماتِ فوترِ فاکتور» آمد. اندازه‌گیری پیش از این: لبهٔ پایینِ سه جعبه
   ۶۹۶ / ۶۷۵ / ۷۱۶ بود (کارتِ متن ۷۶، حالتِ خالی ۵۵، QR ۸۸)، و ردیفِ کنترل فقط
   *تصادفاً* هم‌تراز بود چون راهنمای ستونِ سوم دو خط می‌شد و دو خط دقیقاً ۳۶
   پیکسل است. با subgrid ترازی عمدی است، نه اتفاقی.

     <div class="mb-fields" style="--mb-fields-cols: 1fr 1fr 12rem">
       <div class="mb-field">
         <label class="mb-field__label">…</label>
         <div class="mb-bar">…</div>          ← ردیفِ کنترل
         <div>…</div>                          ← ردیفِ محتوا، تمام‌قد
       </div>
       …
     </div>

   ستونی که ردیفِ کنترل ندارد (فقط راهنما دارد) هم جا می‌افتد: راهنما وسطِ
   عمودیِ همان ردیف می‌نشیند. */
.mb-fields {
  display: grid;
  grid-template-columns: var(--mb-fields-cols, repeat(auto-fit, minmax(14rem, 1fr)));
  grid-template-rows: auto auto 1fr;
  column-gap: var(--sp-4);
  /* فاصلهٔ *میانِ* فیلدها وقتی زیرِ هم می‌افتند؛ داخلِ هر فیلد subgrid
     فاصلهٔ خودش را دارد و این عدد به آن نمی‌رسد. */
  row-gap: var(--sp-4);
  min-inline-size: 0;
}

.mb-fields > .mb-field {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  row-gap: var(--sp-1);
}

/* ردیفِ سوم تمامِ ارتفاعِ ردیف را پر می‌کند، و هر جعبه‌ای که درونش است هم. */
.mb-fields > .mb-field > :nth-child(3) { display: grid; min-block-size: 0; }

.mb-fields > .mb-field > :nth-child(3) > :is(.mb-card, .mb-empty) { block-size: 100%; margin: 0; }

.mb-fields > .mb-field > .mb-field__hint { align-self: center; }

@media (max-width: 640px) {
  .mb-fields { grid-template-columns: minmax(0, 1fr); }
}

/* ── ۵) کنترلِ سگمنتی ───────────────────────────────────────────────────────
   چند گزینهٔ هم‌ارز (مثلاً رنگی/فنی/خطی). دکمه‌ها هم‌قد با کنترل‌های دیگر؛
   گزینهٔ فعال با پس‌زمینه + متنِ تیره گفته می‌شود، نه فقط رنگ.

   یک اندازه، عمداً. تا امروز یک وریانتِ `--sm` هم بود که هیچ صفحه‌ای صدایش
   نمی‌زد و در اطلس فقط یک نمونهٔ دومِ تقریباً هم‌شکل می‌ساخت؛ حذف شد و هر
   ارجاعش به همین پایه برگشت. ظرف ارتفاعِ ثابت ندارد — با دکمه‌هایش بالا
   می‌آید — تا کفِ لمسیِ ≤۱۰۲۴ از ظرف بیرون نزند. */
/* ۱۴۰۵/۰۷/۰۷ (طرحِ مالک): ریلِ خاکستریِ بی‌کادر — گزینهٔ روشن سطحِ سفیدِ رویش است.
   قد همان ۳۶ ماند: ۲۸ + ۲×۴ (قبلاً ۲۸ + ۲×۳ + ۲×۱ کادر). */
.mb-seg {
  display: inline-flex;
  align-items: stretch;
  padding: var(--sp-1);
  gap: 2px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--border);
}

/* پایه‌اش «آیتمِ مجموعه» است (ui/kit/atoms.css)؛ اینجا فقط تفاوت‌های خودش:
   وسط‌چین، پدینگِ پهن‌تر چون داخلِ یک ریلِ بسته می‌نشیند، و گردیِ یک پله
   پایین‌تر از ریل (r-sm در r-md) تا دو گوشه تو در تو نیفتند.
   (‎calc(--ctl-h-md - 8)‎ی قدیمی دقیقاً ۲۸ بود، یعنی همان ‎--ctl-h-sm‎ پایه —
   یک عدد، دو جورِ نوشتن.) */
.mb-seg__btn {
  /* پدینگِ عمودیِ پیش‌فرضِ خودِ <button>؛ چون ارتفاع را min-height تعیین
     می‌کند این عدد دیده نمی‌شود، ولی صریح نوشته می‌شود تا اندازه‌گیریِ قبل/بعد
     صفر بماند و کسی بعداً فکر نکند عوض شده. */
  padding-block: 1px;
  justify-content: center;
  gap: var(--sp-1-5);
  padding-inline: var(--ctl-px-sm);
  border-radius: var(--r-sm);
}

/* --fill: سگمنت تمام‌عرضِ ظرفش؛ دکمه‌ها با فلکس پهن می‌شوند، پس پدینگِ افقی فقط کفِ آن‌هاست
   (پنج دکمهٔ XS…XL در ستونِ باریکِ کتابخانه با پدینگِ پایه جا نمی‌شدند). */
.mb-seg--fill { display: flex; width: 100%; }

.mb-seg--fill > .mb-seg__btn { flex: 1 1 auto; padding-inline: var(--sp-2); }

.mb-seg__btn:hover { color: var(--text); }

.mb-seg__btn:disabled, .mb-seg__btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

.mb-seg__btn:disabled:hover, .mb-seg__btn[aria-disabled="true"]:hover { color: var(--text-2); }

/* سگمنتِ فقط‌خواندنی: گزینهٔ انتخاب‌شده همچنان خوانا می‌ماند — «چه چیزی
   انتخاب شده» همان اطلاعی است که کاربرِ بی‌اجازه باید ببیند. سه نامِ حالت
   (کلاس/aria) همه‌جا با هم‌اند؛ وزن (۰,۳,۰) از قاعدهٔ غیرفعال (۰,۲,۰) می‌بَرد. */
.mb-seg__btn:is(.is-on, [aria-pressed="true"], [aria-selected="true"]):is(:disabled, [aria-disabled="true"]) { opacity: 1; }

/* همان انتخاب‌شدهٔ توندارِ غیرفعال، زیرِ اشاره‌گر: بدونِ این، (۰,۳,۰)ِ
   ‎:disabled:hover‎ (سطر بالا) مرکبِ لحن را به خاکستری می‌بَرد — لحنِ سگمنتِ
   توندار (--ok/--warn/…) باید زیرِ هاور هم بماند، چون کاربر همچنان باید
   ببیند کدام گزینه انتخاب است. گزینشگرِ [class*="mb-seg__btn--"] همان‌طورِ
   سطرِ زیر فقط توندارها را می‌گیرد؛ سگمنتِ خنثی رنگش عمداً هم‌رنگِ غیرفعال است. */
.mb-seg__btn[class*="mb-seg__btn--"]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]):is(:disabled, [aria-disabled="true"]):hover { color: var(--on-accent); }

.mb-seg__btn.is-on, .mb-seg__btn[aria-pressed="true"], .mb-seg__btn[aria-selected="true"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  font-weight: var(--fw-semibold);
}

/* لحن (بعد از قاعدهٔ .is-on — هم‌وزن‌اند و ترتیب تصمیم می‌گیرد): وقتی خودِ گزینه معنا دارد (اولویت، وضعیتِ بررسی). فقط حالتِ فعال
   رنگ می‌گیرد؛ گزینه‌های خاموش همان خاکستریِ سگمنت‌اند. زمینه نسخهٔ
   `-text`ِ رنگ است نه خودِ رنگ‌مایه: سفید روی `--ok` فقط ۲٫۳:۱ می‌داد
   (اندازه‌گیریِ چک‌لیست)، روی `--ok-text` ۵٫۰:۱ — و در تمِ تیره جفت وارونه
   می‌شود و باز رد می‌کند. */
/* :is() وزنِ بزرگ‌ترین آرگومان را می‌گیرد — هر سه (۰,۱,۰)‌اند، پس وزنِ این
   قاعده‌ها همان (۰,۲,۰)ِ ‎.mb-seg__btn--ok.is-on‎ قدیم ماند. */
.mb-seg__btn--accent:is(.is-on, [aria-pressed="true"], [aria-selected="true"]) { background: var(--accent);      color: var(--on-accent); }

.mb-seg__btn--ok:is(.is-on, [aria-pressed="true"], [aria-selected="true"])     { background: var(--ok-text);     color: var(--on-accent); }

.mb-seg__btn--warn:is(.is-on, [aria-pressed="true"], [aria-selected="true"])   { background: var(--warn-text);   color: var(--on-accent); }

.mb-seg__btn--danger:is(.is-on, [aria-pressed="true"], [aria-selected="true"]) { background: var(--danger-text); color: var(--on-accent); }

.mb-seg__btn--info:is(.is-on, [aria-pressed="true"], [aria-selected="true"])   { background: var(--info-text);   color: var(--on-accent); }

.mb-seg__btn--muted:is(.is-on, [aria-pressed="true"], [aria-selected="true"])  { background: var(--muted);       color: var(--on-accent); }

/* چیزی که داخلِ گزینهٔ رنگی است (نقطهٔ اولویت) رنگِ مرکب را می‌گیرد. */
.mb-seg__btn[class*="mb-seg__btn--"]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]) .mb-dot { --mb-dot-c: currentColor; }

/* ── ۵-الف) سگمنتِ سه‌حالته (ویرایشِ گروهی) ─────────────────────────────────
   «بدون تغییر / بله / خیر». خانهٔ «بدون تغییر» همان خانه‌ای است که ‎value=""‎
   دارد (ترتیب آزاد است) و روشن‌بودنش «انتخاب» نیست، «دست‌نزدن» است — پس سطح و
   سایه نمی‌گیرد، فقط قابِ خط‌چین. لحنِ بله/خیر همان ‎--ok/--danger‎ِ همیشگیِ
   خانه‌هاست، نه قاعدهٔ تازه. خواندن و نشاندن: ‎MB.tri(seg)‎ ← null/true/false.
   ‎.is-mixed‎ روی ریل = کالاهای انتخاب‌شده در این ویژگی یکسان نیستند؛ همان
   خط‌خطیِ ‎.mb-input.is-mixed‎ روی خانهٔ «بدون تغییر» می‌نشیند.
   ‎:not(:focus-visible)‎ عمداً: این قاعده ‎(۰،۵،۰)‎ است و بی آن حلقهٔ فوکوسِ
   بندِ ۷ (outline) را می‌خورد. */
.mb-seg--tri > .mb-seg__btn[value=""]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]) {
  background: transparent;
  color: var(--text-2);
  box-shadow: none;
}

.mb-seg--tri > .mb-seg__btn[value=""]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]):not(:focus-visible) {
  outline: 1px dashed var(--border-strong);
  outline-offset: -1px;
}

.mb-seg--tri.is-mixed > .mb-seg__btn[value=""]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]) {
  background-image: repeating-linear-gradient(135deg, color-mix(in srgb, var(--warn) 10%, transparent) 0 6px, transparent 6px 12px);
  color: var(--warn-text);
}

.mb-seg--tri.is-mixed > .mb-seg__btn[value=""]:is(.is-on, [aria-pressed="true"], [aria-selected="true"]):not(:focus-visible) {
  outline-color: color-mix(in srgb, var(--warn) 55%, var(--border));
}

/* ── ۵-ب) زبانه ─────────────────────────────────────────────────────────────
   فرقش با سگمنت: سگمنت *مقداری* را انتخاب می‌کند و همان‌جا چیزی عوض می‌شود؛
   زبانه *بخشی از صفحه* را نشان می‌دهد و بقیه را پنهان می‌کند. پس ریلِ بسته
   ندارد — یک خطِ زیرین که زبانهٔ فعال رویش خطِ تأکید می‌گیرد.
     <div class="mb-tabs" data-mb-tabs>
       <div class="mb-tabs__list" aria-label="…">
         <button type="button" class="mb-tabs__tab" data-tab="a">همه <span class="mb-chip mb-chip--count">۱۲</span></button> …
       </div>
       <div class="mb-tabs__panel" data-tab="a">…</div> …
     </div>
   نقش‌ها (tablist/tab/tabpanel)، aria-selected، ‎tabindex‎ِ گردان و کلیدهای
   پیکان (در راست‌به‌چپ، ← یعنی «بعدی») را ‎MB.tabs(host, {onChange})‎ می‌گذارد.
   جای شمارنده همان ‎.mb-chip--count‎ است (کیت از اول برای «روی تب» ساختش).
   جا نشد؟ می‌پیچد (flex-wrap)، هرگز از ظرف بیرون نمی‌زند و اسکرولِ افقی
   نمی‌سازد. */
.mb-tabs { display: flex; flex-direction: column; gap: var(--sp-3); min-inline-size: 0; }

.mb-tabs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--sp-1);
  min-inline-size: 0;
  border-block-end: 1px solid var(--border);
}

/* پایه‌اش «آیتمِ مجموعه» است (ui/kit/atoms.css)؛ تفاوت‌ها: هم‌قدِ کنترل‌ها،
   پدینگِ پهن‌تر، گوشهٔ پایینِ صاف (خطِ تأکید روی لبه می‌نشیند) و ‎-1px‎ پایین تا
   خطِ زبانه روی خطِ ریل بیفتد نه بالای آن. */
.mb-tabs__tab {
  box-sizing: border-box;
  min-height: var(--ctl-h-md);
  margin-block-end: -1px;
  padding-inline: var(--sp-3);
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

/* پس‌زمینه صریح و ‎(۰،۲،۰)‎: قاعدهٔ عنصریِ ‎button:hover‎ِ صفحه‌ها ‎(۰،۱،۱)‎ از
   ‎.mb-tabs__tab‎ می‌بَرد — همان تلهٔ پیکانِ کامبو. */
.mb-tabs__tab:hover { background: var(--surface-2); color: var(--text); }

.mb-tabs__tab:is([aria-selected="true"], .is-on) {
  color: var(--accent-text);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.mb-tabs__tab:is([aria-selected="true"], .is-on):hover { background: transparent; }

.mb-tabs__tab:is(:disabled, [aria-disabled="true"]) { opacity: .45; cursor: not-allowed; }

.mb-tabs__tab:is(:disabled, [aria-disabled="true"]):hover { background: transparent; color: var(--text-2); }

.mb-tabs__panel { min-inline-size: 0; }

.mb-tabs__panel:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

/* «کنتراستِ بالا»ی ویندوز سایه را دور می‌ریزد — خطِ تأکید باید کادرِ واقعی شود. */
@media (forced-colors: active) {
  .mb-tabs__tab:is([aria-selected="true"], .is-on) { border-block-end: 2px solid Highlight; }
}

/* ── ۶-ت) آمارک (عدد + برچسب) ────────────────────────────────────────────────
   «۳٬۹۲۸ محصول» در این مخزن بیست بار از نو ساخته شده بود — با نام‌های
   `.stat-kpi`، `.ch-kpi`، `.wh-kpi`، `.pm-kpi`، `.cl-stat`، `.cr-stat`، …
   شکلشان تقریباً یکی بود: کاشیِ سطح‌دار، عددِ درشتِ هم‌عرض، برچسبِ ریزِ خاکستری.

   دو چیدمان، هر دو واقعی بودند:
     • ستونی (پیش‌فرض) — عدد بالا، برچسب زیرش، وسط‌چین.
     • --inline با `__icon` — آیکون کنار، عدد و برچسب در یک ستونِ باریک.

   عدد همیشه `tabular-nums` است: بدونش ستونی از آمارک‌ها با هر به‌روزرسانی
   چند پیکسل می‌لرزد، چون عرضِ رقم‌ها فرق دارد. */
.mb-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-3);
}

.mb-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-0-5);
  padding: var(--sp-3) var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: center;
  min-inline-size: 0;
}

.mb-stat__value {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-black);
  line-height: 1.15;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.mb-stat__label {
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.4;
}

/* آیکون کنارِ عدد، نه بالایش: وقتی آمارک در یک ردیفِ باریک می‌نشیند، ستونی
   بودن ارتفاع را دو برابر می‌کند. */
.mb-stat--inline {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sp-3);
  text-align: start;
  padding: var(--sp-3);
}

.mb-stat--inline .mb-stat__body { display: flex; flex-direction: column; min-inline-size: 0; }

/* چیدمانِ سوم: یک‌خطی و *بی‌قاب* — «برچسب: عدد» کنارِ نمودار، در نوارِ ابزار،
   یا تهِ یک ردیفِ قاعده. سه کپیِ زنده همین را می‌خواستند و چون کیت فقط کاشی
   داشت، از صفر نوشتندش؛ --inline هم جوابشان نبود، آن هنوز کادر و پدینگ و
   سطح دارد. پیش از بلوکِ لحن آمده تا رنگِ لحن (۰,۲,۰ و هم‌وزن) برنده بماند. */
.mb-stat--line {
  flex-direction: row; align-items: baseline; justify-content: flex-start; gap: var(--sp-1-5);
  padding: 0; border: 0; background: none; text-align: start; font-size: var(--fs-xs);
}

.mb-stat--line .mb-stat__value { font-size: inherit; font-weight: var(--fw-bold); color: var(--text); }

.mb-stat--line .mb-stat__label { font-size: inherit; font-weight: var(--fw-medium); }

/* نردبانِ اندازه — همان پله‌ای که کارت دارد، برای آمارک: چهار کاشیِ خلاصهٔ
   بالای صفحه عددِ ۳۲ پیکسلی و پدینگِ ۱۶–۲۰ دارند و بی این پله، نشستنشان روی
   کیت یعنی ۱۲ پیکسل کوچک‌شدنِ عدد. */
.mb-stat--lg { padding: var(--sp-4) var(--sp-5); }

.mb-stat--lg .mb-stat__value { font-size: var(--fs-3xl); }

/* لحن: فقط عدد رنگ می‌گیرد، نه کلِ کاشی — وگرنه یک ردیفِ آمارک به یک چراغانی
   تبدیل می‌شود و هیچ‌کدام دیگر برجسته نیست. (۱۴۰۵/۰۶/۲۷ یک بار زمینهٔ کاشی
   اضافه شد تا دو پیچِ اطلس خروجیِ متفاوت بدهند؛ برگشت خورد چون آمارک‌های
   admin / payments / work-hours را بی‌صدا رنگی می‌کرد. فرقِ دو کلاس *جای*
   کلاس است، نه ظاهر — پایین را ببینید.) */
.mb-stat--ok .mb-stat__value { color: var(--ok-text); }

.mb-stat--warn .mb-stat__value { color: var(--warn-text); }

.mb-stat--danger .mb-stat__value { color: var(--danger-text); }

.mb-stat--info .mb-stat__value { color: var(--info-text); }

.mb-stat--accent .mb-stat__value { color: var(--accent-text); }

/* پلهٔ خنثیِ همین نردبان که نبود: «رد‌شده / بی‌اهمیت». دو گزارشِ متفاوت
   (سه‌بعدی و PDF) هر دو برای «رد‌شده» همین یک اعلان را جدا نوشته بودند. */
.mb-stat--muted .mb-stat__value { color: var(--muted); }

/* همان رنگ، ولی کلاس روی *خودِ عدد*: برای عددی که JS جدا بازنویسی‌اش می‌کند
   (اختلافِ نرخ، تغییرِ موجودی — currency-manager.js className عدد را عوض
   می‌کند). ظاهر با لحنِ کاشی یکی است؛ فقط جای کلاس فرق دارد. */
.mb-stat__value--ok     { color: var(--ok-text); }

.mb-stat__value--warn   { color: var(--warn-text); }

.mb-stat__value--danger { color: var(--danger-text); }

.mb-stat__value--info   { color: var(--info-text); }

.mb-stat__value--accent { color: var(--accent-text); }

.mb-stat__value--muted  { color: var(--muted); }

/* …و همان شش‌تا با وزنِ (۰,۲,۰)، چون ‎.mb-stat--line .mb-stat__value‎ بالاتر
   رنگِ ‎--text‎ را با وزنِ بالاتر می‌گذارد و تک‌کلاس‌های بالا را — بی‌توجه به
   ترتیب — خاموش می‌کرد. یعنی ادعای اطلس («دو کلاسِ لحن یک ظاهر دارند و فقط
   جایشان فرق دارد») در چیدمانِ یک‌خطی راست نبود؛ حالا هست. */
.mb-stat--line .mb-stat__value--ok     { color: var(--ok-text); }

.mb-stat--line .mb-stat__value--warn   { color: var(--warn-text); }

.mb-stat--line .mb-stat__value--danger { color: var(--danger-text); }

.mb-stat--line .mb-stat__value--info   { color: var(--info-text); }

.mb-stat--line .mb-stat__value--accent { color: var(--accent-text); }

.mb-stat--line .mb-stat__value--muted  { color: var(--muted); }

/* عددِ لاتین (مبلغِ ارز، کدِ ماشینی) جزیرهٔ LTR می‌شود، نه کلِ کاشی. */
.mb-stat__value--ltr { direction: ltr; unicode-bidi: isolate; }

/* ── ۶-ح) خطِ وضعیت ─────────────────────────────────────────────────────────
   «در حالِ ذخیره…» / «ذخیره شد» / «خطا». بیست‌وچهار کلاس به اسمِ `*-status`
   شمرده شده بود، ولی سه چیزِ متفاوت بودند و همین سه‌تا بودن، خودش یافته است:

   • قرصِ رنگی («پیش‌نویس»، «تأییدشده»، «در حالِ اجرا») — این چیپ است، نه جزءِ
     تازه. `.mb-chip--ok/--warn/--danger` همین حالا جایش است.
   • ستونِ جدول (`.prof-perm-status` فقط عرض و ترازِ یک `th` است) — اصلاً جزء
     نیست.
   • و این یکی: خطِ کوتاهِ بازخورد کنارِ یک فرم.

   یک چیز در این خانواده واقعاً *باگ* بود: از ۱۶ موردی که پیام را نشان
   می‌دادند، فقط ۵ تا `min-height` داشتند. یعنی در ۱۱ جای دیگر لحظه‌ای که
   «ذخیره شد» ظاهر می‌شود، همه‌چیزِ زیرش یک خط می‌پرد — درست همان لحظه‌ای که
   چشمِ کاربر آنجاست. پایهٔ کیت جا را از قبل می‌گیرد، پس پرش حذف می‌شود.

     <span class="mb-status mb-status--ok"><i class="mb-dot mb-dot--sm mb-dot--current"></i>ذخیره شد</span>
*/
.mb-status {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1-5);
  /* جا را از قبل می‌گیرد تا آمدنِ پیام چیدمان را نپراند. */
  min-block-size: 1.5em;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.5;
}

/* وقتی خطِ وضعیت زیرِ فرم خودش یک سطرِ کامل است، نه چیزی داخلِ یک ردیف. */
.mb-status--block { display: flex; }

/* پلهٔ درشت‌تر. نامِ درستش ‎--lg‎ است (md پیش‌فرض است و نوشته نمی‌شود)؛
   ‎--md‎ نام‌مستعارِ همیشگی، چون لحظه‌ها/خانهٔ شرکت/تنظیماتِ فاکتور صدایش می‌زنند. */
.mb-status--md, .mb-status--lg { font-size: var(--fs-sm); }

.mb-status--ok     { color: var(--ok-text); }

.mb-status--warn   { color: var(--warn-text); }

.mb-status--danger { color: var(--danger-text); }

.mb-status--info   { color: var(--info-text); }

.mb-status--accent { color: var(--accent-text); }

/* مرکبِ کامل: برچسبی که معنایش را نقطه‌اش می‌گوید (ستونِ «وضعیت»ِ جدول) — متن
   خنثی و پررنگ می‌ماند تا ده رنگ کنارِ هم فهرست را شلوغ نکنند (طرحِ مالک، ۱۴۰۵/۰۷/۰۷). */
.mb-status--ink    { color: var(--text); }

/* همان پیش‌فرض با نامِ صریح — انتخابگرِ لحن گزینهٔ «بی‌کلاس» نداشته باشد. */
.mb-status--muted  { color: var(--muted); }

/* «هنوز کاری نشده» — کم‌رنگ‌تر از خاموش، چون خبری نیست که خوانده شود. */
.mb-status--idle   { color: var(--faint); }

/* پیامِ گذرا: JS با `.is-on` نشانش می‌دهد. جا همیشه گرفته است، پس محوشدنش
   هم چیزی را جابه‌جا نمی‌کند. */
.mb-status--fade { opacity: 0; transition: opacity 0.2s ease; }

.mb-status--fade.is-on { opacity: 1; }

/* ‎display:block‎ صفتِ hiddenِ مرورگر را می‌بازد — بندِ ۶-ب را ببینید؛ نامِ این
   جزء هم در همان فهرستِ مرکزیِ ‎[hidden]‎ آمده است. */
/* ── ۶-د) منوی شناور ────────────────────────────────────────────────────────
   چهارده پیاده‌سازی در ۱۱ فایل، و همه یک قاب بودند: سطح + کادر + گردی + سایه
   + کف‌عرض + پدینگِ کم. دو تا از آن‌ها *همان کلاس* در دو فایل بودند
   (`.cg-context-menu` در connections-graph و hub با دو مقدارِ متفاوت،
   `.pm-brand-country-dropdown` در org-manager و product-management یکسان).

   z-index از نردبان می‌آید، نه از حدس: ۱۴ پیاده‌سازی هفت عددِ مختلف داشتند
   (۲۰ · ۸۰ · ۱۰۰ · ۲۰۰ · ۱۰۰۵۰ …) و همان است که ترتیبِ روی‌هم‌افتادن را
   تصادفی می‌کرد.

   جای‌گذاری با میزبان است: منو داخلِ یک ظرفِ `position: relative` می‌نشیند و
   `inset` را همان می‌دهد.
*/
/* فقط *ظاهر*: سطح، کادر، گردی، سایه. جای‌گذاری (position / inset / z-index /
   بیشینهٔ ارتفاع) عمداً اینجا نیست — هر منو جای خودش را دارد و آن تصمیمِ صفحه
   است، نه کیت. همین باعث می‌شود افزودنِ .mb-menu به منویی که از قبل هست هیچ
   چیزِ دیگری را جابه‌جا نکند. */
.mb-menu {
  padding: var(--sp-1);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  box-sizing: border-box;
}

/* برای منوی تازه: جای‌گذاریِ آماده، با لایه‌ای که از نردبان می‌آید نه از حدس. */
.mb-menu--float {
  position: absolute;
  z-index: var(--z-dropdown);
  min-inline-size: 200px;
  max-block-size: 320px;
  overflow: auto;
}

.mb-menu--fixed { position: fixed; }

/* منوی پهن (گزینه با توضیح یا میان‌بر) — هم‌واژه با ‎--wide‎ِ حباب و مودال.
   اطلس این کلاس را می‌ساخت و کیت تعریفش نکرده بود: کلیدی که کاری نمی‌کرد. */
.mb-menu--wide { min-inline-size: 280px; }

/* منوی جمع‌وجور — یک پله ریزتر، با آیکونِ هر گزینه (منوی «⋯» سرِ پنجره). طرحِ Claude Design
   (پروفایلِ محصول، ۱۴۰۵/۰۷/۱۴) آن را «کمبودِ کیت» علامت زد و با font-size inline کشیده بود. */
.mb-menu--compact .mb-menu__item { font-size: var(--fs-sm); gap: var(--sp-2); align-items: center; }

/* پایه‌اش «آیتمِ مجموعه» است؛ تفاوت‌های خودش: تمام‌عرضِ فهرست، متنِ پررنگ‌تر
   و یک پله درشت‌تر (آیتمِ منو خوانده می‌شود، نه اسکن)، و وزنِ عادی چون کنار
   هم ده‌تایشان می‌نشیند. */
.mb-menu__item {
  /* ارتفاعِ خط را خودِ مرورگر حساب کند: آیتمِ منو متنِ بلند دارد و 1.2 دو
     پیکسل از ارتفاعش می‌زد. */
  line-height: normal;
  display: flex;
  inline-size: 100%;
  border-radius: var(--r-md);
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  white-space: normal;
  text-align: start;          /* «شروع»، نه «چپ» */
  text-decoration: none;      /* گزینه می‌تواند پیوند باشد (‎<a class="mb-menu__item">‎) */
}

.mb-menu__item:hover { background: var(--surface-2); }

/* گزینهٔ «زیرِ کلید»: پیمایش با ↑/↓ در منوی کامبو همان شکلِ hover را دارد —
   فقط این‌بار صفحه‌کلید اشاره‌گر است، نه موش. */
.mb-menu__item.is-active { background: var(--surface-2); }

.mb-menu__item[aria-selected="true"], .mb-menu__item.is-on { background: var(--accent-soft); color: var(--accent-text); }

.mb-menu__item:disabled, .mb-menu__item[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.mb-menu__item--danger { color: var(--danger-text); }

.mb-menu__item--danger:hover { background: var(--danger-soft); }

.mb-menu__item svg { inline-size: var(--icon-sm); block-size: var(--icon-sm); flex: none; }

.mb-menu__sep { block-size: 1px; margin-block: var(--sp-1); background: var(--border); border: 0; }

.mb-menu__label {
  padding-block: var(--sp-1);
  padding-inline: var(--sp-2);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

/* ── ۶-د-۲) کامبو (سلکتِ جست‌وجوپذیر) ───────────────────────────────────────
   پیش‌فرض یک دراپ‌داون است؛ با تایپ، گزینه‌ها فیلتر می‌شوند و × جست‌وجو (و بعد
   انتخاب) را پاک می‌کند. ساخته از پایه‌ها: ورودی = ‎.mb-input.mb-input--trail‎
   (جای آیکونِ انتهایی را همان پایه کنار گذاشته)، منو = ‎.mb-menu‎، و وقتی گزینه‌ها
   ۲ یا ۳ تاست خودش ‎.mb-seg.mb-seg--fill‎ می‌شود. رفتار در ui-kit.js (MB.combo) —
   `<select data-mb-combo>` کافی است. سلکتِ اصلی پنهان می‌ماند و منبعِ حقیقت است. */
.mb-combo { position: relative; display: block; inline-size: 100%; min-inline-size: 0; }

.mb-combo__native { display: none; }

.mb-combo__box { position: relative; }

.mb-combo__input { text-overflow: ellipsis; cursor: pointer; }

.mb-combo__input:focus { cursor: text; }

/* آیکونِ انتهایی (پیکان یا ×) کلِ شکافی را می‌پوشاند که ‎--trail‎ کنار گذاشته،
   تمام‌قد — پس روی لمس هم هدفش ۴۴ پیکسل ارتفاع دارد. */
.mb-combo__btn {
  position: absolute;
  inset-block: 1px;
  inset-inline-end: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: calc(var(--sp-3) + var(--icon-sm) + var(--sp-2) - 2px);
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

/* پس‌زمینه صریح: قاعدهٔ عنصریِ ‎button:hover‎ِ صفحه‌ها (library.css: پس‌زمینهٔ accent)
   با ‎(0,1,1)‎ از ‎.mb-combo__btn‎ می‌بَرد و پیکان را مربعِ بنفش می‌کرد. */
.mb-combo__btn:hover { color: var(--text); background: transparent; }

.mb-combo__btn:disabled { color: var(--faint); cursor: not-allowed; }

.mb-combo__btn svg { inline-size: var(--icon-sm); block-size: var(--icon-sm); }

.mb-combo.is-open .mb-combo__btn[data-mode="open"] svg { transform: rotate(180deg); }

/* منو بیرونِ ظرف (روی body، fixed) می‌نشیند تا ستونِ اسکرول‌دار یا مودالِ
   ‎overflow: hidden‎ بریده‌اش نکند؛ لایه‌اش یک پله بالای مودال است. */
.mb-combo__menu { z-index: var(--z-popover); }

.mb-combo__text { flex: 1 1 auto; min-inline-size: 0; }

/* نامِ دومِ گزینه (‎<option data-mb-sub="Chrome">‎) — همان ریزِ کم‌رنگِ ‎.mb-field__sub‎،
   پیش از شمارش؛ جست‌وجو آن را هم می‌خواند («chrome» کروم را پیدا می‌کند). */
.mb-combo__sub {
  flex: 0 1 auto;
  min-inline-size: 0;
  max-inline-size: 50%;
  direction: ltr;
  unicode-bidi: isolate;
  color: var(--muted);
  font-size: var(--fs-xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mb-combo__count {
  flex: none;
  margin-inline-start: auto;
  color: var(--faint);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

/* ── ۶-د-۲-الف) کامبوی چندانتخابی ──────────────────────────────────────────
   ‎<select multiple data-mb-combo>‎ — همان کامبو، با سه فرق: ورودی فقط جست‌وجوست
   (placeholder شمارِ انتخاب‌ها را می‌گوید)، انتخاب منو را نمی‌بندد و گزینه را
   روشن/خاموش می‌کند، و هر انتخاب یک چیپِ ✕دار زیرِ ورودی است — همان
   ‎.mb-chip--btn.mb-chip--dismissible‎ِ «فیلترهای فعال»ِ کتابخانه، نه چیپِ تازه.
   تیکِ کنارِ گزینه جای ثابتِ خودش را دارد تا متنِ گزینه‌ها با روشن/خاموش‌شدن
   نلغزد. */
.mb-combo--multi .mb-combo__input { cursor: text; }

.mb-combo__chips { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-block-start: var(--sp-1-5); min-inline-size: 0; }

.mb-combo__chips[hidden] { display: none; }

.mb-combo__check {
  display: inline-grid;
  place-items: center;
  flex: none;
  inline-size: var(--icon-sm);
  block-size: var(--icon-sm);
}

/* ── ۶-د-۴) بازهٔ عددی («از / تا») ───────────────────────────────────────────
   دو ورودیِ ‎.mb-input--sm‎ با برچسبِ کوتاهِ «از/تا» و جای اختیاریِ واحد. عدد
   جزیرهٔ ‎ltr‎ است (‎dir="ltr"‎ روی خودِ ورودی — منها و اعشار سرِ جایشان) و رقمِ
   فارسی/عربی، «٫» و «٬» پذیرفته می‌شوند؛ ‎MB.minmax(el)‎ ← ‎{min, max, valid}‎.
   اعتبارسنجی را شنوندهٔ سراسریِ کیت می‌کند، بی‌نیاز به JSِ صفحه: عددِ نامعتبر
   یا «از» بزرگ‌تر از «تا» ← ‎aria-invalid‎ روی همان ورودی (کادرِ قرمزِ خودِ
   پایه) و ‎.is-invalid‎ روی ظرف؛ رویدادِ ‎mb-change‎ با ‎{name, min, max, valid}‎.
   پیامِ خطا جایش ‎.mb-field__error‎ِ فیلدِ دورش است. */
.mb-minmax { display: flex; align-items: center; gap: var(--sp-1-5); inline-size: 100%; min-inline-size: 0; }

.mb-minmax__cap, .mb-minmax__unit { flex: none; color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }

.mb-minmax__input { flex: 1 1 0; min-inline-size: 0; text-align: start; font-variant-numeric: tabular-nums; }

.mb-minmax.is-invalid .mb-minmax__cap { color: var(--danger-text); }

/* ── ۶-د-۳) نوارِ لغزان (اسکرولِ افقی بی‌نوار) ───────────────────────────────
   خواستهٔ مالک (۱۴۰۵/۰۷/۰۳): وقتی صفحه باریک می‌شود، ردیفِ «مرتبط‌ترین/
   ارزان‌ترین/…» نباید در هم برود؛ باید به چپ و راست بلغزد — بی‌نوارِ اسکرول،
   با محوشدنِ لبه و یک پیکان. هر ردیفی (سگمنت، ردیفِ چیپ) با `data-mb-scroll`
   همین می‌شود؛ ui-kit.js ظرف و پیکان‌ها را می‌سازد. محوشدن ماسک است نه یک
   لایهٔ رنگی، پس روی هر زمینه‌ای (کارت، تمِ تیره) درست می‌نشیند. */
.mb-scroll { position: relative; display: flex; max-inline-size: 100%; min-inline-size: 0; }

.mb-scroll__track {
  --mb-fade: 44px;
  display: flex;
  max-inline-size: 100%;
  min-inline-size: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0, currentColor var(--mb-fade-l, 0px), currentColor calc(100% - var(--mb-fade-r, 0px)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, currentColor var(--mb-fade-l, 0px), currentColor calc(100% - var(--mb-fade-r, 0px)), transparent 100%);
}

.mb-scroll__track::-webkit-scrollbar { display: none; }

.mb-scroll__track > * { flex: none; }

.mb-scroll.is-more-left > .mb-scroll__track { --mb-fade-l: var(--mb-fade); }

.mb-scroll.is-more-right > .mb-scroll__track { --mb-fade-r: var(--mb-fade); }

.mb-scroll__arrow {
  position: absolute;
  inset-block-start: 50%;
  z-index: var(--z-raised);
  display: none;
  align-items: center;
  justify-content: center;
  inline-size: var(--ctl-h-sm);
  block-size: var(--ctl-h-sm);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-2);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transform: translateY(-50%);
}

.mb-scroll__arrow:hover { color: var(--text); border-color: var(--border-strong); }

.mb-scroll__arrow svg { inline-size: var(--icon-sm); block-size: var(--icon-sm); }

.mb-scroll__arrow--left  { left: 0; }

.mb-scroll__arrow--right { right: 0; }

.mb-scroll.is-more-left  > .mb-scroll__arrow--left,
.mb-scroll.is-more-right > .mb-scroll__arrow--right { display: flex; }

/* ── ۶-ذ) گام (ریلِ ویزارد) ─────────────────────────────────────────────────
   «۱۱ گام» که شمرده شده بود، سه چیز بود: سه تا واقعاً گامِ ویزارد بودند، دو
   تا **کارت** بودند (پنل + کادر + سایه؛ `.lp-step`، `.ch-step`)، یکی **چیپ**
   بود (`.flow-step`)، و بقیه چیدمان. فقط همان سه تا اینجا جا می‌شوند.

     <div class="mb-steps">
       <button class="mb-step is-done">…</button>
       <button class="mb-step is-on" aria-current="step">…</button>
       <button class="mb-step">…</button>
     </div>
*/
.mb-steps { display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap; }

/* پایه‌اش «آیتمِ مجموعه» است؛ تفاوتِ خودش: رنگِ استراحتِ کم‌جان‌تر — گامِ
   نرسیده باید از گامِ جاری عقب‌تر دیده شود. گام دکمه است، پس قرص نمی‌شود؛
   فقط شمارهٔ داخلش دایره است. */
.mb-step {
  line-height: normal;   /* مثلِ آیتمِ منو — 1.2 یک پیکسل کوتاهش می‌کرد */
  color: var(--muted);
}

/* گامِ جاری: زمینهٔ کم‌رنگ + مرکبِ تأکید. فقط رنگِ متن کافی نیست — روی دو تم
   یکسان دیده نمی‌شود، همان اشتباهی که چیپ هم داشت. */
.mb-step.is-on, .mb-step[aria-current="step"] { background: var(--accent-soft); color: var(--accent-text); }

.mb-step.is-done { color: var(--ok-text); }

.mb-step:disabled, .mb-step[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* شمارهٔ گام — دایرهٔ هم‌قدِ متن، نه یک قابِ جدا. */
.mb-step__n {
  display: inline-grid;
  place-items: center;
  inline-size: var(--sp-5);
  block-size: var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--surface-3);
  color: var(--text-2);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

/* گامِ جاری با کلاس یا با aria-current — هر دو، همان‌طور که قاعدهٔ خودِ گام
   می‌پذیرد؛ وگرنه صفحه‌ای که فقط aria می‌نشاند شمارهٔ خاکستری می‌گرفت. */
.mb-step:is(.is-on, [aria-current="step"]) .mb-step__n { background: var(--accent); color: var(--on-accent); }

.mb-step.is-done .mb-step__n { background: var(--ok); color: var(--on-accent); }

/* ── ۶-ر) صفحه‌بندی ─────────────────────────────────────────────────────────
   هفت پیاده‌سازی، و هر هفت همین سه خط بودند؛ تفاوتشان فقط جای نشستنشان بود:
   وسطِ زیرِ جدول، ته‌چسبِ نوارِ ابزار، یا دو سرِ یک ردیف. */
.mb-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  color: var(--muted);
  font-size: var(--fs-sm);
}

.mb-pager--between { justify-content: space-between; flex-wrap: wrap; }

/* ته‌چسب: داخلِ یک نوارِ ابزار، به انتهای راستای متن می‌چسبد. */
.mb-pager--end { justify-content: flex-start; margin-inline-start: auto; }

.mb-pager--inline { display: inline-flex; }

/* شمارهٔ صفحه از پرش‌کردن بازمی‌ماند: ۹ و ۱۰ نباید ردیف را جابه‌جا کنند. */
.mb-pager__n { font-variant-numeric: tabular-nums; }

/* ── ۶-ش) نوار (خطِ افقی) ───────────────────────────────────────────────────
   بزرگ‌ترین تکرارِ باقی‌ماندهٔ مخزن، و ساده‌ترینش: «۱۷۸ نوار» و «۱۳۵ ردیف» در
   ممیزی دو خانواده بودند، ولی ۱۲۳تایشان *همین سه خط* را داشتند —

     display: flex;  align-items: center;  gap: N;  [justify-content: space-between]

   سرستونِ کارت، پاورقیِ مودال، نوارِ ابزار، ردیفِ فیلتر: همه یک چیزند و فقط
   نامشان فرق داشت. پس یک جزء، نه دو تا.

   فاصله به پله‌های توکن می‌چسبد: ۶ و ۱۰ و ۱۴ پیکسلی که در مخزن بود تصمیم
   نبودند (۱۰ بیشترین تکرار را داشت و هیچ توکنی نیست). بیشترین جابه‌جایی ۲
   پیکسل است.

   ⚠ با .mb-list--row فرق دارد: آن یکی <ul>ِ افقی است و صفرکردنِ فهرست را هم
   می‌آورد؛ این یکی هر خطِ افقی‌ای است.

     <div class="mb-bar mb-bar--between">…</div>
*/
.mb-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  /* بدونِ این، متنِ بلندِ داخلِ نوار ظرف را پهن‌تر از والد می‌کند و «…» کار
     نمی‌کند — همان چیزی که چند نوار جداگانه وصله‌اش کرده بودند. */
  min-inline-size: 0;
}

.mb-bar--between { justify-content: space-between; }

.mb-bar--end     { justify-content: flex-end; }

.mb-bar--center  { justify-content: center; }

.mb-bar--wrap    { flex-wrap: wrap; }

/* ترازِ عمودی وقتی دو سرِ نوار هم‌قد نیستند (عنوانِ دوخطی کنارِ یک دکمه). */
.mb-bar--top     { align-items: flex-start; }

.mb-bar--bottom  { align-items: flex-end; }

.mb-bar--stretch { align-items: stretch; }

.mb-bar--gap-0 { gap: 0; }

.mb-bar--gap-1 { gap: var(--sp-1); }

.mb-bar--gap-3 { gap: var(--sp-3); }

.mb-bar--gap-4 { gap: var(--sp-4); }

/* نوارِ ابزارِ دیده‌شونده: همان خط، روی یک سطح. */
/* جداکننده و خطِ توضیحی — سنجشِ بومِ Claude Design (۱۴۰۵/۰۷/۱۲) نشان داد هر طرح
   این دو را با border/padding و font-size/color روی خودِ .mb-bar می‌نوشت (۱۵ مغایرت
   در ۶ بورد). یک پله فاصله و یک رنگِ خط؛ تنوعِ ۴ و ۸ و ۱۶ پیکسلیِ بوردها تصمیم نبود.
   «پیش/پس» در محورِ بلوک است، پس RTL و LTR فرقی ندارند. */
.mb-bar--sep-before { padding-block-start: var(--sp-2); border-block-start: 1px solid var(--border); }
.mb-bar--sep-after  { padding-block-end: var(--sp-2); border-block-end: 1px solid var(--border); }
.mb-bar--meta { font-size: var(--fs-sm); color: var(--muted); }

.mb-bar--surface {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}

/* ── ۶-س) فهرست (پشته) ──────────────────────────────────────────────────────
   هشتاد‌ویک کلاسِ `*-list`، و بیشترشان **جزء نبودند** — چیدمان بودند: یک
   پشتهٔ عمودی با فاصله، به‌علاوهٔ همان سه خطِ همیشگیِ صفرکردنِ `<ul>` که در
   ده‌ها فایل تکرار شده بود. پس کیت اینجا یک *ابزارِ چیدمان* می‌دهد، نه یک
   کامپوننتِ ظاهری — و همین درست است: چیزی که ظاهر ندارد نباید ظاهر بگیرد.

     <ul class="mb-list mb-list--gap-3">…</ul>
*/
.mb-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
  min-inline-size: 0;
}

/* افقی. `align-items` عمداً نیست: ترازِ عمودیِ آیتم‌ها تصمیمِ میزبان است. */
.mb-list--row { flex-direction: row; flex-wrap: wrap; }

.mb-list--gap-1 { gap: var(--sp-1); }

.mb-list--gap-3 { gap: var(--sp-3); }

.mb-list--gap-4 { gap: var(--sp-4); }

.mb-list--gap-0 { gap: 0; }

/* فهرستی که خودش اسکرول می‌شود (نتایجِ جست‌وجو، انتخابگرِ ستون). */
.mb-list--scroll { max-block-size: 280px; overflow-y: auto; }

/* ══ kit/blocks.css ══════════════════════════════════════════════════════
 * بلوک‌ها — صفحه‌ای؛ از ترکیب‌ها و پایه‌ها ساخته می‌شوند.
 *
 * تکه‌ای از کیت. سرور هر پنج طبقه را به همین ترتیب به‌هم می‌چسباند و روی
 * /primitives.css سرو می‌کند، پس ترتیبِ طبقه‌ها همان ترتیبِ آبشار است:
 * base → atoms → molecules → blocks → tail.  (tools/kit-css.js)
 */

/* ── ۶-ب) حالتِ خالی ────────────────────────────────────────────────────────
   «هیچ‌چیز اینجا نیست» یک جمله نیست، یک جزء است — و در این مخزن ۱۳۲ کلاسِ
   جدا برای همین یک جمله ساخته شده بود (۱۱۲تا زنده). شکل‌هایشان را شمردم؛
   سه اندازه و دو حالتِ جایگاه همه را می‌پوشاند:

     • پیش‌فرض      ۴۹ جا — بلوکِ مرکزیِ متوسط، همین پایه.
     • --lg         ۳۷ جا — صفحهٔ خالی/کارتِ بزرگ: پدینگِ دوبرابر، متنِ درشت‌تر.
     • --line       ۱۹ جا — فقط یک خطِ خاکستری زیرِ یک فهرستِ کوچک؛ نه پدینگِ
                     بزرگ، نه آیکون. ردیفی است نه ستونی.
     • --framed     کادرِ چین‌دار (هرجا «جای خالیِ قابلِ پرکردن» را می‌گفت).
     • --span        ۵ جا — داخلِ گرید/جدول: تمامِ عرضِ ردیف را می‌گیرد.

   دو موردِ «روی‌هم» (overlay) عمداً بیرون ماندند: آن‌ها پوششِ روی محتوای
   موجودند نه حالتِ خالی، و یکی‌کردنشان با این جزء دروغ بود.

   شرط‌ها: عنوان اختیاری است ولی اگر آیکون هست عنوان هم باید باشد (آیکونِ
   بی‌متن معنا حمل نمی‌کند)؛ --line با آیکون جمع نمی‌شود؛ --span فقط داخلِ
   گرید/جدول معنا دارد. */
.mb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-10) var(--sp-4);
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-md);
  line-height: var(--lh-md);
}

/* `hidden` باید برنده شود. کیت `display: flex` است و آن قاعدهٔ عنصریِ
   مرورگر (`[hidden]{display:none}`) را می‌بازد — یعنی هر حالتِ خالی که با
   صفتِ hidden پنهان می‌شود، پس از ادغام همیشه دیده می‌شد. یک مورد واقعی
   داشتیم: #plOptEmpty در products-list.js. */
/* ‎hidden‎ باید برنده باشد. هر جزئی که ‎display‎ می‌گیرد، صفتِ ‎hidden‎ِ مرورگر را
   بی‌اثر می‌کند، و صفحه‌ای که با ‎el.hidden = true‎ چیزی را پنهان می‌کند یک جعبهٔ
   خالیِ *دیده‌شده* تحویل می‌گیرد. ‎.mb-empty‎ یک‌بار همین را برای خودش وصله کرده
   بود؛ این خط همان وصله را به همهٔ اجزایی می‌دهد که ‎display‎ اعلام می‌کنند. */
.mb-empty[hidden] { display: none; }

.mb-empty svg { width: var(--icon-lg); height: var(--icon-lg); opacity: .7; }

.mb-empty__title { color: var(--text-2); font-weight: var(--fw-semibold); font-size: var(--fs-base); }

.mb-empty__text { color: var(--muted); font-size: inherit; }

/* کنشِ اختیاری («اولین کالا را اضافه کنید») — فاصله‌اش از متن بیشتر از gap است
   تا دکمه به جمله نچسبد. */
.mb-empty__action { margin-block-start: var(--sp-2); }

/* آیکونی که SVG نیست (ایموجی، کاراکتر، یا یک قابِ تزئینی): `.mb-empty svg`
   نمی‌گیردش، پس اسلاتِ خودش را دارد و هم‌اندازهٔ همان می‌ماند. */
.mb-empty__icon { font-size: var(--fs-4xl); line-height: 1; opacity: .7; }

.mb-empty__icon svg { width: var(--icon-lg); height: var(--icon-lg); }

/* چهار پله، از اندازه‌گیریِ پدینگِ واقعیِ ۵۰ کپیِ زنده: ۶۴ / ۴۰ / ۱۶ / ۸.
   بدونِ پلهٔ --sm، هر حالتِ خالیِ کوچکِ داخلِ دراپ‌داون (پدینگِ ۲ تا ۱۶) با
   ادغام به بلوکِ ۴۰ پیکسلی تبدیل می‌شد — ادغامی که ظاهر را خراب می‌کند. */
.mb-empty--lg { padding: var(--sp-16) var(--sp-6); font-size: var(--fs-base); }

.mb-empty--sm { padding: var(--sp-4) var(--sp-3); font-size: var(--fs-sm); gap: var(--sp-1); }

.mb-empty--sm .mb-empty__title { font-size: var(--fs-sm); }

.mb-empty--sm svg { width: var(--icon-md); height: var(--icon-md); }

.mb-empty--lg .mb-empty__title { font-size: var(--fs-xl); }

/* یک خطِ کوتاه، نه یک بلوک: ردیفی، کم‌پدینگ، و کم‌رنگ‌تر — چون کنارِ محتوای
   دیگری می‌نشیند و نباید صفحه را بشکند. */
.mb-empty--line {
  flex-direction: row;
  gap: var(--sp-1);
  padding: var(--sp-2) 0;
  font-size: var(--fs-xs);
  color: var(--faint);
}

.mb-empty--line .mb-empty__title { font-size: var(--fs-xs); font-weight: var(--fw-medium); }

.mb-empty--line svg { width: var(--icon-sm); height: var(--icon-sm); }

.mb-empty--framed { border: 1px dashed var(--border); border-radius: var(--r-lg); }

/* کادرِ توپُر، نه چین‌دار — و این دوتا یکی نیستند: چین‌دار «جای خالیِ
   قابلِ پرکردن» می‌گوید، توپُر «یک پنلِ تمام‌شده که فعلاً چیزی ندارد».
   سه کپیِ زنده همین را داشتند (لاگِ ممیزی، لحظه‌ها، درخواستِ انتشار). */
.mb-empty--boxed { border: 1px solid var(--border); border-radius: var(--r-lg); }

/* روی یک سطحِ کم‌رنگ، نه روی خودِ زمینه. نُه کپیِ زنده همین را داشتند — با چهار
   توکنِ مختلف (--surface، --panel، --border-soft، color-mix از --surface). یک
   سطح برای همه؛ توکن‌های معنادار (--ok-soft/--info-soft) عمداً این‌جا نیستند،
   چون آن‌ها «موفق/اطلاع» می‌گویند نه «خالی». */
.mb-empty--surface { background: var(--surface-2); border-radius: var(--r-lg); }

/* همان جایگاه، ولی پیام خطاست نه خالی‌بودن — درختِ کاربران هر دو را دارد. */
/* ‎--danger‎ نامِ لحن در واژگانِ کیت است؛ ‎--error‎ نام‌مستعارِ همیشگی. */
.mb-empty--error, .mb-empty--danger { color: var(--danger-text); }

.mb-empty--error .mb-empty__title, .mb-empty--danger .mb-empty__title { color: var(--danger-text); }

/* داخلِ گرید یا جدول: تمامِ ردیف. در <tbody> روی خودِ <td> بنشیند (با colspan). */
.mb-empty--span { grid-column: 1 / -1; }

/* توست: روی سطحی که در هر دو تم تیره است، پس مرکبش --on-dark است نه --text. */
.mb-toast {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  max-inline-size: min(92vw, 420px);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--d-surface-3);      /* سطحی که در هر دو تم تیره است — توکنِ تیره، نه عددِ ثابت */
  color: var(--on-dark);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  box-shadow: var(--shadow-lg);
}

/* یک واژگان، دو نام — عمداً: توستِ واقعیِ برنامه (dialog.js) از ok/error/info
   استفاده می‌کند و این کلاس‌ها فقط وقتی به کار می‌آیند که dialog.js نباشد
   (صفحه‌های بی‌نوار). تا امروز آن صفحه‌ها توستِ «خطا» را بی‌رنگ نشان می‌دادند،
   چون --error در کیت نبود. هر دو نام یک چیزند. */
.mb-toast--ok     { box-shadow: var(--shadow-lg), inset 3px 0 0 var(--ok); }

.mb-toast--warn   { box-shadow: var(--shadow-lg), inset 3px 0 0 var(--warn); }

/* اطلاع تا امروز نوارِ کهرباییِ هشدار را قرض گرفته بود — «خبر» مثلِ «مراقب باش» دیده می‌شد. */
.mb-toast--info   { box-shadow: var(--shadow-lg), inset 3px 0 0 var(--info); }

.mb-toast--accent { box-shadow: var(--shadow-lg), inset 3px 0 0 var(--accent); }

.mb-toast--danger,
.mb-toast--error  { box-shadow: var(--shadow-lg), inset 3px 0 0 var(--danger); }

/* ── ۶-ص) بنرِ بالای صفحه ───────────────────────────────────────────────────
   نوارِ باریکِ سرتاسری برای وضعیتی که کاربر باید بداند و خودش انتخابش نکرده:
   «شما در حسابِ دیگری هستید» یا «کسی در حسابِ شماست».

   ⚠ چرا اینجا و نه nav.css: این کلاس را auth.js روی *هر* صفحه می‌نشاند، ولی
   هفت صفحه nav.css را لینک نمی‌کنند (ورود، فرود، صفحهٔ عمومیِ سازمان،
   ویترین، فاکتورِ عمومی، pay-sim، celebrate). تا امروز بنر روی همان‌ها
   بی‌استایل می‌ماند. primitives.css به هر صفحه تزریق می‌شود.

   رنگ مالِ حالت است، نه جزء: .imp-banner (کهربایی) و .impown-banner (آبی)
   در nav.css می‌مانند. */
.mb-topbanner {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: calc(var(--z-modal) + 5);
  min-block-size: var(--topbar-h); box-sizing: border-box;
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--ctl-px-sm) var(--sp-3); padding-block: var(--sp-2); padding-inline: var(--sp-4);
  direction: rtl; color: var(--on-accent);
  font-size: var(--fs-sm); font-weight: var(--fw-semibold); letter-spacing: 0;
  box-shadow: var(--shadow);
  font-family: var(--font);
}

/* ══ کلیدِ تم در صفحه‌هایی که نوارِ بالا ندارند ═════════════════════════════
   ظاهرِ خودِ دکمه در `nav.css` تعریف شده — ولی هفت صفحه اصلاً `nav.css` را
   لینک نمی‌کنند (صفحهٔ عمومیِ سایت، ورود، صفحهٔ عمومیِ سازمان، ویترین، …) و
   دقیقاً همان‌هایند که تا امروز کلید نداشتند. این بلوک فقط برای همان‌هاست و
   عمداً به میزبانِ خودش محدود شده (`.mb-theme-fab` / `.mb-theme-host`)، تا
   با تعریفِ `nav.css` سرِ صفحه‌های دارای نوار دعوا نکند. */
.mb-theme-fab {
  position: fixed;
  inset-block-end: 18px;
  inset-inline-start: 18px;
  z-index: calc(var(--z-nav) + 1);
}

.mb-theme-fab .nav-theme-btn,
.mb-theme-host .nav-theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: color .18s, border-color .18s, background .18s, transform .18s;
}

.mb-theme-fab .nav-theme-btn:hover,
.mb-theme-host .nav-theme-btn:hover { color: var(--accent); border-color: var(--accent); }

/* ── کفِ لمسیِ کلیدِ تم ────────────────────────────────────────────────────
   ۳۴×۳۴ زیرِ کفِ ۴۰ پیکسلیِ لمس است. این کلید را خودِ سرور به هر صفحه تزریق
   می‌کند — از جمله صفحه‌های عمومی (فرود، صفحهٔ شرکت، فروشگاه) که `nav.css`
   را لینک نمی‌کنند، پس کفِ سراسریِ آن‌جا به آن‌ها نمی‌رسد و اندازه‌گیری در
   هر سه صفحه همان ۳۴×۳۴ را نشان داد. جایش این فایل است، چون تنها چیزی است
   که هرجا این کلید هست، آن هم هست. */
@media (max-width: 1024px) {
  .mb-theme-fab .nav-theme-btn,
  .mb-theme-host .nav-theme-btn { width: 40px; height: 40px; }
}

.mb-theme-fab .nav-theme-btn:active,
.mb-theme-host .nav-theme-btn:active { transform: scale(.92); }

.mb-theme-fab .nav-theme-btn.is-dark,
.mb-theme-host .nav-theme-btn.is-dark { color: var(--warn); border-color: var(--border-strong); }

.mb-theme-fab .nav-theme-svg,
.mb-theme-host .nav-theme-svg { overflow: visible; display: block; transition: transform .35s cubic-bezier(.4, 0, .2, 1); }

.mb-theme-fab .nav-theme-btn:hover .nav-theme-svg,
.mb-theme-host .nav-theme-btn:hover .nav-theme-svg { transform: rotate(12deg); }

/* ── ۸) مودال (پوسته؛ رفتارش در ui-kit.js با <mb-modal>) ─────────────────── */
.mb-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--sp-4);
  background: var(--overlay);
}

.mb-modal__box {
  inline-size: min(100%, var(--max-form));
  max-block-size: calc(100dvh - var(--sp-8));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.mb-modal--wide .mb-modal__box { inline-size: min(100%, var(--max-text)); }
/* پهن‌تر (۸۸۰، --max-wide): ویرایشگرِ جدولیِ چندستونه — «گزینه‌های برند» در /brands هشت
   ستون دارد (این شاخه، تصویر، رنگ، نامِ فارسی، English، کد، معادلِ سراسری، کارها) و در ۶۸۰
   متنِ کادرها بریده می‌شد. برای متن و فرم همان «پهن» درست است. */
.mb-modal--xwide .mb-modal__box { inline-size: min(100%, var(--max-wide)); }
/* پهن‌ترین (۱۱۲۰، --max-dialog): دو ستون در یک مودال — فهرستِ گروه‌ها کنارِ جزئیاتِ
   گروهِ انتخاب‌شده («الگوهای پیشنهادی» در /code-reconcile). تا امروز آن صفحه پهنای
   خودش را با کلاسِ صفحه می‌داد؛ Claude Design هم همین را «کمبودِ کیت» علامت زد. */
.mb-modal--xxwide .mb-modal__box { inline-size: min(100%, var(--max-dialog)); }

/* کوچک (۴۲۰): تأییدِ سه‌خطی. کشیده تا ۵۶۰ مثلِ یک فرم خوانده می‌شد؛ نسخه‌های
   دست‌سازش ۳۶۰ / ۴۴۰ / ۴۶۰ بودند. */
.mb-modal--sm .mb-modal__box { inline-size: min(100%, calc(var(--max-form) * .75)); }

/* لخت (لایت‌باکسِ تصویر): همان پوشش، همان قراردادِ Escape و کلیکِ پس‌زمینه و
   تلهٔ فوکوس و قفلِ اسکرول — فقط *قابِ* جعبه غلط است، چون محتوا (تصویر) خودش
   قاب دارد. تا امروز نمایشگرِ رسیدِ پرداخت‌ها با یادداشتِ «بیرون از خانوادهٔ
   مودال» کلِ پوشش را دست‌ساز می‌ساخت — و برای همین نه Escape داشت نه تلهٔ
   فوکوس. لخت یعنی سر و پاورقی ندارد و دکمهٔ بستن روی خودِ محتوا می‌نشیند.
   (دو لایت‌باکسِ دیگرِ مخزن در فایل‌های قفل‌شده‌اند؛ این واریانت جایی است که
   بعداً به‌جای کپیِ سوم، به آن برسند.) */
.mb-modal--bare .mb-modal__box {
  inline-size: auto;
  max-inline-size: 92vw;
  max-block-size: 92dvh;
  background: none;
  border: 0;
  box-shadow: none;
  overflow: visible;
}

/* مودال روی مودال (تأیید از داخلِ ویرایشگر): پلهٔ بعدیِ نردبان، نه ترتیبِ DOM. */
.mb-modal--stacked { z-index: var(--z-modal-2); }

/* ── کشو (۱۴۰۵/۰۷، تنظیماتِ شاخه در /product-groups) ─────────────────────
   همان پوشش، همان سر/بدنه/پاورقی و همان قراردادِ Escape و پرده — فقط جعبه
   به‌جای وسطِ صفحه، تمام‌قد از لبهٔ «پایان» (چپ در RTL) بیرون می‌آید، تا
   درختِ پشتش دیده بماند. روی گوشی تمام‌صفحه است، نه شیتِ پایین.
   ‎.mb-modal.mb-modal--drawer‎ (۰,۲,۰) عمدی است: بلوکِ ≤۱۰۲۴ِ tail.css
   ‎.mb-modal‎ را شیتِ پایینی می‌کند و بعد از این فایل می‌آید. */
.mb-modal.mb-modal--drawer { padding: 0; place-items: stretch end; }
.mb-modal--drawer .mb-modal__box {
  inline-size: min(100%, 800px);
  block-size: 100dvh;
  max-block-size: none;
  border-radius: 0;
  border-block: 0;
  border-inline-end: 0;
}
.mb-modal--drawer .mb-modal__body { flex: 1 1 auto; }

.mb-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-block-end: 1px solid var(--border-soft);
}

.mb-modal__title { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: 1.4; }

/* خطِ دومِ سر (نسخه، مرحلهٔ ویزارد). عنوان و این یکی در یک <div> کنارِ دکمهٔ
   بستن می‌نشینند: <div><h2 class="mb-modal__title">…</h2><p class="mb-modal__sub">…</p></div> */
.mb-modal__sub { margin: var(--sp-0-5) 0 0; font-size: var(--fs-xs); line-height: var(--lh-sm); color: var(--muted); }

.mb-modal__body { padding: var(--sp-4); overflow: auto; line-height: var(--lh-md); }

.mb-modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-block-start: 1px solid var(--border-soft);
  background: var(--surface-2);
}

/* ‎display:grid‎ صفتِ hiddenِ مرورگر را می‌بازد — همان تلهٔ بخشِ ۶-ب. مودال‌های
   ایستا (دفترچهٔ آدرس، پرداخت، سهام‌داران، …) با hidden باز/بسته می‌شوند و
   بدونِ این خط هرگز بسته نمی‌شدند. (۰,۲,۰) از پایه و از بلوکِ ≤۱۰۲۴ می‌بَرد. */
.mb-modal[hidden] { display: none; }

/* ── ۹) جدولِ مشترک: توکن‌های چگالی ──────────────────────────────────────────
   موتورِ جدول (table-engine-common) از این‌ها می‌خواند؛ صفحه فقط کلاسِ چگالی
   می‌گذارد. ارتفاعِ سرستون دقیقاً برابرِ ردیف است. */
.mb-density-compact     { --tbl-row: var(--tbl-row-compact); }

.mb-density-regular     { --tbl-row: var(--tbl-row-regular); }

.mb-density-comfortable { --tbl-row: var(--tbl-row-comfortable); }

/* ── جدول (قراردادِ design-tokens.json → table) ─────────────────────────────
   همان سه قاعده‌ای که موتورِ جدول برای .pl-table تضمین می‌کند، اینجا به شکلِ یک
   جزءِ پایه تا اطلس نشانش بدهد و صفحه‌های ساده بدونِ موتور همان را داشته باشند:
   قدِ ردیف از توکنِ چگالی (--tbl-row؛ .mb-density-* روی جدول یا ظرفش)، سرستون
   دقیقاً هم‌قدِ ردیف، یک خطِ --border-strong زیرِ سرستون، سرستونِ چسبان،
   حاشیهٔ افقیِ --tbl-cell-px، سرستون همیشه rtl/start، عدد با .mb-num. */
.mb-table { inline-size: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text); }

.mb-table th, .mb-table td { block-size: var(--tbl-row, var(--tbl-row-regular)); padding-block: 0; padding-inline: var(--tbl-cell-px); text-align: start; vertical-align: middle; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.mb-table th { position: sticky; inset-block-start: 0; z-index: 1; direction: rtl; font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--muted); background: var(--surface-2); border-block-end: 1px solid var(--border-strong); }

.mb-table td { border-block-end: 1px solid var(--border); background: var(--surface); }

.mb-table tbody tr:hover td { background: var(--surface-2); }

.mb-table td.mb-num, .mb-table th.mb-num { font-variant-numeric: tabular-nums; }

.mb-table--wrap { border: 1px solid var(--border); border-radius: var(--r-lg); overflow: auto; max-block-size: 60vh; }

/* ── لایه و پرده: دو گزینه‌ای که نبودنشان سی پوششِ دست‌ساز ساخت ─────────
   ممیزی سیزده نردبانِ `calc(var(--z-popover) + N)` و یک ۹۹۹۹۹۹ پیدا کرد؛
   همه‌شان یک چیز می‌خواستند: «روی همه». حالا اسم دارد و از نردبانِ
   theme.css می‌خواند، نه از عددی که آن روز کار می‌کرد. */
.mb-modal--above-all { z-index: var(--z-top); }
.mb-modal--above-popover { z-index: calc(var(--z-popover) + 1); }

/* پردهٔ مات — انتظارِ مسدودکننده باید بگوید «الان نه»، نه اینکه فقط تیره کند. */
.mb-modal--blur { backdrop-filter: blur(3px); }

/* ── جمع‌شدنی: بالای صفحه که با پایین‌رفتنِ فهرست باریک می‌شود ────────────
   رفتار در ui-kit.js ← MB.collapseOnScroll(host): پایین‌رفتنِ بیش از ۴۸ پیکسل
   روی host کلاسِ ‎is-collapsed‎ می‌گذارد و هر اسکرولِ رو به بالا بیش از ۸ پیکسل
   (یا رسیدن به بالا) برش می‌دارد. اینجا فقط دو نقش است: ‎__hide‎ در حالتِ جمع
   بسته می‌شود (ارتفاع و شفافیت، بی‌عددِ ثابت)، ‎__show‎ فقط در حالتِ جمع دیده
   می‌شود. چه چیزی کوچک شود (عنوان، کادرِ پیشرفت) کارِ خودِ صفحه است. */
.mb-collapse__hide {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows var(--dur-normal) var(--ease), opacity var(--dur-fast) var(--ease);
}
.mb-collapse__hide > * { min-block-size: 0; overflow: hidden; }
.mb-collapse.is-collapsed .mb-collapse__hide { grid-template-rows: 0fr; opacity: 0; pointer-events: none; }
.mb-collapse:not(.is-collapsed) .mb-collapse__show { display: none; }

/* ── مقایسهٔ کنارِ هم: دو چیز، فیلد‌به‌فیلد ────────────────────────────────
   طرحِ «الگوهای پیشنهادی، مرتب‌شده» (بومِ بازطراحیِ رفعِ مغایرت، صفحهٔ ۱۳–۱۴ —
   مالک، ۱۴۰۵/۰۷/۰۸: «هرجا مقایسهٔ کنارِ هم داریم شبیهِ این بشه»).
   هر طرف ستونِ ته‌رنگِ خودش را دارد (الف = کهربایی، ب = سبز) با خطِ رنگیِ بالا؛
   نشانهٔ هم‌خوانی (✓ ≈ ≠ –) روی درزِ میانِ دو ستون می‌نشیند؛ «سایرِ فیلدها»
   هر کدام زیرِ کالای خودش. رفتار و هم‌ترازکردنِ فیلدها در ui/compare-view.js است.
     .mb-compare                  قاب
       .mb-compare__grid          شبکهٔ «برچسب | الف | درز | ب»
         .mb-compare__corner      خانهٔ خالیِ سرِ ستونِ برچسب/درز
         .mb-compare__head--a|b   سرِ هر طرف (عنوان + کد + عکسِ اختیاری)
         .mb-compare__label       نامِ فیلد
         .mb-compare__cell--a|b   مقدارِ هر طرف
         .mb-compare__seam        درز؛ داخلش .mb-compare__mark--same|near|diff|one
         .mb-compare__rest        «سایرِ فیلدها» — فهرستِ کلید/مقدار
       .mb-compare__legend        راهنمای نشانه‌ها */
.mb-compare {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  min-inline-size: 0;
  container-type: inline-size;
}
.mb-compare__grid {
  display: grid;
  grid-template-columns: minmax(72px, max-content) minmax(0, 1fr) 40px minmax(0, 1fr);
}
.mb-compare__corner,
.mb-compare__label,
.mb-compare__seam {
  background: var(--surface-2);
  border-block-end: 1px solid var(--border);
}
.mb-compare__seam {
  display: flex;
  align-items: center;
  justify-content: center;
  border-inline: 1px solid var(--border);
}
.mb-compare__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-inline-size: 0;
  padding: var(--sp-2) var(--sp-3);
  border-block-start: 3px solid var(--mb-compare-side);
  border-block-end: 1px solid color-mix(in srgb, var(--mb-compare-side) 30%, var(--border));
  background: var(--mb-compare-head-bg);
}
.mb-compare__head-body { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
/* عکسِ سرِ ستون تهِ همان ستون می‌نشیند (دور از درز)، تا مالِ ستونِ همسایه دیده نشود. */
.mb-compare__head > .mb-frame { order: 1; margin-inline-start: auto; }
.mb-compare__head-title { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--mb-compare-ink); }
.mb-compare__code {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--text);
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
  overflow-wrap: anywhere;
}
.mb-compare__head--a, .mb-compare__cell--a, .mb-compare__rest--a {
  --mb-compare-side: var(--warn);
  --mb-compare-ink: var(--warn-text);
  --mb-compare-head-bg: var(--warn-soft);
}
.mb-compare__head--b, .mb-compare__cell--b, .mb-compare__rest--b {
  --mb-compare-side: var(--ok);
  --mb-compare-ink: var(--ok-text);
  --mb-compare-head-bg: var(--ok-soft);
}
.mb-compare__label {
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--muted);
}
.mb-compare__cell,
.mb-compare__rest {
  min-inline-size: 0;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--text);
  background: color-mix(in srgb, var(--mb-compare-head-bg) 35%, var(--surface));
  border-block-end: 1px solid color-mix(in srgb, var(--mb-compare-side) 14%, var(--border));
  overflow-wrap: anywhere;
}
.mb-compare__cell--code { font-family: var(--font-mono); direction: ltr; unicode-bidi: isolate; text-align: end; }
.mb-compare__cell--empty { color: var(--faint); }
.mb-compare__rest {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--sp-3);
  row-gap: var(--sp-1);
  align-content: start;
  font-size: var(--fs-xs);
  border-block-end: 0;
}
.mb-compare__rest-k { color: var(--muted); white-space: nowrap; }
.mb-compare__rest-v { color: var(--text); }
.mb-compare__grid > .mb-compare__label--last,
.mb-compare__grid > .mb-compare__seam--last { border-block-end: 0; }

.mb-compare__mark {
  inline-size: 22px;
  block-size: 22px;
  border-radius: var(--r-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  line-height: 1;
  flex-shrink: 0;
}
.mb-compare__mark--same { background: var(--ok-soft);     color: var(--ok-text); }
.mb-compare__mark--near { background: var(--accent-soft); color: var(--accent-text); }
.mb-compare__mark--diff { background: var(--warn-soft);   color: var(--warn-text); }
.mb-compare__mark--one  { background: var(--surface-3);   color: var(--muted); }

.mb-compare__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  border-block-start: 1px solid var(--border);
  background: var(--surface-2);
  font-size: var(--fs-xs);
  color: var(--muted);
}
.mb-compare__legend-item { display: inline-flex; align-items: center; gap: var(--sp-1); }
.mb-compare__legend .mb-compare__mark { inline-size: 18px; block-size: 18px; font-size: var(--fs-xs); }

/* باریک: درز و برچسب می‌مانند، دو طرف زیرِ هم نمی‌روند — مقایسه یعنی کنارِ هم. */
@container (max-width: 520px) {
  .mb-compare__grid { grid-template-columns: minmax(56px, max-content) minmax(0, 1fr) 32px minmax(0, 1fr); }
  .mb-compare__label, .mb-compare__cell, .mb-compare__rest { padding: var(--sp-1-5) var(--sp-2); }
  /* عکسِ سرِ ستون بالای کد می‌رود تا کد تمام‌عرض بماند و حرف‌به‌حرف نشکند. */
  .mb-compare__head { flex-direction: column; align-items: flex-start; gap: var(--sp-1-5); padding: var(--sp-2); }
  .mb-compare__head > .mb-frame { order: 0; margin-inline-start: 0; }
  .mb-compare__head-body { inline-size: 100%; }
}

/* ══ کارتِ محصول — همان کارتِ واقعیِ کاتالوگ، فروشگاه و فاکتور ══════════════════
   تا امروز این کارت بیرون از کیت بود (ui/library.css) و کیت فقط یک «.mb-product»ِ
   جانگه‌دار داشت که هیچ صفحه‌ای نمی‌کشید — پس Claude Design کارتی را یاد می‌گرفت که
   در سایت وجود نداشت. حالا آناتومیِ کارت همین‌جاست و ui/product-grid.js آن را با
   «card mb-product» می‌سازد: هر چه این‌جا هست، همان است که کاربر در سایت می‌بیند.

   چرا نام‌های داخلی ‎.card-*‎ مانده‌اند: library.js، فروشگاه و تست‌ها با همین نام‌ها
   برش می‌زنند. ولی هر قاعده زیرِ ریشهٔ کیت بسته شده (‎:where(.mb-product)‎)، پس روی
   هیچ ‎.card‎ِ دیگری در سایت نمی‌نشیند و وزنش دقیقاً همان وزنِ قبلی است.

   متغیرهای اندازه (‎--card-min‎، ‎--card-image-height‎) را کاتالوگ با لغزندهٔ
   «اندازهٔ کارت» عوض می‌کند؛ این‌جا فقط مقدارِ پیش‌فرض‌شان به‌عنوانِ fallback آمده
   تا کارت بی library.css هم (روی بومِ طراحی) درست بنشیند.

   ویژگی‌های خودِ کاتالوگ — آفرها، مقایسهٔ تامین‌کننده، تأیید، سبد، اندازهٔ XS — در
   library.css مانده‌اند: بعضی‌شان بیرون از کارت هم کشیده می‌شوند (آفرها در مودال). */

.mb-product {
  position: relative;
  background: var(--surface);
  padding: 0;
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: 0;
  transition: box-shadow 0.2s, border-color 0.2s;
  overflow: hidden;
  min-height: 100%;
}

.mb-product:hover {
  box-shadow: var(--shadow);
  border-color: var(--border-strong);
}

:where(.mb-product).card--interactive {
  cursor: pointer;
}

:where(.mb-product).card--interactive:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--lib-ring-accent, color-mix(in srgb, var(--accent) 22%, transparent)), var(--shadow-lg);
}

:where(.mb-product) .card-media {
  position: relative;
  padding: 0;
}

:where(.mb-product) .card-media-frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 0;
  border: 0;
  background: var(--surface-2);
}

.mb-product > img,
:where(.mb-product) .card-media-frame > img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 0;
  background: var(--surface);
  border: none;
}

:where(.mb-product) .card-img--clickable {
  cursor: inherit;
}

:where(.mb-product) .card-no-image {
  width: 100%;
  height: 100%;
  min-height: var(--card-image-height, 170px);
  border-radius: 0;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
}

:where(.mb-product) .card-no-image-label {
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font);
  color: var(--danger-text);
  /* متنِ این برچسب فارسی است («بدون تصویر») — letter-spacing روی خطِ
     متصل صفر است، وگرنه اتصالِ حروف باز می‌شود. */
  letter-spacing: 0;
}

/* ۱۴۰۵/۰۶ — بررسی شد، عمداً نماند: این فقط تغییرِ رنگ/وزنِ یک برچسبِ درون‌خطیِ
   ۱۲px («بدون تصویر») است، نه یک وضعیتِ خالیِ صفحه/پنل — .mb-empty بلوکی با
   عنوان/توضیح و پدینگِ خودش است و اینجا معنا نمی‌دهد. */

:where(.mb-product) .card-no-image-label--empty {
  color: var(--faint);
  font-weight: 500;
}

:where(.mb-product) .card-pill-group {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

:where(.mb-product) .card-pill {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
}

:where(.mb-product) .card-pill--category {
  background: var(--info-soft);
  border-color: var(--lib-edge-info, color-mix(in srgb, var(--info) 38%, transparent));
  color: var(--info-text);
}

:where(.mb-product) .card-pill--ghost {
  background: var(--surface-2);
  border-color: var(--border);
}

:where(.mb-product) .card-pill--mono {
  font-family: var(--font-mono);
}

:where(.mb-product) .card-shell {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3);
  direction: rtl;
  text-align: start;
}

:where(.mb-product) .card-primary {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

:where(.mb-product) .card-primary > * {
  min-width: 0;
  padding: 0;
  border-bottom: none;
}

:where(.mb-product) .card-primary > :last-child {
  padding-bottom: 0;
  border-bottom: none;
}

:where(.mb-product) .card-topline {
  position: absolute;
  inset-block-start: var(--sp-2);
  inset-inline-start: var(--sp-2);
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-1-5);
}

:where(.mb-product) .card-code-block {
  order: 2;
  display: flex;
  align-items: baseline;
  gap: var(--sp-1-5);
  min-width: 0;
}

:where(.mb-product) .card-code-label {
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--faint);
  flex: 0 0 auto;
  text-align: start;
}

:where(.mb-product) .card-primary-code {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--text-2);
  direction: ltr;
  text-align: start;
  line-height: 1.4;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

:where(.mb-product) .card-website-code {
  font-size: var(--fs-xs);
  line-height: 1.4;
}

:where(.mb-product) .card-title-fa {
  flex: 0 0 auto;
  min-width: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  line-height: 1.5;
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

:where(.mb-product) .card-title-en {
  flex: 0 0 auto;
  min-width: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  direction: ltr;
  text-align: right;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

:where(.mb-product) .card-names-row {
  order: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  min-width: 0;
}

:where(.mb-product) .card-reference-line {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 11px;
}

:where(.mb-product) .card-reference-label {
  color: var(--muted);
  font-weight: 600;
}

:where(.mb-product) .card-reference-value {
  direction: ltr;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--text-2);
}

:where(.mb-product) .card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  padding-top: 0;
  border-top: none;
}

/* ظرفِ مشترکِ «آفرها» + «افزودن به پیش‌فاکتور» — روی دسکتاپ شفاف است
   (فرزندانش عیناً همان دو بخشِ قبلی‌اند)، فقط موبایل از آن برای کنارِ‌هم
   چیدن استفاده می‌کند (ر.ک مدیاکوئری‌های پایینِ فایل). */

:where(.mb-product) .card-secondary-actions {
  display: contents;
}

:where(.mb-product) .card-copyable {
  cursor: pointer;
  transition: opacity 0.12s;
}

:where(.mb-product) .card-copyable:hover {
  opacity: 0.78;
}

:where(.mb-product) .card-info {
  margin-block-start: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1-5);
  font-size: var(--fs-xs);
  direction: rtl;
  text-align: start;
  padding: 0;
}

:where(.mb-product) .card-info > * {
  border-bottom: none;
}

:where(.mb-product) .card-info > :last-child {
  border-bottom: none;
}

:where(.mb-product) .card-info-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
  line-height: 1.5;
  padding: 0;
  min-width: 0;
}

:where(.mb-product) .card-info-row--value-left .card-info-value {
  margin-inline-start: auto;
  text-align: end;
}

:where(.mb-product) .card-info-label {
  color: var(--muted);
  flex-shrink: 0;
  font-size: var(--fs-xs);
  font-weight: 400;
  text-align: start;
}

:where(.mb-product) .card-info-value {
  color: var(--text);
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:where(.mb-product) .card-info-value--mono {
  font-family: var(--font-mono);
}

:where(.mb-product) .card-info-value--ltr {
  direction: ltr;
  text-align: start;
}

/* Copyable — click to copy */

:where(.mb-product) .card-copyable {
  cursor: pointer;
  transition: opacity 0.12s;
}

:where(.mb-product) .card-copyable:hover {
  opacity: 0.85;
}

/* Website code — prominent */

:where(.mb-product) .card-info-value.card-website-code {
  font-weight: 700;
  font-size: 12.5px;
  color: var(--text);
  direction: ltr;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

:where(.mb-product) .card-stock-row {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: 0;
  min-width: 0;
}

:where(.mb-product) .card-stock-group {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  min-width: 0;
  flex: 1 1 0;
}

:where(.mb-product) .card-stock-group .card-info-value {
  flex: 1;
  text-align: start;
  direction: ltr;
}

:where(.mb-product) .card-stock-gap {
  width: 1px;
  align-self: stretch;
  background: var(--info-soft);
  flex: 0 0 1px;
}

:where(.mb-product) .card-stock-value {
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
}

:where(.mb-product) .card-info-value.card-price {
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-bold);
  font-size: var(--fs-lg);
  color: var(--text);
}

:where(.mb-product) .card-info-row--value-left:has(.card-price) {
  align-items: center;
  padding-block-start: var(--sp-2);
  border-block-start: 1px solid var(--border-soft);
}
:where(.mb-product) .card-price--updating {
  color: var(--warn-text) !important;
  font-style: italic;
  font-weight: 400 !important;
}

:where(.mb-product) .card-info-row--color {
  align-items: center;
}

:where(.mb-product) .card-color-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  max-width: 100%;
  overflow: hidden;
  min-width: 0;
}

:where(.mb-product) .card-color-swatch {
  width: 20px;
  height: 20px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--border);
  flex-shrink: 0;
  vertical-align: middle;
  background: transparent;
}

.mb-product img.card-color-swatch {
  width: 20px;
  height: 20px;
  border-radius: var(--r-sm);
  object-fit: cover;
  background: transparent;
  border: 1px solid var(--border);
}

:where(.mb-product) .card-color-name {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.2;
  text-align: end;
}

:where(.mb-product) .card-text-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 640px) {
  :where(.mb-product) .card-media {
    padding: 10px 10px 0;
  }
  :where(.mb-product) .card-shell {
    padding: 12px;
  }
  :where(.mb-product) .card-names-row,
:where(.mb-product) .card-stock-row,
:where(.mb-product) .card-footer {
    flex-direction: column;
    align-items: stretch;
  }
  :where(.mb-product) .card-stock-gap {
    display: none;
  }
  :where(.mb-product) .card-warehouse-badge {
    max-width: 100%;
  }
}

/* Selectable card state */

:where(.mb-product).card--selectable {
  cursor: pointer;
  position: relative;
  user-select: none;
  transition: all 0.15s;
}

:where(.mb-product).card--selectable:hover {
  box-shadow: 0 0 0 2px var(--lib-ring-accent, color-mix(in srgb, var(--accent) 22%, transparent));
}

/* Selected card state — highlight only, no checkbox */

:where(.mb-product).card--selected {
  border-color: var(--accent) !important;
  box-shadow: 0 0 0 2.5px var(--lib-ring-accent, color-mix(in srgb, var(--accent) 22%, transparent)) !important;
  background: color-mix(in srgb, var(--accent) 8%, transparent) !important;
}

:where(.mb-product) .card-warehouse-badge {
  display: inline-block;
  font-size: 10px;
  color: var(--muted);
  background: transparent;
  padding: 0;
  border-radius: 0;
  white-space: nowrap;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 65%;
}

/* scope badges on cards (لایبری خصوصی/عمومی) */

:where(.mb-product) .card-pill--private {
  background: var(--warn-soft);
  color: var(--warn-text);
  border: 1px solid var(--lib-edge-warn, color-mix(in srgb, var(--warn) 38%, transparent));
}

:where(.mb-product) .card-pill--publicscope {
  background: var(--ok-soft);
  color: var(--ok-text);
  border: 1px solid var(--lib-edge-ok, color-mix(in srgb, var(--ok) 38%, transparent));
}

/* هم‌وزنِ `.card-info-value.card-price` نوشته شده، نه تک‌کلاسه: آن قاعده
   `color: var(--accent)` می‌دهد و با یک کلاس شکست نمی‌خورد — جمله را با رنگِ
   قیمتِ واقعی می‌نوشت. */

:where(.mb-product) .card-info-value.card-price--none { color: var(--faint); font-weight: 500; font-style: italic; }

@media (max-width: 640px) {
  .mb-product {
    display: grid;
    grid-template-columns: 96px 1fr;
    grid-template-rows: auto auto;
    column-gap: 10px;
  }
  /* پدینگ‌ها به‌صورت منطقی (inline-start/end) نه چپ/راستِ فیزیکی — کارت در
     RTL است، پس ستونِ اول (بندانگشتی) بصراً سمتِ راست می‌نشیند و لبهٔ بیرونی
     چیزی که در چیدمانِ فیزیکی «راست» می‌نامیم همان inline-start است. */
  :where(.mb-product) .card-media {
    grid-column: 1;
    grid-row: 1 / 3;
    align-self: start;
    width: 96px;
    height: 96px;
    padding-block: 10px;
    padding-inline: 10px 0;
  }
  :where(.mb-product) .card-media-frame,
:where(.mb-product) .card-no-image {
    aspect-ratio: 1;
    border-radius: var(--r-md);
  }
  /* پوسته را حذف می‌کنیم، نه محتوایش — فرزندانش مستقیم آیتمِ گریدِ `.card`
     می‌شوند تا بشود هرکدام را جدا جای گرفت (بندانگشتی کنار، دکمه زیرِ همه). */
  :where(.mb-product) .card-shell {
    display: contents;
  }
  :where(.mb-product) .card-primary {
    grid-column: 2;
    grid-row: 1;
    padding-block-start: 10px;
    padding-inline: 0 10px;
    gap: 2px;
  }
  :where(.mb-product) .card-primary > * {
    padding-block: 2px;
  }
  :where(.mb-product) .card-info {
    grid-column: 2;
    grid-row: 2;
    padding-block: 2px 8px;
    padding-inline: 0 10px;
    font-size: 12.5px;
  }
  /* «خصوصی»/نامِ لیست تزئین‌اند، حذف‌شان اطلاعاتی نمی‌بَرد — می‌مانند مخفی. */
  :where(.mb-product) .card-topline {
    display: none;
  }
  :where(.mb-product) .card-names-row .card-title-en {
    display: none;
  }
  /* برچسبِ «وضعیتِ تایید» یک اکشن نیست، ولی یک هشدارِ واقعی است — فروشنده‌ای
     که از گوشی برآورد می‌گیرد باید بدونِ بازکردنِ کارت بداند رد شده یا هنوز
     منتظر است. زیرِ ردیفِ موجودی/قیمت، چسبیده به سمتِ اطلاعات، نه توی
     بندانگشتی. */
  :where(.mb-product) .card-footer {
    grid-column: 2;
    grid-row: 3;
    min-height: 40px;
    align-items: center;
    padding-block: 4px 0;
    padding-inline: 0 10px;
    border-top: none;
    justify-content: flex-end;
  }
  :where(.mb-product) .card-warehouse-badge {
    font-size: 12px;
  }
  /* «آفرهای دیتابیسی» تنها اکشنِ کارت بود که موبایل اصلاً نداشتش — حذفش
     خطای سخت‌گیرِ ممیزی بود. کنارِ «افزودن به پیش‌فاکتور» می‌نشیند (نه زیرِ
     آن) تا یک ردیفِ اضافه به ارتفاعِ کارت اضافه نشود؛ ظرفِ مشترکشان
     (`card-secondary-actions`، ر.ک library.js) روی دسکتاپ `display:contents`
     است، اینجا فلکسِ افقی می‌شود. */
  :where(.mb-product) .card-secondary-actions {
    display: flex;
    grid-column: 1 / -1;
    grid-row: 4;
    gap: 8px;
    padding: 6px 10px 10px;
    border-top: 1px solid var(--border-soft);
  }
  /* فقط ردیفِ موجودی و آخرین ردیف (که همیشه قیمت است — ر.ک buildCard در
     product-grid.js) می‌مانند؛ صفت‌های دیگر (رنگ/متریال/تامین‌کننده/…) در
     این ارتفاعِ فشرده جا نمی‌شوند. */
  :where(.mb-product) .card-info > .card-info-row:not(.card-stock-row):not(:last-child) {
    display: none;
  }
  :where(.mb-product) .card-code-label,
:where(.mb-product) .card-info-label,
:where(.mb-product) .card-pill {
    font-size: 12px;
  }
}

@media (max-width: 1024px) {
  :where(.mb-product) .card-code-label,
:where(.mb-product) .card-info-label,
:where(.mb-product) .card-pill {
    font-size: 12px;
  }
  :where(.mb-product) .card-info {
    font-size: 12px;
  }
}

/* ══ درختِ شاخه‌های محصول (‎.mb-tree‎) ═══════════════════════════════════════
   از ۱۴۰۵/۰۷/۱۲ جزءِ کیت است، نه CSSِ صفحه: مالک خواست درخت در «MaterialBoard
   Kit»ِ Claude Design هم باشد تا هر طرحی که شاخه نشان می‌دهد همین درخت را
   بکشد. تا پیش از آن ‎ui/taxonomy-tree.css‎ بود و درخت تنها خانوادهٔ «بی‌کیت».

   ── چه کسی markup می‌سازد
   ‎TaxonomyTree.treeHtml(roots, opts)‎ در ‎ui/taxonomy-tree.js‎ — یک رندر برای
   سه حالت: ‎.mb-tree--admin‎ (سازنده، ویرایش)، ‎.mb-tree--view‎ (فقط مشاهده) و
   ‎.mb-tree--pick‎ (انتخابِ برند، تیکِ سه‌حالته). نمونه‌اش کارتِ «درخت» در اطلس.

   ── شکل
   هر شاخهٔ ریشه یک ‎<section class="tx-group mb-hue-N">‎ است و زیرشاخه‌ها
   ردیف‌های تختِ همان گروه. ستون‌ها (نام · منبعِ ویژگی · ویژگی‌ها · عملیات) در
   همهٔ ردیف‌ها یکی‌اند. تورفتگی و خطوطِ راهنما از ‎--d‎ (عمقِ ردیف) و ‎--m‎ (سطحِ
   خط) با calc ساخته می‌شوند. بریک‌پوینت‌ها کوئریِ *ظرف*‌اند (‎@container txtree‎)،
   چون درخت هم تمام‌صفحه است و هم داخلِ پنجرهٔ ویزارد.

   ── قاعده‌ها
   ۱) هرچه *داخلِ* ردیف جزء است — چیپ، دکمه، آواتار، نقطه، تیک، منو، حباب — همان
      جزءِ کیت است؛ این بخش فقط ردیف، خط و ستون را تعریف می‌کند.
   ۲) کلاس‌های داخلی ‎tx-*‎ ماندند (قلاب‌های JS و آزمون‌ها به آن‌ها بسته‌اند)؛ هر
      قاعده زیرِ ریشهٔ کیت بسته شده — ‎:where(.mb-tree)‎؛ حباب و فهرستِ «+N» به ‎<body>‎
      می‌روند و ریشهٔ خودشان را دارند (‎.mb-tree__tip‎، ‎.mb-tree__pop‎) — پس وزنِ هیچ گزینشگری از فایلِ قدیم عوض نشد.
   ۳) رنگِ هر گروه ‎.mb-hue-N‎ِ پایه‌هاست (atoms.css)؛ گروه از آن ‎--mb-c*‎ و دو
      رنگِ خودش (‎--tx-wash‎ زمینهٔ انتخاب، ‎--tx-line‎ قابِ گروهِ باز) را می‌سازد. */
/* ── قابِ درخت و متغیرهای هندسه ─────────────────────────────────────────── */
.mb-tree {
  container: txtree / inline-size;
  --tx-base: 16px;      /* فاصلهٔ لبهٔ شروعِ ردیف تا تاشوِ ریشه */
  --tx-s1: 28px;        /* پلهٔ تورفتگی برای سه سطحِ اول */
  --tx-s2: 20px;        /* پلهٔ تورفتگی از سطحِ چهارم به بعد */
  --tx-cw: 28px;        /* عرضِ تاشو */
  --tx-gap: 10px;
  --tx-lh: 52px;        /* قدِ خطِ اولِ ردیف */
  --tx-lh-root: 64px;
  --tx-guide: color-mix(in srgb, var(--border-strong) 55%, var(--border));
  --tx-cols: minmax(0, 1fr) 124px 400px 148px;
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.mb-tree--view { --tx-cols: minmax(0, 1fr) 124px 440px 56px; }
/* حالتِ انتخاب ستونِ منبع ندارد؛ تیک در لبهٔ شروعِ ردیف جا می‌گیرد. */
/* ستونِ انتخاب به‌اندازهٔ محتوایش است و ستونِ ویژگی‌ها جا می‌دهد — وگرنه
   «N انتخاب» + «گزینه‌های اختصاصی» از ستونِ ۳۴۰ بیرون می‌زد و روی «+N» می‌نشست. */
.mb-tree--pick { --tx-cols: minmax(0, 1fr) 124px minmax(0, 300px) auto; --tx-base: 52px; }
:where(.mb-tree) .tx-groups { display: flex; flex-direction: column; gap: 10px; }

:where(.mb-tree) .tx-head {
  display: grid; grid-template-columns: var(--tx-cols); align-items: center;
  min-height: 28px; padding: 0 1px;
  font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--muted);
}
:where(.mb-tree) .tx-head-name { padding-inline-start: calc(var(--tx-base) + var(--tx-cw) + var(--tx-gap)); }

:where(.mb-tree) .tx-group {
  --mb-c: var(--mb-hue, var(--accent-text));
  --mb-c-ink: var(--mb-c);
  --mb-c-soft: color-mix(in srgb, var(--mb-c) 11%, var(--surface));
  --mb-chip-c: var(--mb-c);
  --tx-wash: color-mix(in srgb, var(--mb-c) 4%, var(--surface));
  --tx-line: color-mix(in srgb, var(--mb-c) 28%, var(--border));
}

/* ── گروهِ یک شاخهٔ ریشه ─────────────────────────────────────────────────── */
:where(.mb-tree) .tx-group {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(20, 22, 26, .03));
  overflow: clip;   /* گوشه‌های ردیف‌ها؛ clip برخلافِ hidden چسبانیِ ردیفِ ریشه را نمی‌کُشد */
}
:where(.mb-tree) .tx-group.is-open { border-color: var(--tx-line); box-shadow: var(--shadow); }

/* ── ردیف ──────────────────────────────────────────────────────────────────── */
:where(.mb-tree) .tx-row {
  --tx-x: calc(min(var(--d), 3) * var(--tx-s1) + max(var(--d) - 3, 0) * var(--tx-s2));
  position: relative;
  display: grid; grid-template-columns: var(--tx-cols); align-items: center;
  min-height: var(--tx-lh);
  border-top: 1px solid var(--border-soft);
  background: var(--surface);
  transition: background-color var(--dur-fast) var(--ease);
}
:where(.mb-tree) .tx-row.is-first { border-top: 0; }
:where(.mb-tree) .tx-row--root { --tx-lh: var(--tx-lh-root); }
:where(.mb-tree) .tx-row:hover { background: var(--surface-2); }
:where(.mb-tree) .tx-row.is-sel { background: var(--tx-wash); }
:where(.mb-tree) .tx-row.is-flash { background: var(--warn-soft); }
/* ردیفِ ریشهٔ بازِ هر گروه بالای صفحه می‌چسبد تا معلوم بماند زیرِ کدام شاخه‌اید. */
:where(.mb-tree) .tx-row.is-sticky {
  position: sticky; top: var(--tx-sticky-top, 0px); z-index: 3;
  background: var(--tx-wash); box-shadow: inset 0 -1px 0 var(--tx-line);
}

/* خطوطِ راهنما: سطحِ m روی مرکزِ تاشوِ سطحِ m. */
:where(.mb-tree) .tx-g, :where(.mb-tree) .tx-elbow, :where(.mb-tree) .tx-stub { position: absolute; background: var(--tx-guide); pointer-events: none; }
:where(.mb-tree) .tx-g {
  inset-inline-start: calc(var(--tx-base) + min(var(--m), 3) * var(--tx-s1) + max(var(--m) - 3, 0) * var(--tx-s2) + var(--tx-cw) / 2);
  top: 0; bottom: 0; inline-size: 1px;
}
:where(.mb-tree) .tx-g--end { bottom: auto; block-size: calc(var(--tx-lh) / 2); }
:where(.mb-tree) .tx-elbow {
  --tx-step: calc((min(var(--d), 3) - min(var(--d) - 1, 3)) * var(--tx-s1) + (max(var(--d) - 3, 0) - max(var(--d) - 4, 0)) * var(--tx-s2));
  inset-inline-start: calc(var(--tx-base) + var(--tx-x) - var(--tx-step) + var(--tx-cw) / 2);
  top: calc(var(--tx-lh) / 2); block-size: 1px;
  inline-size: calc(var(--tx-step) - var(--tx-cw) / 2);
}
/* برگ تاشو ندارد؛ خط تا لبهٔ آواتار ادامه می‌یابد. */
:where(.mb-tree) .tx-elbow--leaf { inline-size: calc(var(--tx-step) + var(--tx-gap) - 4px); }
:where(.mb-tree) .tx-stub {
  inset-inline-start: calc(var(--tx-base) + var(--tx-x) + var(--tx-cw) / 2);
  top: calc(var(--tx-lh) / 2 + var(--tx-cw) / 2); bottom: 0; inline-size: 1px;
}

/* ── ستونِ نام ─────────────────────────────────────────────────────────────── */
:where(.mb-tree) .tx-c { min-width: 0; }
:where(.mb-tree) .tx-c--name { position: relative; display: flex; align-items: center; block-size: var(--tx-lh); }
:where(.mb-tree) .tx-name {
  flex: 1; min-width: 0; block-size: 100%;
  display: flex; align-items: center; gap: var(--tx-gap);
  padding: 0; padding-inline: calc(var(--tx-base) + var(--tx-x)) 12px;
  border: 0; background: transparent; color: inherit; font: inherit; text-align: start;
}
:where(.mb-tree) button.tx-name { cursor: pointer; }
:where(.mb-tree) button.tx-name:focus-visible { outline: var(--focus-ring); outline-offset: -2px; }
:where(.mb-tree) .tx-fold {
  flex: none; inline-size: var(--tx-cw); block-size: var(--tx-cw);
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md); color: var(--muted);
  transition: background-color var(--dur-fast) var(--ease);
}
:where(.mb-tree) .tx-fold--top { background: var(--surface-3); color: var(--text-2); }
:where(.mb-tree) .tx-fold--leaf { background: none; }
:where(.mb-tree) .tx-fold svg { transform: rotate(90deg); transition: transform var(--dur-fast) var(--ease); }
:where(.mb-tree) .tx-name[aria-expanded="true"] .tx-fold svg { transform: none; }
:where(.mb-tree) button.tx-name:hover .tx-fold { background: var(--border); }
:where(.mb-tree) .tx-glyph { flex: none; inline-size: 24px; display: inline-flex; justify-content: center; color: var(--mb-c-ink); }
:where(.mb-tree) .tx-dotw { flex: none; inline-size: 12px; display: inline-flex; }
:where(.mb-tree) .tx-nm {
  flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text);
}
:where(.mb-tree) .tx-row--root .tx-nm { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
:where(.mb-tree) .tx-row--d1 .tx-nm { font-size: var(--fs-base); font-weight: var(--fw-semibold); }
:where(.mb-tree) .tx-nm mark { background: var(--warn-soft); color: inherit; border-radius: var(--r-sm); padding: 0 1px; }
:where(.mb-tree) .tx-mark, :where(.mb-tree) .tx-sub { flex: none; }
:where(.mb-tree) .tx-sub { font-variant-numeric: tabular-nums; }
/* تیکِ حالتِ انتخاب: هدفِ ۳۶×۳۶ دورِ چک‌باکسِ کیت، در لبهٔ شروعِ ردیف. */
:where(.mb-tree) .tx-pick {
  position: absolute; inset-inline-start: 8px; top: calc(var(--tx-lh) / 2 - 18px);
  inline-size: 36px; block-size: 36px; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md); cursor: pointer;
}
:where(.mb-tree) .tx-pick:hover { background: var(--surface-3); }

/* ── ستونِ منبع و ویژگی‌ها ─────────────────────────────────────────────────── */
:where(.mb-tree) .tx-c--src { display: flex; align-items: center; }
:where(.mb-tree) .tx-src { white-space: nowrap; }
:where(.mb-tree) .tx-c--feat { display: flex; align-items: center; gap: 6px; overflow: hidden; white-space: nowrap; padding-inline-end: 12px; }
:where(.mb-tree) .tx-cnt { flex: none; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--text); margin-inline-end: 6px; }
:where(.mb-tree) .tx-cnt--par { font-weight: var(--fw-semibold); color: var(--text-2); margin-inline-end: 0; }
:where(.mb-tree) .tx-from, :where(.mb-tree) .tx-none { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-sm); color: var(--muted); }
:where(.mb-tree) .tx-attrs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; overflow: hidden; }
:where(.mb-tree) .tx-attr { flex: none; cursor: default; }
:where(.mb-tree) .tx-attr[hidden], :where(.mb-tree) .tx-more[hidden] { display: none; }
:where(.mb-tree) .tx-more { flex: none; font-variant-numeric: tabular-nums; }

/* ── ستونِ آخر ─────────────────────────────────────────────────────────────── */
:where(.mb-tree) .tx-c--acts { display: flex; align-items: center; justify-content: flex-end; gap: 2px; padding-inline-end: 8px; }
:where(.mb-tree) .tx-hoveracts { display: flex; align-items: center; gap: 2px; opacity: 0; transition: opacity var(--dur-fast) var(--ease); }
:where(.mb-tree) .tx-row:hover .tx-hoveracts, :where(.mb-tree) .tx-row:focus-within .tx-hoveracts { opacity: 1; }
@media (hover: none) { :where(.mb-tree) .tx-hoveracts { opacity: 1; } }
:where(.mb-tree) .tx-c--sel { display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-2); padding-inline-end: 12px; min-width: 0; }

/* ── ردیفِ افزودنِ درجا ───────────────────────────────────────────────────── */
:where(.mb-tree) .tx-addin {
  display: flex; align-items: center; gap: var(--tx-gap); min-block-size: 56px;
  padding-inline: calc(var(--tx-base) + var(--tx-x)) 12px;
  grid-column: 1 / -1;
}
:where(.mb-tree) .tx-avph { flex: none; inline-size: 28px; block-size: 28px; border: 1px dashed var(--border-strong); border-radius: var(--r-md); }
:where(.mb-tree) .tx-addinput { flex: 1; min-width: 0; max-inline-size: 340px; }
:where(.mb-tree) .tx-kbd { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }

/* ── راهنما و حالت‌های خالی ───────────────────────────────────────────────── */
.mb-tree__legend { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) 18px; font-size: var(--fs-xs); color: var(--muted); }
:where(.mb-tree__legend) .tx-lg { display: inline-flex; align-items: center; gap: 6px; }

/* ── حبابِ چیپ (تیره) و فهرستِ «+N» (روشن) ─────────────────────────────────── */
.mb-tree__tip { inline-size: 240px; display: flex; flex-direction: column; gap: 3px; white-space: normal; }
:where(.mb-tree__tip) .tx-tip-en { font-size: var(--fs-sm); font-weight: var(--fw-bold); }
:where(.mb-tree__tip) .tx-tip-type { font-size: var(--fs-xs); color: var(--d-text-2); }
:where(.mb-tree__tip) .tx-tip-desc { font-size: var(--fs-xs); line-height: 1.7; }
:where(.mb-tree__tip) .tx-tip-in { font-size: var(--fs-xs); line-height: 1.7; color: var(--d-warn-text); border-top: 1px solid var(--d-border-strong); padding-top: 5px; margin-top: 3px; }
.mb-tree__pop { inline-size: 288px; max-inline-size: calc(100vw - 16px); z-index: var(--z-popover); display: flex; flex-direction: column; }
/* ‎display: flex‎ بالا ویژگیِ ‎hidden‎ را بی‌اثر می‌کرد: JS پنهانشان می‌کرد ولی
   روی صفحه می‌ماندند («پاپ‌آپِ +N باز می‌شود و بسته نمی‌شود»). */
.mb-tree__tip[hidden], .mb-tree__pop[hidden] { display: none; }
:where(.mb-tree__pop) .tx-pop-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-block-size: 40px; padding-inline: 8px 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); }
:where(.mb-tree__pop) .tx-pop-list { max-block-size: 252px; overflow-y: auto; display: flex; flex-direction: column; }
:where(.mb-tree__pop) .tx-pop-item { display: flex; align-items: center; flex-wrap: wrap; gap: 2px var(--sp-2); padding: 7px 6px; font-size: var(--fs-sm); border-top: 1px solid var(--border-soft); }
:where(.mb-tree__pop) .tx-pop-en { font-size: var(--fs-xs); color: var(--muted); }
:where(.mb-tree__pop) .tx-pop-type { margin-inline-start: auto; }
:where(.mb-tree__pop) .tx-pop-in { flex-basis: 100%; font-size: var(--fs-xs); color: var(--warn-text); }
:where(.mb-tree__pop) .tx-pop-foot { padding: 8px; border-top: 1px solid var(--border-soft); font-size: var(--fs-xs); color: var(--muted); }

/* ── حالتِ انتخاب زودتر دوخطی می‌شود ──────────────────────────────────────────
   چهار ستون (نام · منبع · ویژگی‌ها · انتخاب) در کارتِ صفحهٔ برند (~۸۵۰) جا
   نمی‌شوند و نام به «سرو…» می‌رسید. زیرِ ۱۲۰۰ نام تمام‌عرض می‌ماند و منبع،
   ویژگی‌ها و «N انتخاب»/گزینه‌ها خطِ دومِ همان ردیف‌اند. */
@container txtree (max-width: 1199px) {
  .mb-tree--pick .tx-head { display: none; }
  .mb-tree--pick .tx-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "name name name" "src feat acts";
    align-items: start;
  }
  .mb-tree--pick .tx-c--name { grid-area: name; }
  .mb-tree--pick .tx-c--src { grid-area: src; padding-inline: calc(var(--tx-base) + var(--tx-x) + var(--tx-cw) + var(--tx-gap)) 6px; }
  .mb-tree--pick .tx-c--feat { grid-area: feat; }
  .mb-tree--pick .tx-c--sel { grid-area: acts; }
  .mb-tree--pick .tx-c--src, .mb-tree--pick .tx-c--feat, .mb-tree--pick .tx-c--sel { block-size: 30px; padding-bottom: 8px; }
}
/* ── تبلت: هر ردیف دو خط (نام / منبع + ویژگی‌ها) ───────────────────────────── */
@container txtree (max-width: 899px) {
  .mb-tree { --tx-base: 12px; --tx-s1: 24px; --tx-s2: 18px; --tx-lh: 48px; --tx-lh-root: 54px; }
  .mb-tree--pick { --tx-base: 48px; }
  :where(.mb-tree) .tx-head { display: none; }
  :where(.mb-tree) .tx-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "name name acts" "src feat acts";
    align-items: start;
  }
  /* انتخاب: نام تمام‌عرض، و خطِ دوم ویژگی‌ها + «N انتخاب»/گزینه‌ها — ستونِ
     انتخاب دیگر کنارِ نام نمی‌نشیند تا نام را به «س…» نرساند. */
  .mb-tree--pick .tx-row { grid-template-areas: "name name name" "src feat acts"; }
  .mb-tree--pick .tx-c--sel { block-size: 30px; padding-bottom: 8px; }
  :where(.mb-tree) .tx-c--name { grid-area: name; }
  :where(.mb-tree) .tx-c--src { grid-area: src; }
  :where(.mb-tree) .tx-c--feat { grid-area: feat; }
  :where(.mb-tree) .tx-c--acts, :where(.mb-tree) .tx-c--sel { grid-area: acts; block-size: var(--tx-lh); }
  :where(.mb-tree) .tx-c--src, :where(.mb-tree) .tx-c--feat { block-size: 30px; padding-bottom: 8px; }
  /* خطِ دوم زیرِ نام می‌نشیند، نه زیرِ تاشو. */
  :where(.mb-tree) .tx-c--src { padding-inline: calc(var(--tx-base) + var(--tx-x) + var(--tx-cw) + var(--tx-gap)) 6px; }
  :where(.mb-tree) .tx-hoveracts { opacity: 1; }
  :where(.mb-tree) .tx-optlbl { display: none; }
}
/* ── گوشی: فقط ⋮ (افزودن و ویرایش هم داخلِ منو)، تورفتگیِ فشرده ─────────── */
@container txtree (max-width: 559px) {
  .mb-tree { --tx-base: 8px; --tx-s1: 16px; --tx-s2: 16px; --tx-cw: 24px; --tx-gap: 8px; --tx-lh: 46px; --tx-lh-root: 52px; }
  .mb-tree--pick { --tx-base: 44px; }
  :where(.mb-tree) .tx-hoveracts, :where(.mb-tree) .tx-name-en, :where(.mb-tree) .tx-sub-all, :where(.mb-tree) .tx-kbd, :where(.mb-tree) .tx-avph { display: none; }
  /* «N زیرشاخه» فقط روی ریشه: پایین‌تر تاشو خودش می‌گوید زیرشاخه هست، و آن
     ۷۰ پیکسل همان جایی است که نامِ شاخه لازم دارد. */
  :where(.mb-tree) .tx-row:not(.tx-row--root) .tx-sub { display: none; }
  :where(.mb-tree) .tx-row--root .tx-nm { font-size: var(--fs-base); }
  /* گوشی در حالتِ انتخاب: ویژگی‌ها جا نمی‌شوند؛ خطِ دوم مالِ انتخاب است. */
  .mb-tree--pick .tx-row { grid-template-areas: "name name" "acts acts"; }
  .mb-tree--pick .tx-c--feat, .mb-tree--pick .tx-c--src { display: none; }
  .mb-tree--pick .tx-c--sel { justify-content: flex-start; padding-inline-start: calc(var(--tx-base) + var(--tx-x) + var(--tx-cw) + var(--tx-gap)); }
  :where(.mb-tree) .tx-addinput { max-inline-size: none; }
}

/* ══ kit/tail.css ══════════════════════════════════════════════════════
 * فراگیرها — فوکوس، کفِ لمس، حرکت‌زدایی. عمداً آخر، چون باید بر همه بنشینند.
 *
 * تکه‌ای از کیت. سرور هر پنج طبقه را به همین ترتیب به‌هم می‌چسباند و روی
 * /primitives.css سرو می‌کند، پس ترتیبِ طبقه‌ها همان ترتیبِ آبشار است:
 * base → atoms → molecules → blocks → tail.  (tools/kit-css.js)
 */

.mb-bar[hidden], .mb-list[hidden], .mb-status[hidden], .mb-chip[hidden],
.mb-btn[hidden], .mb-seg[hidden], .mb-stat[hidden], .mb-stats[hidden], .mb-iconbox[hidden],
.mb-dot[hidden], .mb-switch[hidden], .mb-steps[hidden], .mb-pager[hidden], .mb-field[hidden],
.mb-note[hidden], .mb-wait[hidden], .mb-sk[hidden], .mb-frame[hidden],
.mb-check[hidden], .mb-drop[hidden], .mb-avatar[hidden], .mb-tabs[hidden], .mb-minmax[hidden] { display: none; }
/* زبانه و گزینهٔ منو هم ‎display: inline-flex‎ِ خانوادهٔ «آیتم» را دارند و [hidden]ِ مرورگر را
   می‌باختند: MB.tabs زبانهٔ پنهان را «خاموش» حساب می‌کرد ولی دیده می‌شد — کلیکِ بی‌جواب
   (پروفایلِ محصول، «موجودی» برای کالای بی‌موجودی، ۱۴۰۵/۰۷/۱۵). */
.mb-tabs__tab[hidden], .mb-menu__item[hidden] { display: none; }

@keyframes mbProgress { from { transform: translateX(-120%); } to { transform: translateX(320%); } }

/* ── ۷) فوکوس، یک‌بار برای همه ─────────────────────────────────────────────
   سراسری و بی‌پیشوند، عمداً: ۹ فایل outline:none داشتند و هر کدام حلقهٔ
   خودشان را از نو ساخته بودند. حلقهٔ داخلیِ ۱px هم‌رنگِ سطح، کنتراست را روی
   هر زمینه‌ای تضمین می‌کند. */
/* ‎.mb-card--link‎ اینجا اضافه شد و نه با قاعده‌ای دوم: کارتِ پیوندی تا امروز
   حلقه نداشت، چون این فهرست فقط ‎[tabindex]‎ را می‌شناخت و ‎<a>‎ خودش فوکوس‌پذیر
   است. ‎:where()‎ وزنِ صفر دارد، پس افزودنِ یک نام چیزی را جابه‌جا نمی‌کند. */
:where(.mb-btn, .mb-seg__btn, .mb-chip[tabindex], .mb-card[tabindex], .mb-card--link, .mb-menu__item, .mb-step, .mb-range, .mb-tabs__tab, .mb-modal [tabindex]):focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  box-shadow: inset 0 0 0 1px var(--surface);
}

/* ── ۱۰) لمس یک حالت است ───────────────────────────────────────────────────
   کفِ ۴۴ و متنِ ۱۶ برای ورودی (سافاری روی کمتر زوم می‌کند)، فقط اینجا. */
@media (max-width: 1024px) {
  .mb-btn, .mb-input, .mb-select { min-height: var(--ctl-h-touch); }
  .mb-btn--icon { inline-size: var(--ctl-h-touch); min-inline-size: var(--ctl-h-touch); }
  /* پلهٔ ریز هم به کفِ ۴۴ می‌رسد (۴۰ِ قبلی زیرِ کفِ خودِ پروژه بود و صفحه‌های
     مهاجرت‌شده پیش از کیت ۴۴ داشتند). استثنا دیگر یک *کلاسِ اندازه* نیست، یک
     *بافت* است: پایین‌تر، دکمهٔ ریزِ داخلِ جدول ریز می‌مانَد. تا دیروز --xs این
     نقش را داشت و هر صفحه خودش باید می‌فهمید کِی ریز و کِی کوچک — همان چیزی که
     پنج اندازه ساخت. */
  .mb-btn--sm { min-height: var(--ctl-h-touch); }
  .mb-btn--icon.mb-btn--sm { inline-size: var(--ctl-h-touch); min-inline-size: var(--ctl-h-touch); }
  /* کنترلِ فشرده هم همان مسیرِ دکمهٔ فشرده را می‌رود: روی لمس به ۴۴ می‌رسد.
     قاعدهٔ بالا (هم‌وزن و پیش‌تر) این را از قبل می‌کرد؛ صریح نوشته شده تا
     «کفِ لمسی» جایی خوانده شود که دنبالش می‌گردند، نه از ترتیبِ فایل. */
  .mb-input--sm, .mb-select--sm { min-height: var(--ctl-h-touch); }
  /* استثنا: در بافتِ چگال (سلولِ جدول)، کنترلِ فشرده فشرده می‌ماند. ده ردیفِ
     ۴۴ پیکسلی جدول را نمی‌خوانَد و صفحه‌ها پیش از کیت هم همین استثنا را داشتند
     (ویزاردِ ورود، جدولِ تصمیم). ظرف را `.mb-dense` کنید — نه اینکه قد را از
     CSSِ صفحه بنویسید. هدفِ لمسیِ جدا لازم است؟ کنترل را از سلول بیرون ببرید. */
  :where(.mb-table, .mb-dense) :is(.mb-input--sm, .mb-select--sm, .mb-textarea--sm) { min-height: var(--ctl-h-sm); }
  /* و همان استثنا برای دکمه: ده ردیفِ ۴۴ پیکسلی جدول را نمی‌خوانَد. */
  :where(.mb-table, .mb-dense) :is(.mb-btn--sm) { min-height: var(--ctl-h-sm); }
  :where(.mb-table, .mb-dense) .mb-btn--icon.mb-btn--sm { inline-size: var(--ctl-h-sm); min-inline-size: var(--ctl-h-sm); }
  /* و برعکس: جدولی که روی لمس *کارت* می‌شود (ردیف = کارت، خانه = سطرِ «برچسب
     ⟷ مقدار» — مثلِ ردیف‌های فاکتور) دیگر دادهٔ متراکم نیست، پس ورودیِ کیت
     داخلش کفِ لمسی را پس می‌گیرد. ظرف را `.mb-cards` کنید. وزن عمداً از
     بازنشانیِ «کنترل داخلِ جدول» در nav.css ‎(۰,۳,۱)‎ بیشتر است — آن قاعده هر
     ورودیِ داخلِ ‎<table>‎ را به ‎min-height: 0‎ می‌برد و کادرِ درصدیِ فاکتور
     روی گوشی ۲۴ پیکسل می‌شد (۱۴۰۵/۰۷/۱۹). تکرارِ کلاس ‎(۰,۴,۰)‎ همان وزن را
     می‌دهد و گزینشگر با ‎.mb-‎ شروع می‌شود (قانونِ ۵ِ ui-constitution). */
  .mb-cards.mb-cards.mb-cards :is(.mb-input, .mb-select) { min-height: var(--ctl-h-touch); }
  /* سگمنت: هر گزینه خودش یک هدفِ لمس است، پس کف روی خودِ دکمه — نه فقط روی
     ظرفِ سگمنت. ظرف ارتفاعِ ثابت ندارد، پس با همین کف بالا می‌آید. عدد از
     `--ctl-h-touch` می‌آید نه از دست: ۴۰ِ قبلی زیرِ کفِ لمسیِ خودِ پروژه بود و
     صفحهٔ کتابخانه ناچار بود همان‌جا وصله‌اش کند — همان تکراری که برداشته شد. */
  .mb-seg__btn { min-height: var(--ctl-h-touch); min-inline-size: var(--ctl-h-touch); }
  /* زبانه همان: هر زبانه یک هدفِ لمس است. */
  .mb-tabs__tab { min-height: var(--ctl-h-touch); }
  /* آیتمِ منو هم هدفِ لمس است (۱۴۰۵/۰۷، منوی ⋮ و برگهٔ پایینیِ درختِ شاخه‌ها):
     بی‌این کف، گزینه‌ای مثلِ «حذف…» روی تبلت ۳۲ پیکسل بود. */
  .mb-menu__item { min-height: var(--ctl-h-touch); }
  .mb-input, .mb-select, .mb-textarea { font-size: var(--fs-lg); }
  .mb-chip { min-height: 28px; font-size: var(--fs-xs); }
  /* شمارنده استثناست: نشان است نه هدفِ لمس — کفِ ۲۸ رویش یک قرصِ گندهٔ
     بی‌کار می‌سازد. همان استثنایی که پلهٔ ریزِ دکمه دارد. */
  .mb-chip--count { min-height: 18px; }
  .mb-modal { padding: 0; align-items: end; }
  .mb-modal__box { inline-size: 100%; max-block-size: 92dvh; border-radius: var(--r-xl) var(--r-xl) 0 0; }
  /* اندازه‌ها (۰,۲,۰) قاعدهٔ بالا (۰,۱,۰) را می‌بردند: میانِ ۶۸۱ و ۱۰۲۴ مودالِ
     پهن یک برگهٔ پایینیِ ۶۸۰ پیکسلی می‌شد، نه تمام‌عرض. هم‌وزن و بعدتر، پس می‌بَرد. */
  .mb-modal--sm .mb-modal__box, .mb-modal--wide .mb-modal__box, .mb-modal--xwide .mb-modal__box { inline-size: 100%; }
  /* لایت‌باکس برگهٔ پایینی نمی‌شود: تصویر باید وسطِ صفحه و با حاشیه بنشیند،
     وگرنه روی موبایل به لبهٔ پایین می‌چسبد و گوشه‌هایش بریده می‌شود. */
  .mb-modal--bare { padding: var(--sp-3); align-items: center; }
  .mb-modal--bare .mb-modal__box { inline-size: auto; border-radius: 0; }
}

@media (max-width: 640px) {
  .mb-modal__foot { flex-direction: column-reverse; }
  .mb-modal__foot .mb-btn { inline-size: 100%; }
  /* پاورقیِ دوکنشهٔ کوتاه (تایید / رد، ذخیره / انصراف — پروفایلِ محصول، ۱۴۰۵/۰۷/۱۳): دو
     دکمهٔ تمام‌عرضِ روی‌هم یک‌سومِ صفحهٔ گوشی را می‌گرفت. کنارِ هم و هم‌عرض می‌مانند؛ هر
     چیزِ دیگرِ پاورقی (یادداشت، وضعیت) سطرِ خودش را بالای آن‌ها می‌گیرد. */
  .mb-modal__foot--inline { flex-direction: row; flex-wrap: wrap; }
  .mb-modal__foot--inline .mb-btn { inline-size: auto; flex: 1 1 0; }
  .mb-modal__foot--inline > :not(.mb-btn) { flex: 1 0 100%; }
  /* گروهِ تنظیمات ستونی می‌شود: دو محورِ عمودی در ۳۲۶ پیکسل، بدونِ شکستنِ کفِ
     لمسیِ ۴۴، جا نمی‌شود. عمداً *اینجا* و نه بالاتر در فایل: ویژگیِ گزینشگرها
     یکی است و ترتیبِ منبع تصمیم می‌گیرد؛ بلوکِ ۶۴۰ِ بالاتر، زیرِ ۶۴۰ بازندهٔ
     قاعده‌های پایه می‌شد. */
  .mb-group__body .mb-field { flex-direction: column; align-items: stretch; gap: var(--sp-1); }
  .mb-group__body .mb-field__label { flex: 0 0 auto; }
  .mb-group__body .mb-field > .mb-input,
  .mb-group__body .mb-field > .mb-select,
  .mb-group__body .mb-field > .mb-textarea,
  .mb-group__body .mb-field > .mb-seg,
  .mb-group__body .mb-field > .mb-bar,
  .mb-group__body .mb-field > .mb-switch { flex: 0 0 auto; inline-size: 100%; }
}

/* ── ۱۱) حرکت‌زدایی ─────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .mb-btn, .mb-input, .mb-select, .mb-textarea, .mb-seg__btn, .mb-status--fade,
  .mb-hint, .mb-step, .mb-progress__fill, .mb-card--link, .mb-tabs__tab { transition: none; }
  /* بلندشدنِ کارت زیرِ نشانگر هم حرکت است، نه فقط گذار. */
  .mb-card--link:hover { transform: none; }
  .mb-progress--indeterminate .mb-progress__fill { animation: none; inline-size: 100%; }
  /* حلقهٔ انتظار کند می‌شود، نه اینکه بایستد: کاربری که «حرکتِ کمتر» خواسته
     نباید *لودینگ* را از دست بدهد — نایستادنِ حلقه تنها نشانهٔ «هنوز کار
     دارد انجام می‌شود» است. سه صفحه قبلاً animation: none می‌گذاشتند و
     همان‌ها بودند که کاربرِ کم‌حرکت را جلوی یک صفحهٔ بی‌نشانه می‌گذاشتند.
     یک قاعده اینجا، هر هجده جایی را که به .mb-wait مهاجرت کرد می‌پوشاند. */
  .mb-wait__spin { animation-duration: 2.4s; }
}
