/* ==========================================================================
   نظام طراحی مشترک — پایه ظاهری پنل، صفحه ورود و ادمین
   ==========================================================================

   این فایل پیش از هر شیت دیگری بارگذاری می‌شود و سه چیز می‌دهد: فونت فارسی
   میزبانی‌شده، توکن‌های رنگ و فاصله، و اجزای مشترک (دکمه، کارت، جدول، فرم، پیام).
   شیت‌های بعدی (`panel.css`، `auth.css`، `admin-fa.css`) فقط چیدمان صفحه خودشان
   را می‌سازند و رنگ و اندازه را از همین توکن‌ها می‌گیرند.

   ── پالت رنگ ─────────────────────────────────────────────────────────────
   رنگ‌ها از نشان شرکت گرفته شده‌اند: دایره نشان آبی روشن است و علامت مشکی. همان
   آبی تا انتهای مقیاس تیره شده تا رنگ «نقشه‌کشی» (blueprint) به دست آید که برای
   کار ساختمان و آزمایشگاه، هم حرفه‌ای است و هم آشنا. رنگ مکمل، کهربایی ایمنی
   (hi-vis) است — همان زرد جلیقه و کلاه کارگاه — که گرمی و صمیمیت می‌آورد و
   خنثی‌بودن آبی را می‌شکند. خاکستری‌ها کمی گرم‌اند تا حس بتن بدهند، نه فلز سرد.

   ── قاعده RTL ────────────────────────────────────────────────────────────
   همه فاصله‌ها و مرزهای جهت‌دار با ویژگی‌های منطقی نوشته می‌شوند
   (`margin-inline-start`, `border-inline-end`, `inset-inline-start`) نه
   `left/right`. پس اگر روزی صفحه‌ای LTR شود، چیدمان خودش برمی‌گردد.

   ── قاعده افزایشی ────────────────────────────────────────────────────────
   🔴 هیچ توکن یا کلاسی از این فایل حذف یا تغییرنام نمی‌شود. `auth.css`،
   `admin-fa.css` و `print.css` از همین‌ها می‌خورند و قالب‌های موجود به همین
   کلاس‌ها نوشته شده‌اند؛ بازطراحی «افزودن و تقویت» است، نه «جای‌گزینی نام».
   ========================================================================== */

/* --- فونت فارسی -----------------------------------------------------------
   تعریف `@font-face` در `fonts.css` است و پیش از این فایل بارگذاری می‌شود، چون
   ادمین جنگو هم همان فونت را می‌خواهد ولی بقیه این شیت را نباید بگیرد. */

:root {
    color-scheme: light;

    /* --- آبی نقشه‌کشی (رنگ اصلی) --- */
    --brand-50:  #f1f7fd;
    --brand-100: #dceafb;      /* همان آبی روشن نشان شرکت */
    --brand-200: #bfd9f3;
    --brand-300: #93bde6;
    --brand-400: #5f9bd4;
    --brand-500: #3b7cbb;
    --brand-600: #2b619c;
    --brand-700: #234f81;      /* رنگ اصلی رابط */
    --brand-800: #1c3f68;
    --brand-900: #16324f;
    --brand-950: #0f2438;

    /* --- کهربایی ایمنی (رنگ مکمل) --- */
    --accent-50:  #fff9ec;
    --accent-100: #fef1d3;
    --accent-200: #fde3a8;
    --accent-300: #fbbf24;
    --accent-400: #f5ab0d;
    --accent-500: #ed9a09;
    --accent-600: #c97a06;
    --accent-700: #9a5c07;

    /* --- خاکستری‌های بتنی --- */
    --ink:          #111820;
    --ink-soft:     #33404f;
    --muted:        #64707e;
    --muted-light:  #93a0ae;
    --line:         #e5e9ef;
    --line-strong:  #cfd6e0;
    --surface:      #ffffff;
    --surface-2:    #f7f9fc;
    --surface-3:    #eff3f8;
    --surface-4:    #e6ecf4;
    --bg:           #eff2f7;

    /* --- رنگ‌های معنایی --- */
    --success:     #15803d;
    --success-bg:  #eefbf2;
    --success-line:#bbe9cb;
    --success-ink: #0f5f2d;
    --warning:     #92590e;
    --warning-bg:  #fff8ec;
    --warning-line:#f8dfae;
    --warning-ink: #7a4909;
    --danger:      #b3261e;
    --danger-bg:   #fdf2f1;
    --danger-line: #f4c9c5;
    --danger-ink:  #8f1e17;
    --info:        var(--brand-700);
    --info-bg:     var(--brand-50);
    --info-line:   var(--brand-200);
    --neutral:     var(--muted);
    --neutral-bg:  var(--surface-3);
    --neutral-line:var(--line-strong);

    /* --- شکل و سایه --- */
    --r-xs:   6px;
    --r-sm:   8px;
    --r:      12px;
    --r-lg:   16px;
    --r-xl:   20px;
    --r-pill: 999px;

    --shadow-1: 0 1px 2px rgba(17, 24, 32, .04), 0 1px 3px rgba(17, 24, 32, .06);
    --shadow-2: 0 2px 6px rgba(17, 24, 32, .06), 0 8px 20px rgba(17, 24, 32, .07);
    --shadow-3: 0 10px 40px rgba(17, 24, 32, .18);
    --shadow-4: 0 24px 60px rgba(17, 24, 32, .24);
    --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, .12);

    --ring:        0 0 0 3px rgba(59, 124, 187, .28);
    --ring-danger: 0 0 0 3px rgba(179, 38, 30, .22);
    --ring-success:0 0 0 3px rgba(21, 128, 61, .20);

    /* --- فاصله (چگالی داشبورد) --- */
    --s-1:  4px;
    --s-2:  8px;
    --s-3:  12px;
    --s-4:  16px;
    --s-5:  20px;
    --s-6:  24px;
    --s-8:  32px;
    --s-10: 40px;
    --s-12: 48px;

    /* --- مقیاس متن --- */
    --fs-2xs: 11px;
    --fs-xs:  12px;
    --fs-sm:  13px;
    --fs-base:14px;
    --fs-md:  15px;
    --fs-lg:  17px;
    --fs-xl:  20px;
    --fs-2xl: 24px;
    --fs-3xl: 30px;

    --fw-normal:   400;
    --fw-medium:   500;
    --fw-semibold: 600;
    --fw-bold:     700;

    /* --- ترتیب لایه‌ها --- */
    --z-base:     1;
    --z-sticky:   20;
    --z-topbar:   40;
    --z-backdrop: 50;
    --z-drawer:   60;
    --z-popover:  70;
    --z-modal:    80;
    --z-toast:    90;

    /* --- چیدمان پوسته --- */
    --topbar-h:            60px;
    --sidebar-w:           252px;
    --sidebar-w-collapsed: 66px;
    --content-max:         1600px;

    /* --- حرکت --- */
    --t-fast: .14s ease;
    --t:      .22s ease;
    --t-slow: .34s cubic-bezier(.22, .61, .36, 1);

    --font-fa: 'Vazirmatn', 'IRANSans', 'Segoe UI', Tahoma, sans-serif;
}

/* کاربری که «حرکت کمتر» را در سیستمش خواسته، انیمیشن نمی‌بیند (دسترس‌پذیری) */
@media (prefers-reduced-motion: reduce) {
    :root { --t-fast: 0s; --t: 0s; --t-slow: 0s; }
    * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   پایه
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-fa);
    font-size: 14.5px;
    line-height: 1.8;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { line-height: 1.5; font-weight: var(--fw-semibold); }

a { color: var(--brand-700); }
a:hover { color: var(--brand-800); }

/* عدد در جدول و مبلغ باید هم‌عرض باشد تا ستون‌ها هم‌تراز خوانده شوند */
table, .num, [dir='ltr'] { font-variant-numeric: tabular-nums; }

