/* ===============================================================
   لایه‌ی پروژه.

   style.css همان قالب Mobilekit در PWA/ است، با این تفاوت که رنگ‌های ثابتش
   به توکن تبدیل شده‌اند (tokenize.php این کار را از روی نسخه‌ی خام تکرار می‌کند).
   هر چیزی که مخصوص این پروژه است اینجا می‌آید و چون بعد از قالب بارگذاری
   می‌شود، رویش را می‌گیرد.

   دو کار می‌کند:
     ۱. رنگ‌های ثابت قالب را به توکن وصل می‌کند (مقادیر از جدول setting)
     ۲. روی دسکتاپ برنامه را داخل یک قاب موبایل وسط صفحه نشان می‌دهد
   =============================================================== */


/* ---------------------------------------------------------------
   ۱) پالت
   توکن‌ها را تابع THEME() در <head> چاپ می‌کند.
   اینجا فقط سطح‌های اصلی قالب به آن توکن‌ها وصل می‌شوند.
   --------------------------------------------------------------- */

/* تخصیص عمداً با body.dark-mode-active برابر است، وگرنه قاعده‌ی خود قالب
   (که همان تخصیص را دارد و !important هم دارد) برنده می‌شود. */
body,
body.dark-mode-active {
    background: var(--bg) !important;
    color: var(--fg-muted);
}

/* روی موبایل با زمینه یکی است؛ در حالت دسکتاپ پایین‌تر عوض می‌شود
   تا قاب از پس‌زمینه جدا دیده شود. بدون !important تا قاعده‌ی media بتواند
   رویش را بگیرد. */
html { background: var(--bg); }

/* کپسول باید تمام ارتفاع را پر کند وگرنه زیرش رنگ body لخت دیده می‌شود. */
#appCapsule {
    background: var(--bg);
    min-height: 100vh;
}

/* صفحه‌ی بارگذاری اولیه — قالب رنگ سرمه‌ای و اسپینر آبی خودش را دارد. */
#loader,
body.dark-mode-active #loader {
    background: var(--bg);
}
#loader .spinner-border { color: var(--accent) !important; }

/* نوار دکمه‌ی ثابت پایین فرم‌ها (صفحه‌ی ورود و ۲FA) */
.form-button-group,
body.dark-mode-active .form-button-group {
    background: var(--surface);
    border-top: 1px solid var(--line);
}

/* نوار بالا و پایین */
.appHeader,
body.dark-mode-active .appHeader,
.appBottomMenu,
body.dark-mode-active .appBottomMenu,
.extraHeader,
body.dark-mode-active .extraHeader {
    background: var(--surface);
    border-color: var(--line);
    color: var(--fg);
}

.appHeader .pageTitle,
body.dark-mode-active .appHeader .pageTitle,
.appHeader .left .headerButton,
.appHeader .right .headerButton,
body.dark-mode-active .appHeader .left .headerButton,
body.dark-mode-active .appHeader .right .headerButton {
    color: var(--fg);
}

/* متن‌ها */
h1, h2, h3, h4, h5, h6,
body.dark-mode-active h1, body.dark-mode-active h2, body.dark-mode-active h3,
body.dark-mode-active h4, body.dark-mode-active h5, body.dark-mode-active h6 {
    color: var(--fg);
}

/* سطح‌ها */
.card,
body.dark-mode-active .card,
.listview,
body.dark-mode-active .listview,
.wide-block,
body.dark-mode-active .wide-block,
.section-title {
    background: var(--surface);
    color: var(--fg);
    border-color: var(--line);
}

.section-title { background: transparent; color: var(--fg-muted); }

/* فرم‌ها */
.form-group.boxed .form-control,
body.dark-mode-active .form-group.boxed .form-control,
.form-control,
body.dark-mode-active .form-control {
    background: var(--surface);
    color: var(--fg);
    border-color: var(--line);
}
.form-control:focus { border-color: var(--accent); box-shadow: none; }
.form-control::placeholder { color: var(--fg-muted); }

/* دکمه‌ی اصلی */
.btn-primary,
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
    background: var(--accent) !important;
    border-color: var(--accent) !important;
    color: var(--accent-fg) !important;
}
.btn-outline-primary {
    background: transparent !important;
    border-color: var(--accent) !important;
    color: var(--accent) !important;
}

/* حالت فعال منوی پایین */
.appBottomMenu .item.active i.bi,
.appBottomMenu .item.active strong,
body.dark-mode-active .appBottomMenu .item.active i.bi,
body.dark-mode-active .appBottomMenu .item.active strong {
    color: var(--accent);
}
.appBottomMenu .item i.bi,
.appBottomMenu .item strong,
body.dark-mode-active .appBottomMenu .item i.bi,
body.dark-mode-active .appBottomMenu .item strong {
    color: var(--fg-muted);
}

/* حباب چت */
.message-item .bubble {
    direction: rtl;
    text-align: right;
    background: var(--surface);
    color: var(--fg);
}
/* پیشوند body.dark-mode-active عمدی است: قاعده‌ی خود قالب
   «body.dark-mode-active .message-item .bubble» یک واحد ویژگی بیشتر دارد و
   بدون این پیشوند، متنِ حباب خودی رنگ متن عادی را می‌گیرد — روی رنگ شاخصِ
   روشنِ حالت تیره خوانا نیست. */
.message-item.user .bubble,
body.dark-mode-active .message-item.user .bubble {
    background: var(--accent);
    color: var(--accent-fg);
}

/* امضای سازنده */
.credit-link { font-size: 9pt; color: var(--fg-muted); text-decoration: none; }
.credit-link:hover, .credit-link:focus { color: var(--fg); text-decoration: underline; }


/* ---------------------------------------------------------------
   ۲) حالت دسکتاپ — قاب موبایل وسط صفحه

   قالب برای عرض موبایل ساخته شده و روی مانیتور کشیده و بدریخت می‌شود.
   به‌جای بستن دسترسی دسکتاپ، برنامه داخل یک قاب با عرض موبایل نشان
   داده می‌شود. نوارهای position:fixed هم به همان قاب محدود می‌شوند.
   --------------------------------------------------------------- */


@media (min-width: 768px) {

    /* پس‌زمینه‌ی بیرون قاب — کمی روشن‌تر از خود قاب تا لبه‌هایش دیده شود. */
    html { background: var(--surface-alt); }
    html:not(.dark-mode-active) { background: #E8E8E8; }

    body {
        /* قاب: عرض موبایل، وسط صفحه، با ارتفاع کامل */
        width: var(--frame);
        max-width: 100%;
        min-height: 100vh;
        margin: 0 auto;
        position: relative;
        overflow-x: hidden;
        border-left: 1px solid var(--line);
        border-right: 1px solid var(--line);
        box-shadow: 0 0 40px rgba(0, 0, 0, .18);
    }

    /* عنصرهای fixed نسبت به viewport می‌چسبند، نه به قاب.
       با تبدیل مختصاتشان به همان عرض، داخل قاب می‌مانند.
       هر عنصر position:fixed جدیدی که اضافه شد باید به این فهرست هم بیاید. */
    .appHeader,
    .extraHeader,
    .poll-modal,
    .chat-panel,
    .appBottomMenu,
    .chatFooter,
    .form-button-group,
    .fab-button.bottom-center,
    .notification-box,
    #loader {
        width: var(--frame) !important;
        max-width: 100%;
        left: 50% !important;
        right: auto !important;
        transform: translateX(-50%);
    }

    /* آفکانواس و مودال‌ها هم داخل قاب */
    .offcanvas.offcanvas-bottom,
    .action-sheet {
        width: var(--frame) !important;
        max-width: 100%;
        left: 50% !important;
        right: auto !important;
        transform: translateX(-50%);
    }

    .modal-dialog {
        max-width: var(--frame);
    }

    /* قاب‌های تمام‌صفحه‌ی مسابقه هم محدود شوند */
    .quiz-frame,
    .quiz-actions,
    .quiz-viewers,
    .touch-disabled {
        max-width: var(--frame);
        left: 50% !important;
        right: auto !important;
        transform: translateX(-50%);
    }
    .quiz-frame { width: calc(var(--frame) - 32px); }
    .quiz-actions { width: calc(var(--frame) - 40px); }
    /* کشوی کناری نسبت به viewport می‌چسبد؛ به لبه‌ی قاب منتقلش می‌کنیم.
       بدون این، منو ته صفحه‌ی دسکتاپ باز می‌شد و از برنامه جدا به نظر می‌رسید.
       style.css قالب در حالت راست‌چین start را سمت راست می‌گذارد و end را چپ،
       پس نگاشت اینجا هم همان است. */
    .offcanvas.offcanvas-start {
        right: calc(50% - var(--frame) / 2) !important;
        left: auto !important;
    }
    .offcanvas.offcanvas-end {
        left: calc(50% - var(--frame) / 2) !important;
        right: auto !important;
    }
}


