/* ═══════════════════════════════════════════════════════════════════════════
   مؤشّرات حالة المنصّة — طبقة واحدة فوق كل الصفحات
   ---------------------------------------------------------------------------
   عنصران يخدمان App.razor ولا يخصّان صفحةً بعينها:

   1. .zb-boot  — «جارٍ تجهيز المنصّة»: يُرسم أثناء الـ prerender
                  (RendererInfo.IsInteractive == false) ويختفي لحظة وصول
                  التفاعلية. مصدره PlatformBootIndicator.razor.
   2. #components-reconnect-modal — لافتة انقطاع الـ circuit. تعريف العنصر
                  بهذا الـ id يجعل Blazor يتخلّى عن لافتته الافتراضية الحاجبة
                  (overlay أسود يغطّي الشاشة) ويكتفي بتبديل الأصناف على عنصرنا.

   قواعد التزمنا بها هنا:
   - لا يحجب أيٌّ منهما الشاشة: كلاهما شريط سفلي محاذٍ للوسط، بعرض محدود.
   - الحركة على transform/opacity وحدهما ليعمل الرسم على الـ compositor
     (نفس السبب الموثّق في dev-badge.css).
   - الموضع أسفل الوسط: أسفل اليمين تشغله شارة الـ render mode (dev-badge.css)
     وأسفل inset-inline-end تشغله بطاقة الحصّة المباشرة (live-class.css).
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
    --zb-status-ink: #e8eef5;
    --zb-status-ink-dim: #9fb0c3;
    --zb-status-glass: rgba(15, 23, 35, .88);
    --zb-status-line: rgba(255, 255, 255, .10);
    --zb-status-shadow: 0 18px 48px -12px rgba(2, 8, 20, .55), 0 2px 8px rgba(2, 8, 20, .28);
    --zb-status-ok: var(--primary, #18a171);
    --zb-status-warn: #f2a33c;
    --zb-status-bad: #ef5f5f;
    --zb-status-z: 100000;
}

/* الحاوية المشتركة: شريط سفلي متمركز لا يلتقط النقر إلا على أبنائه */
.zb-status-dock {
    position: fixed;
    inset-inline: 0;
    bottom: 18px;
    z-index: var(--zb-status-z);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    pointer-events: none;
}

/* ═══════════════════════════════════════════════════
   1) مؤشّر تجهيز المنصّة
   ═══════════════════════════════════════════════════ */

.zb-boot {
    pointer-events: none;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: min(420px, calc(100vw - 32px));
    /* منطقية لا فيزيائية: الصفحة RTL فالحلقة في جهة البداية (اليمين)،
       وحشوها أضيق من جهة النص. القيم الفيزيائية كانت تعكس الأمر. */
    padding-block: 11px 13px;
    padding-inline: 14px 18px;
    border-radius: 999px;
    background: var(--zb-status-glass);
    border: 1px solid var(--zb-status-line);
    box-shadow: var(--zb-status-shadow);
    color: var(--zb-status-ink);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    /* التأخير ‎.6s‎ مقصود: الإقلاع السريع (WebAssembly مخزّن أو circuit جاهز)
       ينتهي قبل ظهور اللافتة أصلاً، فلا يرى المستخدم وميضاً بلا معنى.
       ولا تظهر إلا حين يكون الانتظار حقيقياً. */
    animation: zb-boot-in .42s cubic-bezier(.2, .8, .25, 1) .6s both;
}

/* الحلقة الدوّارة: conic-gradient مقنّعة بـ mask فتصير حلقة رفيعة.
   تدور بـ transform وحده — لا إعادة تخطيط ولا إعادة طلاء. */
.zb-boot__ring {
    flex: none;
    position: relative;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: conic-gradient(from 0deg, rgba(255,255,255,0) 0deg, var(--zb-status-ok) 300deg, var(--zb-status-ok) 360deg);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
    animation: zb-spin 1s linear infinite;
}

/* نواة نابضة داخل الحلقة تعطي إحساس «نبض حيّ» لا مجرّد دوران */
.zb-boot__ring::after {
    content: "";
    position: absolute;
    inset: 7px;
    border-radius: 50%;
    background: var(--zb-status-ok);
    animation: zb-pulse-core 1.6s ease-in-out infinite;
}

.zb-boot__text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.zb-boot__title {
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: .1px;
}

/* النقاط الثلاث عناصر حقيقية لا حركة على خاصيّة content:
   تحريك content غير مدعوم في كل المتصفّحات، والعناصر تعمل في كلّها.
   عرضها ثابت فلا يهتزّ النص معها. */
.zb-boot__dots {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin-inline-start: 3px;
    vertical-align: middle;
}

.zb-boot__dots i {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: currentColor;
    opacity: .25;
    animation: zb-dots 1.4s ease-in-out infinite;
}

.zb-boot__dots i:nth-child(2) {
    animation-delay: .18s;
}

.zb-boot__dots i:nth-child(3) {
    animation-delay: .36s;
}

.zb-boot__hint {
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--zb-status-ink-dim);
}

