/* =====================================================================
   mobile-fixes.css — سخت‌سازی ریسپانسیو سامانه همداد
   ---------------------------------------------------------------------
   این فایل باید «آخرین» شیت لینک‌شده در App.razor باشد تا بتواند
   قواعد ناقص tailwind/app.css را در صفحه‌های کوچک بازنویسی کند.

   چه چیزهایی اینجا حل شده:
     ۱) اسکرول افقی موبایل (به سمت چپ در چیدمان راست‌به‌چپ) — قطعی
     ۲) دکمه‌هایی که دو خطی می‌شدند
     ۳) نوار خطای Blazor (تک‌منبع، ریسپانسیو، بی‌اثر روی بقیه صفحه)
     ۴) جدول‌ها، مودال‌ها، منوهای بازشو، فرم‌ها و ارتفاع‌های 100vh
     ۵) بریدگی صفحه (notch) و نوار خانه‌ی آیفون
   ===================================================================== */

/* =====================================================================
   ۱) ریشه — اسکرول افقی هرگز رخ نمی‌دهد
   ---------------------------------------------------------------------
   قبلاً فقط body مقدار overflow-x: hidden داشت. دو اشکال داشت:
     • در iOS اگر عنصری از html بیرون بزند، بازهم صفحه افقی می‌لرزید
     • hidden روی body، body را «کانتینر اسکرول» می‌کند و همین
       position: sticky ناوبار را در بعضی مرورگرها می‌شکند
   راه‌حل درست overflow-x: clip است؛ کانتینر اسکرول نمی‌سازد پس sticky
   سالم می‌ماند. hidden به‌عنوان پشتیبان برای مرورگرهای قدیمی می‌ماند.
   ===================================================================== */
html, body {
    overflow-x: hidden;   /* پشتیبان مرورگرهای قدیمی */
    max-width: 100%;
}

@supports (overflow-x: clip) {
    html, body {
        overflow-x: clip;
        overflow-y: visible;
    }
}

body {
    /* هیچ چیزی پهن‌تر از خودِ صفحه نباشد */
    width: 100%;
    min-width: 0;
    position: relative;
}

/* بریدگی صفحه (notch) — viewport-fit=cover در App.razor روشن است.
   عمداً به body پدینگ نمی‌دهیم، وگرنه ناوبار سفیدِ چسبان تا لبه‌ی صفحه
   کشیده نمی‌شود و یک نوار خاکستری کنارش می‌افتد. به‌جایش فقط عناصر
   شناور (نوار خطا، چت، اعلان) از env استفاده می‌کنند — پایین همین فایل. */
@media (orientation: landscape) {
    main, article, section.hero-min, footer {
        padding-inline-start: env(safe-area-inset-right, 0px);
        padding-inline-end: env(safe-area-inset-left, 0px);
    }
}

/* =====================================================================
   ۲) عناصری که کلاسیک‌ترین دلیل سرریز افقی‌اند
   ===================================================================== */
img, video, canvas, svg, iframe, embed, object, picture, table, pre, code, blockquote {
    max-width: 100%;
}

img, video {
    height: auto;
}

canvas {
    /* نمودارهای Chart.js با width ثابت رندر می‌شوند و صفحه را پهن می‌کردند */
    max-width: 100% !important;
    height: auto !important;
}

pre, code, kbd, samp {
    /* بلوک کد در «API و اتصال سامانه‌ها» صفحه را افقی می‌کشید */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
}

pre {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* =====================================================================
   ۳) متن‌های بلند بدون فاصله: ایمیل، نشانی اینترنتی، توکن API، شماره
   شبا/کارت، کد ملی. اینها در RTL دقیقاً «به سمت چپ» سرریز می‌کردند.
   ===================================================================== */
a, p, span, td, th, li, dd, dt, h1, h2, h3, h4, h5, h6,
label, small, strong, em, figcaption, summary, .break-words, .truncate {
    overflow-wrap: break-word;
}

a[href^="mailto:"], a[href^="http"], a[href^="tel:"],
.font-mono, [style*="overflow-wrap"], .daovi-anywhere {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* =====================================================================
   ۴) flex و grid — بدون min-width:0 هر فرزند به اندازه محتوایش پهن
   می‌شود و کل صفحه را می‌کشد. رایج‌ترین باگ ریسپانسیو تیلویند.
   ===================================================================== */