/* ---------------------------------------------------------------
   ۴) اصلاح‌های موضعی
   --------------------------------------------------------------- */

/* توگل‌ها: در تم سیاه‌وسفید، رنگ شاخص سفید است. اگر دستگیره هم سفید بماند
   روی مسیر سفید ناپدید می‌شود. دستگیره را به رنگ متن‌روی‌شاخص می‌بریم. */
.form-check-input:checked ~ .form-check-label:after,
body.dark-mode-active .form-check-input:checked ~ .form-check-label:after,
.form-switch .form-check-input:checked ~ .form-check-label:after,
body.dark-mode-active .form-switch .form-check-input:checked ~ .form-check-label:after {
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
}
.form-switch .form-check-input:checked ~ .form-check-label:before,
body.dark-mode-active .form-switch .form-check-input:checked ~ .form-check-label:before {
    background: var(--accent-fg) !important;
}
.form-switch .form-check-label:before,
body.dark-mode-active .form-switch .form-check-label:before {
    background: var(--fg-muted);
}
.form-switch .form-check-label:after,
body.dark-mode-active .form-switch .form-check-label:after {
    background-color: var(--surface-alt);
    border-color: var(--line) !important;
}

/* دکمه‌ی تغییر تم روشن/تیره در نوار بالا */
.themeToggle {
    background: none;
    border: 0;
    padding: 0 6px;
    color: var(--fg);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}


/* ===============================================================
   لایه‌ی پروژه

   عمداً آخرین بخش فایل است: اُوِرایدهای تولیدشده‌ی بالا با انتخابگرهایی
   مثل «body.dark-mode-active .form-group.boxed .form-control» ویژگی
   (0,4,1) دارند و هر قاعده‌ی هم‌وزنی که قبل از آنها بیاید را می‌بازانند.
   با آخر بودن، قاعده‌های این بخش در تساوی ویژگی برنده می‌شوند.
   =============================================================== */

/* ---------------------------------------------------------------
   نظرسنجی چت.
   استایلش قبلاً در شیت برندشده بود و با حذف آن از بین رفت، برای همین
   بدون هیچ قاعده‌ای وسط جریان صفحه می‌افتاد و از کادر می‌زد بیرون.
   جاوااسکریپت صفحه به ارتفاعش paddingTop می‌دهد، یعنی انتظار دارد
   چسبیده و روی محتوا باشد — همان کاری که اینجا انجام می‌شود.
   --------------------------------------------------------------- */
.poll-modal {
    position: fixed;
    top: 56px;              /* درست زیر appHeader */
    left: 0;
    right: 0;
    z-index: 1020;
    padding: 12px 16px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.poll-modal .poll-question {
    margin: 0 0 10px;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.7;
    text-align: center;
    color: var(--fg-muted);
}

/* گزینه‌ها از تنظیمات می‌آیند و تعدادشان ثابت نیست، پس به‌جای ستون‌های
   ثابت بوت‌استرپ از flex استفاده می‌شود که ۲ تا ۶ گزینه را جا بدهد. */
.poll-modal .poll-options {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.poll-modal .poll-option {
    position: relative;
    flex: 1 1 calc(50% - 8px);
    min-width: 96px;
    height: 40px;
    padding: 0 10px;
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    color: var(--fg);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    transition: transform 120ms ease, background 120ms ease;
}

/* نوار درصد پشت متن می‌نشیند تا سهم هر گزینه در یک نگاه دیده شود. */
.poll-modal .poll-bar {
    position: absolute;
    inset-inline-start: 0;
    top: 0;
    bottom: 0;
    width: 0;
    background: var(--accent);
    opacity: .16;
    transition: width 320ms cubic-bezier(.22, .61, .36, 1);
    pointer-events: none;
}

.poll-modal .poll-label,
.poll-modal .poll-count {
    position: relative;   /* روی نوار */
    white-space: nowrap;
}

.poll-modal .poll-count {
    font-size: 10.5px;
    font-weight: 500;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

.poll-modal .poll-option.is-picked .poll-count { color: var(--accent-fg); }
.poll-modal .poll-option.is-picked .poll-bar   { opacity: 0; }

.poll-modal .poll-option:active { transform: scale(.96); }

.poll-modal .poll-option.is-picked {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-fg);
}

.poll-modal .poll-option.is-busy { opacity: .55; pointer-events: none; }


/* ---------------------------------------------------------------
   انیمیشن‌ها

   قواعد به صورت عادی نوشته شده‌اند و فقط زیر prefers-reduced-motion: reduce
   خاموش می‌شوند. حالت برعکس (no-preference) روی مرورگری که این پرسش رسانه‌ای
   را نمی‌شناسد هیچ انیمیشنی نمی‌داد.
   --------------------------------------------------------------- */

/* جهت حرکت. در راست‌چین برعکس چپ‌چین است تا حس «هل دادن» درست بماند. */
:root            { --spa-shift: -12px; }
html[dir="rtl"]  { --spa-shift:  12px; }

/* --- جابه‌جایی بین صفحه‌ها ---
   ترنسفورم عمداً روی #spa-root نیست: عنصرهای position:fixed داخلش
   (هدر و منوی پایین) مرجعشان عوض می‌شد و می‌پریدند. opacity این مشکل را
   ندارد، پس محو روی ریشه و اسلاید روی محتوا انجام می‌شود. */
#spa-root {
    transition: opacity 140ms ease;
}

#spa-root.spa-leave {
    opacity: 0;
}

#spa-root.spa-leave #appCapsule {
    transform: translateX(var(--spa-shift));
    transition: transform 140ms ease-in;
}

#spa-root.spa-enter #appCapsule {
    animation: spaEnter 260ms cubic-bezier(.22, .61, .36, 1);
}

/* صفحه‌ای که دکمه‌ی شناور دارد فقط محو می‌شود — چون آن دکمه position:fixed
   است و با ترنسفورمِ #appCapsule مرجعش عوض می‌شود. */
#spa-root.spa-no-slide.spa-leave #appCapsule,
#spa-root.spa-no-slide.spa-enter #appCapsule {
    transform: none;
    transition: none;
    animation: none;
}

@keyframes spaEnter {
    from { opacity: .35; transform: translateX(calc(var(--spa-shift) * -1.4)); }
    to   { opacity: 1;   transform: none; }
}

/* --- ورود پیام تازه در چت ---
   فقط به پیام‌هایی داده می‌شود که در تازه‌سازی قبلی نبودند، وگرنه هر
   ۷ ثانیه کل گفت‌وگو دوباره انیمیت می‌شد. */