/* سطر «أبطأ من المعتاد» يظهر وحده بعد 12 ثانية — بلا JS.
   الانتظار الطويل بلا تفسير هو ما يجعل المستخدم يظنّ الصفحة معطّلة. */
.zb-boot__slow {
    display: block;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--zb-status-warn);
    animation: zb-boot-slow .45s ease 12s forwards;
}

/* شريط تقدّم غير محدّد المدّة على حافّة اللافتة السفلى */
.zb-boot::after {
    content: "";
    position: absolute;
    inset-inline: 18px;
    bottom: 5px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--zb-status-ok), transparent);
    opacity: .75;
    animation: zb-sweep 1.9s ease-in-out infinite;
}

/* ═══════════════════════════════════════════════════
   2) لافتة إعادة الاتصال بالخادم
   ═══════════════════════════════════════════════════ */

/* الحالة الافتراضية مخفية: Blazor لا يضيف صنف الإظهار إلا عند أوّل انقطاع */
#components-reconnect-modal {
    display: none;
    position: fixed;
    inset-inline: 0;
    bottom: 18px;
    margin-inline: auto;
    width: min(430px, calc(100vw - 28px));
    z-index: calc(var(--zb-status-z) + 1);
    box-sizing: border-box;
    padding: 14px 16px;
    border-radius: 16px;
    background: var(--zb-status-glass);
    border: 1px solid var(--zb-status-line);
    box-shadow: var(--zb-status-shadow);
    color: var(--zb-status-ink);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
    overflow: hidden;
}

/* الأصناف التي يبدّلها Blazor. الترتيب: show أثناء المحاولات،
   ثم failed (نفدت المحاولات) أو rejected (الخادم رفض استئناف الـ circuit). */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: block;
    animation: zb-rc-in .34s cubic-bezier(.2, .8, .25, 1) both;
}

#components-reconnect-modal.components-reconnect-hide {
    display: none;
}

/* الشريط العلوي: خيط ملوّن يمسح عرض البطاقة طوال المحاولات */
#components-reconnect-modal::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 3px;
    background: linear-gradient(90deg, transparent, var(--zb-status-warn), transparent);
    animation: zb-sweep 1.6s ease-in-out infinite;
}

.zb-rc__row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

/* أيقونة الموجات: ثلاث حلقات متحدة المركز تنبض تباعاً كإشارة تبحث عن الشبكة */
.zb-rc__sig {
    flex: none;
    position: relative;
    width: 34px;
    height: 34px;
    margin-top: 1px;
    border-radius: 50%;
    background: rgba(242, 163, 60, .12);
}

.zb-rc__sig i,
.zb-rc__sig::after {
    content: "";
    position: absolute;
    inset: 50%;
    width: 7px;
    height: 7px;
    margin: -3.5px 0 0 -3.5px;
    border-radius: 50%;
    background: var(--zb-status-warn);
}

.zb-rc__sig i {
    background: transparent;
    border: 1.5px solid var(--zb-status-warn);
    animation: zb-rc-wave 1.8s ease-out infinite;
}

.zb-rc__sig i:nth-child(2) {
    animation-delay: .6s;
}

.zb-rc__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.zb-rc__title {
    display: block;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
}

.zb-rc__desc {
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--zb-status-ink-dim);
}

/* عدّاد المحاولات: أرقام لاتينية وسط نصّ عربي، فنعزلها بـ isolate
   كي لا تعيد خوارزمية bidi ترتيب المقطع عند تغيّر الرقم. */
.zb-rc__count {
    unicode-bidi: isolate;
    font-variant-numeric: tabular-nums;
    color: var(--zb-status-ink);
    font-weight: 600;
}

.zb-rc__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.zb-rc__btn {
    appearance: none;
    border: 1px solid var(--zb-status-line);
    background: rgba(255, 255, 255, .06);
    color: var(--zb-status-ink);
    font: inherit;
    font-size: 12px;
    line-height: 1;
    padding: 8px 14px;
    border-radius: 999px;
    cursor: pointer;
    transition: background .18s ease, transform .18s ease;
}

.zb-rc__btn:hover {
    background: rgba(255, 255, 255, .13);
    transform: translateY(-1px);
}

.zb-rc__btn--primary {
    background: var(--zb-status-ok);
    border-color: transparent;
    color: #04170f;
    font-weight: 600;
}

.zb-rc__btn--primary:hover {
    background: var(--secondary, #43b78f);
}

/* زرّ الطيّ: يحوّل البطاقة إلى نقطة صغيرة فلا تبقى على الشاشة أبداً كعائق */
.zb-rc__min {
    flex: none;
    margin-inline-start: auto;
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--zb-status-ink-dim);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}

.zb-rc__min:hover {
    background: rgba(255, 255, 255, .10);
    color: var(--zb-status-ink);
}

/* ─── الحالة المطوية ─── */

/* المطوية تبقى في الوسط السفلي لا في زاوية: الزاويتان مشغولتان أصلاً —
   بطاقة «حصة مباشرة الآن» في inset-inline-end وشارة الـ render mode في
   اليمين — فالنقل إلى زاوية يعني تراكباً حقيقياً أثناء الحصة.
   fit-content مع inset-inline: 0 وmargin تلقائي يعطي صندوقاً بحجم محتواه
   ومتمركزاً، بلا transform كي لا يصطدم بحركة الدخول. */
