/* ═══════════════════════════════════════════════════════════════════════════
   طبقة الموبايل — لوحة الطلبات كمعرض بطاقات بملء الشاشة
   ═══════════════════════════════════════════════════════════════════════════

   كل ما في هذا الملف مشروط بـ `body.is-mobile-board` التي يضيفها
   mobile-orders.js وحده عند مطابقة (max-width: 767px). سطح المكتب لا يحصل
   على الصنف إطلاقاً، ولو تعطّل الـJS بقيت الصفحة على سلوكها الحالي بالضبط
   (قواعد @media الموجودة في style.css). أي قاعدة هنا بلا هذا الصنف = خطأ.

   لا يُعاد بناء أي DOM: البطاقات هي نفسها التي يرسلها السيرفر، بنفس
   data-attributes ونفس النماذج، فكل معالجات الأحداث المفوّضة على document
   (الإرسال، الأوفلاين، reconcile، السحب) تعمل بلا تعديل.
   ═══════════════════════════════════════════════════════════════════════════ */

body.is-mobile-board {
  /* يُقاسان فعلياً في mobile-orders.js — القيم هنا احتياطية قبل أول قياس */
  --mob-top: 3.25rem;
  --mob-nav: 3.5rem;
  --mob-tools-h: 6rem;
  /* ارتفاع عنوان المحل اللاصق. هذه قيمة **احتياطية** فقط قبل أول قياس —
     mobile-orders.js يقيس العنوان الظاهر فعلاً ويكتبها بالبكسل. الافتراض
     الثابت كان يجعل العنوان يغطّي أعلى البطاقة المثبّتة (قياس: العنوان يمتدّ
     إلى 157 بينما البطاقة تبدأ عند 148). */
  --mob-store-h: 2.4rem;
  --mob-safe-bottom: env(safe-area-inset-bottom, 0px);
  --mob-safe-top: env(safe-area-inset-top, 0px);
  --mob-gutter: .6rem;

  /* الشاشة ناقص كل ما هو ثابت: الهيدر + شريط الشرائح اللاصق + عنوان المحل
     اللاصق + شريط التنقل. لو أهملنا أياً منها لاختبأ طرف البطاقة خلفه،
     فتفقد «بطاقة = شاشة» معناها.

     ⚠️ svh وليس dvh — وهذا الفرق بين معرض يعمل وآخر يهتزّ.
     `dvh` هو «الارتفاع الديناميكي»: يتغيّر **أثناء التمرير نفسه** بينما
     يختفي شريط عنوان المتصفح ويظهر (الفارق 60–110 بكسل على أجهزة حقيقية).
     أي أن كل بطاقة كانت تتمدّد وتنكمش تحت إصبع الموظف، وكل نقطة تثبيت
     تتحرّك معها — وهذا بالضبط عَرَضا «أحجام الكروت تتغيّر عند الـscroll»
     و«الانتقال بين الكروت لا يعمل».
     `svh` هو «الارتفاع الصغير»: الشاشة وشريط العنوان ظاهر — قيمة **ثابتة**
     لا تتغيّر أثناء التمرير إطلاقاً. أسوأ ما فيها فراغ صغير أسفل البطاقة
     حين يختفي الشريط، وهو ثمن زهيد مقابل تخطيط لا يهتزّ.

     ملاحظة للصيانة: هذا العيب **لا يظهر في محاكاة أبعاد الشاشة** في أدوات
     المطوّر — هناك svh = lvh = dvh لأن لا شريط عنوان متحرّكاً. يُقاس على
     جهاز حقيقي فقط. */
  --mob-card-h: calc(100svh - var(--mob-top) - var(--mob-tools-h) - var(--mob-store-h) - var(--mob-nav));
}

/* لا يدعم svh؟ (Safari أقدم من 15.4) — نعود إلى vh بلا كسر */
@supports not (height: 100svh) {
  body.is-mobile-board {
    --mob-card-h: calc(100vh - var(--mob-top) - var(--mob-tools-h) - var(--mob-store-h) - var(--mob-nav));
  }
}

/* ── منع التمرير الأفقي العَرَضي ─────────────────────────────────────────
   سبب شائع على الموبايل: عنصر واحد أعرض من الشاشة يُطيل المستند أفقياً.
   overflow-x: clip بدل hidden — hidden على body يُنشئ سياق تمرير جديداً
   فيُبطل position: sticky للهيدر على iOS. */
body.is-mobile-board { overflow-x: clip; }
body.is-mobile-board .app-main,
body.is-mobile-board .order-card { max-width: 100%; }

/* ═══ الهيدر ═══════════════════════════════════════════════════════════ */

/* backdrop-filter: blur() على عنصر sticky يُجبر المتصفح على إعادة رسم طبقة
   مموّهة في كل إطار تمرير — أثقل بند منفرد في أداء التمرير على iOS. يُستبدل
   بخلفية معتمة على الموبايل فقط؛ سطح المكتب يحتفظ بالتمويه. */