.message-item.msg-enter {
    animation: msgEnter 300ms cubic-bezier(.22, .61, .36, 1);
}

@keyframes msgEnter {
    from { opacity: 0; transform: translateY(10px) scale(.96); }
    to   { opacity: 1; transform: none; }
}

/* --- بازخورد لمس دکمه‌ی ارسال --- */
#send-chat-btn {
    transition: transform 120ms ease;
}

#send-chat-btn:active {
    transform: scale(.86);
}

/* کاربری که در سیستم‌عاملش کاهش حرکت را روشن کرده، هیچ‌کدام را نمی‌بیند. */
@media (prefers-reduced-motion: reduce) {
    #spa-root,
    #spa-root.spa-leave,
    #spa-root.spa-leave #appCapsule,
    #spa-root.spa-enter #appCapsule,
    .message-item.msg-enter,
    #send-chat-btn,
    #send-chat-btn:active {
        transition: none;
        animation: none;
        transform: none;
    }
    #spa-root.spa-leave { opacity: 1; }
}


/* ---------------------------------------------------------------
   صفحه‌های ورود و ثبت‌نام

   بدون کارت و بدون قاب: محتوا وسط صفحه می‌نشیند و دکمه‌ی اصلی پایین
   می‌چسبد — همان الگویی که برنامه‌های موبایل دارند.
   --------------------------------------------------------------- */
.auth-page {
    min-height: 100vh;
    min-height: 100dvh;          /* روی موبایل نوار آدرس را حساب می‌کند */
    display: flex;
    flex-direction: column;
    padding: 24px 24px calc(24px + env(safe-area-inset-bottom));
    box-sizing: border-box;
}

/* بخش وسط: هرچه فضای آزاد هست را می‌گیرد و محتوایش را وسط می‌گذارد. */
.auth-main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    max-width: 340px;
    margin: 0 auto;
}

/* نشان جای لوگو — حرف اول عنوان برنامه. چون پروژه سفیدبرچسب است
   هیچ تصویر ثابتی اینجا نمی‌گذاریم. */
.auth-mark {
    width: 60px;
    height: 60px;
    margin: 0 auto 18px;
    border-radius: 18px;
    background: var(--accent);
    color: var(--accent-fg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    user-select: none;
}

.auth-title {
    margin: 0 0 5px;
    font-size: 20px;
    font-weight: 700;
    text-align: center;
    color: var(--fg);
}

.auth-sub {
    margin: 0 0 26px;
    font-size: 12.5px;
    text-align: center;
    color: var(--fg-muted);
}

/* هشدارها: فقط ته‌رنگ و لبه، با رنگ از توکن‌های معنایی. */
.auth-page .alert {
    padding: 11px 13px;
    margin-bottom: 18px;
    font-size: 12px;
    line-height: 1.7;
    border-radius: 12px;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    color: var(--fg);
}

.auth-page .alert-success {
    background: color-mix(in srgb, var(--ok) 15%, var(--bg));
    border-color: color-mix(in srgb, var(--ok) 45%, transparent);
}

.auth-page .alert-danger {
    background: color-mix(in srgb, var(--danger) 15%, var(--bg));
    border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}

.auth-page .alert-warning {
    background: color-mix(in srgb, var(--warn) 15%, var(--bg));
    border-color: color-mix(in srgb, var(--warn) 45%, transparent);
}

.auth-page .alert::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-left: 7px;
    vertical-align: middle;
    background: var(--fg-muted);
}

.auth-page .alert-success::before { background: var(--ok); }
.auth-page .alert-danger::before  { background: var(--danger); }
.auth-page .alert-warning::before { background: var(--warn); }

.auth-page .form-group.boxed { margin-bottom: 16px; }

/* قاعده‌ی عمومی قالب «body.dark-mode-active .form-group.boxed .form-control»
   ویژگی (0,4,1) دارد؛ برای همین انتخابگر اینجا هم باید هم‌وزن باشد، وگرنه
   فیلدها پس‌زمینه‌ی پُر می‌گرفتند و شکل کارتی می‌ماندند. */
body .auth-page .form-group.boxed .form-control,
body .auth-page .form-control {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    height: 46px;
    padding: 0 2px;
    color: var(--fg);
}

body .auth-page .form-group.boxed .form-control:focus,
body .auth-page .form-control:focus {
    border-bottom-color: var(--accent);
    box-shadow: none;
}

/* تکمیل خودکار مرورگر رنگ آبی خودش را تحمیل می‌کند و فیلد از پالت بیرون می‌زند. */
.auth-page .form-control:-webkit-autofill,
.auth-page .form-control:-webkit-autofill:hover,
.auth-page .form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--fg);
    -webkit-box-shadow: 0 0 0 1000px var(--bg) inset;
    caret-color: var(--fg);
}

.auth-page .form-label {
    font-size: 11px;
    color: var(--fg-muted);
    margin-bottom: 4px;
}

/* بخش پایین: دکمه‌ی اصلی و لینک‌ها، چسبیده به کف صفحه. */
.auth-bottom {
    flex: 0 0 auto;
    width: 100%;
    max-width: 340px;
    margin: 24px auto 0;
}

.auth-page .btn-block {
    width: 100%;
    height: 50px;
    border-radius: 14px;
    font-size: 15px;
    font-weight: 700;
}

.auth-alt {
    margin: 0 0 14px;
    font-size: 12.5px;
    text-align: center;
    color: var(--fg-muted);
}

.auth-alt a { font-weight: 700; color: var(--accent); }

.auth-hint {
    margin: 10px 0 0;
    font-size: 10.5px;
    line-height: 1.9;
    text-align: center;
    color: var(--fg-muted);
}

.auth-foot {
    margin-top: 10px;
    text-align: center;
}


/* ---------------------------------------------------------------
   تخته‌ی ایموجی و استیکر پیام‌رسان
   --------------------------------------------------------------- */
.chat-panel {
    position: fixed;
    bottom: 64px;                 /* بالای نوار نوشتن پیام */
    left: 0;
    right: 0;
    z-index: 1030;
    max-height: 46vh;
    overflow-y: auto;
    padding: 12px;
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -10px 30px -18px rgba(0, 0, 0, .6);
}

.chat-panel-grid {
    display: grid;
    gap: 6px;
}

.emoji-grid   { grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); }
.sticker-grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; }

.emoji-item {
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: transparent;
    /* فونت متن فارسی برنامه ایموجی ندارد و مربع خالی نشان می‌داد؛
       اینجا صراحتاً فونت ایموجی سیستم خواسته می‌شود. */
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji",
                 "Segoe UI Symbol", "Android Emoji", sans-serif;
    font-size: 23px;
    line-height: 1;
    cursor: pointer;
    transition: background 120ms ease, transform 120ms ease;
}

.emoji-item:hover  { background: var(--surface-alt); }
.emoji-item:active { transform: scale(.88); }

.sticker-item {
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface-alt);
    aspect-ratio: 1 / 1;
    cursor: pointer;
    transition: transform 120ms ease;
}

.sticker-item:active { transform: scale(.92); }

.sticker-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* پیامی که خودش فقط یک نشانی تصویر است، به‌جای متن نشان داده می‌شود. */
.message-item .bubble img.sticker-in-chat {
    display: block;
    width: 128px;
    max-width: 100%;
    height: auto;
    border-radius: var(--radius);
}

/* حبابی که فقط یک استیکر دارد، حباب نیست: قاب رنگی دورش استیکر را
   شبیه دکمه نشان می‌داد. پیشوند body لازم است تا از قاعده‌ی خود قالب
   جلو بزند. */
