/* ======================================================================
   آرتا تاک — ظاهر مشترک
   رنگ‌ها اینجا تعریف نمی‌شوند؛ از theme.css می‌آیند تا تم‌پذیری ممکن باشد.
   ====================================================================== */

:root {
    --radius: 12px;
    --radius-sm: 8px;

    /* گام فاصله روی پایهٔ ۴ پیکسل، مثل دیسکورد و Compound */
    --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;

    --rail: 248px;    /* ستون منو */
    --aside: 232px;   /* ستون کانال‌ها و حاضران */
}

* { box-sizing: border-box; }

/* طرح‌بندی‌ها display دارند و بر display:none خودِ hidden می‌چربند */
[hidden] { display: none !important; }

html, body {
    margin: 0;
    min-height: 100%;
    background: var(--bg-1);
    color: var(--text);
    font-family: 'Vazirmatn', 'Segoe UI', Tahoma, sans-serif;

    /* ۱۵ پیکسل و خط ۱.۷۵: فارسی به فاصلهٔ خطی بیشتری از لاتین نیاز دارد، چون
       وزیرمتن برای تشکیل بالای حرف و دنبالهٔ ح و ر و ج جا نگه می‌دارد
       (مجموع ascender+descender آن ۱۵۶٪ em است، نه ۱۲۰٪ لاتین).
       با ۱.۵، متن از پیش‌فرض خودِ قلم هم تنگ‌تر می‌شد. */
    font-size: 15px;
    line-height: 1.75;
    -webkit-font-smoothing: antialiased;
}

/*
   فاصلهٔ حرفی روی فارسی ممنوع است، نه سلیقه‌ای: خط فارسی پیوسته است و
   letter-spacing اتصال حروف را می‌شکند («الوکلاء» می‌شود «الوکلا ء»).
   این قاعده هر توکنی را که از طراحی لاتین نشت کند بی‌اثر می‌کند.
   حروف بزرگ هم در فارسی معنا ندارد.
*/
:dir(rtl), [dir="rtl"] {
    letter-spacing: normal;
    text-transform: none;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { font-size: 19px; margin: 0; font-weight: 700; }
h2 { font-size: 16px; margin: 0 0 var(--s3); font-weight: 600; }
h3 { font-size: 13px; margin: 0 0 var(--s2); color: var(--muted); font-weight: 600; }

.muted { color: var(--muted); font-size: 13.5px; }
.faint { color: var(--faint); font-size: 12.5px; }
.center { text-align: center; }
.big-icon { font-size: 40px; color: var(--faint); display: block; margin-bottom: var(--s2); }

/*
   ---------- استاندارد اعداد ----------

   ارقام در DOM لاتین می‌مانند و قلم فارسی نشانشان می‌دهد: ss01 وزیرمتن گلیف
   لاتین را به فارسی جانشین می‌کند. کاربر ۱۴۰۵ می‌بیند، DOM «1405» دارد.

   سود این روش در برابر تبدیل سمت سرور: Ctrl+F روی «0912» کار می‌کند، کپی‌کردن
   شماره در شماره‌گیر یا اکسل درست می‌چسبد، ورودی فرم بی‌نیاز از تبدیل پارس
   می‌شود، و خوانندهٔ صفحه عدد را می‌فهمد. سنجیده شد که ss01 در همین نسخهٔ
   وزیرمتن کار می‌کند.
*/
/*
   ...ولی فقط در فارسی. :lang(fa) اجباری است نه آرایه‌ای: ss01 گلیفِ رقم
   لاتین را به فارسی جانشین می‌کند، پس بی این شرط صفحهٔ انگلیسی هم
   «2026-10-03» را «۲۰۲۶-۱۰-۰۳» نشان می‌داد. این بدترین نوع خرابی است
   چون در آزمونِ فارسی هرگز دیده نمی‌شود.
*/
body:lang(fa) { font-feature-settings: "ss01"; }

/*
   هر جا عدد روی هم چیده یا مقایسه می‌شود این کلاس لازم است.
   دلیلش سنجیده شده: ارقام فارسی عرض یکسان ندارند — «۱» حدود ۱۱.۵ پیکسل و «۳»
   حدود ۲۶.۴، یعنی ۲.۳ برابر. بی tnum ستون عددی جدول واقعاً ناهم‌تراز است.

   isolate هم لازم است: دونقطه و خط تیره نویسهٔ بی‌طرف‌اند و «۱۴:۳۰» یا
   «۰۲۱-۱۲۳۴» را در بند راست‌به‌چپ جابه‌جا نشان می‌دهند.
*/
.num {
    font-feature-settings: "tnum";
    unicode-bidi: isolate;
}

/* در فارسی هر دو ویژگی با هم می‌آیند، چون font-feature-settings همه‌یاهیچ
   است: قاعدهٔ بالا که فقط "tnum" دارد، "ss01" بدنه را می‌انداخت و عدد
   لاتین دیده می‌شد. این شایع‌ترین اشکال وزیرمتن است. */
.num:lang(fa) { font-feature-settings: "ss01", "tnum"; }

/*
   استثنا: جایی که عدد باید لاتین دیده شود — کد دعوت، شمارهٔ نسخه، نام کاربری،
   شبا و هر رشته‌ای که کاربر جایی بیرون از سامانه می‌چسباند. «ABCD۱۲۳» قاطی
   غلط به نظر می‌رسد و کد را ناخوانا می‌کند.
*/
.latn, code, kbd, samp {
    font-feature-settings: "tnum";
    direction: ltr;
    unicode-bidi: isolate;
}

/* نام کاربر، کانال و فایل از ورودی کاربر می‌آیند؛ یک نام عبری یا لاتین
   بی‌جداسازی، نشانه‌گذاری کل سطر را به‌هم می‌ریزد. */
bdi { unicode-bidi: isolate; }

/* ---------- طرح‌بندی پنل ---------- */
.app { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 100vh; }

.sidebar {
    background: var(--bg-0);
    border-inline-end: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--line);
    color: var(--text);
}
.brand:hover { text-decoration: none; }
.brand img { width: 32px; height: 32px; }
.brand b { display: block; font-size: 15px; }
.brand span { display: block; font-size: 11.5px; color: var(--muted); }

.nav { flex: 1; overflow-y: auto; padding: var(--s2); }

/*
   دستهٔ کشویی. details/summary است، پس باز و بسته‌شدن کارِ مرورگر است.

   مثلث پیش‌فرضِ summary برداشته می‌شود و جایش یک chevron می‌آید که با باز
   شدن می‌چرخد: مثلثِ بومی در RTL سمتِ غلط را نشان می‌دهد و در فایرفاکس و
   وب‌کیت دو شکل متفاوت دارد. list-style برای فایرفاکس و ::-webkit-details-marker
   برای وب‌کیت — هر دو لازم است، یکی کافی نیست.
*/
.nav-group { margin-bottom: var(--s1); }
.nav-group > summary::-webkit-details-marker { display: none; }

.nav-title {
    display: flex; align-items: center; gap: var(--s2);
    list-style: none; cursor: pointer; user-select: none;
    font-size: 12px; font-weight: 600; color: var(--faint);
    padding: var(--s2) var(--s2);
    border-radius: var(--radius-sm);
    transition: background .14s, color .14s;
}
.nav-title:hover { background: var(--bg-2); color: var(--text); }
.nav-title > span { flex: 1; }
.nav-title > i:first-child { font-size: 15px; }