/* حلقه تمرکز یکسان و همیشه دیدنی — شرط دسترس‌پذیری با صفحه‌کلید */
:focus-visible {
    outline: 2px solid var(--brand-500);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

::selection { background: var(--brand-200); color: var(--brand-900); }

/* نوار پیمایش باریک و کم‌رنگ */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: var(--r-pill);
    border: 3px solid transparent;
    background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--muted-light); background-clip: content-box; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* پرش به محتوا — نخستین چیزی که کاربر صفحه‌کلید می‌گیرد */
.skip-link {
    position: absolute;
    inset-block-start: -100px;
    inset-inline-start: var(--s-3);
    z-index: var(--z-toast);
    background: var(--brand-700);
    color: #fff;
    padding: 9px 16px;
    border-radius: 0 0 var(--r-sm) var(--r-sm);
    font-size: var(--fs-sm);
    text-decoration: none;
    transition: inset-block-start var(--t-fast);
}

.skip-link:focus { inset-block-start: 0; color: #fff; }

/* متن بلندی که نباید ستون را بکشد */
.truncate {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ==========================================================================
   دکمه
   ==========================================================================
   یک پایه و چند گونه. اندازه لمسی روی صفحه کوچک خودکار بزرگ می‌شود (بند ۲
   راهنمای دسترس‌پذیری: هدف لمسی کمتر از ۴۴ پیکسل نباشد).
   ========================================================================== */

.btn {
    --btn-bg:      var(--brand-700);
    --btn-bg-hover:var(--brand-800);
    --btn-fg:      #fff;
    --btn-border:  transparent;

    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 8px 16px;
    min-block-size: 38px;
    border: 1px solid var(--btn-border);
    border-radius: var(--r-sm);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: var(--fw-medium);
    line-height: 1.7;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: var(--shadow-1), var(--shadow-inset);
    transition: background var(--t-fast), border-color var(--t-fast),
                box-shadow var(--t-fast), transform var(--t-fast), color var(--t-fast);
}

.btn:hover { background: var(--btn-bg-hover); color: var(--btn-fg); }
.btn:active { transform: translateY(1px); box-shadow: none; }
.btn:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

.btn:disabled, .btn[aria-disabled='true'], .btn.is-disabled {
    background: var(--surface-3);
    border-color: var(--line);
    color: var(--muted-light);
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

/* گونه خطی — کنش دوم */
.btn--ghost {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--surface-2);
    --btn-fg: var(--ink-soft);
    --btn-border: var(--line-strong);
    box-shadow: var(--shadow-1);
}

.btn--ghost:hover { border-color: var(--brand-300); color: var(--brand-800); }

/* گونه رنگ‌آمیز کم‌رنگ — کنش سوم، برای وقتی چند دکمه کنار هم‌اند */
.btn--soft {
    --btn-bg: var(--brand-50);
    --btn-bg-hover: var(--brand-100);
    --btn-fg: var(--brand-800);
    --btn-border: var(--brand-200);
    box-shadow: none;
}

/* گونه بی‌کادر — کنش کم‌اهمیت داخل ردیف و کارت */
.btn--quiet {
    --btn-bg: transparent;
    --btn-bg-hover: var(--surface-3);
    --btn-fg: var(--muted);
    --btn-border: transparent;
    box-shadow: none;
}

.btn--quiet:hover { color: var(--ink-soft); }

.btn--accent {
    --btn-bg: var(--accent-500);
    --btn-bg-hover: var(--accent-600);
    --btn-fg: #22160a;
}

.btn--danger {
    --btn-bg: var(--danger);
    --btn-bg-hover: var(--danger-ink);
}

.btn--danger:focus-visible { outline-color: var(--danger); }

/* گونه خطی خطرناک — حذف که نباید مثل کنش اصلی جلب توجه کند */
.btn--danger-ghost {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--danger-bg);
    --btn-fg: var(--danger);
    --btn-border: var(--danger-line);
    box-shadow: none;
}

.btn--success {
    --btn-bg: var(--success);
    --btn-bg-hover: var(--success-ink);
}

.btn--xs { padding: 3px 9px; min-block-size: 28px; font-size: var(--fs-xs); gap: 5px; }
.btn--sm { padding: 5px 11px; min-block-size: 32px; font-size: 12.5px; }
.btn--lg { padding: 11px 22px; min-block-size: 46px; font-size: var(--fs-md); }
.btn--block { width: 100%; }

/* دکمه آیکونی — همیشه با `aria-label` */
.btn--icon {
    padding: 0;
    inline-size: 34px;
    min-block-size: 34px;
    block-size: 34px;
    gap: 0;
}

.btn--icon.btn--sm { inline-size: 30px; block-size: 30px; min-block-size: 30px; }
.btn--icon.btn--lg { inline-size: 42px; block-size: 42px; min-block-size: 42px; }
.btn--icon .ico { font-size: 1.05em; }

/* حالت «در حال ارسال» — `panel-ui.js` روی ارسال فرم می‌گذارد */
.btn.is-loading { color: transparent !important; pointer-events: none; }

.btn.is-loading::after {
    content: '';
    position: absolute;
    inset: 50% auto auto 50%;
    inline-size: 15px;
    block-size: 15px;
    margin: -8px 0 0 -8px;
    border: 2px solid currentColor;
    border-radius: 50%;
    border-block-start-color: transparent;
    color: #fff;
    animation: zn-spin .6s linear infinite;
}

.btn--ghost.is-loading::after, .btn--soft.is-loading::after, .btn--quiet.is-loading::after {
    color: var(--brand-700);
}

@keyframes zn-spin { to { transform: rotate(360deg); } }

/* ==========================================================================
   نوار ابزار و ردیف کنش‌ها
   ==========================================================================
   جای `<p><a class="btn">…</a> <a class="btn">…</a></p>`. روی صفحه کوچک
   دکمه‌ها تمام‌عرض می‌شوند تا هدف لمسی درست بماند.
   ========================================================================== */

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin-block-end: var(--s-4);
}

.toolbar__group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.toolbar__group--end { margin-inline-start: auto; }
.toolbar__sep { inline-size: 1px; block-size: 22px; background: var(--line); }
.toolbar__label { font-size: var(--fs-sm); color: var(--muted); }

/* 🔴 نوار ابزاری که برای این کاربر هیچ کنشی ندارد نباید فاصله خالی بگذارد.
   کنش‌ها معمولاً هرکدام `{% if %}` خودشان را دارند، پس برای کاربری با هیچ
   اجازه‌ای، پوشش می‌ماند و محتوایش خالی است — ۱۶ پیکسل فاصله بی‌دلیل. `:empty`
   کار نمی‌کند چون فاصله سفید قالب درون عنصر است، پس با `:has()` سنجیده می‌شود. */
.toolbar:not(:has(a, button, input, select, label, span, p, form)),
.toolbar__group:not(:has(a, button, input, select, label, span, p, form)),
.page-head__actions:not(:has(a, button, input, select, label, span, p, form)) {
    display: none;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin-block-start: var(--s-5);
    padding-block-start: var(--s-4);
    border-block-start: 1px solid var(--line);
}

.form-actions--plain { border-block-start: none; padding-block-start: 0; }

/* ==========================================================================
   نشان (badge)، تراشه و برچسب وضعیت
   ========================================================================== */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--brand-100);
    color: var(--brand-800);
    border-radius: var(--r-pill);
    padding: 2px 11px;
    font-size: 12px;
    font-weight: var(--fw-medium);
    white-space: nowrap;
}