.flex > *,
.grid > *,
.inline-flex > * {
    min-width: 0;
}

.flex, .inline-flex, .grid {
    max-width: 100%;
}

/* عناصر مطلق و ثابت هم نباید کاغذ را پهن کنند */
.fixed, .absolute, .sticky {
    max-width: 100vw;
}

/* =====================================================================
   ۵) جدول‌ها — اسکرول داخل قاب خودشان، نه کل صفحه
   ---------------------------------------------------------------------
   قاعده‌ی قبلی در app.css به همه‌ی .overflow-x-auto ها زورکی
   max-height: 70vh می‌داد؛ بلوک‌های کد و کارت‌های غیرجدولی هم بریده
   می‌شدند. حالا آن رفتار فقط برای قابی که واقعاً جدول دارد می‌ماند.
   ===================================================================== */
.overflow-x-auto {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

.overflow-x-auto:not(:has(> table)) {
    max-height: none;
    overflow-y: visible;
}

@media (max-width: 767px) {
    .overflow-x-auto:has(> table) {
        max-height: none;   /* ۷۰٪ ارتفاع صفحه روی موبایل یعنی دو ردیف */
        overflow-y: visible;
    }

    /* سرستون چسبانِ داخل قاب روی موبایل بی‌فایده و پرلرزش است */
    .overflow-x-auto thead th {
        position: static;
    }

    table {
        font-size: .8125rem;
    }

    th, td {
        padding-inline: .5rem !important;
        white-space: nowrap;   /* ردیف کوتاه می‌ماند، قاب اسکرول می‌شود */
    }

    /* سلول‌هایی که عمداً متن بلند دارند نباید بی‌نهایت پهن شوند */
    td.daovi-cell-wrap, th.daovi-cell-wrap,
    td .break-words, td .line-clamp-2 {
        white-space: normal;
        max-width: 16rem;
    }
}

/* نوار اسکرول باریک و دیدنی، تا کاربر بفهمد جدول افقی حرکت می‌کند */
.overflow-x-auto::-webkit-scrollbar {
    height: 6px;
}

.overflow-x-auto::-webkit-scrollbar-thumb {
    background: #cbd5e1;
    border-radius: 999px;
}

/* =====================================================================
   ۶) دکمه‌ها — دیگر دو خطی نمی‌شوند
   ---------------------------------------------------------------------
   علت باگ: دکمه در یک ردیف flex بود، flex-shrink پیش‌فرض ۱ است، پس
   ردیف تنگ دکمه را فشار می‌داد و متن فارسی می‌شکست («ثبت / درخواست»).
   راه‌حل دو تکه‌ای:
     • متن دکمه هرگز نشکند (nowrap)
     • ردیفِ دکمه‌ها اجازه‌ی سطر جدید بگیرد تا دکمه‌ی کامل پایین برود
   ===================================================================== */
button,
[role="button"],
input[type="button"],
input[type="submit"],
input[type="reset"],
.btn,
.navbar-item,
a.reload {
    white-space: nowrap;
    overflow-wrap: normal;
    word-break: keep-all;
    max-width: 100%;
    line-height: 1.5;
}

/* دکمه‌ی آیکن‌دار: آیکن و متن روی یک خط.
   وسط‌چینی فقط برای دکمه‌هایی که خودشان چیدمان تعیین نکرده‌اند؛ وگرنه
   آیکن دکمه‌های تمام‌عرض (فهرست راهنما، منوها) از لبه کنده می‌شد و
   چسبیده به متن وسط کادر می‌افتاد. */
button:not(.dismiss),
input[type="submit"],
input[type="button"] {
    align-items: center;
}

button:not(.dismiss):not([class*="justify-"]):not([class*="text-right"]):not([class*="text-left"]):not([class*="text-start"]):not([class*="w-full"]),
input[type="submit"],
input[type="button"] {
    justify-content: center;
}

@media (max-width: 640px) {
    /* ردیف دکمه‌ها/برچسب‌ها اجازه‌ی شکستن به سطر بعد دارد.
       چون flex-wrap فقط وقتی عمل می‌کند که جا کم باشد، چیدمان‌های
       جاشده هیچ تغییری نمی‌بینند. */
    .flex:not(.flex-col):not(.flex-nowrap):not(.dnav):not(.daovi-navlinks):not(.daovi-navtools) {
        flex-wrap: wrap;
    }

    /* دکمه روی موبایل کمی جمع‌وجورتر تا در همان یک خط جا شود */
    button, .btn, a.btn,
    input[type="submit"], input[type="button"] {
        min-height: 44px;             /* هدف لمسی استاندارد */
        flex: 0 1 auto;
        padding-inline: .9rem;
        font-size: .875rem;
    }

    /* دکمه‌های خیلی طولانی (ورود/ثبت‌نام، ثبت درخواست…) تمام‌عرض
       می‌شوند تا متن قطعاً یک‌خطی بماند */
    .daovi-btn-block,
    form > button:only-of-type,
    .flex-col > button,
    .flex-col > a.btn {
        width: 100%;
    }

    /* شمارنده‌ها و برچسب‌های کوچک داخل دکمه نچسبند */
    button > svg, .btn > svg, button > i, .btn > i {
        flex: 0 0 auto;
    }
}

@media (max-width: 380px) {
    button, .btn, a.btn,
    input[type="submit"], input[type="button"] {
        padding-inline: .7rem;
        font-size: .8125rem;
    }
}

/* =====================================================================
   ۷) گریدها — دو ستون روی صفحه ۳۶۰ پیکسلی جا نمی‌شود
   ---------------------------------------------------------------------
   در سامانه ۳۱ جای مختلف grid-cols-2 بدون هیچ حالت موبایلی نوشته شده
   بود (فرم‌ها، کارت‌های آمار، تنظیمات). حالا زیر ۵۴۰px تک‌ستونه می‌شود.
   ===================================================================== */
@media (max-width: 540px) {
    .grid-cols-2:not(.daovi-keep-cols),
    .grid-cols-3:not(.daovi-keep-cols):not(.dp-grid),
    .grid-cols-4:not(.daovi-keep-cols):not(.dp-grid) {
        grid-template-columns: repeat(1, minmax(0, 1fr));
    }

    /* تقویم فارسی باید ۷ ستونه بماند وگرنه بی‌معنی می‌شود */
    .grid-cols-7 {
        grid-template-columns: repeat(7, minmax(0, 1fr));
    }
}

@media (min-width: 541px) and (max-width: 767px) {
    .grid-cols-4:not(.daovi-keep-cols):not(.dp-grid) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* فاصله‌های بزرگ دسکتاپی روی موبایل نصف می‌شوند */
@media (max-width: 640px) {
    .gap-8, .gap-12, .gap-14 { gap: 1rem; }
    .p-10, .p-12 { padding: 1.25rem; }
    .p-8 { padding: 1rem; }
    .px-10 { padding-inline: 1rem; }
    .py-16, .py-20 { padding-block: 2rem; }
    .pt-24 { padding-top: 3rem; }
    .text-5xl { font-size: 2.25rem; line-height: 1.15; }
    .text-4xl { font-size: 1.75rem; line-height: 1.25; }
    .text-3xl { font-size: 1.5rem; line-height: 1.3; }
    .tracking-\[0\.5em\] { letter-spacing: .18em; }
}

/* =====================================================================
   ۸) ارتفاع‌های 100vh — نوار آدرس موبایل باعث پرش و بریدگی می‌شود
   ===================================================================== */
@supports (height: 100dvh) {
    .min-h-screen { min-height: 100dvh; }
    .max-h-\[90vh\] { max-height: 90dvh; }
    .max-h-\[70vh\] { max-height: 70dvh; }
}

/* =====================================================================
   ۹) مودال‌ها — روی موبایل تمام‌عرض، با اسکرول داخلی
   ===================================================================== */
@media (max-width: 640px) {
    .fixed.inset-0.z-50 {
        padding: .75rem;
        padding-bottom: calc(.75rem + env(safe-area-inset-bottom, 0px));
    }

    .fixed.inset-0.z-50 > .bg-white,
    .fixed.inset-0.z-50 > * > .bg-white {
        width: 100% !important;
        max-width: 100% !important;
        max-height: calc(100dvh - 1.5rem);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* =====================================================================
   ۱۰) منوهای بازشو — با w-max از لبه‌ی صفحه بیرون می‌زدند
   ===================================================================== */
.dropdown-menu {
    max-width: calc(100vw - 1.5rem);
    max-height: min(70dvh, 35rem);
    overflow-y: auto;
    overscroll-behavior: contain;
}

@media (max-width: 767px) {
    .dropdown-menu {
        width: max-content;
        max-width: calc(100vw - 1.5rem);
    }
}

/* =====================================================================
   ۱۱) فرم‌ها — هیچ ورودی‌ای پهن‌تر از قابش نیست و iOS زوم نمی‌کند
   ===================================================================== */
input, select, textarea {
    max-width: 100%;
    box-sizing: border-box;
}

@media (max-width: 767px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select, textarea {
        font-size: 16px;   /* زیر ۱۶px، سافاری خودش صفحه را زوم می‌کند */
        width: 100%;
    }

    /* عرض‌های ثابت دسکتاپی روی موبایل تمام‌عرض می‌شوند */
    .w-44, .w-48, .w-80, .w-28, .w-24,
    .w-1\/2, .w-2\/3, .w-\[640px\] {
        width: 100%;
        max-width: 100%;
    }

    /* پیام اعتبارسنجی زیر فیلد بشکند، نه اینکه قاب را بکشد */
    .validation-message, .invalid-feedback {
        overflow-wrap: anywhere;
    }
}

/* =====================================================================
   ۱۲) ناوبار و کشوی موبایل
   ===================================================================== */
nav.sticky, header.sticky {
    max-width: 100%;
}

.container {
    max-width: 100%;
}

@media (max-width: 767px) {
    .container {
        padding-inline: 1rem;
    }
}

/* کشوی موبایل هرگز پهن‌تر از صفحه نشود */
.dnav {
    max-width: min(88vw, 20rem);
}

/* =====================================================================
   ۱۳) نوار خطای Blazor — تک‌منبع و ریسپانسیو
   ---------------------------------------------------------------------
   قبلاً سه تعریف موازی داشت (MainLayout.razor.css با دامنه‌ی محدود،
   tw-supplement.css و ...). چون یکی از آنها «scoped» بود، وقتی خطا در
   خود لایه‌ی MainLayout رخ می‌داد نوار بدون استایل و لخت می‌آمد و
   چیدمان صفحه را می‌شکست. حالا نشانه‌گذاری در App.razor است (خارج از
   درخت تعاملی، پس همیشه رندر می‌شود) و استایل فقط همین‌جاست.
   ===================================================================== */
#blazor-error-ui {
    color-scheme: light only;
    direction: rtl;
    display: none;
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: var(--z-toast);
    box-sizing: border-box;
    max-width: 100vw;
    max-height: 45dvh;
    overflow-y: auto;
    padding: .8rem 1rem;
    padding-bottom: calc(.8rem + env(safe-area-inset-bottom, 0px));
    background: #fff7ed;
    border-top: 2px solid #f97316;
    color: #7c2d12;
    font-family: var(--daovi-font, Tahoma, sans-serif);
    font-size: .9rem;
    line-height: 1.9;
    box-shadow: 0 -6px 20px rgb(0 0 0 / .12);
    text-align: center;
}

#blazor-error-ui .daovi-err-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .5rem .75rem;
    max-width: 60rem;
    margin-inline: auto;
}

#blazor-error-ui .daovi-err-title {
    font-weight: 700;
    overflow-wrap: anywhere;
}