body .message-item .bubble:has(> img.sticker-in-chat),
body.dark-mode-active .message-item .bubble:has(> img.sticker-in-chat) {
    background: none;
    padding: 0;
    box-shadow: none;
}

/* ---------------------------------------------------------------
   مدیریت گزینه‌های نظرسنجی و استیکرها در صفحه‌ی تنظیمات
   --------------------------------------------------------------- */
/* ردیف گزینه خودش یک form-group boxed است تا فیلدش دقیقاً مثل بقیه‌ی
   صفحه‌های تنظیمات دیده شود؛ دکمه‌ی حذف کنارش می‌نشیند. */
.option-row {
    display: flex;
    align-items: flex-end;
    gap: 6px;
}

.option-row .input-wrapper { flex: 1 1 auto; }

.option-remove {
    flex: 0 0 34px;
    height: 42px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--fg-muted);
    font-size: 13px;
    cursor: pointer;
}

.option-remove:hover { background: var(--surface-alt); color: var(--danger); }

/* با دو گزینه، حذف معنا ندارد و دکمه‌اش خاموش می‌شود. */
#poll-option-list.at-minimum .option-remove { opacity: .3; pointer-events: none; }
#add-option { margin-top: 4px; }
#add-option:disabled { opacity: .4; }

.sticker-manager {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 10px;
}

.sticker-card {
    position: relative;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface-alt);
    overflow: hidden;
}

.sticker-card img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 6px;
    display: block;
}

.sticker-del {
    position: absolute;
    top: 5px;
    left: 5px;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, .55);
    color: #fff;
    font-size: 12px;
    cursor: pointer;
}

/* خانه‌ی «افزودن» هم‌اندازه‌ی بقیه است تا شبکه یکدست بماند. */
.sticker-add {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    aspect-ratio: 1 / 1;
    border: 1px dashed var(--line);
    border-radius: 14px;
    color: var(--fg-muted);
    font-size: 11px;
    cursor: pointer;
    transition: border-color 120ms ease, color 120ms ease;
}

.sticker-add:hover { border-color: var(--accent); color: var(--accent); }
.sticker-add i { font-size: 17px; }

.sticker-empty {
    margin: 12px 0 0;
    font-size: 12px;
    color: var(--fg-muted);
}

/* ---------------------------------------------------------------
   نوار نوشتن پیام

   دکمه‌های ایموجی و استیکر با کلاس btn-secondary قالب، مربع‌های خاکستریِ
   بی‌ربط به پالت می‌شدند. اینجا هم‌شکل و هم‌اندازه‌ی دکمه‌ی ارسال می‌شوند.
   --------------------------------------------------------------- */
.chatFooter .chat-tool {
    flex: 0 0 38px;
    width: 38px;
    height: 38px;
    padding: 0;
    border-radius: 50%;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    color: var(--fg-muted);
    font-size: 17px;
    line-height: 1;
    transition: color 120ms ease, transform 120ms ease, border-color 120ms ease;
}

.chatFooter .chat-tool:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.chatFooter .chat-tool:active { transform: scale(.9); }

/* دکمه‌ی باز، حالت فعال بگیرد تا معلوم باشد کدام تخته باز است. */
.chatFooter .chat-tool.is-open {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-fg);
}

.chatFooter #send-chat-btn {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
}

/* فاصله‌ی یکدست بین دکمه‌ها و کادر متن */
.chatFooter form {
    display: flex;
    align-items: center;
    gap: 7px;
}

.chatFooter .form-group.boxed {
    flex: 1 1 auto;
    margin-bottom: 0;
}

/* ---------------------------------------------------------------
   پخش زنده
   --------------------------------------------------------------- */
.stream-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;      /* به‌جای ترفند padding-top */
    background: #000;
}

.stream-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.stream-bad,
.stream-empty {
    margin: 0;
    padding: 18px;
    font-size: 12.5px;
    line-height: 1.9;
    text-align: center;
    color: var(--fg-muted);
}

/* شبکه‌ی انتخاب کانال وقتی بیش از یکی تعریف شده. */
.stream-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 12px;
}

.stream-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    color: var(--fg);
    text-decoration: none;
}

.stream-tile-art {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface-alt);
    overflow: hidden;
    transition: border-color 120ms ease, transform 120ms ease;
}

.stream-tile:active .stream-tile-art { transform: scale(.95); }
.stream-tile:hover  .stream-tile-art { border-color: var(--accent); }

.stream-tile-art img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 8px;
}

.stream-tile-art i { font-size: 26px; color: var(--fg-muted); }

.stream-tile span {
    font-size: 11.5px;
    text-align: center;
    line-height: 1.5;
}

/* نوار کانال‌های دیگر، زیر پخش جاری. */
.stream-strip {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding: 0 16px 4px;
    -webkit-overflow-scrolling: touch;
}

.stream-chip {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    width: 70px;
    color: var(--fg);
    text-decoration: none;
    font-size: 10.5px;
    text-align: center;
}

.stream-chip img,
.stream-chip i {
    width: 54px;
    height: 54px;
    border-radius: 14px;
    border: 1px solid var(--line);
    background: var(--surface-alt);
    object-fit: contain;
    padding: 6px;
}

.stream-chip i {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    color: var(--fg-muted);
}

/* دکمه‌های ردیف کانال در صفحه‌ی مدیریت. */
.stream-actions { display: flex; gap: 4px; }

.stream-btn {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--fg-muted);
    font-size: 13px;
    cursor: pointer;
}

.stream-btn:hover { background: var(--surface-alt); color: var(--accent); }
.stream-btn-danger:hover { color: var(--danger); }

/* ---------------------------------------------------------------
   مودال‌ها

   قالب برای dialogbox فقط عرض را محدود می‌کند، نه ارتفاع را؛ پس مودالی
   که محتوایش بلند بود تا کف صفحه کش می‌آمد و عملاً تمام‌صفحه می‌شد.
   اینجا ارتفاع سقف می‌گیرد و فقط بدنه اسکرول می‌شود، تا سربرگ و دکمه‌ها
   همیشه دیده شوند.

   modalbox و stories عمداً تمام‌صفحه‌اند و دست نمی‌خورند.
   --------------------------------------------------------------- */
.modal.dialogbox .modal-dialog,
.modal.action-sheet .modal-dialog {
    max-width: 340px;
    margin: auto;                 /* وسط افقی و عمودی */
}

.modal.dialogbox .modal-dialog {
    display: flex;
    align-items: center;
    min-height: calc(100% - 32px);
}