#components-reconnect-modal.zb-rc--min {
    width: fit-content;
    padding-block: 9px;
    padding-inline: 10px 14px;
    border-radius: 999px;
}

/* الـ id ضروري هنا لا زينة: قواعد إظهار نصّ الحالة أدناه
   (‎.components-reconnect-show .zb-rc__state--retry‎) بنفس الأسبقية وتأتي بعدها
   في الملف، فتغلبها وتُبقي السطر ظاهراً في الحالة المطوية. قِيس فعلاً:
   ارتفاع اللافتة المطوية 59px بدل 40px وعرضها 367px بدل ~210px. */
#components-reconnect-modal.zb-rc--min .zb-rc__desc,
#components-reconnect-modal.zb-rc--min .zb-rc__actions,
#components-reconnect-modal.zb-rc--min .zb-rc__min {
    display: none;
}

.zb-rc--min .zb-rc__sig {
    width: 22px;
    height: 22px;
}

.zb-rc--min .zb-rc__title {
    font-size: 12.5px;
    font-weight: 500;
    white-space: nowrap;
}

.zb-rc--min .zb-rc__row {
    align-items: center;
    cursor: pointer;
}

/* ─── حالتا الفشل والرفض: الاستئناف لن ينجح، والصفحة تُحدَّث تلقائياً ─── */

#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    border-color: rgba(239, 95, 95, .35);
}

.components-reconnect-failed::before,
.components-reconnect-rejected::before {
    background: linear-gradient(90deg, transparent, var(--zb-status-bad), transparent);
}

.components-reconnect-failed .zb-rc__sig,
.components-reconnect-rejected .zb-rc__sig {
    background: rgba(239, 95, 95, .14);
}

.components-reconnect-failed .zb-rc__sig i,
.components-reconnect-rejected .zb-rc__sig i {
    border-color: var(--zb-status-bad);
}

.components-reconnect-failed .zb-rc__sig::after,
.components-reconnect-rejected .zb-rc__sig::after {
    background: var(--zb-status-bad);
}

/* نصوص كل حالة: نُظهر السطر الموافق للحالة ونخفي البقية.
   البدائل الثلاثة موجودة في الـ DOM دائماً فلا نحتاج JS لتبديل النصوص. */
.zb-rc__state {
    display: none;
}

.components-reconnect-show .zb-rc__state--retry,
.components-reconnect-retrying .zb-rc__state--retry,
.components-reconnect-failed .zb-rc__state--failed,
.components-reconnect-rejected .zb-rc__state--rejected {
    display: block;
}

/* ═══════════════════════════════════════════════════
   الحركات
   ═══════════════════════════════════════════════════ */

@keyframes zb-boot-in {
    from {
        opacity: 0;
        transform: translateY(14px) scale(.96);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes zb-rc-in {
    from {
        opacity: 0;
        transform: translateY(18px) scale(.97);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes zb-spin {
    to {
        transform: rotate(360deg);
    }
}

@keyframes zb-pulse-core {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }

    50% {
        transform: scale(.55);
        opacity: .45;
    }
}

@keyframes zb-sweep {
    0% {
        transform: translateX(-60%) scaleX(.5);
    }

    50% {
        transform: translateX(0) scaleX(1);
    }

    100% {
        transform: translateX(60%) scaleX(.5);
    }
}

@keyframes zb-dots {
    0%, 100% {
        opacity: .25;
        transform: translateY(0);
    }

    40% {
        opacity: 1;
        transform: translateY(-2px);
    }
}

@keyframes zb-boot-slow {
    to {
        max-height: 2.4em;
        opacity: 1;
    }
}

@keyframes zb-rc-wave {
    0% {
        width: 7px;
        height: 7px;
        margin: -3.5px 0 0 -3.5px;
        opacity: .9;
    }

    100% {
        width: 30px;
        height: 30px;
        margin: -15px 0 0 -15px;
        opacity: 0;
    }
}

/* ═══════════════════════════════════════════════════
   الشاشات الصغيرة وتفضيل تقليل الحركة
   ═══════════════════════════════════════════════════ */

@media (max-width: 480px) {
    .zb-status-dock,
    #components-reconnect-modal {
        bottom: 12px;
    }

    #components-reconnect-modal {
        width: calc(100vw - 20px);
    }

    .zb-boot__hint {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .zb-boot,
    #components-reconnect-modal.components-reconnect-show,
    #components-reconnect-modal.components-reconnect-retrying,
    #components-reconnect-modal.components-reconnect-failed,
    #components-reconnect-modal.components-reconnect-rejected {
        animation-duration: .01ms;
        animation-delay: 0s;
    }

    .zb-boot::after,
    .zb-boot__ring::after,
    #components-reconnect-modal::before,
    .zb-rc__sig i {
        animation: none;
    }

    .zb-boot__ring {
        animation-duration: 2.4s;
    }
}