#blazor-error-ui .daovi-err-hint {
    flex: 1 1 100%;
    font-size: .78rem;
    opacity: .8;
    line-height: 1.8;
    overflow-wrap: anywhere;
}

#blazor-error-ui .reload {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 40px;
    padding: .35rem 1rem;
    border-radius: .55rem;
    background: #ea580c;
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}

#blazor-error-ui .reload:hover,
#blazor-error-ui .reload:focus-visible {
    background: #c2410c;
    color: #fff;
}

#blazor-error-ui .dismiss {
    position: absolute;
    inset-inline-start: .5rem;
    top: .4rem;
    width: 34px;
    height: 34px;
    min-height: 34px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 0;
    border-radius: 999px;
    color: inherit;
    font-size: 1rem;
    line-height: 1;
    opacity: .65;
    cursor: pointer;
}

#blazor-error-ui .dismiss:hover { opacity: 1; background: rgb(249 115 22 / .12); }

@media (max-width: 480px) {
    #blazor-error-ui {
        padding-inline: .75rem;
        font-size: .8125rem;
    }

    #blazor-error-ui .daovi-err-row { padding-top: 1.4rem; }
    #blazor-error-ui .daovi-err-title { flex: 1 1 100%; }
    #blazor-error-ui .reload { width: 100%; justify-content: center; }
    #blazor-error-ui .daovi-err-hint { font-size: .72rem; }
}