.modal.dialogbox .modal-content {
    width: 100%;
    max-height: calc(100vh - 48px);
    max-height: calc(100dvh - 48px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.modal.dialogbox .modal-header,
.modal.dialogbox .modal-footer {
    flex: 0 0 auto;
}

.modal.dialogbox .modal-body {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* فرم داخل مودال همان شکل بقیه‌ی صفحه‌ها را داشته باشد. */
.modal.dialogbox .modal-body .form-group.boxed:last-of-type { margin-bottom: 6px; }

/* ---------------------------------------------------------------
   دکمه‌های هدر

   قاعده‌ی .headerButton قالب برای <a> نوشته شده و پس‌زمینه/حاشیه را ریست
   نمی‌کند. هر <button> با همان کلاس، جعبه‌ی خاکستری پیش‌فرض مرورگر را
   نگه می‌داشت. (دکمه‌های تازه‌سازی و تغییر تم و افزودن همه <button>اند،
   چون کارشان ناوبری نیست.)
   --------------------------------------------------------------- */
button.headerButton {
    background: transparent;
    border: 0;
    padding: 10px;
    font: inherit;
    color: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

button.headerButton:focus { outline: none; }

/* ---------------------------------------------------------------
   دکمه‌های داخل مودال

   قاعده‌های قالب برای dialogbox رنگ‌های سرمه‌ای ثابت دارند
   (#0F1C2F برای دکمه، #1B283B برای جداکننده) و ویژگی‌شان خیلی بالاست
   (هفت کلاس تو در تو). برای همین دکمه‌ی «انصراف» آبی می‌شد و «بستن» در
   پس‌زمینه گم. انتخابگرها اینجا هم‌وزن نوشته شده‌اند تا پالت برنده شود.
   حالت hover/focus قالب !important دارد، پس اینجا هم لازم است.
   --------------------------------------------------------------- */
body .dialogbox .modal-dialog .modal-content .btn-inline,
body .dialogbox .modal-dialog .modal-content .modal-footer {
    background: var(--line);
    border-top: 1px solid var(--line);
}

body .dialogbox .modal-dialog .modal-content .btn-inline .btn,
body .dialogbox .modal-dialog .modal-content .modal-footer .btn {
    background: var(--surface);
    color: var(--fg);
    border: 0 !important;
    min-height: 52px;
    font-size: 14px;
    font-weight: 600;
}

body .dialogbox .modal-dialog .modal-content .btn-inline .btn:hover,
body .dialogbox .modal-dialog .modal-content .btn-inline .btn:focus,
body .dialogbox .modal-dialog .modal-content .btn-inline .btn:active,
body .dialogbox .modal-dialog .modal-content .btn-inline .btn.active,
body .dialogbox .modal-dialog .modal-content .modal-footer .btn:hover,
body .dialogbox .modal-dialog .modal-content .modal-footer .btn:focus,
body .dialogbox .modal-dialog .modal-content .modal-footer .btn:active {
    background: var(--surface-alt) !important;
    color: var(--fg) !important;
}

/* قاعده‌ی تیره‌ی قالب رنگ متن را #8195a6 می‌کند و یک واحد ویژگی بیشتر
   دارد (body.dark-mode-active به‌جای body)، پس اینجا هم هم‌وزن می‌شود. */
body.dark-mode-active .dialogbox .modal-dialog .modal-content .btn-inline .btn,
body.dark-mode-active .dialogbox .modal-dialog .modal-content .modal-footer .btn,
body.dark-mode-active .dialogbox .modal-dialog .modal-content .btn-list .btn {
    background: var(--surface);
    color: var(--fg);
}

body.dark-mode-active .dialogbox .modal-dialog .modal-content .btn-inline {
    background: var(--line);
}

/* دکمه‌ی تأیید (آخرین دکمه) پررنگ‌تر باشد تا کنش اصلی معلوم شود. */
body .dialogbox .modal-dialog .modal-content .btn-inline .btn[type="submit"],
body.dark-mode-active .dialogbox .modal-dialog .modal-content .btn-inline .btn[type="submit"] {
    color: var(--accent);
}

body .dialogbox .modal-dialog .modal-content .btn-list .btn {
    background: var(--surface);
    color: var(--fg);
    border-bottom-color: var(--line) !important;
}

body .dialogbox .modal-dialog .modal-content .btn-list .btn:hover,
body .dialogbox .modal-dialog .modal-content .btn-list .btn:focus,
body .dialogbox .modal-dialog .modal-content .btn-list .btn:active {
    background: var(--surface-alt) !important;
}

body .dialogbox .modal-dialog .modal-content .modal-title { color: var(--fg); }
body .dialogbox .modal-dialog .modal-content .modal-body  { color: var(--fg); }

/* فوتر تک‌دکمه‌ای هم مثل btn-inline تمام‌عرض شود. */
body .dialogbox .modal-dialog .modal-content .modal-footer {
    padding: 0;
    display: block;
}

body .dialogbox .modal-dialog .modal-content .modal-footer .btn {
    width: 100%;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg) !important;
}

/* ---------------------------------------------------------------
   ۱۰) گردی گوشه‌ها

   قالب همه‌جا 6px ثابت گذاشته بود، برای همین هر پالتی هم که انتخاب می‌شد
   شکل برنامه یکی بود. اینجا سطح‌های اصلی به --radius وصل می‌شوند تا هر
   پالت بتواند حس متفاوتی بدهد: تیز، ملایم یا کاملاً گرد.
   فقط سطح‌هایی که کاربر واقعاً می‌بیند در این فهرست‌اند؛ گردی‌های ۱۰۰٪
   (آواتارها) و نوارها عمداً دست‌نخورده‌اند.
   --------------------------------------------------------------- */

.btn,
body.dark-mode-active .btn,
.form-control,
body.dark-mode-active .form-control,
.custom-select,
.form-group.boxed .form-control,
body.dark-mode-active .form-group.boxed .form-control {
    border-radius: var(--radius) !important;
}

/* کارت‌ها و بلوک‌های محتوا */
.card,
.chat-panel,
.poll-opt,
.sticker-card,
.sticker-add,
.stream-tile-art,
.stream-chip,
.stream-frame,
.alert {
    border-radius: var(--radius) !important;
}

/* تصویرهایی که قالب گردشان کرده بود */
.imaged.radius   { border-radius: var(--radius-sm) !important; }

/* حباب چت کمی گردتر از بقیه است — این شکل استاندارد پیام‌رسان‌هاست. */
.message-item .bubble,
body.dark-mode-active .message-item .bubble {
    border-radius: var(--radius-lg) !important;
}

/* مودال و فوتر تمام‌عرضش باید یک عدد داشته باشند وگرنه گوشه‌ی پایین می‌شکند. */
.dialogbox .modal-dialog .modal-content,
body.dark-mode-active .dialogbox .modal-dialog .modal-content {
    border-radius: var(--radius-lg) !important;
}


/* اکشن‌شیت از پایین بالا می‌آید، پس فقط دو گوشه‌ی بالایش گرد است. */
.action-sheet .modal-content,
body.dark-mode-active .action-sheet .modal-content {
    border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
}

/* ---------------------------------------------------------------
   ۱۱) صفحه‌ی قالب و رنگ

   کارت‌های پالت عمداً هر دو نیمه (روشن و تیره) را نشان می‌دهند، چون
   انتخاب فقط برای حالت فعلی نیست و کاربر باید هر دو را با هم ببیند.
   --------------------------------------------------------------- */

.preset-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 12px;
}

.preset-card {
    background: none;
    border: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-family: inherit;
}

.preset-swatch {
    display: flex;
    width: 100%;
    height: 62px;
    overflow: hidden;
    border: 2px solid var(--line);
    transition: border-color .15s, transform .15s;
}

.preset-card:active .preset-swatch { transform: scale(.95); }
.preset-card.is-on .preset-swatch  { border-color: var(--accent); }

.preset-half {
    flex: 1;
    padding: 8px 7px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 5px;
}

.preset-dot {
    width: 16px;
    height: 16px;
    border-radius: 100%;
    display: block;
}

/* دو خط نازک، نمایندهٔ متن اصلی و خطوط جداکننده. */
.preset-line {
    height: 3px;
    border-radius: 3px;
    display: block;
    opacity: .85;
}
.preset-line:nth-of-type(2) { width: 80%; }
.preset-line:nth-of-type(3) { width: 55%; }

.preset-name {
    font-size: 11px;
    color: var(--fg);
}
.preset-card.is-on .preset-name {
    color: var(--accent);
    font-weight: 700;
}

.theme-hint {
    margin: 12px 0 0;
    font-size: 11px;
    line-height: 1.8;
    color: var(--fg-muted);
}

/* --- نمونه‌ی زنده --- */

.theme-demo {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--bg);
}

.theme-demo-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    color: var(--fg);
    font-size: 13px;
    font-weight: 700;
}
.theme-demo-bar i { color: var(--accent); font-weight: 400; }