.badge--muted   { background: var(--surface-3); color: var(--muted); }
.badge--accent  { background: var(--accent-100); color: var(--accent-700); }
.badge--success { background: var(--success-bg); color: var(--success); }
.badge--warning { background: var(--warning-bg); color: var(--warning); }
.badge--danger  { background: var(--danger-bg); color: var(--danger); }
.badge--info    { background: var(--info-bg); color: var(--info); }
.badge--solid   { background: var(--brand-700); color: #fff; }
.badge--outline { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--ink-soft); }
.badge--count   { min-inline-size: 20px; justify-content: center; padding: 1px 7px; font-variant-numeric: tabular-nums; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--ink-soft);
    font-size: var(--fs-xs);
    white-space: nowrap;
}

.chip--active { border-color: var(--brand-300); background: var(--brand-50); color: var(--brand-800); }

/* --- برچسب وضعیت -----------------------------------------------------------
   🔴 قاعده دسترس‌پذیری: وضعیت هرگز تنها با رنگ گفته نمی‌شود. هر گونه یک آیکون
   هم می‌گیرد (`--pill-ico`) تا کاربر کم‌بینا و چاپ سیاه‌وسفید هم آن را بخواند.
   کلاس‌های قدیمی (`--draft`, `--expert`, `--final`, `--danger`) دست‌نخورده
   کار می‌کنند؛ نام‌های معنایی تازه هم‌ارز آن‌ها اضافه شده‌اند. */

.status-pill {
    --pill-bg:   var(--surface-3);
    --pill-fg:   var(--muted);
    --pill-line: var(--line-strong);
    --pill-ico:  var(--i-dot);

    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 11px;
    border: 1px solid var(--pill-line);
    border-radius: var(--r-pill);
    background: var(--pill-bg);
    color: var(--pill-fg);
    font-size: 12px;
    font-weight: var(--fw-medium);
    line-height: 1.7;
    white-space: nowrap;
}

.status-pill::before {
    content: '';
    inline-size: 1em;
    block-size: 1em;
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--pill-ico) center / contain no-repeat;
    mask: var(--pill-ico) center / contain no-repeat;
}

/* خاکستری — پیش‌نویس، ثبت‌شده (حالت‌های «آغاز زنجیره»، پس مداد) */
.status-pill--draft, .status-pill--registered {
    --pill-bg: var(--surface-3); --pill-fg: var(--ink-soft);
    --pill-line: var(--line-strong); --pill-ico: var(--i-pencil);
}

/* خاکستری خنثی — «تعیین‌نشده»، «خیر»، «غیرفعال»: خط تیره، نه تیک و نه مداد.
   🔴 پیش‌تر این حالت‌ها تیک می‌گرفتند و «خیر» با علامت تأیید دیده می‌شد. */
.status-pill--neutral, .status-pill--muted, .status-pill--inactive {
    --pill-bg: var(--surface-2); --pill-fg: var(--muted);
    --pill-line: var(--line); --pill-ico: var(--i-minus);
}

.status-pill--neutral { --pill-bg: var(--surface-3); --pill-fg: var(--ink-soft); --pill-line: var(--line-strong); }

/* خاکستری کم‌رنگ — بسته‌شده و دیده‌شده، هرکدام با نشانه خودش */
.status-pill--closed { --pill-bg: var(--surface-2); --pill-fg: var(--muted); --pill-line: var(--line); --pill-ico: var(--i-lock); }
.status-pill--read { --pill-bg: var(--surface-2); --pill-fg: var(--muted); --pill-line: var(--line); --pill-ico: var(--i-mail-open); }
.status-pill--skipped { --pill-bg: var(--surface-2); --pill-fg: var(--muted); --pill-line: var(--line); --pill-ico: var(--i-x); }

/* آبی پررنگ — دیده‌نشده؛ باید در ردیف جدول بپرد */
.status-pill--unread {
    --pill-bg: var(--brand-700); --pill-fg: #fff;
    --pill-line: var(--brand-800); --pill-ico: var(--i-mail);
    font-weight: var(--fw-semibold);
}

/* کهربایی — تأیید میانی، در انتظار */
.status-pill--expert, .status-pill--pending, .status-pill--warning {
    --pill-bg: var(--warning-bg); --pill-fg: var(--warning-ink);
    --pill-line: var(--warning-line); --pill-ico: var(--i-hourglass);
}

/* آبی — در جریان */
.status-pill--progress, .status-pill--info, .status-pill--open {
    --pill-bg: var(--brand-50); --pill-fg: var(--brand-800);
    --pill-line: var(--brand-200); --pill-ico: var(--i-activity);
}

/* سبز — تأیید نهایی، فعال، تسویه، پاسخ‌داده */
.status-pill--final, .status-pill--success, .status-pill--active, .status-pill--settled {
    --pill-bg: var(--success-bg); --pill-fg: var(--success-ink);
    --pill-line: var(--success-line); --pill-ico: var(--i-check-circle);
}

/* سرخ — لغو، ناموفق، راکد، ردشده */
.status-pill--danger, .status-pill--failed, .status-pill--cancelled, .status-pill--rejected {
    --pill-bg: var(--danger-bg); --pill-fg: var(--danger-ink);
    --pill-line: var(--danger-line); --pill-ico: var(--i-x-circle);
}

.status-pill--idle { --pill-bg: var(--danger-bg); --pill-fg: var(--danger-ink); --pill-line: var(--danger-line); --pill-ico: var(--i-alert); }

/* گونه بی‌آیکون، وقتی جا تنگ است */
.status-pill--bare::before { display: none; }

/* نقطه زنده — «آنلاین»، «حاضر» */
.status-dot {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-xs);
    color: var(--muted);
}

.status-dot::before {
    content: '';
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--muted-light);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--muted-light) 22%, transparent);
}

.status-dot--online::before { background: var(--success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 20%, transparent); }
.status-dot--busy::before   { background: var(--accent-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-500) 20%, transparent); }
.status-dot--off::before    { background: var(--muted-light); }

/* ==========================================================================
   کارت
   ========================================================================== */

.card {
    position: relative;
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: 16px 18px;
    background: var(--surface);
    box-shadow: var(--shadow-1);
}

.card--disabled { opacity: .72; box-shadow: none; background: var(--surface-2); }
.card--flat { box-shadow: none; }
.card--tinted { background: linear-gradient(180deg, var(--brand-50), var(--surface) 70%); }

.card__head {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    margin-block-end: var(--s-3);
    padding-block-end: var(--s-3);
    border-block-end: 1px solid var(--line);
}

.card__head--plain { border-block-end: none; padding-block-end: 0; }
.card__head h2, .card__head h3 { margin: 0; font-size: var(--fs-md); color: var(--brand-900); }
.card__head .toolbar, .card__head--actions { margin: 0 0 0 auto; }
.card__body > :first-child { margin-block-start: 0; }
.card__body > :last-child { margin-block-end: 0; }
.card__foot {
    margin-block-start: var(--s-3);
    padding-block-start: var(--s-3);
    border-block-start: 1px solid var(--line);
}

/* 🔴 پیش‌تر `card__icon` یک ایموجی ۲۲ پیکسلی بود. اکنون کاشی رنگ‌شده است و
   آیکون خطی درونش می‌نشیند، پس در همه سیستم‌عامل‌ها یک شکل دیده می‌شود. */
.card__icon {
    display: inline-grid;
    place-items: center;
    inline-size: 38px;
    block-size: 38px;
    border-radius: 10px;
    background: var(--brand-50);
    color: var(--brand-700);
    box-shadow: inset 0 0 0 1px var(--brand-100);
    font-size: 19px;
    line-height: 1;
    flex: 0 0 auto;
}

.card__icon--accent  { background: var(--accent-50); color: var(--accent-600); box-shadow: inset 0 0 0 1px var(--accent-100); }
.card__icon--success { background: var(--success-bg); color: var(--success); box-shadow: inset 0 0 0 1px var(--success-line); }
.card__icon--danger  { background: var(--danger-bg); color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger-line); }
.card__icon--muted   { background: var(--surface-3); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); }