/* همان رفتار برای پوسته‌ی خطای مرزی (ErrorBoundary) */
.blazor-error-boundary {
    max-width: 100%;
    overflow-wrap: anywhere;
}

/* =====================================================================
   ۱۴) ویجت چت شناور و پنل هوش مصنوعی
   ===================================================================== */
.pas-chat-widget, .pas-chat-panel, .pas-chat-frame-wrap {
    max-width: 100vw;
}

@media (max-width: 640px) {
    .pas-chat-widget {
        inset-inline-end: max(.75rem, env(safe-area-inset-right, 0px));
        bottom: max(.75rem, env(safe-area-inset-bottom, 0px));
    }
}

/* اعلان شناور و توست‌ها */
.daovi-toast-host, .dpush-prompt {
    max-width: calc(100vw - 1.5rem);
}

/* =====================================================================
   ۱۵) تقویم فارسی و صفحه‌بندی
   ===================================================================== */
.dp-pop, .dp-panel, [class*="w-[min(22rem"] {
    max-width: calc(100vw - 1.5rem);
}

@media (max-width: 480px) {
    .daovi-pager, .pager {
        flex-wrap: wrap;
        gap: .35rem;
    }
    .md\:pl-24 { padding-left: 0; }
}

/* =====================================================================
   ۱۶) ابزار عیب‌یابی (فقط دستی)
   ---------------------------------------------------------------------
   کلاس daovi-debug-overflow را موقتاً روی <body> بگذارید تا هر عنصری که
   از عرض صفحه بیرون زده با کادر قرمز مشخص شود.
   ===================================================================== */