body.is-mobile-board .app-header {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: var(--surface);
  padding-top: var(--mob-safe-top);   /* تحت نتوء iPhone لا خلفه */
}
body.is-mobile-board .header-inner {
  padding: .45rem .7rem;
  gap: .5rem;
}
body.is-mobile-board .app-header h1 { font-size: 1rem; }

/* روابط الصفحات تنتقل إلى شريط التنقل السفلي — بقاؤها في الهيدر كان يلتهم
   سطرين من ارتفاع الشاشة ويترك أهدافاً أصغر من 44 بكسل. */
body.is-mobile-board .header-actions > a.btn { display: none; }
body.is-mobile-board .header-actions {
  gap: .3rem;
  flex-wrap: nowrap;
}
body.is-mobile-board .user-badge {
  max-width: 7.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* التدرّجان الشعاعيان على body يُعاد رسمهما مع كل تمرير على iOS.
   لون مسطّح على الموبايل — الفارق البصري معدوم خلف البطاقات المعتمة. */
body.is-mobile-board { background-image: none; }

/* ═══ شريط الأدوات: بحث فوري + شرائح تصفية ══════════════════════════════ */

/* شريط البحث **غير** لاصق عمداً: التصاقه مع الهيدر وشريط الشرائح كان
   يلتهم 173 بكسل من 812 قبل أن تبدأ أول بطاقة. يمرّ مع الصفحة ويعود بالتمرير
   لأعلى، وتبقى الشرائح وحدها لاصقة (50 بكسل) لأن التنقّل بينها دائم. */
body.is-mobile-board .board-toolbar {
  z-index: 60;
  flex-wrap: nowrap;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  margin: 0;
  padding: .45rem var(--mob-gutter);
  border-radius: 0;
  display: flex;
  gap: .4rem;
  align-items: center;
}
body.is-mobile-board .board-search {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
}
body.is-mobile-board .board-search input[type="search"] {
  min-height: 2.6rem;
  font-size: 16px;  /* أقل من 16px يُجبر iOS على تكبير الصفحة عند التركيز */
}
/* زر «بحث» يختفي: البحث فوري أثناء الكتابة، ولا داعي لهدف لمس إضافي */
body.is-mobile-board .board-search-submit { display: none; }
body.is-mobile-board .btn-offline-chip { min-height: 2.6rem; }

/* شرائح التصفية — بديل الأكورديون المتشعّب على الموبايل */
.mob-filters {
  display: none;
  position: sticky;
  top: var(--mob-top);
  z-index: 55;
  gap: .35rem;
  padding: .4rem var(--mob-gutter);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.mob-filters::-webkit-scrollbar { display: none; }
body.is-mobile-board .mob-filters { display: flex; }

.mob-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  min-height: 2.25rem;
  padding: .35rem .75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--muted);
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.mob-chip[aria-selected="true"] {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.mob-chip-count {
  font-size: .75rem;
  font-weight: 700;
  opacity: .85;
  font-variant-numeric: tabular-nums;
}

/* ═══ إخفاء زينة سطح المكتب التي لا تفيد على شاشة صغيرة ═══════════════════ */

body.is-mobile-board .stats-dashboard,
body.is-mobile-board .ah-board-strip,
body.is-mobile-board .top-skus-section,
body.is-mobile-board .stock-alerts-panel,
body.is-mobile-board .admin-toolbar { display: none; }

/* شريط التنقل السفلي يفتحها عند الطلب */
body.is-mobile-board.mob-show-panels .stats-dashboard,
body.is-mobile-board.mob-show-panels .ah-board-strip,
body.is-mobile-board.mob-show-panels .top-skus-section,
body.is-mobile-board.mob-show-panels .stock-alerts-panel,
body.is-mobile-board.mob-show-panels .admin-toolbar { display: block; }
body.is-mobile-board.mob-show-panels .board-section { display: none !important; }
body.is-mobile-board.mob-show-panels .mob-filters { display: none; }

/* ═══ الأقسام: قسم واحد نشط تحدّده الشريحة ══════════════════════════════ */

body.is-mobile-board .app-main { padding: 0; }
body.is-mobile-board .board-section { display: none; }
body.is-mobile-board .board-section.mob-active { display: block; }

/* عنوان القسم يُستبدل بالشريحة — لا حاجة لأكورديون داخل قسم واحد ظاهر.
   ⚠️ لكن صفّ العنوان (.section-title-row) يحمل أيضاً زر «تصفير القائمة»،
   فإخفاء الصفّ كله كان يُخفي الزر معه — وهو إجراء إداري لا بديل عنه على
   الموبايل. الآن يُخفى **العنوان** وحده، ويبقى الصفّ ظاهراً إذا كان يحمل
   زر تصفير (يضع الصنف mobile-orders.js). */
body.is-mobile-board .board-section.mob-active .section-title { display: none; }
body.is-mobile-board .board-section.mob-active > .section-title-row { display: none; }
body.is-mobile-board .board-section.mob-active > .section-body { display: block !important; }

/* القوائم الفرعية (الطلبات الحالية / تم الشراء) تصير شرائح أيضاً */
body.is-mobile-board .sub-section { display: none; }
body.is-mobile-board .sub-section.mob-active { display: block !important; }
body.is-mobile-board .sub-section.mob-active .sub-title { display: none; }
body.is-mobile-board .sub-section.mob-active > .sub-header-row { display: none; }

/* صفّ الإجراءات الإدارية: يظهر فقط حين يحمل زر تصفير فعلاً */
body.is-mobile-board .board-section.mob-active > .section-title-row.mob-has-purge,
body.is-mobile-board .sub-section.mob-active > .sub-header-row.mob-has-purge {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: .4rem;
  margin: 0;
  padding: .4rem var(--mob-gutter);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
body.is-mobile-board .btn-purge-list {
  min-height: 2.5rem;   /* هدف لمس مريح */
  font-size: .82rem;
}

/* نوافذ التأكيد (تصفير قائمة / تصفير كل القوائم): حقل كتابة DELETE بخطّ
   أصغر من 16px يجعل iOS يُكبّر الصفحة عند التركيز فيه، فتخرج النافذة عن
   الشاشة ويصعب إتمام التأكيد. نفس القاعدة المطبَّقة على كل حقول الموبايل. */
body.is-mobile-board .confirm-delete-input {
  font-size: 16px;
  min-height: 2.75rem;
}
body.is-mobile-board .confirm-modal-footer .btn { min-height: 2.75rem; }
body.is-mobile-board .sub-section.mob-active > .sub-body { display: block !important; }
body.is-mobile-board .transfer-priority-block > .transfer-priority-label {
  margin: .5rem var(--mob-gutter) .25rem;
  font-size: .82rem;
}

/* ═══ مجموعات المحلات: عناوين لاصقة قابلة للطيّ ═════════════════════════ */

body.is-mobile-board .store-listing,
body.is-mobile-board .store-groups-block { display: block; }

body.is-mobile-board .store-group {
  border: 0;
  border-radius: 0;
  margin: 0;
  background: transparent;
  box-shadow: none;

  /* ⚠ حاسم: style.css يضع `overflow: hidden` على .store-group (لتقصّ الحواف
     الدائرية على سطح المكتب). أي سلف بـoverflow غير visible يصير هو
     «حاوية التمرير» التي يُقاس منها `top` في position: sticky — فكان عنوان
     المحل يهبط 109 بكسل داخل المجموعة ويطفو **فوق** أول بطاقة بدل أن يلتصق
     أعلى الشاشة (قياس: طبيعي 185، فعلي 294). visible يُعيد المرجع إلى
     الشاشة نفسها. */
  overflow: visible;
}
/* الطيّ والفتح يعملان على الموبايل كما على سطح المكتب.
   كان هنا `display: block !important` يُبقي كل المحلات مفتوحة — وهو ما كان
   يُبطل زرّ الطيّ بصرياً: الضغطة تصل إلى board-accordion.js ويكتب
   `style.display = none` فعلاً، لكن القاعدة ذات !important تتجاوزه فلا يتغيّر
   شيء أمام الموظف. حُذفت القاعدة، فصار سلوك الطيّ هو سلوك اللوحة نفسه بلا
   منطق مكرّر: محل واحد مفتوح، والباقي مطويّ. */
body.is-mobile-board .store-group-body { display: block; }

body.is-mobile-board .store-group-header {
  position: sticky;
  top: calc(var(--mob-top) + var(--mob-tools-h));
  z-index: 40;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .4rem;
  padding: .2rem var(--mob-gutter);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  /* ⚠️ ثابت — **لا** var(--mob-store-h).
     ذلك المتغيّر يُقاس **من هذا العنصر نفسه** في measureChrome، فربطه
     بـmin-height يصنع حلقة تغذية راجعة موجبة: يُقاس الارتفاع ← يُكتب في
     المتغيّر ← يصير حداً أدنى للعنصر ← يكبر ← يُقاس أكبر… النتيجة المقاسة:
     صفوف المحلات انتفخت إلى 185 بكسل وابتلعت شاشة قائمة المحلات كلها.
     المتغيّر مُخرَج للقياس فقط، لا مُدخَل للتنسيق. */
  min-height: 2.5rem;
}
body.is-mobile-board .store-group-toggle {
  /* الأساس 0 لا auto: مع auto يأخذ الزرّ عرض نصّه كاملاً فيُزاح زرّ إجراءات
     المحل إلى سطر ثانٍ ويتضاعف ارتفاع الصفّ في قائمة المحلات. */
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .88rem;
  font-weight: 700;
  padding: .2rem 0;
  background: none;
  border: 0;
  color: var(--text);
  text-align: start;
}
/* السهم يعود: هو الدليل الوحيد على أن الصفّ قابل للطيّ. مقبض السحب وحده
   يختفي (السحب باللمس غير موثوق — مشكلة موثّقة، وأزرار ↑↓ تُغني عنه). */
body.is-mobile-board .store-drag-handle { display: none; }
body.is-mobile-board .store-chevron {
  display: inline-block;
  flex: 0 0 auto;
  font-size: .7rem;
  color: var(--muted);
}
/* المحل المفتوح يتميّز بوضوح عن المطويّ في قائمة العناوين */
body.is-mobile-board .store-group.store-group-expanded > .store-group-header {
  background: var(--primary-soft, rgba(37, 99, 235, .1));
  border-bottom-color: var(--primary);
}
/* هدف لمس كامل الصفّ لا الأيقونة وحدها */
body.is-mobile-board .store-group-toggle { min-height: 2.5rem; }
body.is-mobile-board .store-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* أزرار ترتيب المحل بالسحب لا تعمل بشكل موثوق باللمس (مشكلة موثّقة)،
   وأزرار الأعلى/الأسفل تُغني عنها. تُنقل خلف زر «إجراءات المحل». */
body.is-mobile-board .store-group-actions {
  display: none;
  flex-wrap: wrap;
  gap: .3rem;
  padding: .35rem 0 .5rem;
  width: 100%;
}
body.is-mobile-board .store-group.mob-actions-open .store-group-actions { display: flex; }
body.is-mobile-board .store-group-actions .btn { min-height: 2.4rem; }

.mob-store-actions-btn {
  flex: 0 0 auto;
  min-width: 2.4rem;
  min-height: 2.4rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--muted);
  font-size: 1rem;
  cursor: pointer;
  touch-action: manipulation;
}
body:not(.is-mobile-board) .mob-store-actions-btn { display: none; }

/* ═══ المعرض: بطاقة واحدة بملء الشاشة + تثبيت التمرير ══════════════════ */

/* حاوية التمرير هي المستند نفسه (لا حاوية داخلية): حاوية داخلية على iOS
   تكسر الهيدر اللاصق، وتمنع إخفاء شريط العنوان، وتُفقد استعادة موضع
   التمرير عند الرجوع.

   mandatory: تم التحقق قياسياً من أنها **لا** تُبطل تعويض التمرير في
   board-accordion.js — حذف بطاقة فوق الشاشة يُزيح 642 بكسل، والتعويض
   يُعيد المرجع إلى موضعه بفارق 0 تحت mandatory تماماً كما تحت proximity.
   (كان هذا هو الخطر الوحيد الجدّي في اختيارها.)

   بلا `scroll-snap-stop: always`: مع 106 بطاقات وأكثر، إجبار التوقّف عند
   كل بطاقة يجعل الوصول لآخر القائمة عشرات الحركات. الدفعة الواحدة تمرّ عبر
   عدة بطاقات لكنها **تستقرّ دائماً على واحدة**. */
body.is-mobile-board {
  scroll-snap-type: y mandatory;
  scroll-padding-top: calc(var(--mob-top) + var(--mob-tools-h) + var(--mob-store-h));
}

/* مَخرج الأمان: بطاقة أطول من الشاشة (سجل نشاط مفتوح، لوحة تحويل مفتوحة،
   أو «المزيد») لا يمكن قراءة وسطها تحت mandatory — المتصفح يجذبك بعيداً عن
   أي موضع ليس نقطة تثبيت. عند وجود أي بطاقة موسّعة يتوقف التثبيت مؤقتاً.
   الصنف mob-snap-off يضعه mobile-orders.js للمتصفحات بلا :has(). */
body.is-mobile-board.mob-snap-off { scroll-snap-type: none; }
body.is-mobile-board:has(.order-card.mob-expanded),
body.is-mobile-board:has(.order-card .action-panel[open]),
body.is-mobile-board:has(.order-card .activity-details[open]) { scroll-snap-type: none; }

body.is-mobile-board .orders-list {
  display: block;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

body.is-mobile-board .order-card {
  scroll-snap-align: start;
  /* توقّف إجباري عند كل بطاقة: الدفعة الواحدة تنقل طلباً واحداً بالضبط،
     وهو سلوك المعرض المطلوب. الوصول البعيد يتم بالشرائح والبحث وزرّي
     التنقّل، لا بعشرات الدفعات. */
  scroll-snap-stop: always;
  scroll-margin-top: calc(var(--mob-top) + var(--mob-tools-h) + var(--mob-store-h));

  /* ── ارتفاع **ثابت** لا حد أدنى ──────────────────────────────────────
     `min-height` كان يجعل ارتفاع كل بطاقة تابعاً لمحتواها، فتختلف نقاط
     التثبيت من بطاقة لأخرى، ومع `content-visibility` يتغيّر ارتفاع البطاقة
     لحظة ظهورها أول مرة (من التقدير إلى الواقع) فيقفز كل ما تحتها.
     الارتفاع الثابت يجعل الشبكة منتظمة تماماً: نقطة تثبيت واحدة لكل بطاقة،
     في موضع معلوم، لا يتغيّر عند الرسم. القياس على البيانات الحقيقية: أطول
     بطاقة ممكنة (بانر تحويل + شارة تكرار + كل الأزرار) ارتفاعها الطبيعي
     623 بكسل مقابل ميزانية 643 — تدخل بالكامل. وما زاد على الميزانية على
     شاشة أقصر يكشفه زر «المزيد» (انظر mob-clipped). */
  height: var(--mob-card-h);
  overflow: hidden;
  margin: 0 0 var(--mob-gutter);
  border-radius: 0;
  border-inline-start: 0;
  border-inline-end: 0;

  /* ── التحجيم للأعداد الكبيرة ─────────────────────────────────────────
     content-visibility: auto يجعل المتصفح يتخطّى تنسيق ورسم كل بطاقة خارج
     الشاشة — 500 طلب تُنسَّق كـ500 صندوق بدل 27000 عنصر.
     بلا كلمة `auto` في contain-intrinsic-size: مع ارتفاع صريح يصبح التقدير
     مطابقاً للواقع دائماً، فلا إعادة تخطيط عند أول ظهور لأي بطاقة. */
  content-visibility: auto;
  contain-intrinsic-size: var(--mob-card-h);

  display: grid;
  /* عمود الصورة يكبر مع الشاشة: 88 بكسل على iPhone SE و112 على Pro Max.
     الهدف من «بطاقة = شاشة» أن تُستغل المساحة لا أن تبقى فارغة. */
  /* عمود الصورة أوسع. لا يزيد ارتفاع البطاقة إطلاقاً: الارتفاع ثابت من
     --mob-card-h وصف المحتوى `minmax(0,1fr)` يملأ ما تبقّى، فالصورة تكبر
     داخل مساحة كانت فارغة أصلاً أسفل عمود الصورة. */
  grid-template-columns: clamp(6.75rem, 34vw, 9.5rem) minmax(0, 1fr);
  /* صفّ مستقل لزر «المزيد» بين المحتوى والأزرار.
     ⚠️ ليس تجميلاً: البطاقة ذات ارتفاع ثابت تقصّ ما يفيض من جسمها، وزر
     «المزيد» هو مَخرج الطوارئ الذي يكشف المقصوص — فلو بقي داخل الجسم لكان
     أول ما يُقصّ على شاشة قصيرة (قياس على 375×667: الجسم يحتاج 553 بكسل
     ويحصل على 290)، أي يختفي المَخرج مع المحتوى الذي يكشفه. */
  grid-template-areas:
    "media body"
    "more  more"
    "actions actions";
  grid-template-rows: minmax(0, 1fr) auto auto;
  align-content: stretch;
  gap: .5rem .65rem;
  /* ⚠️ حشو **منطقي** لا فيزيائي.
     اختصار `padding` يأخذ أعلى/يمين/أسفل/يسار بالمعنى الفيزيائي، وفي صفحة
     RTL يقع «اليمين الفيزيائي» على جهة بداية السطر — أي جهة الصورة تماماً.
     ممرّ محجوز كُتب هناك دفع الصورة ومحتوى البطاقة كله بعيداً عن حافة اليمين
     (قياس: 71 بكسل فجوة) بينما عمود التنقّل كان على الجهة المقابلة أصلاً.
     `padding-inline` متماثل يُعيد المحتوى ملاصقاً لليمين، وعمود التنقّل صار
     يسكن الفراغ الطبيعي أسفل الصورة فلا يحتاج حجز ممرّ إطلاقاً. */
  padding-block: .7rem .5rem;
  padding-inline: var(--mob-gutter);
}

/* البطاقة النشطة — إشارة بصرية خفيفة بلا حركة */
body.is-mobile-board .order-card.mob-current {
  box-shadow: inset 0 0 0 2px var(--primary-soft, rgba(37, 99, 235, .18));
}

/* المتصفحات بلا content-visibility (Safari 17 وما دونه): نفس الأثر عبر
   IntersectionObserver يضيف mob-dormant — لا حذف من الـDOM إطلاقاً، حتى
   يظل querySelectorAll('.order-card') في باقي الملفات صحيحاً. */
body.is-mobile-board .order-card.mob-dormant {
  contain: size layout paint style;
  height: var(--mob-card-h);
}
body.is-mobile-board .order-card.mob-dormant > * { visibility: hidden; }

/* ── ترتيب المعلومات: الأهم أولاً ──────────────────────────────────────
   يُنفَّذ عبر order على العناصر الموجودة، بلا أي تغيير في القالب — فبطاقة
   سطح المكتب ونسخة الأوفلاين المخزّنة تبقيان كما هما. */
body.is-mobile-board .order-card-media { grid-area: media; }
body.is-mobile-board .order-card-body   { grid-area: body; }
body.is-mobile-board .card-actions      { grid-area: actions; }

body.is-mobile-board .order-card-media {
  width: 100%;
  align-self: start;   /* لا يتمدّد مع الصف فتبقى الصورة أعلى البطاقة */
  display: flex;
  flex-direction: column;
  gap: .35rem;
  align-items: center;
}
body.is-mobile-board .order-card-media img,
body.is-mobile-board .order-card-media .img-placeholder,
body.is-mobile-board .product-thumb-btn {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
body.is-mobile-board .qty-badge {
  width: 100%;
  padding: .25rem;
  text-align: center;
}
body.is-mobile-board .qty-value { font-size: 1.5rem; line-height: 1.1; }
body.is-mobile-board .qty-label { font-size: .68rem; }

body.is-mobile-board .order-card-body {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  /* ⚠️ الثلاثة معاً ضرورية لحبس الجسم في صفّه من الشبكة:
     • `align-self: stretch` صريحة — القيمة الافتراضية `normal` لم تكن تمدّد
       هذا العنصر (وهو حاوية flex)، فكان يأخذ ارتفاع محتواه ويتجاوز صفّه:
       قياس فعلي 448 بكسل داخل صفّ ارتفاعه 225، فيرسم فوق زر «المزيد» وفوق
       أزرار الإجراءات ويخفيها تحت النص.
     • `min-height: 0` تُلغي الحد الأدنى التلقائي الذي يمنع الانكماش.
     • `overflow: hidden` تقصّ الفائض قصّاً نظيفاً يكشفه زر «المزيد». */
  align-self: stretch;
  min-height: 0;
  overflow: hidden;
}
/* بلا هذا ينكمش الأبناء تحت ضغط المساحة بدل أن يفيضوا — فيلتصق نص بانر
   التحويل بعضه ببعض ويبدو مشوّهاً، بدل قصّ نظيف يكشفه زر «المزيد». */
body.is-mobile-board .order-card-body > * { flex-shrink: 0; }

/* تعليق التحويل قد يكون فقرة كاملة يكتبها الموظف — سطران يكفيان في العرض
   المختصر، والباقي يظهر مع «المزيد». */
body.is-mobile-board .order-card:not(.mob-expanded) .transfer-review-comment {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* البطاقة الموسّعة تخرج من كل القيود: ارتفاع حر، بلا احتواء، بلا قصّ —
   والتثبيت معطّل أصلاً في هذه الحالة. */
body.is-mobile-board .order-card.mob-expanded {
  height: auto;
  min-height: var(--mob-card-h);
  overflow: visible;
  content-visibility: visible;
  contain-intrinsic-size: none;
}
body.is-mobile-board .order-card.mob-expanded .order-card-body { overflow: visible; }

/* بطاقة محتواها أطول من الشاشة (جهاز قصير): يُبرز زر «المزيد» بدل أن يُقصّ
   المحتوى بصمت. تُكتشف في mobile-orders.js عند دخول البطاقة الشاشة. */
body.is-mobile-board .order-card.mob-clipped .mob-more-btn {
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 700;
}
body.is-mobile-board .transfer-review-banner,
body.is-mobile-board .transfer-reviewed-banner { order: 0; }
body.is-mobile-board .order-type-wrap  { order: 1; }
body.is-mobile-board .repeat-order-wrap { order: 2; }
body.is-mobile-board .product-name     { order: 3; }
body.is-mobile-board .order-fields     { order: 4; }
body.is-mobile-board .order-datetime   { order: 5; }
body.is-mobile-board .activity-details { order: 7; }

body.is-mobile-board .product-name {
  font-size: 1rem;
  line-height: 1.35;
  margin: 0;
  /* ثلاثة أسطر ثم اختصار: عنوان أمازون قد يبلغ 200 حرف فيدفع كل شيء خارج
     الشاشة ويُبطل فكرة «بطاقة = شاشة». */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body.is-mobile-board .order-card.mob-expanded .product-name {
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}

body.is-mobile-board .order-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .35rem .5rem;
  padding: .5rem;
  margin: 0;
}
/* رقم الطلب أولاً وبعرض كامل — هو ما ينسخه الموظف ويبحث به */
body.is-mobile-board .order-fields > .field:nth-of-type(1) { grid-column: 1 / -1; order: 1; }
body.is-mobile-board .order-fields > .field:nth-of-type(2) { order: 2; }   /* SKU */
body.is-mobile-board .order-fields > .field:nth-of-type(3) { order: 3; }   /* ASIN */
body.is-mobile-board .order-fields > .field-price      { grid-column: 1 / -1; order: 4; }
body.is-mobile-board .order-fields > .field-sku-block  { grid-column: 1 / -1; order: 5; }
body.is-mobile-board .order-fields dt { font-size: .68rem; }
body.is-mobile-board .order-fields dd { font-size: .92rem; word-break: break-all; }

body.is-mobile-board .order-datetime {
  display: flex;
  gap: .6rem;
  font-size: .8rem;
  color: var(--muted);
}

/* ── الثانوي يُطوى خلف «المزيد» ───────────────────────────────────────── */
body.is-mobile-board .order-card:not(.mob-expanded) .field-sku-block,
body.is-mobile-board .order-card:not(.mob-expanded) .activity-details,
body.is-mobile-board .order-card:not(.mob-expanded) .order-fields > .field:nth-of-type(3) {
  display: none;
}

.mob-more-btn {
  grid-area: more;
  /* الجهة المقابلة لعمود التنقّل: كلاهما كان على حافة اليمين فتراكبا
     (قياس: العمود يطفو فوق زر «المزيد» في بطاقة الموظف). */
  justify-self: end;
  min-height: 2.25rem;
  padding: .3rem .7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--muted);
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
}
body:not(.is-mobile-board) .mob-more-btn { display: none; }

/* ── الأزرار: أهداف إبهام، بلا اعتماد على hover ───────────────────────── */
body.is-mobile-board .card-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .4rem;
  min-width: 0;
  margin-top: .35rem;
  padding-top: .5rem;
  border-top: 1px solid var(--border);
}
body.is-mobile-board .card-actions > form,
body.is-mobile-board .card-actions > .action-panel,
body.is-mobile-board .card-actions > .btn { min-width: 0; }
body.is-mobile-board .card-actions .btn,
body.is-mobile-board .card-actions summary.btn {
  width: 100%;
  min-height: 2.85rem;   /* أكبر من 44 بكسل: الحد الأدنى لهدف اللمس على iOS */
  font-size: .9rem;
  padding-inline: .5rem;
}
/* لوحة التحويل/الإرجاع تأخذ العرض كاملاً عند فتحها */
body.is-mobile-board .card-actions .action-panel[open] { grid-column: 1 / -1; }
body.is-mobile-board .card-actions .panel-body select,
body.is-mobile-board .card-actions .panel-body textarea,
body.is-mobile-board .card-actions .panel-body input {
  font-size: 16px;       /* منع تكبير iOS التلقائي عند التركيز */
  min-height: 2.6rem;
  width: 100%;
}
body.is-mobile-board .btn-zero-stock { grid-column: 1 / -1; }
/* بطاقة المراجعة فيها إجراء واحد («استلام الطلب») — نصف عرض بلا سبب */
body.is-mobile-board .card-actions > *:only-child { grid-column: 1 / -1; }

/* ═══ مؤشر الموضع ══════════════════════════════════════════════════════ */

/* عدّاد الموضع — يعيش داخل عمود التنقّل بين السهمين، فلا يزاحم شيئاً */
.mob-position {
  display: none;
  padding: .2rem .45rem;
  border-radius: 999px;
  background: rgba(15, 23, 42, .78);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  pointer-events: none;
}
body.is-mobile-board .mob-position { display: block; }

/* ═══ منتقي المحلات ═════════════════════════════════════════════════════ */

/* زر في شريط الأدوات يفتح ورقة سفلية بكل محلات القسم الحالي وعدد طلبات كلٍّ
   منها. التنقّل بين المحلات بضغطة واحدة بدل تمرير طويل بحثاً عن العنوان. */
.mob-store-btn {
  display: none;
  flex: 0 0 auto;
  align-items: center;
  gap: .3rem;
  min-height: 2.6rem;
  padding: .35rem .6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
}
body.is-mobile-board .mob-store-btn { display: inline-flex; }

.mob-store-list { display: grid; gap: .25rem; margin: 0; padding: 0; list-style: none; }
.mob-store-item {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  min-height: 3rem;
  padding: .5rem .65rem;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  text-align: start;
  cursor: pointer;
  touch-action: manipulation;
}
.mob-store-item[aria-current="true"] {
  border-color: var(--primary);
  background: var(--primary-soft, rgba(37, 99, 235, .1));
  color: var(--primary);
}
.mob-store-item-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mob-store-item-count {
  flex: 0 0 auto;
  padding: .1rem .5rem;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
}
.mob-empty-inline {
  margin: 0;
  padding: 1.25rem .5rem;
  text-align: center;
  color: var(--muted);
  font-size: .88rem;
}
.mob-sheet-title {
  margin: 0 0 .5rem;
  font-size: .95rem;
  font-weight: 700;
}

/* ═══ زرّا الانتقال بين الطلبات ═════════════════════════════════════════ */

/* التثبيت وحده لا يكفي: فيزياء اللمس تختلف بين iOS وأندرويد، وعناوين
   المحلات اللاصقة تفصل بين البطاقات فتختلف المسافات. زرّان صريحان يجعلان
   «الطلب التالي/السابق» عملية مؤكّدة لا تعتمد على قوة الدفعة. */
/* عمود واحد في منتصف الحافة: [التالي] [٩ / ١٠٥] [السابق].
   ⚠️ منتصف الحافة لا أسفلها: أسفل البطاقة صفُّ الإجراءات («استلام الطلب»،
   «تم الشراء»…)، ووضع الأزرار هناك كان يغطّي أهدافاً قابلة للضغط. والمنتصف
   هو الفراغ الطبيعي في بطاقة بملء الشاشة، فلا يحجب شيئاً. */
.mob-pager {
  display: none;
  position: fixed;
  z-index: 70;
  /* جهة اليمين في صفحة RTL = بداية السطر — وهي أيضاً جهة عمود الصورة.
     ⚠️ الموضع الرأسي يُقاس من **أسفل** لا من المنتصف: بعد تكبير الصورة صار
     عمود الصورة وشارة الكمية يمتدّان إلى منتصف الشاشة، فكان العمود يطفو
     فوقهما (قياس: طفا فوق product-thumb وqty-badge). النطاق الحرّ الوحيد على
     هذه الجهة هو ما بين أسفل شارة الكمية وأعلى صفّ الإجراءات؛ والقياس من
     أسفل يجعله يعلو صفّ الإجراءات دائماً مهما اختلف عدد أزراره (55 بكسل في
     بطاقة المراجعة، 163 في بطاقة الموظف). */
  inset-inline-start: .45rem;
  bottom: calc(var(--mob-nav, 0px) + var(--mob-safe-bottom, 0px) + 11rem);
  flex-direction: column;
  align-items: center;
  gap: .35rem;
}
body.is-mobile-board .mob-pager { display: flex; }
/* كل المحلات مطويّة = لا بطاقات = لا معنى لـ«التالي/السابق»، وكان العمود
   يعرض «٠ / ٠» ويطفو فوق قائمة المحلات. */
body.is-mobile-board.mob-no-cards .mob-pager { display: none; }

.mob-pager-btn {
  width: 2.6rem;
  height: 2.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-size: .95rem;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 1px 4px rgba(15, 23, 42, .16);
  opacity: .92;
}
.mob-pager-btn:active { transform: scale(.94); }
/* العمود لا يعترض لمس ما تحته خارج الأزرار نفسها */
.mob-pager { pointer-events: none; }
.mob-pager-btn { pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  .mob-pager-btn:active { transform: none; }
}

/* ═══ شريط التنقل السفلي ════════════════════════════════════════════════ */

.mob-nav {
  display: none;
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 90;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: var(--mob-safe-bottom);   /* فوق شريط الـHome على iPhone */
}
body.is-mobile-board .mob-nav { display: block; }
.mob-nav-row {
  display: flex;
  align-items: stretch;
  justify-content: space-around;
}
.mob-nav-item {
  flex: 1 1 0;
  min-width: 0;
  min-height: 3.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .1rem;
  padding: .3rem .15rem;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: .66rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.mob-nav-item:hover { text-decoration: none; }
.mob-nav-item[aria-current="page"],
.mob-nav-item.is-active { color: var(--primary); }
.mob-nav-icon { font-size: 1.15rem; line-height: 1; }
.mob-nav-item.is-blocked { opacity: .4; }

/* المحتوى لا يختفي خلف الشريط السفلي */
body.is-mobile-board { padding-bottom: calc(var(--mob-nav) + var(--mob-safe-bottom)); }

/* ═══ ورقة سفلية «المزيد» ═══════════════════════════════════════════════ */

.mob-sheet {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: none;
}
.mob-sheet[data-open="1"] { display: block; }
.mob-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, .45);
}
.mob-sheet-panel {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  max-height: 80dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--surface);
  border-radius: 16px 16px 0 0;
  padding: .5rem .9rem calc(1rem + var(--mob-safe-bottom));
}
@media (prefers-reduced-motion: no-preference) {
  .mob-sheet[data-open="1"] .mob-sheet-panel { animation: mobSheetUp .18s ease-out; }
}
@keyframes mobSheetUp { from { transform: translateY(12%); } to { transform: translateY(0); } }
.mob-sheet-grip {
  width: 2.5rem;
  height: .25rem;
  margin: .35rem auto .6rem;
  border-radius: 999px;
  background: var(--border);
}
.mob-sheet-list { display: grid; gap: .3rem; margin: 0; padding: 0; list-style: none; }
.mob-sheet-link {
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 3rem;
  padding: .5rem .6rem;
  border-radius: 10px;
  color: var(--text);
  font-weight: 600;
}
.mob-sheet-link:hover { text-decoration: none; background: var(--bg); }
.mob-sheet-link.is-blocked { opacity: .45; }

/* ═══ لافتة الاتصال ═════════════════════════════════════════════════════ */

/* اللافتة تعمل على سطح المكتب أيضاً (تُنشئها offline-nav.js في كل صفحة)،
   لذا كل متغيّر هنا له قيمة احتياطية — على سطح المكتب لا تُعرَّف هذه
   المتغيّرات إطلاقاً، وcalc() بمتغيّر غير معرّف يُبطل الخاصية كلها. */
.mob-conn {
  position: fixed;
  inset-inline: 0;
  z-index: 110;
  bottom: calc(var(--mob-nav, 0px) + var(--mob-safe-bottom, 0px));
  padding: .45rem .8rem;
  font-size: .82rem;
  font-weight: 600;
  text-align: center;
  color: #fff;
  transform: translateY(120%);
  transition: transform .2s ease;
}
.mob-conn.is-shown { transform: translateY(0); }
.mob-conn--offline { background: #b45309; }
.mob-conn--syncing { background: #0369a1; }
.mob-conn--online  { background: #15803d; }

@media (prefers-reduced-motion: reduce) {
  .mob-conn { transition: none; }
}

/* ═══ حالة «لا نتائج» للبحث/التصفية المحلية ════════════════════════════ */
.mob-empty {
  display: none;
  padding: 1.5rem 1rem;
  text-align: center;
  color: var(--muted);
}
body.is-mobile-board.mob-no-results .mob-empty { display: block; }

/* بطاقة مستبعَدة بالبحث/التصفية المحلية — لا تُحذف من الـDOM إطلاقاً */
body.is-mobile-board .order-card.mob-filtered-out { display: none !important; }
/* مجموعة محل فرغت من نتائج البحث: يختفي عنوانها أيضاً */
body.is-mobile-board .store-group.mob-filtered-out { display: none !important; }