.card__title { display: block; font-size: 14.5px; font-weight: var(--fw-semibold); margin: 10px 0 0; }
.card__label { display: block; font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--muted); }
.card__link { color: var(--brand-700); text-decoration: none; font-size: 13px; }
.card__link:hover { text-decoration: underline; }
.card__soon { font-size: 12px; color: var(--muted-light); }

.card__value {
    display: block;
    margin-top: 6px;
    font-size: 24px;
    font-weight: var(--fw-bold);
    color: var(--brand-800);
    letter-spacing: -.01em;
    line-height: 1.3;
}

.card__hint { display: block; margin-top: 4px; font-size: 12px; color: var(--muted); }

/* کارت شمارشی (KPI) — آیکون گوشه، عدد درشت */
.card--stat { padding: 14px 16px; }
.card--stat .card__icon { position: absolute; inset-block-start: 12px; inset-inline-end: 12px; }
.card--stat .card__value { margin-top: 2px; font-size: 26px; }
.card--stat .card__label { padding-inline-end: 44px; }

/* ==========================================================================
   جدول
   ==========================================================================
   ── قاعده عرض ─────────────────────────────────────────────────────────────
   هر جدول داخل `.table-scroll` می‌نشیند تا خودش بلغزد و صفحه را نکشد. کادر و
   گوشه گرد روی همان پوشش است، پس ردیف‌ها زیر گوشه بریده می‌شوند بی‌آنکه
   `overflow` روی خودِ `<table>` بیفتد.

   ── قاعده موبایل ──────────────────────────────────────────────────────────
   `panel-ui.js` هر جدول «ساده» را روی صفحه کوچک به کارت تبدیل می‌کند: برچسب هر
   سلول از `<thead>` برداشته و در `data-label` گذاشته می‌شود. جدول پیچیده
   (`colspan` در سرستون یا ستون‌های بسیار) لغزان می‌ماند. قالب کاری نمی‌کند.
   ========================================================================== */

.table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    overflow: hidden;
}

/* داخل پوشش لغزان، کادر و گوشه از پوشش می‌آید نه جدول */
.table-scroll > .table { border: none; border-radius: 0; }

.table__caption {
    text-align: start;
    color: var(--muted);
    padding-block-end: 10px;
    font-size: var(--fs-xs);
    caption-side: top;
}

.table th, .table td {
    padding: 10px 12px;
    text-align: start;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

.table thead th {
    background: var(--surface-2);
    font-weight: var(--fw-semibold);
    color: var(--ink-soft);
    font-size: 12.5px;
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: var(--z-base);
    border-block-end: 1px solid var(--line-strong);
}

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background var(--t-fast), box-shadow var(--t-fast); }
.table tbody tr:hover { background: var(--brand-50); }
.table tbody tr:focus-within { background: var(--brand-50); }

/* ردیف‌های زوج کم‌رنگ — خواندن جدول‌های پرستون را آسان می‌کند */
.table--zebra tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface-2) 60%, transparent); }
.table--zebra tbody tr:nth-child(even):hover { background: var(--brand-50); }

.table--compact th, .table--compact td { padding: 6px 9px; font-size: 12.5px; }
.table--roomy th, .table--roomy td { padding: 13px 14px; }

/* پاورقی جمع — مبلغ کل و جمع ستون */
.table tfoot td, .table tfoot th {
    background: var(--surface-2);
    font-weight: var(--fw-semibold);
    color: var(--brand-900);
    border-block-start: 1px solid var(--line-strong);
    border-bottom: none;
}

.table__empty { text-align: center; color: var(--muted); padding: 26px 12px; }

/* 🔴 ستون کنش‌ها «به‌اندازه محتوایش» باریک می‌شود، نه ۶۴ پیکسل ثابت. با عرض
   ثابت، دکمه‌ای که برچسب متنی دارد (مثل «ثبت نتیجه» یا «پیوست‌ها») در ۶۴ پیکسل
   فشرده می‌شد و دو خط می‌شکست. `width: 1%` + `nowrap` یعنی «کمترین عرضی که
   محتوا جا شود». */
.table__actions { width: 1%; text-align: center; white-space: nowrap; }
.table__row--muted td { color: var(--muted); background: var(--surface-2); }

/* ردیف تأکیدی — نامه دیده‌نشده، مانده بدهی، ردیف ردشده */
.table__row--unread td { background: color-mix(in srgb, var(--brand-50) 70%, transparent); font-weight: var(--fw-medium); }
.table__row--unread td:first-child { box-shadow: inset 3px 0 0 var(--brand-500); }
[dir='ltr'] .table__row--unread td:first-child { box-shadow: inset -3px 0 0 var(--brand-500); }
.table__row--danger td { background: color-mix(in srgb, var(--danger-bg) 70%, transparent); }
.table__row--success td { background: color-mix(in srgb, var(--success-bg) 60%, transparent); }
.table__row--warning td { background: color-mix(in srgb, var(--warning-bg) 60%, transparent); }

.table td.num, .table th.num { text-align: center; font-variant-numeric: tabular-nums; }
.table td.empty-gate { color: var(--muted-light); text-align: center; }

/* پیام خطای فیلدِ درون سلول عددی باید از ابتدا خوانده شود، نه وسط‌چین */
.table td.num .field-error, .table td.num .field-help { text-align: start; justify-content: flex-start; }

/* ستون کنش‌ها — دکمه‌های آیکونی چسبیده به هم */
.table__actions .btn { vertical-align: middle; }
.row-actions { display: inline-flex; align-items: center; gap: 4px; justify-content: center; }

/* جدول عریض (شیت بتن، جستجوی مالی) باید خودش بلغزد، نه آنکه صفحه را بکشد */
.table-scroll {
    position: relative;
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
    box-shadow: var(--shadow-1);
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* جدول بلند: سرستون چسبان می‌شود چون پوشش خودش می‌لغزد */
.table-scroll--tall { max-block-size: min(72vh, 760px); overflow-y: auto; }

/* سایه لبه — نشانه اینکه ستون بیشتری هست. `panel-ui.js` کلاس را می‌گذارد. */
.table-scroll::after {
    content: '';
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    inline-size: 26px;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--t);
    background: linear-gradient(to left, rgba(17, 24, 32, .10), transparent);
}

[dir='ltr'] .table-scroll::after { background: linear-gradient(to right, rgba(17, 24, 32, .10), transparent); }
.table-scroll.has-overflow-end::after { opacity: 1; }