.theme-demo-body { padding: 12px 14px 14px; }

.theme-demo-in,
.theme-demo-out {
    max-width: 78%;
    padding: 8px 12px;
    border-radius: var(--radius-lg);
    font-size: 12px;
    margin-bottom: 8px;
}

.theme-demo-in {
    background: var(--surface-alt);
    color: var(--fg);
    margin-left: auto;
}

.theme-demo-out {
    background: var(--accent);
    color: var(--accent-fg);
    margin-right: auto;
}

.theme-demo-muted {
    font-size: 11px;
    color: var(--fg-muted);
    margin: 0 0 12px;
}

/* --- رنگ دستی --- */

.theme-subhead {
    font-size: 12px;
    color: var(--fg-muted);
    margin: 20px 0 8px;
    font-weight: 700;
}

.theme-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--line);
    margin: 0;
    cursor: pointer;
}
.theme-row:last-child { border-bottom: 0; }

/* کادر رنگ مرورگر لبه و زمینه‌ی خودش را دارد؛ برداشته می‌شود تا فقط
   خودِ رنگ دیده شود. */
.theme-swatch {
    flex: none;
    width: 40px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: none;
    cursor: pointer;
}
.theme-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.theme-swatch::-webkit-color-swatch { border: 0; border-radius: calc(var(--radius-sm) - 1px); }
.theme-swatch::-moz-color-swatch { border: 0; border-radius: calc(var(--radius-sm) - 1px); }

.theme-row-label { flex: 1; font-size: 13px; color: var(--fg); }
/* فونت فارسی رقم‌های لاتین را به فارسی نگاشت می‌کند و کد رنگ «#F۴F۵FB»
   درمی‌آید. فونت تک‌فاصله این نگاشت را ندارد. */
.theme-row-hex {
    font-size: 11px;
    color: var(--fg-muted);
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* --- لغزنده --- */

.form-range {
    width: 100%;
    height: 24px;
    background: none;
    padding: 0;
    -webkit-appearance: none;
    appearance: none;
}
.form-range::-webkit-slider-runnable-track {
    height: 4px;
    border-radius: 4px;
    background: var(--line);
}
.form-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    margin-top: -8px;
    border-radius: 100%;
    background: var(--accent);
    border: 0;
}
.form-range::-moz-range-track {
    height: 4px;
    border-radius: 4px;
    background: var(--line);
}
.form-range::-moz-range-thumb {
    width: 20px;
    height: 20px;
    border-radius: 100%;
    background: var(--accent);
    border: 0;
}

/* ---------------------------------------------------------------
   ۱۲) نشان ثانویه

   رنگ ثانویه‌ی قالب به --fg-muted نگاشت شده. وقتی همان رنگ پس‌زمینه‌ی یک
   نشان می‌شود، متن رویش دیگر نباید رنگ متن عادی باشد — خاکستری روی خاکستری
   می‌شد (۲٫۳ در حالت تیره). متنِ «روی رنگ» در هر دو حالت درست است: در روشن
   سفید و در تیره تقریباً مشکی.
   --------------------------------------------------------------- */

.badge.bg-secondary,
.badge-secondary,
a.badge-secondary,
.icon-box.bg-secondary,
body.dark-mode-active .badge.bg-secondary,
body.dark-mode-active .badge-secondary,
body.dark-mode-active a.badge-secondary,
body.dark-mode-active .icon-box.bg-secondary {
    color: var(--accent-fg) !important;
}

/* ---------------------------------------------------------------
   ۱۳) انیمیشن‌های بیشتر

   همه با transform و opacity کار می‌کنند — تنها دو خاصیتی که مرورگر بدون
   چیدمان دوباره‌ی صفحه انیمیت می‌کند. انیمیت کردن width/height/top روی گوشی
   پرش می‌دهد.

   هر چیزی که اینجا اضافه شود باید به بلوک prefers-reduced-motion انتهای
   همین بخش هم برود.
   --------------------------------------------------------------- */

/* --- ورود ردیف‌های فهرست ---
   تأخیر پلکانی فقط برای ده ردیف اول: بعد از آن کاربر اسکرول کرده و
   دیگر اول فهرست را نمی‌بیند، ولی تأخیرِ بلند باعث می‌شد ردیف‌های پایین
   دیر ظاهر شوند. */
#appCapsule .listview > li {
    animation: rowIn 320ms cubic-bezier(.22, .61, .36, 1) backwards;
}
#appCapsule .listview > li:nth-child(1) { animation-delay: 0ms; }
#appCapsule .listview > li:nth-child(2) { animation-delay: 25ms; }
#appCapsule .listview > li:nth-child(3) { animation-delay: 50ms; }
#appCapsule .listview > li:nth-child(4) { animation-delay: 75ms; }
#appCapsule .listview > li:nth-child(5) { animation-delay: 100ms; }
#appCapsule .listview > li:nth-child(6) { animation-delay: 125ms; }
#appCapsule .listview > li:nth-child(7) { animation-delay: 150ms; }
#appCapsule .listview > li:nth-child(8) { animation-delay: 175ms; }
#appCapsule .listview > li:nth-child(n+9) { animation-delay: 200ms; }

@keyframes rowIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

/* --- ورود بخش‌ها --- */
#appCapsule > .section,
#appCapsule > .section-title {
    animation: sectionIn 360ms cubic-bezier(.22, .61, .36, 1) backwards;
}
#appCapsule > *:nth-child(2) { animation-delay: 40ms; }
#appCapsule > *:nth-child(3) { animation-delay: 80ms; }
#appCapsule > *:nth-child(n+4) { animation-delay: 120ms; }

