/* ============================================================================
   Fluent 2 — نظام تصميم Resalaty LMS المرجعي (يُطبَّق على كل الصفحات المحوّلة)
   ----------------------------------------------------------------------------
   • كل الألوان مربوطة برموز الثيم في app.css → تعمل في الوضعين (ليلي/نهاري)
     والسمات الست، وتتبع التباين المصمَّم في النظام.
   • RTL: تُستخدم الخصائص المنطقية حصراً (inline/block, start/end) لا الفيزيائية.
   • رموز هذا الملف مسبوقة بـ --f- لتفادي أي تصادم مع app.css أو أنظمة أخرى.
   الاستخدام: <link rel="stylesheet" href="assets/css/fluent.css"> ثم أصناف .f-*
   ============================================================================ */

:root {
    /* ── العلامة (Brand) ── */
    --f-brand:         var(--accent-primary);
    --f-on-brand:      var(--text-on-accent, #fff);        /* نص فوق البراند — يتبع تباين النظام */
    --f-brand-hover:   color-mix(in srgb, var(--accent-primary) 85%, #000);
    --f-brand-pressed: color-mix(in srgb, var(--accent-primary) 72%, #000);
    --f-brand-ink:     var(--accent-ink, var(--accent-primary)); /* لون العلامة حين يكون نصّاً — مقروء على السطح في كل سمة */
    --f-brand-tint:    var(--accent-soft);                 /* خلفية نغمية خفيفة (مصمَّمة مقروءة مع --f-brand) */
    /* ── الأسطح والنصوص ── */
    --f-surface:       var(--bg-card);
    --f-surface-alt:   var(--bg-sunken);
    /* رأس الجدول: رمادي محايد مشتقّ من لون النصّ لا من ‎--bg-sunken‎ (‎#eef1f8‎)،
       فذاك رمادي بارد مائل للأزرق يُقرأ شريطاً إنديغو أعلى كل جدول. يعمل في
       الوضعين: في الليلي يكون ‎--f-fg‎ فاتحاً فيُنتج المزج تفتيحاً خفيفاً. */
    --f-thead:         color-mix(in srgb, var(--f-fg) 6%, var(--f-surface));
    --f-surface-hover: color-mix(in srgb, var(--text-main) 5%, transparent);
    --f-fg:            var(--text-main);
    --f-fg-2:          var(--text-muted);
    --f-fg-3:          var(--text-faint);
    --f-stroke:        var(--border-color);
    --f-stroke-2:      var(--border-strong);
    /* ── الدلالات (Semantic) ── */
    --f-ok:   var(--accent-success);  --f-ok-soft:   var(--success-soft);
    --f-warn: var(--accent-warning);  --f-warn-soft: var(--warning-soft);
    --f-err:  var(--accent-danger);   --f-err-soft:  var(--danger-soft);
    --f-info: var(--accent-info);     --f-info-soft: var(--info-soft);
    --f-on-warn: #3a2c00;    /* نص/أيقونة داكنة فوق الأصفر — التباين الأبيض ضعيف عليه */
    /* ── الزوايا والظلال (Fluent) ── */
    --f-r-s: 2px; --f-r-m: 4px; --f-r-l: 6px; --f-r-xl: 8px; --f-r-c: 9999px;
    --f-sh-2:  0 0 2px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.14);
    --f-sh-4:  0 0 2px rgba(0,0,0,.12), 0 2px 4px rgba(0,0,0,.14);
    --f-sh-8:  0 0 2px rgba(0,0,0,.12), 0 4px 8px rgba(0,0,0,.14);
    --f-sh-16: 0 0 2px rgba(0,0,0,.12), 0 8px 16px rgba(0,0,0,.14);
    /* ── الخطوطُ الرياضية في ذيل السلسلة ──
       بلاغ المالك (٢٦ أيلول ٢٠٢٦): كتب ‎ΣF⃗=0⃗‎ فخرجت مربّعاتٍ فارغة.
       والسببُ أنّ سهمَ الشعاع ‎U+20D7‎ محرفٌ مركَّبٌ لا يملكه ‎Segoe UI‎ ولا
       ‎Arial‎ ولا ‎Tajawal‎، فلم يجد المتصفّحُ له شكلاً في السلسلة كلّها.

       والإضافةُ **في الذيل لا في الرأس**: المتصفّح يختار الخطَّ لكلّ محرفٍ
       على حدة، فما يملكه ‎Segoe UI‎ يبقى فيه ولا ينزل إلى هذه إلّا محرفٌ
       عجز عنه ما قبله. فلا يتغيّر شكلُ حرفٍ واحدٍ في الواجهة.

       ولكلّ نظامٍ خطُّه: ‎Cambria Math‎ مرفقٌ بويندوز · ‎Noto Sans Math‎
       بأندرويد · ‎STIX Two Math‎ بماك · ‎DejaVu Sans‎ بلينكس. */
    --f-font: 'Segoe UI', 'Tajawal', 'Cambria Math', 'Segoe UI Symbol',
              'Noto Sans Math', 'Noto Sans Symbols 2', 'STIX Two Math',
              'DejaVu Sans', sans-serif;
}

/* ── سلّم الطباعة ── */
.f-display  { font: 700 3.4rem/1.1 var(--f-font); margin: 0; }
.f-title1   { font: 700 2rem var(--f-font); margin: 0; }
.f-title2   { font: 600 1.5rem var(--f-font); margin: 0; }
.f-title3   { font: 600 1.25rem var(--f-font); margin: 0; }
.f-subtitle { font: 600 1rem var(--f-font); margin: 0; }
.f-body     { font: 400 .875rem var(--f-font); margin: 0; }
.f-caption  { font: 400 .75rem var(--f-font); color: var(--f-fg-2); margin: 0; }

/* ============================ الأزرار (Button) ============================ */
.f-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font: 600 .875rem var(--f-font); line-height: 1; cursor: pointer; white-space: nowrap;
    padding-block: 0; padding-inline: 14px; block-size: 34px;
    border-radius: var(--f-r-m); border: 1px solid var(--f-stroke-2);
    background: var(--f-surface); color: var(--f-fg);
    transition: background .1s, border-color .1s, box-shadow .1s;
}
.f-btn:hover { background: var(--f-surface-hover); }
.f-btn:active { background: var(--f-surface-alt); }
.f-btn--primary { background: var(--f-brand); border-color: transparent; color: var(--f-on-brand); }
.f-btn--primary:hover { background: var(--f-brand-hover); }
.f-btn--primary:active { background: var(--f-brand-pressed); }
.f-btn--outline { background: transparent; border-color: var(--f-stroke-2); color: var(--f-fg); }
.f-btn--subtle { background: transparent; border-color: transparent; color: var(--f-fg); }
.f-btn--subtle:hover { background: var(--f-surface-hover); }
.f-btn--transparent { background: transparent; border-color: transparent; color: var(--f-brand-ink); }
.f-btn--transparent:hover { background: var(--f-brand-tint); }
.f-btn--danger { background: var(--f-err); border-color: transparent; color: #fff; }
/* بلا هذين السطرين يختفي زرّ الخطر عند المرور عليه في الوضع الفاتح:
   ‎.f-btn:hover‎ أعلى ترجيحاً (صنف + صنف زائف) من ‎.f-btn--danger‎ (صنف واحد)،
   فتغلب خلفيّتُه الرمادية الفاتحة ويبقى النصّ أبيض — أبيضُ على فاتح. */
.f-btn--danger:hover  { background: color-mix(in srgb, var(--f-err) 88%, #000); color: #fff; }
.f-btn--danger:active { background: color-mix(in srgb, var(--f-err) 78%, #000); color: #fff; }
.f-btn--sm { block-size: 26px; padding-inline: 10px; font-size: .78rem; }
.f-btn--lg { block-size: 42px; padding-inline: 20px; font-size: 1rem; }
.f-btn--circular { border-radius: var(--f-r-c); }
.f-btn--icon { inline-size: 34px; padding-inline: 0; }
.f-btn:disabled { opacity: .5; cursor: not-allowed; }
/* زر رئيسي بعرض كامل (لصفحات الإجراء) */
.f-btn-primary {
    inline-size: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
    padding-block: 13px; padding-inline: 16px; border: 1px solid transparent; border-radius: var(--f-r-m);
    background: var(--f-brand); color: var(--f-on-brand); font: 700 1.08rem var(--f-font);
    cursor: pointer; box-shadow: var(--f-sh-4); transition: background .1s, box-shadow .1s;
}
.f-btn-primary:hover { background: var(--f-brand-hover); box-shadow: var(--f-sh-8); }
.f-btn-primary:active { box-shadow: none; }
.f-btn-subtle {
    display: inline-flex; align-items: center; gap: 8px; padding-block: 8px; padding-inline: 12px;
    border: 1px solid var(--f-stroke); border-radius: var(--f-r-m); background: transparent;
    color: var(--f-fg); text-decoration: none; font: 600 .92rem var(--f-font); cursor: pointer; transition: background .1s;
}
.f-btn-subtle:hover { background: var(--f-surface-alt); }

/* ============================ الشارات (Badge) ============================ */
.f-badge { display: inline-flex; align-items: center; gap: 5px; block-size: 20px; padding-inline: 8px;
    font: 600 .72rem var(--f-font); border-radius: var(--f-r-c); }
.f-badge--brand { background: var(--f-brand); color: var(--f-on-brand); }
.f-badge--danger { background: var(--f-err); color: #fff; }
.f-badge--success { background: var(--f-ok); color: #fff; }
.f-badge--warning { background: var(--f-warn); color: var(--f-on-warn); }   /* نص داكن للتباين */
.f-badge--info { background: var(--f-info); color: #fff; }
.f-badge--tint { background: var(--f-brand-tint); color: var(--f-brand-ink); }
.f-badge--outline { background: transparent; border: 1px solid var(--f-stroke-2); color: var(--f-fg); }
.f-badge--dot { inline-size: 10px; block-size: 10px; padding: 0; border-radius: var(--f-r-c); }
.f-counter { display: inline-grid; place-items: center; min-inline-size: 20px; block-size: 20px; padding-inline: 6px;
    background: var(--f-err); color: #fff; border-radius: var(--f-r-c); font: 700 .72rem var(--f-font); }

/* ============================ الحقول (Field) ============================ */
.f-field { display: flex; flex-direction: column; gap: 4px; margin-block-end: 16px; }
.f-field > label, .f-field > .f-label { font-size: .84rem; font-weight: 600; color: var(--f-fg);
    display: inline-flex; align-items: center; gap: 5px; }
.f-field > .f-hint { font-size: .74rem; color: var(--f-fg-2); }
.f-field > .f-err  { font-size: .74rem; color: var(--f-err); }
.f-inputwrap { position: relative; display: flex; align-items: center;
    background: var(--f-surface-alt); border: 1px solid var(--f-stroke); border-block-end-color: var(--f-stroke-2);
    border-radius: var(--f-r-m); transition: border-color .1s; }
.f-inputwrap:hover { border-color: var(--f-stroke-2); }
/* المؤشّر السفلي المتحرّك — توقيع Fluent (منطقي: inline-block) */
.f-inputwrap::after { content: ''; position: absolute; inset-inline: 0; inset-block-end: -1px; block-size: 2px;
    background: var(--f-brand); border-end-start-radius: var(--f-r-m); border-end-end-radius: var(--f-r-m);
    transform: scaleX(0); transition: transform .15s cubic-bezier(.33,0,.67,1); pointer-events: none; }
.f-inputwrap:focus-within::after { transform: scaleX(1); }
.f-inputwrap.is-invalid { border-color: var(--f-err); }
.f-inputwrap.is-invalid::after { background: var(--f-err); transform: scaleX(1); }
.f-input, .f-control { flex: 1; min-inline-size: 0; border: 0; background: transparent; outline: none;
    color: var(--f-fg); font: 400 .9rem var(--f-font); padding-block: 8px; padding-inline: 10px; text-align: start; }
.f-input::placeholder, .f-control::placeholder { color: var(--f-fg-3); }
.f-inputwrap .f-affix { padding-inline: 10px; color: var(--f-fg-2); font-size: .9rem; display: inline-flex; }
textarea.f-input, textarea.f-control { resize: vertical; min-block-size: 72px; padding: 10px; }
/* قائمة منسدلة (Dropdown) — السهم على جهة النهاية (يسار في RTL، وهو المعتاد عربياً) */
/* اللون والسطح مُصرَّحان لا موروثَين: صفحات Fluent قد تُحيّد app.css فيرجع النصّ
   إلى لون المتصفح الافتراضي — داكن على سطح داكن. وعناصر option يرسمها النظام
   فلا ترث شيئاً، لذا تُصرَّح هي الأخرى. */
/* ══ ‎select.f-input‎ يدخل القاعدة مع ‎f-select‎ و‎f-dropdown‎ ══
   بلاغ المالك ١٢ أيلول ٢٠٢٦ (بصورة من الثيم الليليّ): «أسهم تشوّه المظهر في
   قوائم الاختيار بمعظم الصفحات». والسبب أنّ ‎<select class="f-input">‎ — بلا
   ‎f-select‎ — لا يناله ‎appearance:none‎، فيرسم المتصفّحُ سهمَه الأصليّ فوق
   سطحٍ داكن لا يعرفه: سهمٌ باهت أو مزدوج بجانب حدود الحقل.

   قِيس: ٣٧ قائمة في ١٥ ملفاً مقابل ١٨٦ سليمة. وتصحيحُها في الملفّات يعني
   خمسة عشر تعديلاً، ونسيانَ القادم. والصنف ‎f-input‎ هو ما يكتبه الناس فعلاً،
   فليكن هو ما يعمل.

   ‎:not([multiple]):not([size])‎ استثناءٌ لازم: صندوق القائمة المفتوحة
   (‎listbox‎) ليس منسدلاً، ووضعُ سهمٍ خلفيّ عليه يطبعه في وسط الخيارات.
   و‎calendar.php‎ يضبط ‎size‎ بجافاسكربت عند البحث — فيسقط الاستثناء من تلقائه
   وقتَها، وهو المطلوب. */
.f-select, .f-dropdown, select.f-input { color: var(--f-fg); background-color: var(--f-surface); }
.f-select option, .f-dropdown option, select.f-listbox option, select.f-input option,
.f-select optgroup, .f-dropdown optgroup, select.f-input optgroup { background-color: var(--f-surface); color: var(--f-fg); }
.f-select, .f-dropdown,
select.f-input:not([multiple]):not([size]) {
    -webkit-appearance: none; appearance: none; cursor: pointer; padding-inline-start: 34px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='%23808080' d='M4 6l4 4 4-4z'/></svg>");
    background-repeat: no-repeat; background-position: left 10px center; }
[dir="ltr"] .f-select, [dir="ltr"] .f-dropdown,
[dir="ltr"] select.f-input:not([multiple]):not([size]) {
    background-position: right 10px center; padding-inline-start: 10px; padding-inline-end: 34px; }
.f-select.is-readonly { background-color: var(--f-surface); color: var(--f-fg-2); pointer-events: none; font-weight: 600; }
/* حقل بحث بأيقونة أمامية (على جهة البداية) */
.f-search { position: relative; margin-block-end: 10px; }
.f-search-icon { position: absolute; inset-inline-start: 12px; inset-block-start: 50%; transform: translateY(-50%);
    color: var(--f-fg-2); font-size: .95rem; pointer-events: none; z-index: 1; }
.f-search-input { padding-inline-start: 36px; }
/* قائمة عناصر (listbox size=n) — نلغي سهم select الموروث */
select.f-listbox { block-size: 220px; padding: 4px; background-image: none !important; }
select.f-listbox option { padding-block: 10px; padding-inline: 12px; margin-block: 1px; border-radius: var(--f-r-m);
    font-size: .96rem; cursor: pointer; }
select.f-listbox option:checked { box-shadow: 0 0 10px 100px var(--f-brand-tint) inset; color: var(--f-brand-ink); font-weight: 600; }
/* عدّاد (SpinButton) */
.f-spin { display: inline-flex; }
.f-spin .f-spin-btns { display: flex; flex-direction: column; border-inline-start: 1px solid var(--f-stroke); }
.f-spin .f-spin-btns button { border: 0; background: transparent; color: var(--f-fg-2); cursor: pointer; block-size: 17px; inline-size: 26px; font-size: .6rem; }
.f-spin .f-spin-btns button:hover { background: var(--f-surface-hover); color: var(--f-fg); }

/* ============ الاختيار (Checkbox · Radio · Switch) ============ */
.f-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: .875rem; color: var(--f-fg); user-select: none; }
.f-check input { position: absolute; opacity: 0; inline-size: 0; block-size: 0; }
.f-check .box { inline-size: 18px; block-size: 18px; border: 1px solid var(--f-stroke-2); border-radius: var(--f-r-s);
    display: grid; place-items: center; color: #fff; font-size: .68rem; transition: background .1s, border-color .1s; }
.f-check.is-radio .box { border-radius: var(--f-r-c); }
.f-check input:checked + .box { background: var(--f-brand); border-color: var(--f-brand); color: var(--f-on-brand); }
.f-check input:not(:checked) + .box > i { opacity: 0; }
.f-check input:focus-visible + .box { box-shadow: 0 0 0 2px var(--f-brand-tint); }
.f-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: .875rem; color: var(--f-fg); }
.f-switch input { position: absolute; opacity: 0; }
.f-switch .track { inline-size: 40px; block-size: 20px; border-radius: var(--f-r-c); background: transparent;
    border: 1px solid var(--f-stroke-2); position: relative; transition: background .1s, border-color .1s; }
.f-switch .track::before { content: ''; position: absolute; inset-inline-start: 3px; inset-block-start: 50%; transform: translateY(-50%);
    inline-size: 12px; block-size: 12px; border-radius: var(--f-r-c); background: var(--f-fg-2); transition: inset-inline-start .12s, background .1s; }
.f-switch input:checked + .track { background: var(--f-brand); border-color: var(--f-brand); }
.f-switch input:checked + .track::before { inset-inline-start: 23px; background: var(--f-on-brand); }

/* ============================ TabList ============================ */
.f-tabs, .f-tablist { display: flex; gap: 2px; border-block-end: 1px solid var(--f-stroke); }
.f-tab { position: relative; display: inline-flex; align-items: center; gap: 7px; padding-block: 10px; padding-inline: 14px;
    border: 0; background: transparent; color: var(--f-fg-2); font: 600 .9rem var(--f-font); cursor: pointer; }
.f-tab:hover { color: var(--f-fg); background: var(--f-surface-hover); border-start-start-radius: var(--f-r-m); border-start-end-radius: var(--f-r-m); }
.f-tab.is-selected, .f-tab.active { color: var(--f-brand-ink); }
.f-tab.is-selected::after, .f-tab.active::after { content: ''; position: absolute; inset-inline: 12px; inset-block-end: -1px; block-size: 2px;
    background: var(--f-brand); border-radius: 2px; }

/* ==================== الشريحة المجزّأة (Segmented) ====================
   اختيارٌ **واحد من مجموعة** يبقى في الصفحة نفسها: مضمارٌ تعلوه قطعةٌ
   ممتلئة. وهي **ليست** ‎TabList‎ — ذاك صفٌّ بخطٍّ سفليّ متحرّك — ولا صفَّ
   أزرارٍ متفرّقة. الفرق ليس ذوقاً: المضمار يقول «هذه خياراتٌ متنافية»،
   وصفُّ الأزرار يقول «هذه أفعالٌ مستقلّة».

   بُنيت بعد أن وُجدت **مرسومةً بيدٍ مرّتين**: ‎user_management.php‎ يسمّيها
   ‎.um-tab‎ و‎student_subjects.php‎ يسمّيها ‎.reg-tab‎، وكلتاهما نسختان من
   الشكل نفسه بأرقامٍ تفترق قليلاً — وكلتاهما كانتا تُعَدّان «تبويباً
   قديماً» في تدقيق التغطية وهما قرارُ تصميمٍ مكتوبٌ سببُه في الملفّين. */
.f-seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px;
    background: var(--f-surface-alt); border: 1px solid var(--f-stroke); border-radius: var(--f-r-l); }
.f-seg-item { display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding-block: 0; padding-inline: 14px; block-size: 30px; border: 0; background: transparent;
    border-radius: var(--f-r-m); font: 600 .84rem var(--f-font); color: var(--f-fg-2);
    cursor: pointer; text-decoration: none; white-space: nowrap;
    transition: background .1s, color .1s; }
.f-seg-item:hover:not(.is-on):not(.active) { background: var(--f-surface); color: var(--f-fg); }
.f-seg-item.is-on, .f-seg-item.active,
.f-seg-item.is-on:hover, .f-seg-item.active:hover { background: var(--f-brand); color: var(--f-on-brand); }
/* ‎--fill‎: القطع تتقاسم العرض بالتساوي بدل أن تلتصق ببعضها في الابتداء.
   تُستعمل حين تكون الشريحة داخل رأس لوحةٍ بعرضٍ كامل. */
.f-seg--fill { display: flex; }
.f-seg--fill .f-seg-item { flex: 1 1 160px; }
/* العدّاد داخل القطعة: حبّةٌ تستعير لون النصّ الحالي فتنقلب معه على الخلفية
   الممتلئة بلا قاعدةٍ ثانية ولا لونٍ مكتوب مرّتين. */
.f-seg-item .f-seg-n { padding-inline: 7px; border-radius: var(--f-r-c);
    font-size: .74rem; font-variant-numeric: tabular-nums;
    background: color-mix(in srgb, currentColor 16%, transparent); }

/* ============================ MessageBar ============================ */
.f-msgbar, .f-messagebar { display: flex; align-items: center; gap: 10px; padding-block: 9px; padding-inline: 12px;
    border-radius: var(--f-r-m); border: 1px solid var(--f-stroke); font-size: .84rem; color: var(--f-fg); }
.f-msgbar .mb-ic { inline-size: 20px; block-size: 20px; display: grid; place-items: center; border-radius: var(--f-r-c);
    color: #fff; font-size: .7rem; flex-shrink: 0; }
.f-msgbar .mb-actions { margin-inline-start: auto; display: flex; gap: 6px; }
.f-msgbar--info    { background: var(--f-info-soft); border-color: color-mix(in srgb, var(--f-info) 30%, transparent); }
.f-msgbar--info .mb-ic { background: var(--f-info); }
.f-msgbar--success { background: var(--f-ok-soft); border-color: color-mix(in srgb, var(--f-ok) 30%, transparent); }
.f-msgbar--success .mb-ic { background: var(--f-ok); }
.f-msgbar--warning { background: var(--f-warn-soft); border-color: color-mix(in srgb, var(--f-warn) 34%, transparent); }
.f-msgbar--warning .mb-ic { background: var(--f-warn); color: var(--f-on-warn); }
.f-msgbar--error   { background: var(--f-err-soft); border-color: color-mix(in srgb, var(--f-err) 30%, transparent); }
.f-msgbar--error .mb-ic { background: var(--f-err); }
/* لافتة خطأ مبسّطة (بحدّ جانبي على جهة البداية) */
.f-messagebar { border-inline-start: 3px solid var(--f-err); background: var(--f-err-soft); color: var(--f-err); font-weight: 600; }

/* ============================ البطاقات (Card) ============================ */
.f-card { background: var(--f-surface); border: 1px solid var(--f-stroke); border-radius: var(--f-r-xl);
    box-shadow: var(--f-sh-4); padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.f-card--subtle { box-shadow: none; background: var(--f-surface-alt); }
.f-subcard { background: var(--f-surface-alt); border: 1px solid var(--f-stroke); border-radius: var(--f-r-xl); padding: 16px; }
.f-card-head { display: flex; align-items: center; gap: 10px; }
.f-card-head .ch-av { inline-size: 36px; block-size: 36px; border-radius: var(--f-r-l); background: var(--f-brand-tint);
    color: var(--f-brand-ink); display: grid; place-items: center; font-size: 1rem; }
.f-card-foot { display: flex; gap: 8px; }

/* النافذة المغلقة تبقى مخفيّة — لا تحذف هذا السطر.
   المتصفّح يخفي <dialog> بقاعدته dialog:not([open]){display:none}، لكنّها قاعدة
   متصفّح تسقط أمام أي قاعدة مؤلِّف تضبط display. و.f-card أعلاه تضبطه flex،
   فكل <dialog class="f-card"> كان يُرسم دائماً داخل الصفحة فوق ما تحته.
   التخصيص هنا (0,1,1) فيغلب .f-card (0,1,0)، ولا يمسّ النافذة المفتوحة. */
dialog:not([open]) { display: none; }

.f-stat { background: var(--f-surface); border: 1px solid var(--f-stroke); border-radius: var(--f-r-l); padding: 12px 14px; box-shadow: var(--f-sh-2); }
.f-price { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap;
    background: var(--f-brand-tint); color: var(--f-brand-ink); border: 1px solid color-mix(in srgb, var(--f-brand) 22%, transparent);
    border-radius: var(--f-r-xl); padding: 18px; font-size: 1.35rem; font-weight: 700; }
.f-price strong { font-size: 1.9rem; font-weight: 800; }
.f-price .old-price, .old-price { text-decoration: line-through; color: var(--f-fg-2); font-size: 1.15rem; margin-inline-start: 8px; opacity: .75; }

/* ============================ الجدول (DataGrid) ============================
   تُلغى تنسيقات app.css المركزية (تدرّج الترويسة + زوايا RTL المنطقية + التلاصق). */
.f-table { inline-size: 100%; border-collapse: collapse; border-spacing: 0; font-size: .86rem; background: var(--f-surface);
    border: 1px solid var(--f-stroke); border-radius: var(--f-r-l); overflow: hidden; }
.f-table thead th, .f-table th,
.f-table thead th:first-child, .f-table thead th:last-child {
    position: static; z-index: auto; text-align: start; font-weight: 600; color: var(--f-fg-2); font-size: .78rem;
    padding-block: 9px; padding-inline: 12px; border-block-end: 1px solid var(--f-stroke); background: var(--f-thead);
    background-image: none; border-start-start-radius: 0; border-start-end-radius: 0; border-radius: 0; box-shadow: none; white-space: nowrap;
}
.f-table tbody td { padding-block: 9px; padding-inline: 12px; border-block-end: 1px solid var(--f-stroke); color: var(--f-fg); text-align: start; }
.f-table tbody tr:hover { background: var(--f-surface-hover); }
.f-table tbody tr:nth-child(even) { background: transparent; }
.f-table tbody tr:last-child td { border-block-end: 0; }
.f-table .num { text-align: end; font-variant-numeric: tabular-nums; }

/* ── فرز الأعمدة (assets/js/f-table.js على <table data-sortable>) ── */
.f-table th.f-sortable { cursor: pointer; user-select: none; transition: background .1s, color .1s; }
.f-table th.f-sortable:hover { background: var(--f-surface-hover); color: var(--f-fg); }
.f-table th.f-sortable:focus-visible { outline: 2px solid var(--f-brand); outline-offset: -2px; }
/* السهم دائماً حاضر كي لا يتحرّك عرض العمود عند الفرز */
.f-table th.f-sortable::after { content: '⇅'; margin-inline-start: 6px; font-size: .95em; opacity: .35; }
.f-table th.f-sortable[aria-sort="ascending"],
.f-table th.f-sortable[aria-sort="descending"] { color: var(--f-brand-ink); }
.f-table th.f-sortable[aria-sort="ascending"]::after { content: '▲'; font-size: .7em; opacity: 1; }
.f-table th.f-sortable[aria-sort="descending"]::after { content: '▼'; font-size: .7em; opacity: 1; }
/* فاصل الأصناف: أول صفّ من كل قيمة جديدة في العمود المفروز */
.f-table tbody tr.f-group-start > td { border-block-start: 2px solid var(--f-stroke-2); }
.f-table tbody tr.f-group-start:first-child > td { border-block-start: 0; }
/* على الورق يبقى الترتيب المختار ويختفي مؤشّر التفاعل */
@media print {
    .f-table th.f-sortable::after { content: none; }
    .f-table th.f-sortable[aria-sort="ascending"],
    .f-table th.f-sortable[aria-sort="descending"] { color: inherit; }
}

/* ── الغلاف الذي يصنعه app.js ─────────────────────────────────────────────
   ‎wrapTables()‎ في ‎assets/js/app.js‎ يلفّ كل ‎<table>‎ بـ‎<div class="table-scroll">‎
   ما لم يكن ملفوفاً أصلاً. وغلاف ‎app.css‎ يحمل ‎--radius-lg‎ (18px) وظلّاً، بينما
   جدول Fluent نصف قطره ‎--f-r-l‎ (6px) بلا ظلّ. وقاعدة ‎.table-scroll > table‎
   تخصيصها (0,1,1) فتغلب ‎.f-table‎ (0,1,0) وتنزع إطار الجدول ونصف قطره.
   فالنتيجة: **كل ‎f-table‎ في النظام مؤطَّرٌ بإطار ‎app.css‎ لا بإطار Fluent.**
   مقيسٌ بالأنماط المحسوبة: ‎wrapper_radius = 18px‎ · ‎table_radius = 0px‎.

   اللون وحده متّفق (‎--f-stroke: var(--border-color)‎)، والخلاف في نصف القطر
   والظلّ. كان يُحيَّد يدوياً في ‎news_management‎ و‎settings‎ و‎student_calendar‎
   و‎screen_management‎ و‎payments‎ — خمس نسخ من القاعدة نفسها. يُوحَّد هنا مرّة.

   ‎:has()‎ تخصيصها تخصيصُ أثقل وسيطٍ فيها، فـ(0,2,0) تغلب ‎.table-scroll‎ (0,1,0).
   ومتصفّحٌ لا يفهم ‎:has()‎ يُسقط هذه القاعدة وحدها فيعود إلى السلوك القائم. */
.table-scroll:has(> .f-table) {
    border: 1px solid var(--f-stroke);
    border-radius: var(--f-r-l);
    box-shadow: none;
    background: var(--f-surface);
}
/* والجدول داخله بلا إطارٍ ثانٍ — (0,2,0) تغلب ‎.table-scroll > table‎ (0,1,1) */
.table-scroll > .f-table { border: 0; border-radius: 0; }

/* ── ازدواج الحدّ على الورق ──
   ‎app.css:1138‎ يضع ‎border: 1px solid #ccc !important‎ على ‎table‎ و‎.table-scroll‎
   **معاً**، والـ‎!important‎ يغلب نزعَ الإطار أعلاه، فيُرسم خطّان متلاصقان.
   مقيس: ‎wrapper_border = 1px‎ و‎table_border = 1px‎ في آنٍ واحد.
   يُنزع إطار الجدول الداخليّ ويبقى إطار الغلاف — بـ‎!important‎ اضطراراً.

   ملاحظة مقيسة: ‎overflow: hidden‎ في ‎.f-table‎ **لا** يمنع كسر الصفحات على
   Chromium 152 — ١٢٠ صفّاً تُطبع كاملة على خمس صفحات، داخل ‎.f-card‎ و‎.f-shell‎
   أيضاً، ورأس الجدول يتكرّر تلقائياً. فلا تُضَف له معالجةٌ بلا قياس. */
@media print {
    .table-scroll > .f-table { border: 0 !important; }
}

/* ============ Spinner / Progress / Avatar ============ */
.f-spinner { inline-size: 28px; block-size: 28px; border-radius: var(--f-r-c); border: 3px solid var(--f-stroke);
    border-block-start-color: var(--f-brand); animation: f-spin .8s linear infinite; }
.f-spinner--lg { inline-size: 44px; block-size: 44px; border-width: 4px; }
@keyframes f-spin { to { transform: rotate(360deg); } }
.f-progress { block-size: 4px; background: var(--f-surface-alt); border-radius: var(--f-r-c); overflow: hidden; }
.f-progress > i { display: block; block-size: 100%; background: var(--f-brand); border-radius: var(--f-r-c); }
.f-avatar { inline-size: 36px; block-size: 36px; border-radius: var(--f-r-c); display: grid; place-items: center;
    font-weight: 700; font-size: .85rem; color: var(--f-on-brand); background: var(--f-brand); }
.f-avatar--sq { border-radius: var(--f-r-l); }

/* ============ Chip / Tooltip / Divider / Accordion ============ */
.f-chip { display: inline-flex; align-items: center; gap: 6px; block-size: 28px; padding-inline: 10px; border-radius: var(--f-r-c);
    background: var(--f-surface-alt); border: 1px solid var(--f-stroke); font-size: .8rem; color: var(--f-fg); }
.f-chip .x { cursor: pointer; color: var(--f-fg-2); }
/* ── ‎--action‎: شريحةُ ترشيحٍ تُضغط ──
   ‎.f-chip‎ وحدها ساكنة: وسمٌ يُعرض ولا يُنقر. ومرشّحاتُ ‎data_gaps.php‎ و
   ‎applications.php‎ شرائحُ **تُختار** — كانتا مرسومتين بيدٍ باسمَي ‎.dg-tab‎
   و‎.ap-tab‎ بالشكل نفسه وأرقامٍ تفترق قليلاً (‎14px‎ مقابل ‎13px‎ و‎.84rem‎
   مقابل ‎.82rem‎). ‎32px‎ لا ‎28px‎: الشريحةُ الساكنة وسمٌ يُقرأ، وهذه هدفُ
   إصبعٍ في صفٍّ من الأهداف. */
.f-chip--action { block-size: 32px; padding-inline: 14px; gap: 7px;
    background: var(--f-surface); border-color: var(--f-stroke-2);
    cursor: pointer; text-decoration: none;
    transition: background .1s, border-color .1s, color .1s; }
.f-chip--action:hover:not(.is-on) { background: var(--f-surface-hover); }
.f-chip--action.is-on, .f-chip--action.is-on:hover {
    background: var(--f-brand); border-color: var(--f-brand); color: var(--f-on-brand); font-weight: 600; }
/* عدّادُ الشريحة **باهتٌ لا حبّة** — بخلاف ‎.f-seg-n‎. الشرائحُ تُصطفّ عشراً
   في سطر (مرشّحات حالة الاستمارات)، فحبّةٌ داخل كلٍّ منها تصنع صفّاً من
   الحلقات يسرق النظر من الاختيار نفسه. */
.f-chip-n { font-variant-numeric: tabular-nums; opacity: .8; font-size: .78rem; }
.f-divider { display: flex; align-items: center; gap: 10px; color: var(--f-fg-2); font-size: .76rem; margin-block: 4px; }
.f-divider::before, .f-divider::after { content: ''; flex: 1; block-size: 1px; background: var(--f-stroke); }
.f-tip { position: relative; display: inline-flex; }
.f-tip .tip-body { position: absolute; inset-block-end: calc(100% + 8px); inset-inline-start: 50%; transform: translateX(50%) scale(.96);
    background: var(--f-fg); color: var(--f-surface); font-size: .74rem; padding-block: 5px; padding-inline: 9px; border-radius: var(--f-r-m);
    white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .12s, transform .12s; box-shadow: var(--f-sh-8); }
[dir="ltr"] .f-tip .tip-body { transform: translateX(-50%) scale(.96); }
.f-tip:hover .tip-body { opacity: 1; transform: translateX(50%) scale(1); }
[dir="ltr"] .f-tip:hover .tip-body { transform: translateX(-50%) scale(1); }
.f-accordion { border: 1px solid var(--f-stroke); border-radius: var(--f-r-l); overflow: hidden; background: var(--f-surface); }
.f-acc-item + .f-acc-item { border-block-start: 1px solid var(--f-stroke); }
.f-acc-head { inline-size: 100%; display: flex; align-items: center; gap: 10px; padding-block: 12px; padding-inline: 14px;
    border: 0; background: transparent; color: var(--f-fg); font: 600 .9rem var(--f-font); cursor: pointer; text-align: start; }
.f-acc-head:hover { background: var(--f-surface-hover); }
.f-acc-head .chev { transition: transform .15s; color: var(--f-fg-2); }
.f-acc-item.is-open .f-acc-head .chev { transform: rotate(90deg); }
.f-acc-panel { display: none; padding-block: 0 14px; padding-inline: 14px 40px; font-size: .86rem; color: var(--f-fg-2); }
.f-acc-item.is-open .f-acc-panel { display: block; }

/* ── حاويات صفحة شائعة (رأس/جسم/بطاقة صفحة) ── */
/* ⚠ ‎min(860px, 100%)‎ لا ‎860px‎ وحدها: السقفُ يمنع التمدّد فوق ٨٦٠ ولا
   يُجبر الانكماشَ دونه. و‎.f-page‎ عنصرٌ في حاوية ‎flex‎ عمودية (‎.main-content‎)،
   وسطرُ ‎flex‎ العموديّ يأخذ عرضَ أكبر عناصره فيتجاوز حاويته بلا رادع —
   فجدولٌ عريض يمدّ المستندَ كلَّه، وتخرج القائمةُ الجانبية من مخبئها على
   الجوال ويُزاح المحتوى (قِيس على ‎app_security‎: ‎f-page‎ ٦٤٦ بكسل في شاشة
   ٥٠٠، و‎scrollWidth‎ ٦٦٦).
   و‎min-inline-size: 0‎ تُكمل الحيلة: بدونها لا تنكمش أبناؤها كذلك. */
.f-page { max-inline-size: min(860px, 100%); min-inline-size: 0;
    margin-block: 24px; margin-inline: auto; padding-inline: 12px; font-family: var(--f-font); }
.f-shell { background: var(--f-surface); border: 1px solid var(--f-stroke); border-radius: var(--f-r-xl); box-shadow: var(--f-sh-16); overflow: hidden; }
.f-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-block: 16px; padding-inline: 20px;
    border-block-end: 1px solid var(--f-stroke); background: var(--f-surface); }
.f-header h1 { margin: 0; font: 700 1.25rem var(--f-font); color: var(--f-fg); display: flex; align-items: center; gap: 10px; }
.f-header-icon { display: grid; place-items: center; inline-size: 34px; block-size: 34px; border-radius: var(--f-r-l);
    background: var(--f-brand-tint); color: var(--f-brand-ink); font-size: 1rem; }
.f-body { padding-block: 22px 26px; padding-inline: 22px; }

/* ═══════════════════════════════════════════════════════════════════════
   العملة — الجديدة بارزة والقديمة تحتها للتنويه (١٢ أيلول ٢٠٢٦)
   السطر القديم يختفي من كلّ الموقع بمفتاح ‎LMS_SHOW_OLD_CURRENCY‎ في
   ‎includes/money.php‎ — لا حاجة إلى لمس هذه القواعد عند إلغائه.
   ═══════════════════════════════════════════════════════════════════════ */
.lms-money { display: inline-flex; flex-direction: column; align-items: flex-start;
    line-height: 1.25; vertical-align: middle; }
.lms-money.is-inline { flex-direction: row; align-items: baseline; gap: 6px; }
.lms-money .m-cur { font-size: .92em; opacity: .8; }
/* القديمة: أصغر وأخفت — تُقرأ عند الحاجة ولا تزاحم الرقم الحقيقيّ */
.lms-money .m-old { font-size: .72em; opacity: .58; white-space: nowrap; font-weight: 400; }
/* في الطباعة تبقى: الوصل الورقيّ هو أكثر ما يحتاج فيه القارئ المقارنة */
@media print { .lms-money .m-old { opacity: .7; } }

/* ═══════════════════════════════════════════════════════════════════════
   منعُ سحبِ الصور — الشعارُ والخاتم وثيقتان لا زينة
   -----------------------------------------------------------------------
   سحبُ صورةٍ بالفأرة إلى سطح المكتب ينسخها بضغطةٍ واحدة بلا قائمةٍ ولا
   قرار. والخاتمُ الرسميّ وشعارُ المجموعة يظهران في صفحة التحقّق العامّة —
   وهي مفتوحةٌ لكلّ من يحمل رقم وثيقة.

   ⚠ هذا **رفعُ عتبةٍ لا حماية**: من أراد الصورة نالها من «حفظ الصورة» أو
   من مصدر الصفحة أو بلقطة شاشة. الحمايةُ الحقيقية هي أنّ الورقة لا تُصدَّق
   بخاتمها بل برقمها على ‎/cert‎ — ولذلك لا نُثقل الصفحة بمنع القائمة اليمنى
   ولا بطبقةٍ شفّافة فوق الصور: كلاهما يُزعج الصادقين ولا يوقف غيرهم.

   و‎Firefox‎ لا يعرف ‎-webkit-user-drag‎، فيتولّاه حارسُ ‎dragstart‎ في
   ‎assets/js/app.js‎ (وفي صفحة التحقّق نسخةٌ منه لأنها لا تحمّل الملفّ).
   ═══════════════════════════════════════════════════════════════════════ */
img, svg, .f-avatar, .contact-avatar {
    -webkit-user-drag: none;
    user-drag: none;
}

/* ==================== شريط رموز المعادلات (EqBar) ====================
   يُبنى من ‎assets/js/eqbar.js‎ فوق أيّ حقلٍ يحمل ‎data-eqbar‎.
   لماذا في النظام لا في الصفحة: الحاجة نفسها في التسميعات وبنك أسئلة
   «اختبر نفسي» واختبارات التصحيح التلقائي — ثلاث نسخٍ تفترق عند أوّل
   رمزٍ يُضاف. */
/* ── خطُّ حقول المعادلات ──
   بلاغ المالك (٢٦ أيلول ٢٠٢٦): «الشعاع فوق الصفر كسر».
   السببُ أنّ ‎F⃗‎ حرفٌ يتبعه محرفٌ مركَّب، وموضعُ المركَّب فوق الحرف مكتوبٌ
   في جدول ‎GPOS‎ **داخل الخطّ الواحد**. فحين يأتي الحرفُ من ‎Segoe UI‎
   والسهمُ من خطٍّ رياضيٍّ احتياطيّ، لا يجد المتصفّحُ ربطاً بينهما فيضعه
   على ارتفاعٍ افتراضيّ — يصحّ فوق ‎v‎ ويقطع ‎0‎ و‎F‎ و‎d‎.

   فالعلاجُ أن يأتي **الحرفُ والسهمُ من خطٍّ واحد**: خطٌّ رياضيٌّ في رأس
   السلسلة لا في ذيلها. والعربيةُ بعده مباشرةً — الخطوطُ الرياضية لا تحمل
   عربيةً، فتنزل إليها وحدها ولا يتغيّر شكلُ حرفٍ عربيّ.

   ويُقصر هذا على الحقول التي فوقها شريطُ المعادلات: هي وحدها التي تُكتب
   فيها الرموز، وتغييرُ خطّ الواجهة كلِّها ثمنٌ لا داعي له. */
/* وأزرارُ الشريط نفسها: زرُّ ‎x⃗‎ يعرض الحرفَ ومحرفَه المركَّب معاً،
   فيصيبه العطبُ نفسه إن جاءا من خطّين. */
.eqbar-field, .eqbar-b {
    font-family: 'Cambria Math', 'STIX Two Math', 'Segoe UI', 'Tajawal',
                 'Noto Sans Math', 'DejaVu Sans', sans-serif !important;
}
.eqbar { display: flex; flex-wrap: wrap; align-items: center; gap: 3px;
    padding: 5px 6px; margin-block-end: 6px;
    background: var(--f-surface-alt); border: 1px solid var(--f-stroke);
    border-radius: var(--f-r-m); }
.eqbar-lab { font-size: .68rem; color: var(--f-fg-3); margin-inline-end: 2px;
    user-select: none; white-space: nowrap; }
.eqbar-sep { inline-size: 1px; block-size: 16px; background: var(--f-stroke-2);
    margin-inline: 4px; flex-shrink: 0; }
/* ‎min-inline-size‎ لا ‎inline-size‎: رموزٌ كـ‎∛‎ و‎⅔‎ أعرض من ‎₂‎، وتثبيت
   العرض يقصّها. والخطّ ‎1rem‎: المنخفضاتُ صغيرةٌ بطبعها فتصير غير مقروءة
   بحجم الواجهة المعتاد. */
.eqbar-b { min-inline-size: 28px; block-size: 28px; padding-inline: 5px;
    display: inline-grid; place-items: center;
    border: 1px solid transparent; border-radius: var(--f-r-s);
    background: var(--f-surface); color: var(--f-fg);
    font-size: 1rem; line-height: 1; cursor: pointer;
    transition: background .1s, border-color .1s; }
.eqbar-b:hover { background: var(--f-brand-tint); border-color: var(--f-brand); }
.eqbar-b:active { background: var(--f-brand); color: var(--f-on-brand); }
@media (max-width: 560px) {
    .eqbar { gap: 2px; padding: 4px; }
    .eqbar-b { min-inline-size: 26px; block-size: 26px; font-size: .95rem; }
    .eqbar-lab { display: none; }   /* على الجوّال الرموزُ أولى بالمساحة */
}
/* زرّ التحويل: أعرضُ من زرّ الرمز لأنّه يحمل نصّاً، ومميَّزٌ بلون العلامة
   لأنّه الفعل الرئيسيّ في الشريط لا رمزاً من سبعةٍ وستّين. */
.eqbar-conv { min-inline-size: auto; padding-inline: 10px; gap: 4px;
    font: 600 .74rem var(--f-font);
    background: var(--f-brand-tint); border-color: var(--f-brand);
    color: var(--f-brand-ink); }
.eqbar-conv:hover { background: var(--f-brand); color: var(--f-on-brand); }