/* --- تبدیل به کارت روی صفحه کوچک ---------------------------------------- */
@media (max-width: 768px) {
    .table[data-stack='on'] {
        display: block;
        border: none;
        background: transparent;
        border-radius: 0;
        font-size: 13px;
    }

    .table[data-stack='on'] thead { display: none; }
    .table[data-stack='on'] tbody, .table[data-stack='on'] tfoot { display: block; }

    .table[data-stack='on'] tbody tr {
        display: block;
        background: var(--surface);
        border: 1px solid var(--line);
        border-radius: var(--r);
        box-shadow: var(--shadow-1);
        margin-block-end: 10px;
        padding: 4px 12px;
    }

    .table[data-stack='on'] tbody tr:hover { background: var(--surface); }

    .table[data-stack='on'] td {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: var(--s-3);
        padding: 8px 0;
        border-block-end: 1px dashed var(--line);
        text-align: start;
        min-width: 0;
    }

    .table[data-stack='on'] tr td:last-child { border-block-end: none; }

    .table[data-stack='on'] td::before {
        content: attr(data-label);
        flex: 0 0 40%;
        max-inline-size: 45%;
        color: var(--muted);
        font-size: var(--fs-xs);
        font-weight: var(--fw-medium);
    }

    /* سلول بی‌برچسب (ردیف خالی با colspan، ردیف جمع) تمام‌عرض می‌شود */
    .table[data-stack='on'] td[colspan]::before,
    .table[data-stack='on'] td[data-label='']::before { display: none; }
    .table[data-stack='on'] td[colspan] { display: block; }

    .table[data-stack='on'] td.num { justify-content: space-between; text-align: end; }
    .table[data-stack='on'] .table__actions { width: auto; justify-content: flex-end; padding-block: 10px; }
    .table[data-stack='on'] .table__actions::before { flex: 0 0 auto; }

    /* سلولِ ورودی‌دار (ردیف‌های فرم‌ست) — برچسب بالا و ورودی تمام‌عرض زیرش.
       بی این، برچسب ۴۰٪ سلول را می‌گیرد و برای نامِ کامل ۱۶۰ پیکسل می‌ماند. */
    .table[data-stack='on'] td:has(> input:not([type='checkbox']):not([type='radio'])),
    .table[data-stack='on'] td:has(> select),
    .table[data-stack='on'] td:has(> textarea) { flex-wrap: wrap; gap: 4px; }

    .table[data-stack='on'] td:has(> input:not([type='checkbox']):not([type='radio']))::before,
    .table[data-stack='on'] td:has(> select)::before,
    .table[data-stack='on'] td:has(> textarea)::before { flex: 0 0 100%; max-inline-size: none; }

    .table[data-stack='on'] tfoot td { border-radius: var(--r); background: var(--surface-2); margin-block-end: 10px; }
    .table[data-stack='on'] .table__row--unread td:first-child { box-shadow: none; }
    .table[data-stack='on'] .table__row--unread { border-inline-start: 3px solid var(--brand-500); }

    /* پوشش لغزان دور جدول کارت‌شده کادر ندارد */
    .table-scroll:has(> .table[data-stack='on']) {
        border: none;
        background: transparent;
        box-shadow: none;
        overflow: visible;
    }
}

/* ==========================================================================
   حالت خالی
   ========================================================================== */

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-2);
    padding: var(--s-8) var(--s-4);
    text-align: center;
    color: var(--muted);
}

.empty__icon {
    display: inline-grid;
    place-items: center;
    inline-size: 52px;
    block-size: 52px;
    border-radius: var(--r-pill);
    background: var(--surface-3);
    color: var(--muted-light);
    font-size: 24px;
}

.empty__title { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--ink-soft); }
.empty__hint { margin: 0; font-size: var(--fs-sm); color: var(--muted); max-inline-size: 46ch; }
.empty--sm { padding: var(--s-5) var(--s-3); }
.empty--sm .empty__icon { inline-size: 40px; block-size: 40px; font-size: 19px; }

/* ==========================================================================
   فهرست مشخصات، یادداشت و پیام
   ========================================================================== */

.details {
    display: grid;
    grid-template-columns: minmax(140px, 210px) 1fr;
    gap: 2px 16px;
    margin: 0;
}

.details dt { color: var(--muted); font-size: 13px; }
.details dd { margin: 0; }
.details dt, .details dd { padding: 5px 0; border-bottom: 1px dashed var(--line); }
.details dt:last-of-type, .details dd:last-of-type { border-bottom: none; }

/* دو جفت در هر ردیف — برای صفحه‌های جزئیات پرقلم روی صفحه بزرگ */
@media (min-width: 1100px) {
    .details--split { grid-template-columns: minmax(130px, 190px) 1fr minmax(130px, 190px) 1fr; }

    /* 🔴 در چیدمان چهارستونه، «آخرین dt/dd» وسطِ ردیف پایانی می‌افتد و
       برداشتن خطش یک خط‌چین معلق می‌ساخت؛ پس در این حالت خط می‌ماند. */
    .details--split dt:last-of-type, .details--split dd:last-of-type { border-bottom: 1px dashed var(--line); }
}

/* کادر سفید دور فهرست مشخصات */
.details--boxed {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: var(--s-3) var(--s-4);
    box-shadow: var(--shadow-1);
}

.note { color: var(--muted); font-size: 13px; }

/* 🔴 این‌ها `display: block` می‌مانند، نه `flex`. با فلکس، هر عنصر درون‌خطیِ
   داخل یادداشت — `<strong>`، `<a>`، `<span dir="ltr">` — خودش یک آیتم فلکس
   می‌شد و جمله تکه‌تکه و بی‌ترتیب چیده می‌شد. آیکون با `position: absolute`
   می‌نشیند تا جریان متن دست‌نخورده بماند. */
.note--warning, .note--danger, .note--success, .note--info {
    display: block;
    position: relative;
    border-radius: var(--r-sm);
    padding: 9px 13px;
    padding-inline-start: 34px;
    border: 1px solid;
    font-size: 13px;
}

.note--warning { background: var(--warning-bg); color: var(--warning-ink); border-color: var(--warning-line); }
.note--danger  { background: var(--danger-bg);  color: var(--danger-ink);  border-color: var(--danger-line); }
.note--success { background: var(--success-bg); color: var(--success-ink); border-color: var(--success-line); }
.note--info    { background: var(--info-bg);    color: var(--info);        border-color: var(--info-line); }

/* آیکون خودکار برای یادداشت‌های معنایی — بی‌نیاز از تغییر قالب */
.note--warning::before, .note--danger::before, .note--success::before, .note--info::before {
    content: '';
    position: absolute;
    inset-inline-start: 11px;
    inset-block-start: 13px;
    inline-size: 1.15em;
    block-size: 1.15em;
    background-color: currentColor;
    -webkit-mask: var(--note-ico) center / contain no-repeat;
    mask: var(--note-ico) center / contain no-repeat;
}

.note--warning { --note-ico: var(--i-alert); }
.note--danger  { --note-ico: var(--i-x-circle); }
.note--success { --note-ico: var(--i-check-circle); }
.note--info    { --note-ico: var(--i-info); }

.notice {
    display: flex;
    align-items: flex-start;
    gap: var(--s-3);
    background: var(--warning-bg);
    border: 1px solid var(--warning-line);
    border-radius: var(--r);
    padding: 16px 18px;
}

.notice__icon {
    display: inline-grid;
    place-items: center;
    inline-size: 40px;
    block-size: 40px;
    flex: 0 0 auto;
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--warning);
    font-size: 19px;
    box-shadow: inset 0 0 0 1px var(--warning-line);
}

.notice__body { min-width: 0; }
.notice__body > :first-child { margin-block-start: 0; }
.notice__body > :last-child { margin-block-end: 0; }
.notice__title { margin: 0 0 8px; font-size: 16px; color: var(--warning-ink); }

.messages { list-style: none; padding: 0; margin: 0 0 18px; }

.message {
    border-radius: var(--r-sm);
    padding: 10px 14px;
    font-size: 13px;
    margin-bottom: 8px;
    border: 1px solid;
    display: flex;
    align-items: center;
    gap: 8px;
    box-shadow: var(--shadow-1);
    animation: zn-slide-in var(--t-slow) both;
}

@keyframes zn-slide-in { from { opacity: 0; transform: translateY(-6px); } }

.message::before {
    content: '';
    flex: 0 0 auto;
    inline-size: 1.2em;
    block-size: 1.2em;
    background-color: currentColor;
    -webkit-mask: var(--msg-ico, var(--i-info)) center / contain no-repeat;
    mask: var(--msg-ico, var(--i-info)) center / contain no-repeat;
}