body.daovi-debug-overflow * {
    outline: 1px solid rgb(255 0 0 / .35) !important;
}
@media (max-width: 540px) {
    .grid:not(.daovi-keep-cols):not(.grid-cols-7) {
        grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
    }
}

/* =====================================================================
   ۱۸) پایان صفحه — «اسکرول می‌خورد ولی هیچی نیست»
   ---------------------------------------------------------------------
   گزارش کاربر: در «پرداخت حق‌الوکاله»، «امور مالی» و خیلی از صفحه‌های
   دیگر، صفحه اسکرول می‌خورد و انتهایش یک ناحیه‌ی خالی بلند بود.

   علت: قالب همه‌ی صفحه‌ها یک <div class="min-h-screen"> است؛ یعنی
   «حداقل ۱۰۰٪ ارتفاع پنجره». این ارتفاع به هر چیزی که بیرون آن قاب
   باشد (ناوبار چسبان، حاشیه‌ها، نوارهای پایین صفحه) اضافه می‌شد و سند
   همیشه چند صد پیکسل بلندتر از محتوای واقعی می‌شد. آن اضافه‌ی خالی
   همان چیزی است که کاربر می‌دید.

   راه‌حل: ناحیه محتوا یک ستون flex به ارتفاع دقیقاً یک پنجره است و قابِ
   صفحه «باقیمانده» را پر می‌کند (flex: 1) نه «یک پنجره کامل». پس:
     • صفحه کوتاه: پس‌زمینه تا پایین پنجره کشیده می‌شود، بدون نوار اسکرول.
     • صفحه بلند: دقیقاً تا انتهای محتوا اسکرول می‌شود، بدون فضای مرده.
   ===================================================================== */
#main-content {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

@supports (height: 100dvh) {
    #main-content { min-height: 100dvh; }
}

#main-content > * {
    min-width: 0;
}

/* قابِ اصلی هر صفحه: به‌جای «یک پنجره کامل»، باقیمانده‌ی پنجره را پر می‌کند */
#main-content > .min-h-screen {
    min-height: 0;
    flex: 1 1 auto;
}

/* قاب نمودارِ بی‌نمودار (site.js → daoviCharts._fallback): ارتفاع ثابتش
   جمع می‌شود تا مستطیل سفید خالی روی صفحه نماند. */
.daovi-chart-off {
    height: auto !important;
    min-height: 0 !important;
}

.daovi-chart-fallback {
    margin: 0;
    padding: 1rem 0;
    text-align: center;
    font-size: .8125rem;
    color: #64748b;
}