@keyframes sectionIn {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

/* --- بازخورد لمس ---
   هر چیزی که کاربر روی آن انگشت می‌گذارد باید کمی فرو برود. */
.btn,
.appBottomMenu .item,
.listview > li > .item,
.listview > li > a,
.preset-card,
.stream-tile,
.icon-pick,
.stream-btn {
    transition: transform 120ms ease, background-color 160ms ease, color 160ms ease;
}

.btn:active,
.listview > li > .item:active,
.listview > li > a:active,
.stream-btn:active { transform: scale(.97); }

.appBottomMenu .item:active .col { transform: scale(.9); }
.appBottomMenu .item .col { transition: transform 140ms ease; }

/* --- ردیف فعال نوار پایین ---
   آیکون کمی بالا می‌آید تا بدون خواندن متن هم معلوم باشد کجایی. */
.appBottomMenu .item i {
    transition: transform 220ms cubic-bezier(.34, 1.56, .64, 1);
}
.appBottomMenu .item.active i {
    transform: translateY(-2px) scale(1.12);
}

/* --- کشوی کناری ---
   ردیف‌ها پشت سر هم می‌آیند؛ بدون این، کشو یکجا ظاهر می‌شود و سنگین
   به نظر می‌رسد. */
.offcanvas.show .listview > li {
    animation: sideIn 300ms cubic-bezier(.22, .61, .36, 1) backwards;
}
.offcanvas.show .listview > li:nth-child(1) { animation-delay: 40ms; }
.offcanvas.show .listview > li:nth-child(2) { animation-delay: 70ms; }
.offcanvas.show .listview > li:nth-child(3) { animation-delay: 100ms; }
.offcanvas.show .listview > li:nth-child(4) { animation-delay: 130ms; }
.offcanvas.show .listview > li:nth-child(5) { animation-delay: 160ms; }
.offcanvas.show .listview > li:nth-child(6) { animation-delay: 190ms; }
.offcanvas.show .listview > li:nth-child(n+7) { animation-delay: 220ms; }

.offcanvas.show .profileBox {
    animation: sideIn 320ms cubic-bezier(.22, .61, .36, 1) backwards;
}

@keyframes sideIn {
    from { opacity: 0; transform: translateX(24px); }
    to   { opacity: 1; transform: none; }
}
html[dir="ltr"] .offcanvas.show .listview > li,
html[dir="ltr"] .offcanvas.show .profileBox {
    animation-name: sideInLtr;
}
@keyframes sideInLtr {
    from { opacity: 0; transform: translateX(-24px); }
    to   { opacity: 1; transform: none; }
}

/* --- مودال --- */
.modal.fade .modal-dialog {
    transition: transform 260ms cubic-bezier(.22, .61, .36, 1), opacity 200ms ease;
    transform: scale(.94) translateY(10px);
    opacity: 0;
}
.modal.show .modal-dialog {
    transform: none;
    opacity: 1;
}

/* --- ورود تصویرها ---
   عکسی که دیر می‌رسد به‌جای پریدن، محو می‌شود. */
.imaged,
.card-img-top {
    animation: imgIn 400ms ease backwards;
}
@keyframes imgIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* --- تغییر پالت --- *
   وقتی رنگ‌ها عوض می‌شوند، پرش ناگهانی بد است. فقط روی سطح‌های بزرگ. */
body,
#appCapsule,
.appHeader,
.appBottomMenu,
.wide-block,
.card {
    transition: background-color 220ms ease, color 220ms ease, border-color 220ms ease;
}

/* --- نوار درصد نظرسنجی --- */
.poll-modal .poll-bar {
    transition: width 420ms cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {

    /* فقط حرکت خاموش می‌شود، نه ترنسفورم.
       نسخه‌ی قبلی همین بلوک روی .appHeader و .appBottomMenu هم
       «transform: none !important» می‌گذاشت. آن دو نوار position:fixed هستند و
       با left:50% + translateX(-50%) وسط قاب دسکتاپ می‌نشینند — یعنی ترنسفورمشان
       چیدمان است، نه انیمیشن. نتیجه این بود که برای هرکس که در سیستم‌عاملش
       کاهش حرکت روشن بود، هر دو نوار نصف عرض قاب به کنار می‌پریدند.
       پس اینجا فقط animation و transition برداشته می‌شوند. */
    #appCapsule .listview > li,
    #appCapsule > .section,
    #appCapsule > .section-title,
    .offcanvas.show .listview > li,
    .offcanvas.show .profileBox,
    .imaged,
    .card-img-top,
    .modal.fade .modal-dialog,
    .modal.show .modal-dialog,
    .appBottomMenu .item i,
    .appBottomMenu .item .col,
    .btn,
    .listview > li > .item,
    .listview > li > a,
    .preset-card,
    .stream-tile,
    .icon-pick,
    .stream-btn,
    .poll-modal .poll-bar,
    body,
    #appCapsule,
    .appHeader,
    .appBottomMenu,
    .wide-block,
    .card {
        animation: none !important;
        transition: none !important;
    }

    /* ترنسفورم فقط جایی صفر می‌شود که خودش حرکتِ تزئینی بوده:
       بازخورد لمس و بالا آمدن آیکون ردیف فعال. */
    .btn:active,
    .listview > li > .item:active,
    .listview > li > a:active,
    .stream-btn:active,
    .preset-card:active .preset-swatch,
    .stream-tile:active .stream-tile-art,
    .appBottomMenu .item:active .col,
    .appBottomMenu .item.active i,
    .poll-modal .poll-option:active,
    #send-chat-btn:active {
        transform: none !important;
    }
}
/* ---------------------------------------------------------------
   ۱۴) کشوی کناری

   قالب برای این بخش عکس پروفایل فرض کرده بود. اینجا پروژه سفیدبرچسب است و
   کاربرها عکس ندارند، پس حرف اول نامشان روی یک مربع رنگی می‌نشیند.
   --------------------------------------------------------------- */

.offcanvas {
    background: var(--surface);
    color: var(--fg);
}

.offcanvas .profileBox,
body.dark-mode-active .offcanvas .profileBox {
    background: var(--accent);
    color: var(--accent-fg);
}
.offcanvas .profileBox strong,
.offcanvas .profileBox .text-muted,
.offcanvas .profileBox .close-sidebar-button {
    color: var(--accent-fg) !important;
}
.offcanvas .profileBox .text-muted { opacity: .75; }

.sidebar-avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--radius);
    background: var(--accent-fg);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 17px;
}

.offcanvas .listview .icon-box,
body.dark-mode-active .offcanvas .listview .icon-box {
    background: var(--surface-alt) !important;
    color: var(--fg-muted);
    border-radius: var(--radius-sm);
}

.offcanvas .listview .item.is-here .icon-box {
    background: var(--accent) !important;
    color: var(--accent-fg);
}
.offcanvas .listview .item.is-here .in { color: var(--accent); font-weight: 700; }

.offcanvas .listview .item,
body.dark-mode-active .offcanvas .listview .item { color: var(--fg); }


/* ---------------------------------------------------------------
   ۱۵) انتخاب آیکون (صفحه‌ی منو)
   --------------------------------------------------------------- */

.icon-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    gap: 6px;
    max-height: 168px;
    overflow-y: auto;
    padding: 4px 2px;
}

.icon-pick {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--fg-muted);
    font-size: 18px;
    cursor: pointer;
    padding: 0;
}

.icon-pick.is-on {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--accent-fg);
}

.nav-off { opacity: .5; text-decoration: line-through; }


/* ---------------------------------------------------------------
   ۱۶) اعلان همگانی
   --------------------------------------------------------------- */

.notify-stat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    background: var(--surface-alt);
    border-radius: var(--radius);
}
.notify-stat b     { font-size: 26px; color: var(--fg); display: block; line-height: 1.2; }
.notify-stat span  { font-size: 12px; color: var(--fg-muted); }
.notify-stat i     { font-size: 28px; color: var(--accent); }


/* ---------------------------------------------------------------
   ۱۷) ردیف آیکون در تنظیمات کلی
   --------------------------------------------------------------- */

.icon-row {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 12px 0;
    border-bottom: 1px solid var(--line);
}
.icon-row:last-of-type { border-bottom: 0; }

.icon-row-art {
    flex: none;
    width: 56px;
    height: 56px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface-alt);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.icon-row-art img { width: 100%; height: 100%; object-fit: cover; }
.icon-row-art i   { font-size: 22px; color: var(--fg-muted); }

.icon-row-in { flex: 1; min-width: 0; }

/* ورودی فایل در قالب استایل ندارد و خام دیده می‌شود. */
input[type="file"].form-control,
body.dark-mode-active input[type="file"].form-control {
    padding: 8px 10px;
    height: auto;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    color: var(--fg-muted);
    font-size: 12px;
}


/* ---------------------------------------------------------------
   ۱۸) تب‌های صفحه‌ی کاربران
   --------------------------------------------------------------- */

.nav-tabs.style1 .nav-link,
body.dark-mode-active .nav-tabs.style1 .nav-link {
    color: var(--fg-muted);
    border-bottom: 2px solid transparent;
    background: none;
}

.nav-tabs.style1 .nav-link.active,
body.dark-mode-active .nav-tabs.style1 .nav-link.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    background: none;
}

.nav-tabs.style1 .nav-link .badge { margin-inline-start: 4px; }

/* توضیح وضعیت اعلان زیر فهرست کشو. وقتی سوییچ خاموش و غیرفعال است، بدون
   این جمله معلوم نیست چرا کار نمی‌کند. */
.push-note {
    margin: 4px 16px 0;
    font-size: 11px;
    line-height: 1.8;
    color: var(--fg-muted);
}
.push-note:empty { display: none; }