.message--success { background: var(--success-bg); color: var(--success-ink); border-color: var(--success-line); --msg-ico: var(--i-check-circle); }
.message--warning { background: var(--warning-bg); color: var(--warning-ink); border-color: var(--warning-line); --msg-ico: var(--i-alert); }
.message--error   { background: var(--danger-bg);  color: var(--danger-ink);  border-color: var(--danger-line); --msg-ico: var(--i-x-circle); }
.message--info,
.message--debug   { background: var(--info-bg);    color: var(--info);        border-color: var(--info-line); --msg-ico: var(--i-info); }

.message__text { flex: 1 1 auto; min-width: 0; }

.message__close {
    flex: 0 0 auto;
    inline-size: 26px;
    block-size: 26px;
    display: inline-grid;
    place-items: center;
    border: none;
    background: transparent;
    color: inherit;
    opacity: .6;
    border-radius: var(--r-xs);
    cursor: pointer;
    font-family: inherit;
}

.message__close:hover { opacity: 1; background: rgba(17, 24, 32, .06); }

.list { margin: 0; padding-inline-start: 20px; font-size: 13px; }
.list li { margin-bottom: 4px; }

/* فهرست فایل — پیوند دانلود با آیکون، بی‌گلوله و با فاصله درست میان آیکون و نام */
.list--files { list-style: none; padding-inline-start: 0; }
.list--files li { display: flex; align-items: center; gap: 6px; padding: 3px 0; }

.file-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    text-decoration: none;
    color: var(--brand-700);
}

.file-link:hover { color: var(--brand-800); text-decoration: underline; }

/* ==========================================================================
   فرم
   ========================================================================== */

.form { max-width: 640px; }
.form--wide { max-width: 100%; }
.form--narrow { max-width: 440px; }

.field, .form-row { margin-bottom: 15px; min-width: 0; }

.field label, .form-row label {
    display: block;
    margin-bottom: 5px;
    font-size: 13px;
    font-weight: var(--fw-medium);
    color: var(--ink-soft);
}

/* برچسب فیلد اجباری — ستاره کهربایی، نه سرخ (سرخ برای خطاست) */
.field--required > label::after, .form-row--required > label::after {
    content: '*';
    color: var(--accent-600);
    margin-inline-start: 3px;
    font-weight: var(--fw-bold);
}

input[type='text'], input[type='password'], input[type='email'], input[type='number'],
input[type='tel'], input[type='url'], input[type='date'], input[type='search'],
input[type='time'], input[type='datetime-local'], input[type='month'],
input[type='file'], textarea, select {
    width: 100%;
    padding: 9px 12px;
    min-block-size: 38px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 14px;
    background: var(--surface);
    color: var(--ink);
    transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}

textarea { line-height: 1.8; resize: vertical; min-height: 84px; }

input:hover:not(:disabled), textarea:hover:not(:disabled), select:hover:not(:disabled) {
    border-color: var(--brand-300);
}

input:focus, textarea:focus, select:focus {
    outline: none;
    border-color: var(--brand-500);
    box-shadow: var(--ring);
}

input:disabled, textarea:disabled, select:disabled {
    background: var(--surface-3);
    color: var(--muted);
    cursor: not-allowed;
    border-color: var(--line);
}

input[readonly], textarea[readonly] { background: var(--surface-2); color: var(--ink-soft); }

::placeholder { color: var(--muted-light); opacity: 1; }

/* فیلدی که سرور ردش کرده — کادر سرخ، پس خطا فقط متن نیست */
input[aria-invalid='true'], textarea[aria-invalid='true'], select[aria-invalid='true'],
.field--invalid input, .field--invalid textarea, .field--invalid select,
.form-row--invalid input, .form-row--invalid textarea, .form-row--invalid select {
    border-color: var(--danger-line);
    background: color-mix(in srgb, var(--danger-bg) 55%, var(--surface));
}

.field--invalid input:focus, .form-row--invalid input:focus,
input[aria-invalid='true']:focus { border-color: var(--danger); box-shadow: var(--ring-danger); }

/* --- کشوی انتخاب — پیکان یکسان در همه مرورگرها ------------------------- */
select:not([multiple]):not([size]) {
    appearance: none;
    -webkit-appearance: none;
    padding-inline-end: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364707e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-size: 16px 16px;
    cursor: pointer;
}

[dir='rtl'] select:not([multiple]):not([size]) { background-position: left 11px center; }
[dir='ltr'] select:not([multiple]):not([size]) { background-position: right 11px center; }

select[multiple], select[size] { padding: 6px; min-block-size: 96px; }
select[multiple] option, select[size] option { padding: 5px 8px; border-radius: var(--r-xs); }

/* --- تیک و رادیو -------------------------------------------------------- */
input[type='checkbox'], input[type='radio'] {
    width: auto;
    min-block-size: 0;
    inline-size: 17px;
    block-size: 17px;
    accent-color: var(--brand-600);
    margin-inline-end: 6px;
    vertical-align: -.18em;
    cursor: pointer;
}

/* ردیف تیک‌ها — هدف لمسی کل ردیف، نه فقط مربع ۱۷ پیکسلی */
.check-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--r-sm);
    font-size: 13px;
    cursor: pointer;
}

.check-row:hover { background: var(--surface-2); }
.check-row input { margin: 0; }

/* --- انتخاب فایل -------------------------------------------------------- */
input[type='file'] {
    padding: 6px 10px;
    background: var(--surface-2);
    cursor: pointer;
    line-height: 2;
}

/* ردیف‌های ویجت فایلِ پرشده (`templates/django/forms/widgets/`) — هر تکه بلوک
   خودش، وگرنه نام فایل و تیک «پاک کردن» در یک سطر به‌هم می‌ریزند */
.file-current, .file-change {
    display: block;
    color: var(--muted);
    font-size: 12px;
    margin-block-end: 4px;
}

.file-change { margin-block-start: 6px; }

/* نام فایل لاتین است و در متن راست‌به‌چپ می‌نشیند، پس جدا نگه داشته می‌شود */
.file-current a, .file-current > span {
    unicode-bidi: isolate;
    color: var(--brand-700);
    font-weight: var(--fw-medium);
}

/* 🔴 برچسبِ درونِ `check-row` را قاعده کلی `.form-row label` بلوک می‌کرد و متن
   تیک به سطر بعد می‌افتاد. اینجا پس‌از آن قاعده می‌آید، پس همین می‌ماند
   (`display` را دست نمی‌زنیم: تعریف بالای همین شیت `flex` است و همان درست است).
   `padding-inline: 0` تیک را با لبه فیلد هم‌تراز می‌کند؛ هدف لمسی همچنان تمام‌عرض
   و ۳۶ پیکسل بلند است. */
.field label.check-row, .form-row label.check-row {
    padding-inline: 0;
    margin-block-end: 0;
    font-size: 13px;
    font-weight: var(--fw-normal);
    color: var(--ink-soft);
}

input[type='file']::file-selector-button {
    margin-inline-end: 10px;
    padding: 5px 13px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-xs);
    background: var(--surface);
    color: var(--ink-soft);
    font-family: inherit;
    font-size: var(--fs-xs);
    font-weight: var(--fw-medium);
    cursor: pointer;
    transition: background var(--t-fast), border-color var(--t-fast);
}

input[type='file']::file-selector-button:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-800); }

/* ورودی عددی و شناسه‌ها چپ‌به‌راست خوانده می‌شوند */
input[dir='ltr'], input[inputmode='numeric'] { direction: ltr; text-align: start; }

/* ورودی با آیکون یا پسوند (واحد، ریال، متر) */
.input-group { display: flex; align-items: stretch; }
.input-group > input, .input-group > select { border-start-end-radius: 0; border-end-end-radius: 0; }

.input-group__addon {
    display: inline-flex;
    align-items: center;
    padding: 0 11px;
    border: 1px solid var(--line-strong);
    border-inline-start: none;
    border-start-end-radius: var(--r-sm);
    border-end-end-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: var(--fs-xs);
    white-space: nowrap;
}