/* =====================================================================
   قرارداد مشترک پوسته — نام‌ها را صفحه‌ها تغییر ندهند.
   مقیاس لایه‌ها: چت ۴۰، نوار چسبان ۵۰، کشو ۶۰، مودال ۱۰۰، اعلان ۱۲۰.
   .tap-44 هدف لمس، .tbl-scroll قاب جدول، و desk/mob-only دو نمای جدول‌اند.
   .mob-card* برای نمایش «برچسب: مقدار» در موبایل است و جهت RTL را حفظ می‌کند.
   ===================================================================== */
:root {
    --z-chat: 40;
    --z-sticky: 50;
    --z-drawer: 60;
    --z-modal: 100;
    --z-toast: 120;
}

.tap-44 {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.tbl-scroll {
    position: relative;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
}
.tbl-scroll::after {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: 1.25rem;
    pointer-events: none;
    background: linear-gradient(to left, rgb(15 23 42 / .14), transparent);
    opacity: .65;
}

.desk-only { display: block; }
.mob-only { display: none; }
@media (max-width: 767px) {
    .desk-only { display: none !important; }
    .mob-only { display: block; }
    .mob-card {
        display: block;
        direction: rtl;
        width: 100%;
        padding: 1rem;
        border: 1px solid #e2e8f0;
        border-radius: .75rem;
        background: #fff;
        box-shadow: 0 2px 8px rgb(15 23 42 / .06);
    }
    .mob-card-row {
        display: flex;
        align-items: baseline;
        gap: .75rem;
        min-width: 0;
        padding-block: .4rem;
        border-block-end: 1px solid #f1f5f9;
    }
    .mob-card-row:last-child { border-block-end: 0; }
    .mob-card-label {
        flex: 0 0 7rem;
        color: #64748b;
        font-size: .78rem;
        font-weight: 700;
    }
    .mob-card-value {
        min-width: 0;
        flex: 1 1 auto;
        overflow-wrap: anywhere;
        color: #1e293b;
    }
}

.modal-shell {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-modal);
    overscroll-behavior: contain;
}
.modal-card {
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
@supports (max-height: 100dvh) {
    .modal-card { max-height: calc(100dvh - 2rem); }
}

/* ورودی موبایل کمتر از ۱۶px در سافاری باعث بزرگ‌نمایی ناخواسته می‌شود. */
@media (max-width: 767px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select, textarea, .slf-input { font-size: 16px !important; }
    .dnav, .dnav-head, .dnav-foot, nav.sticky, header.sticky {
        padding-bottom: max(0px, env(safe-area-inset-bottom, 0px));
    }
    /* ‏قبلاً اینجا نوشته بود:  padding-top: env(safe-area-inset-top, 0px)
       و همین یک خط، پدینگ ۱۲ پیکسلیِ سربرگ کشو (.dnav-head در app.css) را
       صفر می‌کرد — چون در اندروید و کرومِ نصب‌شده مقدار env صفر برمی‌گردد.
       نتیجه: سربرگ کشو و ناوبار به لبه‌ی بالای صفحه می‌چسبید و زیر نوار
       وضعیت سیستم می‌رفت. مقدار نهایی از متغیر ‎--daovi-safe-top‎ می‌آید
       (تعریف و توضیح کامل: wwwroot/ui-fix.css — بخش ۱۱). */
    .dnav-head, nav.sticky, header.sticky {
        padding-top: calc(var(--daovi-safe-top, 0px) + var(--daovi-navbar-gap, 6px));
    }
    .pas-chat-widget { inset-inline-start: max(.75rem, env(safe-area-inset-left, 0px)); bottom: max(.75rem, env(safe-area-inset-bottom, 0px)); }
    .pas-chat-panel { padding-bottom: env(safe-area-inset-bottom, 0px); }
    .daovi-toast-wrap { inset-inline-start: max(.75rem, env(safe-area-inset-left, 0px)); inset-inline-end: max(.75rem, env(safe-area-inset-right, 0px)); max-width: none; width: auto; }
}

/* selector عمومی شبکه را به تقویم هفت‌ستونه تحمیل نکن. */
@media (max-width: 540px) {
    .grid:not(.daovi-keep-cols):not(.grid-cols-7) { grid-template-columns: repeat(1, minmax(0, 1fr)) !important; }
    .grid.grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)) !important; }
}