.nav-caret {
    font-size: 11px; opacity: .6;
    transition: transform .18s ease;
}
.nav-group[open] > .nav-title > .nav-caret { transform: rotate(180deg); }

/* آیتم‌های دستهٔ بسته را نباید tab گرفت — جاوااسکریپت لازم نیست، details
   خودش محتوا را از درخت دسترسی بیرون می‌برد. فقط تورفتگی می‌دهیم تا
   سلسله‌مراتب دیده شود. */
.nav-group > .nav-item { margin-inline-start: var(--s3); }

/*
   هر آیتم منو برچسب متنی دارد، نه آیکون تنها. پرتکرارترین گلایهٔ کاربران
   دیسکورد همین است: «دکمه‌ها را پیدا نمی‌کنم»، «آن‌قدر کوچک است که تنظیمات
   را ندیدم». آیکون اینجا کمکِ متن است، جانشینش نه.
*/
.nav-item {
    position: relative;
    display: flex; align-items: center; gap: var(--s2);
    padding: var(--s2) var(--s3);
    border-radius: var(--radius-sm);
    color: var(--muted); font-size: 14px;
    transition: background .14s, color .14s;
}
.nav-item:hover { background: var(--bg-2); color: var(--text); text-decoration: none; }
.nav-item i { font-size: 16px; }

/* آیکون هر آیتم رنگ دستهٔ خودش را می‌گیرد — دسته‌بندی در یک نگاه دیده
   می‌شود، بی‌آنکه عنوان دسته را بخوانی. */
.nav-item[data-hue] i { color: var(--hue-fg); }

/*
   آیتم فعال: سطحِ برآمده + متنِ رنگ شاخص + نوار باریک لبه.

   پُرکنندهٔ تمام‌رنگ امتحان شد و غلط بود: یک بلوک درشتِ رنگِ اشباع در منو
   می‌زند و با رنگ لایم یا سایان چشم را خسته می‌کند. رنگ شاخص باید روی
   درصد کمی از پیکسل‌ها بنشیند — متن، نوار، حلقه — نه روی سطح.

   ترکیب سه نشانه (پس‌زمینهٔ روشن‌تر، رنگ متن، نوار لبه) یعنی «کجا هستم»
   بی‌تکیه بر رنگِ تنها هم خوانده می‌شود؛ برای کوررنگ مهم است.
*/
/* آیتم فعال رنگ دستهٔ خودش را می‌گیرد، و اگر دسته رنگ نداشت به رنگ شاخص
   برمی‌گردد — پس منوی بی‌دسته هم کار می‌کند. */
.nav-item.on {
    background: var(--hue-bg, var(--bg-3));
    color: var(--hue-fg, var(--accent));
    font-weight: 600;
}
.nav-item.on i { color: inherit; }

.nav-item.on::before {
    content: '';
    position: absolute;
    inset-inline-start: 0;
    inset-block: 18%;
    width: 3px;
    border-radius: 999px;
    background: var(--hue-fg, var(--accent));
}

/* عنوان دسته هم رنگ می‌گیرد تا سرِ گروه از آیتم‌هایش جدا خوانده شود.
   data-hue روی details نشسته، پس از آنجا خوانده می‌شود نه از خودِ summary. */
.nav-group[data-hue] > .nav-title { color: var(--hue-fg); }
.nav-group[data-hue] > .nav-title > i:first-child { color: var(--hue-fg); }

.sidebar-foot {
    padding: var(--s3); border-top: 1px solid var(--line);
    display: flex; align-items: center; gap: var(--s2);
}
.who { display: flex; align-items: center; gap: var(--s2); flex: 1; min-width: 0; }
.who-text { min-width: 0; }
.who-text b { display: block; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-text span { display: block; font-size: 11.5px; color: var(--muted); }

.main { display: flex; flex-direction: column; min-width: 0; }

/* نوار بالا یک پله روشن‌تر از بوم است. در تم تاریک سایه دیده نمی‌شود، پس
   جداشدن سرصفحه از محتوا را باید با روشنایی ساخت نه box-shadow. */
.topbar {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4);
    background: var(--bg-2);
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 5;
}
.topbar h1 { flex: 1; min-width: 0; }

.content { padding: var(--s4) var(--s4) 80px; }