.field-help, .form-row small {
    display: block;
    color: var(--muted);
    font-size: 12px;
    margin-block-start: 3px;
    line-height: 1.65;
}

.field-error, .form-error {
    display: flex;
    align-items: flex-start;
    gap: 5px;
    color: var(--danger);
    font-size: 12px;
    margin-top: 3px;
    margin-bottom: 0;
    font-weight: var(--fw-medium);
}

.field-error::before, .form-error::before {
    content: '';
    flex: 0 0 auto;
    inline-size: 1.1em;
    block-size: 1.1em;
    margin-block-start: .2em;
    background-color: currentColor;
    -webkit-mask: var(--i-alert) center / contain no-repeat;
    mask: var(--i-alert) center / contain no-repeat;
}

.form-errors {
    background: var(--danger-bg);
    border: 1px solid var(--danger-line);
    border-inline-start: 3px solid var(--danger);
    border-radius: var(--r-sm);
    padding: 11px 14px;
    margin-bottom: 16px;
    color: var(--danger-ink);
    font-size: 13px;
}

.form-errors p, .form-errors ul { margin: 0; }
.form-errors > * + * { margin-block-start: 4px; }
.form-errors__title { display: block; font-weight: var(--fw-semibold); margin-block-end: 4px; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 0 20px;
}

.form-grid .field--full, .form-grid .form-row--full { grid-column: 1 / -1; }
.form-grid--tight { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }

.fieldset {
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: 16px 18px;
    margin: 0 0 20px;
    background: var(--surface);
    min-width: 0;
}

.fieldset__legend {
    padding: 0 8px;
    font-size: 13.5px;
    font-weight: var(--fw-semibold);
    color: var(--brand-700);
}

/* --- نوار فیلتر --------------------------------------------------------- */

.filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin-bottom: 18px;
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-1);
}

.filters__field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; min-width: 0; }
.filters__field label { margin: 0; font-size: var(--fs-xs); color: var(--muted); font-weight: var(--fw-medium); }
.filters__field input, .filters__field select { min-width: 140px; }
.filters__actions { display: flex; align-items: center; gap: 8px; margin-inline-start: auto; }

/* دکمه «فیلترها» — `panel-ui.js` روی صفحه کوچک می‌سازد */
.filters-toggle { display: none; }

/* 🔴 جمع‌شدن نوار فیلتر تنها `display` را عوض می‌کند؛ فیلدها در DOM می‌مانند و
   ارسال فرم دقیقاً همان است که بود. */
.filters.is-collapsed { display: none; }

/* --- جدول ردیف‌افزا (G5) و آپلودر چندفایلی --- */

.dynamic-rows__add {
    margin-top: 12px;
    background: var(--brand-50);
    border: 1px dashed var(--brand-400);
    color: var(--brand-700);
    box-shadow: none;
}

.dynamic-rows__add:hover { background: var(--brand-100); border-style: solid; color: var(--brand-800); }

.dynamic-rows__remove {
    display: inline-grid;
    place-items: center;
    inline-size: 30px;
    block-size: 30px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--danger);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 0;
    border-radius: var(--r-xs);
    font-family: inherit;
    transition: background var(--t-fast), border-color var(--t-fast);
}

.dynamic-rows__remove:hover { background: var(--danger-bg); border-color: var(--danger-line); }
.dynamic-rows__row--deleted { display: none; }

/* ورودی‌های داخل جدول ردیف‌افزا فشرده‌اند تا ردیف بلند نشود */
.table td input, .table td select, .table td textarea { min-block-size: 34px; padding: 5px 9px; font-size: 13px; }
.table td textarea { min-height: 56px; }

.multi-file__list { list-style: none; padding: 0; margin: 8px 0 0; font-size: 12px; }
.multi-file__list li {
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 0;
}
.multi-file__list li::before {
    content: '';
    inline-size: 1.1em;
    block-size: 1.1em;
    background-color: currentColor;
    -webkit-mask: var(--i-paperclip) center / contain no-repeat;
    mask: var(--i-paperclip) center / contain no-repeat;
}
.multi-file__list li[data-oversize='true'] { color: var(--danger); font-weight: var(--fw-medium); }

/* ==========================================================================
   بارگذاری
   ========================================================================== */

.skeleton {
    display: block;
    border-radius: var(--r-xs);
    background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
    background-size: 400% 100%;
    animation: zn-shimmer 1.4s ease-in-out infinite;
    color: transparent;
    min-block-size: 1em;
}

@keyframes zn-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.spinner {
    display: inline-block;
    inline-size: 18px;
    block-size: 18px;
    border: 2px solid var(--line-strong);
    border-block-start-color: var(--brand-600);
    border-radius: 50%;
    animation: zn-spin .6s linear infinite;
}

.progress {
    inline-size: 100%;
    block-size: 7px;
    border-radius: var(--r-pill);
    background: var(--surface-3);
    overflow: hidden;
}

.progress__bar {
    display: block;
    block-size: 100%;
    border-radius: inherit;
    background: var(--brand-600);
    transition: inline-size var(--t-slow);
}

.progress__bar--success { background: var(--success); }
.progress__bar--warning { background: var(--accent-500); }
.progress__bar--danger  { background: var(--danger); }

/* نوار بارگذاری بالای صفحه — روی ارسال فرم و پیمایش */
.route-progress {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    z-index: var(--z-toast);
    background: var(--brand-500);
    transform-origin: inline-start;
    transform: scaleX(0);
    opacity: 0;
    pointer-events: none;
    transition: transform 1.4s cubic-bezier(.12, .78, .28, 1), opacity var(--t);
}

.route-progress.is-active { transform: scaleX(.92); opacity: 1; }

/* ==========================================================================
   کشوی کنش (بی‌جاوااسکریپت، با <details>)
   ========================================================================== */

.action-menu { position: relative; display: inline-block; }

.action-menu > summary {
    display: inline-grid;
    place-items: center;
    inline-size: 30px;
    block-size: 30px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-xs);
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
    list-style: none;
    transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}

.action-menu > summary::-webkit-details-marker { display: none; }
.action-menu > summary::marker { content: ''; }
.action-menu > summary:hover { background: var(--surface-2); border-color: var(--brand-300); color: var(--brand-800); }
.action-menu[open] > summary { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-800); }

.action-menu__list {
    position: absolute;
    inset-block-start: calc(100% + 5px);
    inset-inline-end: 0;
    z-index: var(--z-popover);
    min-inline-size: 172px;
    padding: 5px;
    margin: 0;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    box-shadow: var(--shadow-2);
    text-align: start;
}

.action-menu__list a, .action-menu__list button {
    display: flex;
    align-items: center;
    gap: 8px;
    inline-size: 100%;
    padding: 7px 10px;
    border: none;
    border-radius: var(--r-xs);
    background: transparent;
    color: var(--ink-soft);
    font-family: inherit;
    font-size: var(--fs-sm);
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

.action-menu__list a:hover, .action-menu__list button:hover { background: var(--brand-50); color: var(--brand-800); }
.action-menu__list .is-danger { color: var(--danger); }
.action-menu__list .is-danger:hover { background: var(--danger-bg); color: var(--danger-ink); }
.action-menu__sep { block-size: 1px; margin: 4px 2px; background: var(--line); }

/* ==========================================================================
   گفتگو (modal)
   ========================================================================== */

.modal {
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-4);
    max-inline-size: min(560px, calc(100vw - 32px));
    max-block-size: calc(100vh - 48px);
    font-family: inherit;
}

.modal::backdrop { background: rgba(17, 24, 32, .5); backdrop-filter: blur(2px); }

.modal__head {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    padding: 14px 18px;
    border-block-end: 1px solid var(--line);
}