/* breakpoint اصلی پوسته: ۱۰۲۴ تا ۱۲۷۹ همچنان کشو است. */
@media (min-width: 1280px) { .dnav { display: none !important; } }

:focus-visible {
    outline: 3px solid #4f46e5;
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .modal-shell *, .mob-card *, .tbl-scroll { scroll-behavior: auto !important; animation: none !important; transition-duration: .01ms !important; }
}


/* =====================================================================
   پرده‌ی کشوی ناوبار عمومی
   ---------------------------------------------------------------------
   باگ: پرده تمام صفحه را تاریک نمی‌کرد؛ فقط دو نوار خاکستری در حاشیه‌ی
   خود ناوبار دیده می‌شد و کلیک بیرون منو هم آن را نمی‌بست.
   علت: <header> کلاس backdrop-blur دارد و عنصری که backdrop-filter
   می‌گیرد برای فرزندان position:fixed خودش «بلوک دربرگیرنده» می‌شود.
   پس inset:0 دیگر یعنی «اندازه‌ی همان هدر»، نه اندازه‌ی صفحه.
   حالا این <div> در PublicTopBar.razor بیرون از <header> رندر می‌شود، و
   انتخابگر هم دیگر به [data-public-nav] وابسته نیست.
   ===================================================================== */
.public-nav-backdrop { display: none; }
@media (max-width: 767px) {
    [data-public-nav] { z-index: var(--z-sticky); }
    .public-nav-backdrop {
        display: block; position: fixed; inset: 0; background: rgb(15 23 42 / .35);
        z-index: var(--z-chat);
    }
    [data-public-nav] #public-mobile-nav { position: relative; z-index: var(--z-drawer); background: #fff; }
}
.dv-picker-menu, .z-\[60\] { z-index: var(--z-drawer) !important; }


@media (max-width: 767px) {
    .slf-page select, .slf-page select option { white-space: normal; text-overflow: clip; }
    /* کشو باید از «راست» بیاید. صفحه dir="rtl" است، پس در منطق CSS
       inline-start = راست و inline-end = چپ. نسخه‌ی قبل این دو را جابه‌جا
       نوشته بود (inset-inline-end: 0 یعنی left: 0) و به همین دلیل روی
       موبایل کشو به لبه‌ی چپ می‌چسبید؛ با translateX(100%) هم بیرون کادر
       نمی‌رفت بلکه وسط صفحه ظاهر می‌شد و نیمی از محتوا را می‌پوشاند. */
    .dnav { inset-inline-start: 0; inset-inline-end: auto; left: auto; transform: translateX(100%); }
    .dnav.is-open { transform: translateX(0); }
}

@media (min-width: 768px) { .mob-only { display: none !important; } }
@supports (max-height: 100dvh) { @media (max-height: 760px) { .daovi-adminmenu { max-height: calc(100dvh - 6rem) !important; } } }

.daovi-sticky { z-index: var(--z-sticky) !important; }

/* =====================================================================
   ۲۵) کلاس‌های hidden باید از .tap-44 قوی‌تر باشند
   ---------------------------------------------------------------------
   mobile-fixes.css بعد از tailwind.css بارگذاری می‌شود و .tap-44 مقدار
   display را ست می‌کند (inline-flex). چون هم‌ویژگی (specificity) با
   .md\:hidden است و دیرتر می‌آید، برنده می‌شود؛ نتیجه: دکمه‌ی همبرگری
   PublicTopBar روی دسکتاپ هم دیده می‌شد، درست کنار منوی افقی.
   انتخابگر دوکلاسه این را بی‌نیاز از !important حل می‌کند.
   ===================================================================== */
.tap-44.hidden { display: none; }
@media (min-width: 640px) { .tap-44.sm\:hidden { display: none; } }
@media (min-width: 768px) { .tap-44.md\:hidden { display: none; } }
@media (min-width: 1024px) { .tap-44.lg\:hidden { display: none; } }
@media (min-width: 1280px) { .tap-44.xl\:hidden { display: none; } }

/* کشوی موبایل و پرده‌اش روی دسکتاپ هرگز نباید رندر شوند؛ .dnav در
   app.css مقدار display:flex دارد و باید صریح خنثی شود. */
@media (min-width: 1280px) {
    .dnav, .dnav-overlay { display: none !important; }
}