/* ---------- کارت و شبکه ---------- */
.card {
    background: var(--bg-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: var(--s4);
    margin-bottom: var(--s3);
}
.card.narrow { max-width: 520px; margin-inline: auto; }

.grid { display: grid; gap: var(--s3); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.row { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.row-end { justify-content: flex-end; }
.spacer { flex: 1; }

/* ---------- آمار ---------- */
.stat {
    background: var(--bg-2); border: 1px solid var(--line);
    border-radius: var(--radius); padding: var(--s3) var(--s4);
}
.stat b {
    display: block; font-size: 23px; font-weight: 700; line-height: 1.3;
    font-feature-settings: "tnum";
}
/* همان تلهٔ ss01 که در .num توضیح داده شد. این یکی جا مانده بود و در
   صفحهٔ انگلیسی، عددِ درشتِ آمار را فارسی نشان می‌داد. */
.stat b:lang(fa) { font-feature-settings: "ss01", "tnum"; }
.stat span { font-size: 12.5px; color: var(--muted); }

/* ---------- دکمه ---------- */
.btn {
    font: inherit; cursor: pointer;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line-strong);
    background: var(--bg-3);
    color: var(--text);
    padding: var(--s2) var(--s3);
    display: inline-flex; align-items: center; gap: var(--s1);
    transition: background .14s, border-color .14s, transform .08s;
}
.btn:hover:not(:disabled) { background: var(--bg-2); text-decoration: none; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* جوهر تیره روی رنگ شاخص، نه سفید: رنگ شاخصِ روشن با متن سفید خوانا نیست */
.btn-primary {
    background: var(--accent); border-color: var(--accent);
    color: var(--accent-ink); font-weight: 600;
}
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn-danger:hover:not(:disabled) { background: var(--danger); color: var(--bg-0); }

.btn-warn { background: var(--warn); border-color: var(--warn); color: var(--bg-0); font-weight: 600; }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--muted); }
.btn-ghost:hover:not(:disabled) { background: var(--bg-2); color: var(--text); }
.btn-sm { padding: var(--s1) var(--s2); font-size: 13px; }
.btn-block { width: 100%; justify-content: center; margin-top: var(--s3); }
.btn.on { background: var(--danger); border-color: var(--danger); color: var(--bg-0); }

/* حلقهٔ تمرکز پیدا — برای کسی که با کیبورد حرکت می‌کند */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ---------- فرم ---------- */
label { display: block; font-size: 13px; color: var(--muted); margin: var(--s3) 0 var(--s1); }
label.inline { display: inline-flex; align-items: center; gap: var(--s2); color: var(--text); margin: 0; cursor: pointer; }

input[type=text], input[type=password], input[type=number], input[type=search], select, textarea {
    width: 100%; font: inherit; color: var(--text);
    background: var(--bg-0);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    padding: var(--s2) var(--s3);
}
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { resize: vertical; min-height: 84px; line-height: 1.7; }
input[type=checkbox], input[type=radio] { accent-color: var(--accent); width: 17px; height: 17px; cursor: pointer; }
.field-error { color: var(--danger); font-size: 12.5px; margin-top: var(--s1); }

/* ---------- هشدار ---------- */
.alert {
    display: flex; gap: var(--s2); align-items: flex-start;
    border-radius: var(--radius-sm); padding: var(--s2) var(--s3);
    margin-bottom: var(--s3); font-size: 13.5px;
    border: 1px solid;
}
.alert i { margin-top: 5px; }
.alert-ok { background: color-mix(in srgb, var(--ok) 12%, transparent); border-color: var(--ok); color: var(--ok); }
.alert-bad { background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: var(--danger); color: var(--danger); }
.alert-warn { background: color-mix(in srgb, var(--warn) 12%, transparent); border-color: var(--warn); color: var(--warn); }

/* ---------- نشان ---------- */
.pill {
    display: inline-flex; align-items: center; gap: var(--s1);
    font-size: 11.5px; padding: 2px 10px; border-radius: 999px;
    border: 1px solid var(--line); color: var(--muted); white-space: nowrap;
}
.pill-live { color: var(--ok); border-color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.pill-wait { color: var(--warn); border-color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.pill-bad { color: var(--danger); border-color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.pill-info { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.pill-idle { color: var(--muted); }

/*
   نشانگر حضور با شکل هم فرق دارد نه فقط رنگ: برای کوررنگِ سرخ‌سبز، تکیه
   بر رنگِ تنها یعنی آنلاین و «مزاحم نشوید» یکی دیده می‌شود. همین کمبود
   یکی از گلایه‌های مستند کاربران دیسکورد است.
*/
.dot {
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--faint); display: inline-block; flex: none;
    border: 2px solid var(--bg-2);
    box-sizing: content-box;
}
.dot-online { background: var(--ok); }
.dot-idle { background: var(--warn); border-radius: 50% 50% 50% 0; }
.dot-busy { background: var(--danger); border-radius: 2px; height: 4px; }
.dot-offline { background: transparent; border-color: var(--faint); }

/* ---------- جدول ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th, td { text-align: start; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--line); }
th { color: var(--muted); font-weight: 600; font-size: 12.5px; white-space: nowrap; }
tbody tr:hover { background: var(--bg-3); }
.empty { text-align: center; color: var(--muted); padding: var(--s6) var(--s3); }

/* ستون عددی در جدول راست‌به‌چپ هم فیزیکاً راست‌چین می‌ماند: عدد مستقل از
   جهت بند، چپ‌به‌راست رندر می‌شود، پس رقم یکان همیشه سمت راست است. */
td.num, th.num { text-align: right; }

/* ---------- آواتار ---------- */
.avatar {
    width: 36px; height: 36px; flex: none;
    display: grid; place-items: center;
    border-radius: 34%;   /* مربعِ گرد، نه دایره — تمایز بصری از دیسکورد */
    background: var(--bg-3);
    border: 2px solid transparent;
    font-weight: 700; font-size: 14px;
    transition: border-radius .25s, border-color .12s;
}
.avatar-sm { width: 28px; height: 28px; font-size: 12px; }

/*
   ---------- هشت رنگ شاد ----------
   هر کاربر، گروه، دستهٔ منو و باکس شمارهٔ رنگ خودش را می‌گیرد
   (Services/Palette.cs) و هر تم آن شماره را به رنگِ مناسبِ روشن یا تاریک
   ترجمه می‌کند.

   data-hue خودش رنگ نمی‌گذارد؛ فقط دو متغیر محلی تعریف می‌کند و هر مؤلفه
   تصمیم می‌گیرد آن را کجا به کار ببرد — یکی پس‌زمینه، یکی نوار لبه، یکی
   رنگ عدد. بی این لایه، برای هر مؤلفه هشت قاعدهٔ تکراری لازم بود.

   جوهر از همان خانوادهٔ زمینه است نه مشکیِ خنثا؛ با مشکی، رنگ گل‌آلود
   به نظر می‌رسد.
*/
[data-hue="1"] { --hue-bg: var(--h1-bg); --hue-fg: var(--h1-fg); }
[data-hue="2"] { --hue-bg: var(--h2-bg); --hue-fg: var(--h2-fg); }
[data-hue="3"] { --hue-bg: var(--h3-bg); --hue-fg: var(--h3-fg); }
[data-hue="4"] { --hue-bg: var(--h4-bg); --hue-fg: var(--h4-fg); }
[data-hue="5"] { --hue-bg: var(--h5-bg); --hue-fg: var(--h5-fg); }
[data-hue="6"] { --hue-bg: var(--h6-bg); --hue-fg: var(--h6-fg); }
[data-hue="7"] { --hue-bg: var(--h7-bg); --hue-fg: var(--h7-fg); }
[data-hue="8"] { --hue-bg: var(--h8-bg); --hue-fg: var(--h8-fg); }

/*
   رنگِ موقعیتی: هر باکس در هر شبکه به ترتیب یکی از هشت رنگ را می‌گیرد، بی
   آن‌که لازم باشد در ویو چیزی نوشته شود.

   :where ویژگیِ صفر دارد، و همین نکتهٔ کلیدی است: رنگِ معنایی (کاربر، گروه،
   دستهٔ منو) که با data-hue می‌آید بر رنگِ موقعیتی می‌چربد. پس رنگ اکبر
   همه‌جا یکی می‌ماند، ولی باکس‌های بی‌هویت هم بی‌رنگ نمی‌مانند.
*/
   گزینهٔ دوم هر قاعده، کارت‌هایی را می‌گیرد که فرزند مستقیم شبکه نیستند:
   در صفحه‌هایی مثل پروفایل، ستون دوم یک div است و چند کارت در خود دارد. بی
   آن، همهٔ آن کارت‌ها رنگ ستون را به ارث می‌بردند و یک‌رنگ می‌شدند. شمارهٔ
   رنگشان دو واحد جابه‌جا شده تا با کارت ستون اول همسایه‌ٔ هم‌رنگ نشوند.
*/
:where(.grid > *:nth-child(8n+1), .grid > div > .card:nth-child(8n+7)) { --hue-bg: var(--h1-bg); --hue-fg: var(--h1-fg); }
:where(.grid > *:nth-child(8n+2), .grid > div > .card:nth-child(8n+8)) { --hue-bg: var(--h2-bg); --hue-fg: var(--h2-fg); }
:where(.grid > *:nth-child(8n+3), .grid > div > .card:nth-child(8n+1)) { --hue-bg: var(--h3-bg); --hue-fg: var(--h3-fg); }
:where(.grid > *:nth-child(8n+4), .grid > div > .card:nth-child(8n+2)) { --hue-bg: var(--h4-bg); --hue-fg: var(--h4-fg); }
:where(.grid > *:nth-child(8n+5), .grid > div > .card:nth-child(8n+3)) { --hue-bg: var(--h5-bg); --hue-fg: var(--h5-fg); }
:where(.grid > *:nth-child(8n+6), .grid > div > .card:nth-child(8n+4)) { --hue-bg: var(--h6-bg); --hue-fg: var(--h6-fg); }
:where(.grid > *:nth-child(8n+7), .grid > div > .card:nth-child(8n+5)) { --hue-bg: var(--h7-bg); --hue-fg: var(--h7-fg); }
:where(.grid > *:nth-child(8n+8), .grid > div > .card:nth-child(8n+6)) { --hue-bg: var(--h8-bg); --hue-fg: var(--h8-fg); }

/* آواتار: زمینهٔ کم‌رنگ و حرفِ پررنگ از همان خانواده */
.avatar[data-hue] { background: var(--hue-bg); color: var(--hue-fg); }

/*
   نوار رنگیِ لبهٔ باکس، نه پس‌زمینهٔ رنگیِ کل آن.

   پس‌زمینهٔ رنگی برای همهٔ باکس‌ها مسئله‌اش روشن است: متن بدنه روی هشت
   زمینهٔ مختلف باید هشت بار کنتراست‌سنجی شود و در تم روشن هم خوانا بماند.
   نوار لبه همان تشخیصِ رنگی را می‌دهد بی‌آنکه خوانایی را گرو بگذارد.

   با شبه‌عنصر است نه border، چون border مرزِ موجودِ کارت را جابه‌جا می‌کرد
   و باکس‌های بی‌رنگ هم ناهم‌تراز می‌شدند. transparent یعنی جایی که رنگی
   تعریف نشده، نواری هم دیده نمی‌شود.
*/
.card, .stat { position: relative; }

.card::after, .stat::after {
    content: '';
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    width: 4px;
    background: var(--hue-fg, transparent);
    border-start-start-radius: var(--radius);
    border-end-start-radius: var(--radius);
    pointer-events: none;
}

/* عدد و عنوان باکس هم رنگ می‌گیرند — نشانهٔ دوم، پیداتر از نوار لبه */
.stat b { color: var(--hue-fg, var(--text)); }
.card > h2:first-child, .card > h3:first-child { color: var(--hue-fg, inherit); }

/* h3 پیش‌فرض خاکستری است؛ وقتی رنگ دارد نباید خاکستری بماند، و وقتی ندارد
   باید همان خاکستری بماند نه رنگ متن اصلی. */
.card > h3:first-child { color: var(--hue-fg, var(--muted)); }

/* پس‌زمینه و متن بدنه دست‌نخورده می‌مانند، وگرنه کنتراست می‌شکند */
.card.card-hue { background: var(--bg-2); color: var(--text); }

/* ---------- گفت‌وگو ---------- */
.chat-shell { display: grid; grid-template-columns: var(--aside) 1fr; gap: var(--s3); align-items: start; }

.channel-list { list-style: none; margin: 0; padding: 0; }
.channel-list a {
    display: flex; align-items: center; gap: var(--s2);
    padding: var(--s2) var(--s2);
    border-radius: var(--radius-sm);
    color: var(--muted); font-size: 13.5px;
}
.channel-list a:hover { background: var(--bg-3); color: var(--text); text-decoration: none; }
/* همان قاعدهٔ منو: سطح برآمده و متنِ شاخص، نه بلوک تمام‌رنگ */
.channel-list a.on { background: var(--bg-3); color: var(--accent); font-weight: 600; }
.channel-list .count { margin-inline-start: auto; font-size: 11px; color: var(--accent); }

/*
   ---------- نشان نخوانده ----------
   شمار پیام خاکستری و آرام است؛ اشاره‌به‌من قرمز و پیدا. تفکیکشان یعنی کاربر
   می‌فهمد کدام کانال واقعاً فوری است، نه فقط «چیزی شد».
*/
.unread-slot { margin-inline-start: auto; display: inline-flex; gap: 4px; align-items: center; }

.unread {
    display: inline-flex; align-items: center; gap: 2px;
    min-width: 19px; padding: 0 6px;
    border-radius: 999px;
    background: var(--bg-3); color: var(--text);
    font-size: 11px; font-weight: 600;
    justify-content: center;
}
.unread-mention { background: var(--danger); color: var(--bg-0); }
.unread-mention i { font-size: 11px; }

/* کانالی که نخوانده دارد پررنگ‌تر دیده می‌شود — نشانهٔ دوم، بی‌تکیه بر رنگ */
.channel-list a:has(.unread) { color: var(--text); font-weight: 600; }

/*
   حاضرانِ اتاق صوتی زیر نام کانال فهرست می‌شوند. این مهم‌ترین قابلیت
   تک‌مؤلفه‌ای دیسکورد است: پیش از پیوستن می‌دانی چه کسی داخل است.
*/
.channel-present {
    list-style: none; margin: 0 0 var(--s1); padding: 0;
    padding-inline-start: 26px;
}
.channel-present li {
    display: flex; align-items: center; gap: 6px;
    font-size: 12px; color: var(--muted); padding: 1px 0;
}
.channel-present .avatar { width: 18px; height: 18px; font-size: 10px; border-width: 1.5px; }

.messages {
    height: 58vh; min-height: 320px;
    overflow-y: auto;
    padding: var(--s2) var(--s1);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg-1);
}

.msg { padding: var(--s1) var(--s3); border-radius: var(--radius-sm); }
.msg:hover { background: var(--bg-2); }
.msg:hover .msg-tools { visibility: visible; }

/* پیام پشت‌سرهم از یک نفر: نام و ساعت تکرار نمی‌شود. همان الگوی
   گروه‌بندی دیسکورد که ستون گفت‌وگو را خوانا نگه می‌دارد. */
.msg-grouped { padding-top: 0; }
.msg-grouped .msg-head { display: none; }

.msg-head { display: flex; align-items: center; gap: var(--s2); font-size: 12px; color: var(--muted); }
.msg-author { color: var(--text); font-weight: 600; font-size: 13.5px; }
.msg-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.msg-deleted { color: var(--faint); font-style: italic; }
.msg-tools { visibility: hidden; margin-inline-start: auto; display: flex; gap: 2px; }
.msg-system { font-size: 12px; color: var(--faint); font-style: italic; padding: var(--s1) var(--s3); }

/* پیامی که مرا اشاره کرده: نوار کناری و پس‌زمینهٔ کم‌رنگِ رنگ شاخص */
.msg-mine { background: var(--accent-soft); border-inline-start: 3px solid var(--accent); }

.quote {
    border-inline-start: 3px solid var(--line-strong);
    padding-inline-start: var(--s2); margin-bottom: var(--s1);
    font-size: 12.5px; color: var(--muted);
}

.reactions { display: flex; gap: var(--s1); flex-wrap: wrap; margin-top: var(--s1); }
.reaction {
    font: inherit; cursor: pointer; font-size: 12.5px;
    background: var(--bg-3); border: 1px solid var(--line);
    border-radius: 999px; padding: 1px 10px; color: var(--text);
}
.reaction:hover { border-color: var(--line-strong); }
.reaction.mine { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

.attach { display: inline-flex; align-items: center; gap: var(--s1); font-size: 12.5px; margin-top: var(--s1); }
.attach img { max-width: min(340px, 100%); border-radius: var(--radius-sm); display: block; }

.chat-form { display: flex; gap: var(--s2); margin-top: var(--s3); align-items: flex-start; }
.chat-form textarea { min-height: 44px; max-height: 150px; }

/* ---------- اتاق صوتی ---------- */
.voice-shell { display: grid; grid-template-columns: var(--aside) 1fr; gap: var(--s3); align-items: start; }

.meter {
    flex: 1; height: 8px; min-width: 80px;
    background: var(--bg-0); border: 1px solid var(--line);
    border-radius: 999px; overflow: hidden;
}
.meter-sm { flex: none; width: 72px; }

/* سنجهٔ صدا در راست‌به‌چپ از راست پر می‌شود — نشانگر سطح باید با جهت
   خواندن هم‌جهت باشد، برخلاف دکمهٔ پخش که هرگز آینه نمی‌شود. */
.meter-fill { height: 100%; width: 0; background: var(--accent); transition: width .08s linear; }

.members { list-style: none; margin: 0; padding: 0; }
.member {
    display: grid; grid-template-columns: auto 1fr auto;
    align-items: center; gap: var(--s2);
    padding: var(--s2); border-radius: var(--radius-sm);
}
.member:hover { background: var(--bg-3); }

/* حلقهٔ «در حال صحبت» — تنها جایی که رنگ لایم اجازهٔ حضور دارد */
.member.speaking .avatar {
    border-color: var(--accent);
    border-radius: 50%;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 24%, transparent);
}

.member-name { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.member-sub { font-size: 11.5px; color: var(--muted); }
.member-tools { display: flex; gap: 2px; align-items: center; }
.volume { width: 72px; accent-color: var(--accent); }

.controls {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s3); flex-wrap: wrap;
    padding: var(--s3) var(--s4); margin-top: var(--s3);
    background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
}
.controls > div { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }

.audio-sink { display: none; }

/* ---------- شناسه و QR ---------- */
.qr-share { display: flex; gap: var(--s4); align-items: flex-start; flex-wrap: wrap; }

/*
   قاب سفید زیر QR اجباری است، نه تزئینی: کد برای خوانده‌شدن به کنتراست بالا
   و حاشیهٔ روشن (quiet zone) نیاز دارد. گذاشتنش روی پس‌زمینهٔ تیرهٔ تم،
   اسکنر را ناکام می‌گذارد.
*/
.qr-frame {
    background: #fff;
    /* در تم روشن، سفید روی سفید گم می‌شود؛ مرز نازک جدایش می‌کند */
    border: 1px solid var(--line);
    padding: var(--s2);
    border-radius: var(--radius-sm);
    width: 168px; height: 168px;
    flex: none;
    display: grid; place-items: center;
}
.qr-frame svg { width: 100%; height: 100%; display: block; }

/* ---------- کارت عضویت ----------
   نسبت ۱.۵۸۶ همان کارت بانکی (۸۵٫۶ × ۵۴ میلی‌متر) است، پس چاپش در اندازهٔ
   واقعی جا می‌شود و در جاکارتی معمولی می‌نشیند. */
.memcard {
    width: min(100%, 440px);
    min-width: 280px;      /* زیر این عرض، نام و شناسه روی هم می‌افتند */
    aspect-ratio: 1.586;
    background: linear-gradient(145deg, var(--bg-2), var(--bg-0));
    border: 1px solid var(--line-strong);
    border-radius: 16px;
    padding: var(--s4);
    display: grid;
    /* minmax(0, 1fr) و نه 1fr: کمینهٔ خودکارِ ستون، اندازهٔ محتوای درون آن است،
       پس یک نام بلند ستون را پهن می‌کرد و کارت را می‌ترکاند. */
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto 1fr;
    gap: var(--s3);
    position: relative;
    overflow: hidden;
}

/* درخششی که از گوشه می‌آید — نورِ محیطی، نه رنگِ پهن‌شده روی سطح */
.memcard::before {
    content: '';
    position: absolute;
    inset-block-start: -40%;
    inset-inline-end: -20%;
    width: 70%; aspect-ratio: 1;
    background: radial-gradient(circle, var(--glow), transparent 70%);
    pointer-events: none;
}

.memcard-head { grid-column: 1 / -1; display: flex; align-items: center; gap: var(--s2); }
.memcard-head img { width: 26px; height: 26px; }
.memcard-head b { display: block; font-size: 13.5px; line-height: 1.4; }

/* فرزند مستقیم، نه هر span: بی این قید، همین قاعده روی نشان بسته هم می‌افتاد
   (ویژگی ۰٫۱٫۱ در برابر ۰٫۱٫۰ کلاسِ نشان) و متنِ خاکستری روی پس‌زمینهٔ لایم
   می‌نشست — کنتراستی حدود ۲:۱ که خوانا نیست. */
.memcard-head > div > span { display: block; font-size: 10.5px; color: var(--muted); }

.memcard-tier {
    margin-inline-start: auto;
    font-size: 11px; font-weight: 600;
    padding: 2px 10px; border-radius: 999px;
    background: var(--accent); color: var(--accent-ink);
}

.memcard-body { display: flex; flex-direction: column; gap: var(--s2); justify-content: space-between; min-width: 0; }

.memcard-who { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
.memcard-who b { display: block; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.memcard-who span { display: block; font-size: 11.5px; color: var(--muted); }

.memcard label { display: block; font-size: 9.5px; color: var(--faint); margin: 0 0 1px; }

/* شناسه با فاصلهٔ حرفی باز — این رشته لاتین است و قاعدهٔ «بی فاصلهٔ حرفی
   برای فارسی» شاملش نمی‌شود؛ اینجا فاصله خواندن گروه‌ها را آسان می‌کند. */
.memcard-id #memberId {
    font-size: 12px; font-weight: 600;
    letter-spacing: .06em;
    word-spacing: .18em;
}

/* دکمهٔ کپیِ روی کارت: کنارِ شناسه می‌نشیند، پس باید در ۸۵ میلی‌متر عرض
   جا شود. مربعِ ۲۲ پیکسلی بی‌برچسب، و برچسب در title و aria-label. */
.memcard-id { display: flex; align-items: flex-end; gap: var(--s2); }
.memcard-id > div:first-child { min-width: 0; }

.copy-mini {
    flex: none;
    width: 24px; height: 24px;
    display: grid; place-items: center;
    border: 1px solid var(--line); border-radius: 6px;
    background: var(--bg-2); color: var(--muted);
    font-size: 12px; cursor: pointer; padding: 0;
    transition: background .14s, color .14s, border-color .14s;
}
.copy-mini:hover { color: var(--text); border-color: var(--muted); }
.copy-mini.copied { color: var(--ok); border-color: currentColor; }
.copy-mini.copy-failed { color: var(--danger); border-color: currentColor; }

/* فیلد خواندنی + دکمهٔ کپی چسبیده به آن. ورودی flex:1 می‌گیرد و
   min-width:0 لازم است، وگرنه عرض پیش‌فرضِ input شبکه را پهن می‌کند. */
.copy-field { display: flex; align-items: stretch; gap: var(--s2); }
.copy-field > input { flex: 1; min-width: 0; }
.copy-field > .copy-mini { width: 32px; height: auto; font-size: 13px; }

/* دکمهٔ کپی وقتی موفق شد سبز می‌شود. همین نشانه کافی است؛ متن را عوض
   نمی‌کنیم چون دکمهٔ مربعی برچسب ندارد. */
.btn-copy.copied { color: var(--ok); }
.btn-copy.copy-failed { color: var(--danger); }

.memcard-meta { display: flex; gap: var(--s4); }
.memcard-meta span { font-size: 12px; }

.memcard-qr {
    background: #fff;
    border: 1px solid rgba(0,0,0,.08);
    border-radius: 10px;
    padding: 6px;
    width: 104px; height: 104px;
    align-self: end;
    display: grid; place-items: center;
}
.memcard-qr svg { width: 100%; height: 100%; display: block; }

/* روی گوشی باریک، QR کوچک‌تر می‌شود تا ستون متن جا بماند — کارت نسبتش را
   نگه می‌دارد، پس کوچک‌کردن ارتفاع هم با آن می‌آید. */
@media (max-width: 420px) {
    .memcard { padding: var(--s3); }
    .memcard-qr { width: 78px; height: 78px; padding: 4px; }
    .memcard-id #memberId { font-size: 10.5px; letter-spacing: .03em; }
}

/* ---------- چاپ ----------
   فقط ناحیهٔ print-area چاپ می‌شود و منو و نوارها حذف.

   اندازهٔ صفحه اینجا <b>تعیین نمی‌شود</b>. @page قاعده‌ای سندی است و با کلاس
   مشروط نمی‌شود، پس هر چه اینجا بنویسیم به همهٔ صفحه‌ها می‌چسبد: کارت
   عضویت به اندازهٔ کارت بانکی چاپ می‌شود و فاکتور هم — که آن را به نوار
   باریکِ بی‌فایده تبدیل می‌کرد. اندازهٔ کارت در print-card.css است و فقط
   خودِ صفحهٔ کارت آن را برمی‌دارد. */
@media print {
    body { background: #fff; }
    .sidebar, .topbar, .bottom-nav, .no-print, .alert { display: none !important; }
    .app { display: block; }
    .content { padding: 0; }
    .print-area { margin: 0; }

    /* کارت رنگِ تیره دارد و مرورگر پیش‌فرض پس‌زمینه را حذف می‌کند؛
       بی این دو خط، کارتِ سفیدِ خالی در می‌آمد. */
    .memcard, .invoice {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* فاکتور روی کاغذ: سایه و حاشیهٔ رنگی روی چاپگر فقط جوهر می‌برد. */
    .invoice { border: none; box-shadow: none; }
    .invoice::after { display: none; }
}

/* ---------- تعرفه و پرداخت ---------- */

.term-form { display: flex; gap: var(--s4); flex-wrap: wrap; align-items: flex-end; }

/*
   گزینه‌های مدت، دکمهٔ submit‌اند نه رادیو با جاوااسکریپت: فرم GET است، پس
   زدن هر دکمه نشانی را عوض می‌کند و دکمهٔ «بازگشت» مرورگر درست کار می‌کند.
   با رادیو، باید onchange می‌نوشتیم و بی جاوااسکریپت از کار می‌افتاد.
*/
.term-pills { display: flex; gap: var(--s2); flex-wrap: wrap; }
.term-pill {
    cursor: pointer; font: inherit; text-align: center;
    border: 2px solid var(--line); border-radius: var(--radius-sm);
    background: var(--bg-1); color: var(--text);
    padding: var(--s2) var(--s4); min-width: 104px;
    display: grid; gap: 2px;
    transition: border-color .14s, background .14s;
}
.term-pill:hover { border-color: var(--line-strong); }
.term-pill.on { border-color: var(--accent); background: var(--accent-soft); }
.term-pill b { font-size: 13.5px; }
.term-pill span { font-size: 11px; color: var(--ok); }

.plan-grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); align-items: start; }

.plan-card { display: flex; flex-direction: column; gap: var(--s2); }
.plan-card > .btn { margin-top: auto; }

/* بستهٔ پیشنهادی با حاشیه برجسته می‌شود، نه با بزرگ‌ترشدن: تغییر اندازه در
   شبکه، بقیهٔ کارت‌ها را هم جابه‌جا می‌کرد. */
.plan-card.featured { border-color: var(--accent); }
.plan-card.current { border-color: var(--ok); }

.plan-badge {
    position: absolute; top: calc(-1 * var(--s2)); inset-inline-end: var(--s4);
    font-size: 10.5px; font-weight: 600;
    padding: 2px var(--s2); border-radius: 999px;
    background: var(--accent); color: var(--accent-ink);
}
.plan-badge.now { background: var(--ok); color: #fff; inset-inline-end: auto; inset-inline-start: var(--s4); }

.plan-price { display: grid; gap: 2px; padding-block: var(--s2); }
.plan-price > b { font-size: 22px; line-height: 1.3; }
.plan-total { font-size: 12px; color: var(--muted); }
.plan-save { color: var(--ok); }

.plan-features { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.plan-features li { display: flex; gap: var(--s2); font-size: 13px; color: var(--muted); }
.plan-features i { color: var(--ok); margin-top: 4px; flex: none; }

/* نوار مصرف. از رنگِ hue همان کارت استفاده می‌کند، پس در هر تم و هر
   جایگاه خودش را جور می‌کند. */
.meter {
    margin-top: 6px;
    height: 5px; border-radius: 999px;
    background: var(--bg-3);
    overflow: hidden;
}
.meter > span {
    display: block; height: 100%;
    background: var(--hue-fg, var(--accent));
    border-radius: 999px;
}

/* ---------- صورت‌حساب ---------- */

.invoice-table th {
    text-align: start; font-weight: 400; color: var(--muted);
    padding: 5px 0; white-space: nowrap;
}
.invoice-table td { text-align: end; padding: 5px 0; }
.invoice-table .row-off td { color: var(--ok); }
.invoice-table .row-total th,
.invoice-table .row-total td {
    border-top: 1px solid var(--line-strong);
    padding-top: var(--s2);
    font-size: 15px; font-weight: 700; color: var(--text);
}

.invoice-head { display: flex; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; }
.invoice-head > div:first-child { display: flex; align-items: center; gap: var(--s2); }
.invoice-head img { width: 30px; height: 30px; }
.invoice-head b { display: block; }
.invoice-no { text-align: end; }
.invoice-state { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; padding-block: var(--s2); }

.pay-amount { padding-block: var(--s2); }
.pay-amount b { font-size: 22px; }

.pay-options { display: grid; gap: var(--s2); margin-bottom: var(--s3); }

/* کلِ کارتِ گزینه کلیک‌پذیر است، نه فقط دایرهٔ کوچک رادیو — روی گوشی
   هدف‌گیریِ ۱۶ پیکسل با انگشت، خطای کلیک می‌سازد. */
.pay-option {
    display: flex; align-items: flex-start; gap: var(--s2);
    border: 2px solid var(--line); border-radius: var(--radius-sm);
    padding: var(--s2) var(--s3); cursor: pointer;
}
.pay-option:hover { border-color: var(--line-strong); }
.pay-option:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.pay-option input { margin-top: 6px; flex: none; }
.pay-option > span { display: grid; gap: 1px; }
.pay-option b { font-size: 13.5px; }

/* صفحهٔ درگاه آزمایشی طرح‌بندیِ پنل ندارد؛ وسطِ صفحه می‌نشیند. */
.sandbox-wrap { min-height: 100vh; display: grid; place-items: center; padding: var(--s4); }

/* ---------- نمودار ----------
   SVG سمت سرور است، پس رنگ‌هایش از همین‌جا می‌آید و با عوض‌شدن تم خودش
   عوض می‌شود. مقدارِ ثابت در خودِ SVG، نمودار را در تم روشن ناخوانا
   می‌کرد. */
.chart-card { overflow: hidden; }

.chart {
    display: block;
    width: 100%;
    height: 220px;
    margin-top: var(--s2);

    /* preserveAspectRatio="none" ستون‌ها را با عرض ظرف می‌کشد؛ ارتفاع ثابت
       می‌ماند تا نمودارهای پشت‌سرهم هم‌قد باشند و مقایسه‌شدنی. */
}

.chart-grid { stroke: var(--line); stroke-width: 1; }

.chart-bar {
    fill: var(--hue-fg, var(--accent));
    transition: opacity .12s;
}
.chart-bar:hover { opacity: .72; }

/* ستونِ صفر به ارتفاع دو پیکسل کشیده می‌شود و کم‌رنگ: جای خالی در محور
   زمان با «داده نداریم» اشتباه می‌شد، و ستونِ پُررنگِ کوتاه با «مقدار کم». */
.chart-bar.zero { fill: var(--line-strong); opacity: .55; }

.chart-label {
    fill: var(--faint);
    font-size: 11px;
    text-anchor: middle;

    /* قلم در SVG ارث نمی‌برد و باید صریح باشد، وگرنه مرورگر سریف
       پیش‌فرض را می‌گذارد و برچسب‌ها با بقیهٔ صفحه ناجور می‌شوند. */
    font-family: 'Vazirmatn', 'Segoe UI', Tahoma, sans-serif;
}

/* ---------- ابزارهای درون‌ردیفی ----------
   details به‌عنوان کشویِ ابزارهای یک ردیف جدول. چرا نه مودال: مودال
   جاوااسکریپت و مدیریتِ تمرکز می‌خواهد، و details هر دو را از مرورگر
   می‌گیرد. position:relative روی خودِ details است تا پنل به همان ردیف
   بچسبد نه به صفحه. */
.row-tools { position: relative; }
.row-tools > summary { list-style: none; cursor: pointer; display: inline-flex; }
.row-tools > summary::-webkit-details-marker { display: none; }

.tool-panel {
    position: absolute; z-index: 40;
    inset-inline-end: 0; top: calc(100% + 4px);
    min-width: 300px; max-width: 92vw;
    background: var(--bg-2);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: var(--s3);
    box-shadow: 0 14px 40px rgba(0,0,0,.35);
    text-align: start;
}
.tool-panel hr { border: none; border-top: 1px solid var(--line); margin: var(--s3) 0; }
.tool-panel label { margin-top: var(--s2); }

/* ---------- برچسب و کشف گروه ---------- */

.tag-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s3); }
.tag-row.tight { margin-top: var(--s2); }

/*
   برچسب هم پیوند است و هم چک‌باکس، پس یک ظاهر برای هر دو. رنگش از
   --hue-fg برچسب می‌آید تا دسته‌ها در یک نگاه از هم جدا شوند — همان
   قاعده‌ای که منوی پنل دارد.
*/
.tag-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px var(--s2);
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--bg-1);
    color: var(--hue-fg, var(--muted));
    font-size: 12px; cursor: pointer; user-select: none;
    transition: background .14s, border-color .14s;
}
.tag-chip:hover { border-color: var(--hue-fg, var(--line-strong)); text-decoration: none; }
.tag-chip i { font-size: 12px; }
.tag-chip > b { font-size: 11px; opacity: .75; }

/* برچسبِ انتخاب‌شده پُر می‌شود، تا «روی چه صافی‌ای هستم» بی‌خواندن دیده شود */
.tag-chip.on {
    background: var(--hue-bg, var(--accent-soft));
    border-color: var(--hue-fg, var(--accent));
    font-weight: 600;
}
.tag-chip.sm { font-size: 11px; padding: 2px 7px; }
.tag-chip.clear { color: var(--danger); border-color: var(--danger); }

/* چک‌باکسِ درونِ برچسبِ انتخابی پنهان است: کلِ قرص هدفِ کلیک می‌شود، که
   روی گوشی تفاوتِ عملی دارد — مربعِ ۱۳ پیکسلی با انگشت خطا می‌دهد. */
.tag-chip.pick > input { position: absolute; opacity: 0; width: 0; height: 0; }
.tag-chip.pick:has(input:checked) {
    background: var(--hue-bg, var(--accent-soft));
    border-color: var(--hue-fg, var(--accent));
    font-weight: 600;
}

/* نشانِ تمرکزِ صفحه‌کلید، چون چک‌باکس پنهان است و حلقهٔ پیش‌فرض دیده نمی‌شد */
.tag-chip.pick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.explore-card { display: flex; flex-direction: column; gap: var(--s2); }

/* توضیح به دو خط بسته می‌شود تا کارت‌های یک ردیف هم‌قد بمانند؛ بی آن،
   یک گروه با توضیح بلند کلِ شبکه را کج می‌کرد. */
.explore-desc {
    margin: 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.explore-foot { margin-top: auto; }

/* ---------- تماس یک‌به‌یک ---------- */

/*
   تماس ورودی تمام صفحه را می‌گیرد و این عمدی است: زنگ باید مثل زنگ تلفن
   نادیده‌نگرفتنی باشد. نشانِ گوشه‌ای، در صفحهٔ پرِ گفت‌وگو گم می‌شد.
*/
.call-incoming {
    position: fixed; inset: 0; z-index: 70;
    display: grid; place-items: center;
    background: color-mix(in srgb, var(--bg-0) 86%, transparent);
    backdrop-filter: blur(3px);
}

.call-card {
    background: var(--bg-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: var(--s6) var(--s5);
    display: grid; gap: var(--s2); justify-items: center;
    min-width: 260px; text-align: center;
    box-shadow: 0 18px 50px rgba(0,0,0,.35);
}
.call-card > b { font-size: 19px; }

.call-ring-icon {
    font-size: 40px; color: var(--accent);
    /* تپش، نه چرخش: حرکتِ ملایمِ تکراری نگاه را می‌کشد بی‌آنکه آزار بدهد. */
    animation: call-pulse 1.4s ease-in-out infinite;
}
@keyframes call-pulse {
    0%, 100% { transform: scale(1); opacity: .85; }
    50% { transform: scale(1.14); opacity: 1; }
}

/* کاربری که animation را خاموش کرده، نباید تپش ببیند — و نشانِ تماس هم
   نباید از دست برود، پس آیکون می‌ماند و فقط حرکتش می‌رود. */
@media (prefers-reduced-motion: reduce) {
    .call-ring-icon { animation: none; }
}

.call-actions { display: flex; gap: var(--s2); margin-top: var(--s2); }

/*
   نوار تماس در جریان: پایین صفحه، بالای نوار پایینِ موبایل.
   ثابت می‌ماند تا کاربر بتواند وسط تماس در برنامه بچرخد — همان کاری که
   هر برنامهٔ تماسی می‌کند و نبودش یعنی قطعِ تماس با هر پیمایش.
*/
.call-bar {
    position: fixed; z-index: 60;
    inset-inline: var(--s4); bottom: var(--s4);
    margin-inline: auto; max-width: 420px;
    display: flex; align-items: center; gap: var(--s2);
    padding: var(--s2) var(--s3);
    background: var(--bg-2);
    border: 1px solid var(--accent);
    border-radius: 999px;
    box-shadow: 0 10px 30px rgba(0,0,0,.3);
}
.call-bar > i:first-child { color: var(--accent); font-size: 17px; }
.call-bar-text { flex: 1; min-width: 0; display: grid; }
.call-bar-text > b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.call-bar-text > span { font-size: 11px; }
.call-bar-time { font-size: 13px; font-variant-numeric: tabular-nums; }

/* روی موبایل نوار پایین هست، پس نوار تماس بالاترش می‌نشیند تا دکمه‌ها
   روی هم نیفتند. */
@media (max-width: 760px) {
    .call-bar { bottom: calc(var(--s4) + 56px); }
}

/* دکمهٔ تماس در کنار نام کاربر */
.btn-call { color: var(--ok); }

/*
   «رد تماس» و «پایان تماس» پُرِ قرمز می‌شوند، نه خط‌دور.
   کلاس جدا دارند و btn-danger را بازنویسی نمی‌کنند: آن کلاس در سراسر
   برنامه خط‌دور است و عوض‌کردنش یعنی هر دکمهٔ حذف و اخراج هم پُر می‌شد —
   تغییری که نخواسته بودم و در دیفِ CSS هم پیدا نبود.
*/
.btn-hangup {
    background: var(--danger); color: #fff; border-color: var(--danger);
}
.btn-hangup:hover:not(:disabled) { filter: brightness(1.1); color: #fff; }

/* نشانِ تماس بی‌پاسخ روی آیتم منو. در .nav-item که flex است، margin-inline-start
   خودکار آن را به لبهٔ انتهایی می‌چسباند بی‌نیاز به spacer. */
.call-badge {
    min-width: 17px; height: 17px; padding: 0 4px;
    border-radius: 999px;
    background: var(--danger); color: #fff;
    font-size: 10.5px; font-weight: 700;
    display: inline-grid; place-items: center;
    margin-inline-start: auto;
    font-variant-numeric: tabular-nums;
}

/* ردیفِ تماسِ بی‌پاسخِ دیده‌نشده. نوارِ لبه و نه پس‌زمینهٔ پُر: پس‌زمینهٔ
   قرمز در جدول، خواندنِ متن را سخت می‌کند و «خطا» معنا می‌دهد نه «تازه». */
tr.row-fresh > td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
tr.row-fresh > td { background: color-mix(in srgb, var(--danger) 7%, transparent); }

/* ---------- انتخاب تم ---------- */
.theme-row { display: flex; gap: var(--s2); flex-wrap: wrap; }
.theme-swatch {
    cursor: pointer; border: 2px solid var(--line);
    border-radius: var(--radius-sm); padding: var(--s2);
    background: var(--bg-1); color: var(--text);
    display: grid; gap: 6px; justify-items: center;
    font: inherit; font-size: 12px; min-width: 88px;
}
.theme-swatch:hover { border-color: var(--line-strong); }
.theme-swatch[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }
.theme-dots { display: flex; gap: 3px; }
.theme-dots span { width: 15px; height: 15px; border-radius: 50%; }

/* ---------- صفحهٔ ورود و عمومی ---------- */
.auth-page, .public-page { display: flex; flex-direction: column; min-height: 100vh; }

.auth-wrap {
    flex: 1; display: grid; place-content: center; gap: var(--s3);
    padding: var(--s5); justify-items: center;
    /* یک درخشش محیطی پشت کارت، نه گرادیان روی سطح — همان تفاوت میان
       «نور» و «رنگِ پهن‌شده» که ظاهر ۲۰۲۶ را از ۲۰۲۱ جدا می‌کند. */
    background: radial-gradient(ellipse 70% 55% at 50% 0%, var(--glow), transparent 70%);
}
.auth-brand { display: flex; align-items: center; gap: var(--s2); color: var(--text); font-size: 18px; font-weight: 700; }
.auth-brand:hover { text-decoration: none; }
.auth-brand img { width: 32px; height: 32px; }
.auth-card { width: min(100%, 420px); margin: 0; background: var(--bg-2); }
.auth-foot { color: var(--muted); font-size: 12.5px; }
.auth-links { display: flex; justify-content: space-between; gap: var(--s2); margin-top: var(--s3); font-size: 13px; }

.public-top {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
    padding: var(--s3) var(--s5); background: var(--bg-0); border-bottom: 1px solid var(--line);
}
.public-top nav { display: flex; gap: var(--s2); }
.public-main { flex: 1; max-width: 1040px; margin-inline: auto; padding: var(--s5); width: 100%; }
.public-foot { padding: var(--s4) var(--s5); border-top: 1px solid var(--line); color: var(--muted); font-size: 12.5px; text-align: center; }

.hero {
    text-align: center; padding: var(--s6) 0 var(--s4);
    background: radial-gradient(ellipse 60% 60% at 50% 0%, var(--glow), transparent 70%);
}
.hero h1 { font-size: 30px; margin-bottom: var(--s3); line-height: 1.45; }
.hero p { color: var(--muted); max-width: 640px; margin-inline: auto; }
.hero .row { justify-content: center; margin-top: var(--s4); }

.feature i { font-size: 22px; color: var(--accent); }

/* ---------- نوار پایین موبایل ---------- */
.bottom-nav { display: none; }
.only-narrow { display: none; }

@media (max-width: 960px) {
    .app { grid-template-columns: 1fr; }

    .sidebar {
        position: fixed; inset-block: 0; inset-inline-start: 0;
        width: var(--rail); z-index: 30;
        transform: translateX(100%);
        transition: transform .2s;
    }
    .sidebar.open { transform: none; }
    [dir="ltr"] .sidebar { transform: translateX(-100%); }
    [dir="ltr"] .sidebar.open { transform: none; }

    .only-narrow { display: inline-flex; }
    .content { padding-bottom: 86px; }

    .chat-shell, .voice-shell { grid-template-columns: 1fr; }

    .bottom-nav {
        display: flex; position: fixed; inset-block-end: 0; inset-inline: 0;
        background: var(--bg-0); border-top: 1px solid var(--line);
        padding: 6px var(--s1); z-index: 20;
    }
    .bottom-nav a {
        flex: 1; display: grid; justify-items: center; gap: 2px;
        color: var(--muted); font-size: 11px; padding: var(--s1) 0;
    }
    .bottom-nav a:hover { text-decoration: none; }
    .bottom-nav a.on { color: var(--accent); }
    .bottom-nav i { font-size: 19px; }
}

/* کسی که حرکت کمتر خواسته، نباید انیمیشن بگیرد */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}