/* کادر پروفایل کشو.
   قالب آن را position:fixed با left:0 گذاشته و جایش را با margin-top روی
   بدنه باز کرده. آن ترفند فقط وقتی می‌خواند که کشو چسبیده به لبه‌ی
   صفحه‌نمایش باشد؛ داخل قاب وسط‌چینِ دسکتاپ، کادر از کشو کنده می‌شد و
   می‌پرید گوشه‌ی صفحه. اینجا به جریان عادی برمی‌گردد و بالای کشو می‌چسبد. */
#sidebarPanel .profileBox,
body.dark-mode-active #sidebarPanel .profileBox {
    position: sticky;
    top: 0;
    left: auto;
    right: auto;
    width: 100%;
}
#sidebarPanel .profileBox::before { display: none; }
#sidebarPanel .offcanvas-body { margin-top: 0; }

/* عنوان بخش.
   قالب این عنوان را داخل .section می‌گذارد که ۱۶ پیکسل پدینگ افقی دارد.
   وقتی مستقیم زیر #appCapsule بنشیند آن پدینگ را ندارد و عنوان به لبه‌ی
   صفحه می‌چسبد، در حالی که محتوای زیرش ۱۶ پیکسل تورفته است. */
.section-title {
    padding-left: 16px;
    padding-right: 16px;
}

/* .section (بدون full) خودش ۱۶ پیکسل پدینگ دارد؛ عنوان داخلش نباید دوباره بگیرد. */
.section:not(.full) > .section-title {
    padding-left: 0;
    padding-right: 0;
}

/* ---------------------------------------------------------------
   ۱۹) فاصله از نوار پایین

   قالب .fab-button.bottom-center را ۱۶ پیکسل از کف می‌گذارد، در حالی که
   نوار پایین ۵۶ پیکسل ارتفاع دارد — دکمه دقیقاً پشت نوار می‌افتاد.
   --------------------------------------------------------------- */

.fab-button.bottom-center,
.fab-button.bottom-right,
.fab-button.bottom-left {
    bottom: calc(56px + 16px);
    margin-bottom: env(safe-area-inset-bottom);
}


/* ---------------------------------------------------------------
   ۲۰) ردیف‌های مدیریت پیام
   --------------------------------------------------------------- */

.comment-block .item .comment-header .title,
body.dark-mode-active .comment-block .item .comment-header .title {
    color: var(--fg);
    font-size: 13px;
    margin: 0;
}

.comment-block .item .comment-header .time,
body.dark-mode-active .comment-block .item .comment-header .time {
    color: var(--fg-muted);
    font-size: 11px;
}

.comment-block .item .text,
body.dark-mode-active .comment-block .item .text { color: var(--fg); }

.comment-block .item {
    background: var(--surface-alt);
    border-radius: var(--radius);
    padding: 10px 12px;
    margin-bottom: 10px;
}

.comment-footer.stream-actions { justify-content: flex-start; }

/* دکمه‌ی تأیید همان شکل بقیه را دارد، فقط رنگش معنایی است. */
.stream-btn-ok        { color: var(--ok); }
.stream-btn-ok:hover,
.stream-btn-ok:focus  { background: color-mix(in srgb, var(--ok) 15%, transparent); }


/* ---------------------------------------------------------------
   ۲۱) استوری
   --------------------------------------------------------------- */

/* نام و دکمه‌ی بستن روی تصویر تیره ناپیدا می‌شدند. یک سایه‌ی ملایم از بالا
   خوانا نگهشان می‌دارد بدون اینکه تصویر را بپوشاند. */
.modal.stories .modal-header {
    background: linear-gradient(to bottom, rgba(0, 0, 0, .55), transparent);
    position: relative;
    z-index: 3;
}
.modal.stories .modal-header h4,
.modal.stories .modal-header .close-stories,
body.dark-mode-active .modal.stories .modal-header h4,
body.dark-mode-active .modal.stories .modal-header .close-stories {
    color: #FFF;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
.modal.stories .modal-header .close-stories { font-size: 24px; }

.modal.stories .story-bar {
    position: absolute;
    top: 8px;
    left: 12px;
    right: 12px;
    height: 3px;
    border-radius: 3px;
    background: rgba(255, 255, 255, .35);
    overflow: hidden;
    z-index: 4;
}
.modal.stories .story-bar span {
    display: block;
    width: 0;
    height: 100%;
    background: #FFF;
}

/* حلقه‌ی استوریِ دیده‌شده کمرنگ می‌شود — همان قراردادی که همه می‌شناسند. */
.story-block .splide__slide a .imaged {
    border: 2px solid var(--accent);
    padding: 2px;
    transition: border-color .2s, opacity .2s;
}
.story-block .splide__slide a.story-seen .imaged {
    border-color: var(--line);
    opacity: .65;
}


/* ---------------------------------------------------------------
   ۲۲) نوار پیشنهاد (اعلان و نصب)
   --------------------------------------------------------------- */

.prompt-bar {
    position: fixed;
    left: 50%;
    bottom: calc(56px + 20px);
    transform: translate(-50%, 20px);
    width: min(var(--frame, 480px) - 24px, calc(100% - 24px));
    margin-bottom: env(safe-area-inset-bottom);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 6px 24px rgba(0, 0, 0, .18);
    opacity: 0;
    transition: opacity .25s ease, transform .25s ease;
    z-index: 9000;
}
.prompt-bar.is-on { opacity: 1; transform: translate(-50%, 0); }

.prompt-text  { flex: 1; font-size: 12px; color: var(--fg); line-height: 1.6; }
.prompt-yes   { flex: none; }
.prompt-close {
    flex: none;
    background: none;
    border: 0;
    padding: 0 2px;
    font-size: 18px;
    color: var(--fg-muted);
    cursor: pointer;
}

/* ---------------------------------------------------------------
   ۲۳) توست

   قالب توست را یک نوار تمام‌عرض از بالای صفحه می‌آورد که روی هدر می‌نشیند و
   تا بسته نشود جای محتوا را می‌گیرد. اینجا به همان شکل آشنای اندروید درآمده:
   یک قرص کوچک وسطِ پایین که خودش می‌رود.

   قاعده روی خود .toast-box است، پس همه‌ی توست‌های پروژه — بدون استثنا —
   همین شکل را می‌گیرند.
   --------------------------------------------------------------- */

.toast-box,
body.dark-mode-active .toast-box {
    top: auto !important;
    bottom: calc(56px + 20px);
    left: 50% !important;
    right: auto !important;
    width: auto !important;
    max-width: min(var(--frame, 480px) - 48px, calc(100% - 48px));
    min-height: 0;
    margin: 0 0 env(safe-area-inset-bottom) 0;

    padding: 10px 18px;
    border-radius: 999px;
    background: rgba(28, 28, 30, .94);
    color: #FFF;
    font-size: 12px;
    line-height: 1.7;
    text-align: center;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .28);

    opacity: 0;
    transform: translate(-50%, 12px);
    transition: opacity .22s ease, transform .22s ease;
    pointer-events: none;   /* نباید جلوی کلیک روی چیزی که زیرش است را بگیرد */
}

.toast-box.show,
body.dark-mode-active .toast-box.show {
    opacity: 1;
    transform: translate(-50%, 0);
}

.toast-box .in,
body.dark-mode-active .toast-box .in {
    display: block;
    padding: 0;
}

.toast-box .text,
body.dark-mode-active .toast-box .text {
    color: #FFF;
    font-size: 12px;
}

/* توست اندروید دکمه ندارد؛ خودش می‌رود. */
.toast-box .close-button,
.toast-box .btn {
    display: none !important;
}

/* در صفحه‌هایی که نوار پایین ندارند (چت) کمی پایین‌تر می‌نشیند. */
#appCapsule ~ .toast-box { bottom: calc(56px + 20px); }