.modal__title { margin: 0; font-size: var(--fs-md); color: var(--brand-900); }
.modal__close { margin-inline-start: auto; }
.modal__body { padding: 16px 18px; overflow-y: auto; }
.modal__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    padding: 12px 18px;
    border-block-start: 1px solid var(--line);
    background: var(--surface-2);
    border-end-start-radius: var(--r-lg);
    border-end-end-radius: var(--r-lg);
}

/* ==========================================================================
   پیمایش کمکی — راهنمای مسیر، زبانه، صفحه‌بندی
   ==========================================================================
   🔴 نماها هنوز صفحه‌بندی سمت سرور ندارند؛ این کلاس‌ها آماده‌اند تا اگر روزی
   `Paginator` اضافه شد، ظاهرش از همین نظام بیاید. اینجا چیزی به قالب‌ها تحمیل
   نمی‌شود.
   ========================================================================== */

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 0 0 6px;
    padding: 0;
    list-style: none;
    font-size: var(--fs-xs);
    color: var(--muted);
}

.breadcrumb li { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--brand-700); text-decoration: underline; }
.breadcrumb li + li::before {
    content: '';
    inline-size: .85em;
    block-size: .85em;
    background-color: var(--muted-light);
    -webkit-mask: var(--i-chevron-start) center / contain no-repeat;
    mask: var(--i-chevron-start) center / contain no-repeat;
}
[dir='ltr'] .breadcrumb li + li::before { -webkit-mask-image: var(--i-chevron-end); mask-image: var(--i-chevron-end); }
.breadcrumb [aria-current='page'] { color: var(--ink-soft); font-weight: var(--fw-medium); }

.tabs {
    display: flex;
    gap: 4px;
    margin-block-end: var(--s-4);
    padding-block-end: 2px;
    border-block-end: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tabs__item {
    padding: 8px 14px;
    border: none;
    border-block-end: 2px solid transparent;
    background: transparent;
    color: var(--muted);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    margin-block-end: -3px;
}

.tabs__item:hover { color: var(--brand-700); }
.tabs__item[aria-selected='true'], .tabs__item[aria-current='page'] {
    color: var(--brand-800);
    border-block-end-color: var(--brand-600);
}

.pagination { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-block-start: var(--s-4); }

.pagination a, .pagination span {
    display: inline-grid;
    place-items: center;
    min-inline-size: 34px;
    block-size: 34px;
    padding: 0 9px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-xs);
    background: var(--surface);
    color: var(--ink-soft);
    font-size: var(--fs-sm);
    text-decoration: none;
}

.pagination a:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-800); }
.pagination [aria-current='page'] { background: var(--brand-700); border-color: var(--brand-700); color: #fff; font-weight: var(--fw-semibold); }
.pagination .is-disabled { color: var(--muted-light); background: var(--surface-2); cursor: not-allowed; }

/* ==========================================================================
   راهنمای ابزار و کلید
   ========================================================================== */

[data-tip] { position: relative; }

[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    inset-block-end: calc(100% + 6px);
    inset-inline-start: 50%;
    transform: translateX(50%) translateY(3px);
    z-index: var(--z-popover);
    padding: 4px 9px;
    border-radius: var(--r-xs);
    background: var(--ink);
    color: #fff;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-normal);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t-fast), transform var(--t-fast);
}

[dir='ltr'] [data-tip]::after { transform: translateX(-50%) translateY(3px); }
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; transform: translateX(50%) translateY(0); }
[dir='ltr'] [data-tip]:hover::after { transform: translateX(-50%) translateY(0); }

.kbd {
    display: inline-block;
    padding: 1px 6px;
    border: 1px solid var(--line-strong);
    border-block-end-width: 2px;
    border-radius: var(--r-xs);
    background: var(--surface-2);
    color: var(--ink-soft);
    font-family: inherit;
    font-size: var(--fs-2xs);
}

/* ==========================================================================
   نشان شرکت
   ========================================================================== */

.brand-mark {
    display: block;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    object-fit: contain;
    background: var(--surface);
    flex: 0 0 auto;
}

/* ==========================================================================
   آواتار کاربر — عکس ۳×۴ پروفایل، با جای‌گزین حرف‌اول
   ========================================================================== */

.avatar {
    display: inline-grid;
    place-items: center;
    inline-size: 38px;
    block-size: 38px;
    border-radius: var(--r-pill);
    background: var(--brand-100);
    color: var(--brand-800);
    font-size: 13px;
    font-weight: var(--fw-semibold);
    overflow: hidden;
    flex: 0 0 auto;
    box-shadow: inset 0 0 0 1px var(--line-strong);
}

/* عکس ۳×۴ است، پس `cover` تا کادر گرد پر شود و کشیده نشود */
.avatar img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }

.avatar--sm { inline-size: 30px; block-size: 30px; font-size: var(--fs-xs); }
.avatar--lg { inline-size: 84px; block-size: 84px; font-size: 26px; border-radius: var(--r); }
.avatar--lg img { border-radius: inherit; }

/* ==========================================================================
   واکنش‌گرایی اجزای مشترک
   ========================================================================== */

@media (max-width: 768px) {
    /* هدف لمسی: هیچ دکمه‌ای زیر ۴۲ پیکسل نماند (به‌جز دکمه‌های داخل جدول) */
    .btn { min-block-size: 42px; padding-inline: 18px; }
    .btn--sm { min-block-size: 36px; }
    .btn--xs { min-block-size: 30px; }
    .btn--icon { inline-size: 42px; block-size: 42px; padding: 0; }
    .btn--icon.btn--sm { inline-size: 36px; block-size: 36px; }
    .table__actions .btn--icon { inline-size: 36px; block-size: 36px; min-block-size: 36px; }

    .form-grid, .form-grid--tight { grid-template-columns: 1fr; }
    .details { grid-template-columns: 1fr; gap: 0; }
    .details dt { border-bottom: none; padding-bottom: 0; color: var(--muted); font-size: var(--fs-xs); }
    .details dd { padding-top: 2px; font-weight: var(--fw-medium); }
    .details dd:not(:last-of-type) { border-bottom: 1px dashed var(--line); padding-bottom: 7px; }

    .filters { padding: 12px; gap: 10px; }
    .filters__field, .filters__field input, .filters__field select { width: 100%; min-width: 0; }
    .filters__actions { inline-size: 100%; margin-inline-start: 0; }
    .filters__actions .btn { flex: 1 1 auto; }
    .filters-toggle { display: inline-flex; width: 100%; margin-block-end: var(--s-3); }

    .toolbar { gap: var(--s-2); }
    .toolbar__group { inline-size: 100%; }
    .toolbar__group--end { margin-inline-start: 0; }
    .toolbar .btn { flex: 1 1 auto; }
    .toolbar__sep { display: none; }

    .form-actions .btn { flex: 1 1 auto; }
    .card--stat .card__value { font-size: 22px; }
    .modal { max-inline-size: calc(100vw - 20px); }
    .action-menu__list { min-inline-size: 190px; }
}

@media (max-width: 480px) {
    .empty { padding: var(--s-6) var(--s-3); }
    .badge, .status-pill { font-size: 11.5px; }
}

/* ==========================================================================
   چاپ — اجزای رابط کنار می‌روند تا برگ تمیز بماند
   ========================================================================== */

@media print {
    .btn, .toolbar, .filters, .messages, .action-menu, .route-progress,
    .skip-link, .filters-toggle, .message__close { display: none !important; }

    .card, .table, .table-scroll, .fieldset, .details--boxed {
        box-shadow: none !important;
        border-color: #999 !important;
    }

    .table-scroll { overflow: visible !important; max-block-size: none !important; }
    .status-pill, .badge { border: 1px solid #999 !important; background: #fff !important; color: #000 !important; }
    .skeleton { animation: none; background: none; }
}
