/**
 * interaction-laws.css — قوانين مرحلة السلوك والتفاعل
 * ====================================================
 * طبقة تصحيح مشتركة لواجهات المنصة الداخلية، مبنية على قوانين التصميم
 * المنشورة في uxlp.online (مرحلة السلوك والتفاعل) ومعايير WCAG 2.2 AA.
 *
 * تُحمَّل بعد أنظمة التصميم الأخرى، ولا تعيد تعريف الهوية البصرية —
 * تضبط فقط ما يمسّ قدرة المستخدم على الوصول والتفاعل والفهم.
 *
 * النطاق: هذا الملف يُربَط من قوالب اللوحات الداخلية فقط، فلا يحتاج
 * إلى صنف حاصر — الوسم <body> هنا هو دائمًا لوحة داخلية.
 *
 * القوانين المطبَّقة:
 *   ١. قانون فيتس            → أحجام أهداف نقر كافية حسب نوع المؤشر
 *   ٢. حلقة التغذية الراجعة  → دلالة فورية بعد كل تفاعل
 *   ٣. عتبة دوهرتي           → حالة انتظار مرئية بدل الصمت
 *   ٤. وضوح التركيز          → SC 2.4.7 و2.4.11 و1.4.11
 *   ٥. قانون بوستل           → لا ألوان تحذيرية في الأخطاء البسيطة
 *   ٦. تأثير زيغارنيك        → إبراز غير المكتمل
 *   ٧. تقليل الحركة          → SC 2.3.3
 */

/* ===========================================================================
   ١) قانون فيتس — الوقت اللازم للوصول للهدف يعتمد على حجمه وقربه
   ---------------------------------------------------------------------------
   المصدر يقول: «المستخدم يفضل العناصر الواضحة والقريبة من اصبعه» و«مراعات
   فرق المسافات بين كل جهاز مثل الحاسوب والجوال». لذلك نكبّر الأهداف على
   الأجهزة اللمسية فقط (pointer: coarse) ونترك كثافة الحاسوب كما هي.
   يوافق ذلك WCAG 2.2 SC 2.5.8 (٢٤px حدًّا أدنى، و٤٤px هو المستوى المريح).
   =========================================================================== */

/* على كل الأجهزة: لا يقلّ أي هدف تفاعلي عن الحد الأدنى الملزم (٢٤px).
   الارتفاع فقط — فرض عرض أدنى هنا يكسر الأزرار داخل أعمدة شبكة ضيقة. */
body :is(
  button,
  [role="button"],
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  summary
) {
  min-height: 24px;
}

@media (pointer: coarse) {
  /* النموّ الرأسي آمن على أي تخطيط، فيُطبَّق على كل هدف تفاعلي. */
  body :is(
    button,
    [role="button"],
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    summary,
    .user-btn,
    .btn,
    .admin-nav-link,
    .admin-nav-dropdown-toggle,
    .admin-nav-dropdown-link,
    .admin-header-action-btn
  ) {
    min-height: 44px;
  }

  /* أمّا العرض فيُفرض على الأزرار الأيقونية وحدها — وهي الوحيدة التي
     تكون أضيق من إصبع. فرضه على كل زر كان سيُطفح أزرارًا تعيش داخل
     أعمدة شبكة مثبّتة العرض (مثل زرّ إغلاق الإشعار في عمود ٣٠px). */
  body :is(button, a, [role="button"]):not(.admin-sidebar-toggle):has(> i:only-child),
  body :is(button, a, [role="button"]):not(.admin-sidebar-toggle):has(> svg:only-child),
  body button:empty {
    min-width: 44px;
  }

  /* لسان طيّ القائمة ضيّقٌ عمداً (25px في مساحة المستخدم) ويتدلّى على
     حافتها. فرض ‎44px‎ عرضاً مدّه داخل القائمة على اللوحي الأفقي فغطّى حقل
     البحث وزرّ الميكروفون. يبقى بمقاسه المرئي، وتتسع منطقة لمسه نحو هامش
     المحتوى الفارغ خارج القائمة (اليسار في RTL). */
  body .admin-sidebar-toggle::after {
    content: "";
    position: absolute;
    inset-block: -2px;
    inset-inline-start: 0;
    inset-inline-end: -19px;
  }

  /* حقول الإدخال والقوائم المنسدلة أهداف نقر أيضًا. */
  body :is(
    input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
    select,
    textarea
  ) {
    min-height: 44px;
  }

  /* مربعات الاختيار صغيرة بطبيعتها، فنوسّع منطقة النقر حول تسميتها. */
  body :is(input[type="checkbox"], input[type="radio"]) {
    min-height: 22px;
    min-width: 22px;
  }

  /* بوزنٍ صفري (‎:where‎): كانت القاعدة بوزن (0,1,3) تغلب ‎flex‎ و‎block‎
     اللذين تعلنهما الصفحة للتسمية، فتصير قائمة الخيارات العمودية صفّاً
     ملتفّاً من تسميات متلاصقة — على الجوال واللوحي وحدهما، لأن الفأرة لا
     تفعّل هذا الاستعلام. التسمية بلا عرضٍ معلن تبقى ‎inline-flex‎ كما كانت. */
  :where(body label:has(> input[type="checkbox"]), body label:has(> input[type="radio"])) {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }

  /* فاصل بين الأهداف المتجاورة يقلّل النقر الخاطئ — متمّم لقانون فيتس.
     لا يُطبَّق في الأعمدة والشبكات: هناك الأزرار مكدّسة فوق بعضها فتنزاح
     الثانية وما بعدها ‎8px‎ عن أخواتها وتتجاوز عرض الصف إن كانت بعرضه.
     وبوزنٍ صفري فيغلبه أي هامش تعلنه الصفحة. */
  :where(body :not(:is(.grid, .flex-col, [class*="grid"], [class*="-col"], [class*="stack"], [style*="grid"], [style*="column"])) > :is(.user-btn, .btn) + :is(.user-btn, .btn)) {
    margin-inline-start: 8px;
  }

  /* الروابط المصمَّمة أزراراً (حبوب التبويب، «فتح»، روابط واتساب الصغيرة،
     أزرار الأعذار المصغّرة) لا تشملها قاعدة الأزرار أعلاه فتبقى 28-36px.
     يُرفع ارتفاعها فقط حين تكون مرنة أو كتلية أصلاً: فرض display هنا كان
     سيكسر الروابط المضمَّنة في النص والبطاقات. */
  body .admin-content a:is(.inline-flex, .flex, .block)[class*="rounded"],
  body :is(.ntf-wa-link, .exc-mini-btn, .ff-btn, .sc-nav__link) {
    min-height: 44px;
  }

  /* زر الإغلاق «✕» نصّ لا أيقونة، فلا تلتقطه قاعدة العرض الأيقونية. */
  body .exc-modal-head button {
    min-width: 44px;
  }

  /* خط الحقول لا يقل عن 16px: سفاري iOS يكبّر الصفحة عند التركيز على أي
     حقل أصغر فيقفز المستخدم عن موضعه. لا نستعمل maximum-scale=1 في وسم
     viewport لأنه يمنع التكبير عمّن يحتاجه. */
  body :is(
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="hidden"]),
    select,
    textarea
  ) {
    font-size: max(16px, 1em) !important;
  }

  /* الروابط النصية داخل فقرة قراءة تبقى بحجم النص — تكبيرها يكسر السطر. */
  body :is(p, td, th, .prose) a:not(.btn):not(.user-btn):not([role="button"]) {
    min-height: 0;
    min-width: 0;
  }
}

/* ===========================================================================
   ٢) حلقة التغذية الراجعة — «اعطاء دلالة تغذية راجعة بعد اي تفاعل»
   ---------------------------------------------------------------------------
   كل عنصر قابل للنقر يحتاج ردّ فعل لحظيًا عند الضغط، لا عند اكتمال الطلب فقط.
   =========================================================================== */

/* القشرة تُلغي وميض اللمس الذي يوفّره نظام التشغيل:
     * { -webkit-tap-highlight-color: transparent; }
   فبقيت النقرة بلا أي دلالة على الجوال. هذه القاعدة هي البديل: انكماش
   طفيف يُرى فورًا، فيغلق حلقة التغذية الراجعة قبل وصول ردّ الخادم. */
body :is(a, button, [role="button"], label[for], summary, .user-btn, .btn):not(:disabled):not([aria-disabled="true"]):active {
  transform: scale(0.97);
  transition-duration: 60ms;
}

/* الروابط النصّية داخل فقرة لا تُنكمش — الانكماش يزحزح سطر القراءة. */
body :is(p, li, td, th, .prose) a:not(.btn):not(.user-btn):not([role="button"]):active {
  transform: none;
  opacity: 0.6;
}

/* حالة الانشغال: يراها المبصر ويسمعها قارئ الشاشة (aria-busy). */
body [aria-busy="true"] {
  cursor: progress;
  opacity: 0.7;
}

body button:disabled,
body [aria-disabled="true"] {
  cursor: not-allowed;
}

/* ===========================================================================
   ٣) عتبة دوهرتي — «اضافة تاثير بصري لتقليل الانتظار» تحت ٠٫٤ ثانية
   ---------------------------------------------------------------------------
   أي عنصر يحمل data-loading يعرض شريط تقدّم غير محدَّد بدل الصمت.
   =========================================================================== */

body [data-loading="true"] {
  position: relative;
  pointer-events: none;
}

body [data-loading="true"]::after {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, currentColor, transparent);
  opacity: 0.65;
  animation: interaction-laws-indeterminate 900ms linear infinite;
}

@keyframes interaction-laws-indeterminate {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* ===========================================================================
   ٤) وضوح التركيز — WCAG 2.2 SC 2.4.7 و2.4.11 و1.4.11
   ---------------------------------------------------------------------------
   حلقة تركيز مزدوجة (داكنة + هالة فاتحة) تحقّق تباين ٣:١ فوق أي خلفية،
   فاتحة كانت أو داكنة، فلا نحتاج لونًا مختلفًا لكل سمة.
   الحلقة البرتقالية السابقة (‎#f97316‎) كانت ٢٫٨٠:١ على الأبيض — دون الحد.
   =========================================================================== */

body :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid #0b1220;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px #ffffff, 0 0 0 6px #0b1220;
  border-radius: 4px;
}

html[data-user-theme="night"] body :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline-color: #ffffff;
  box-shadow: 0 0 0 4px #0b1220, 0 0 0 6px #ffffff;
}

/* العنصر المركَّز عليه يجب ألا يختفي خلف شريط علوي ثابت — SC 2.4.11. */
html {
  scroll-padding-block-start: calc(var(--topbar-height, 64px) + 16px);
  scroll-padding-block-end: 24px;
}

/* ===========================================================================
   ٥) قانون بوستل — «عدم استخدام الوان تحذيرية في الاخطاء البسيطة»
   =========================================================================== */

body :is(input, select, textarea)[aria-invalid="true"]:not([data-submitted]) {
  border-color: #b45309;
}

body .field-hint {
  color: #475569;
  font-size: 0.8125rem;
  margin-block-start: 4px;
}

/* ===========================================================================
   ٦) تأثير زيغارنيك — «استخدام مؤشرات او عناصر تظهر عدم الاكتمال»
   =========================================================================== */

body [data-incomplete="true"] {
  position: relative;
}

body [data-incomplete="true"]::before {
  content: "";
  position: absolute;
  inset-block-start: 6px;
  inset-inline-end: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #b45309;
  box-shadow: 0 0 0 2px #ffffff;
}

/* ===========================================================================
   ٧) احترام تفضيل تقليل الحركة — WCAG 2.2 SC 2.3.3
   ---------------------------------------------------------------------------
   واجهة المستخدم كانت مغطّاة عبر user-workspace.css، أما لوحات الإدارة
   والمتجر والمصمّم والتاجر وcodemap فلم تكن مشمولة. هذه القاعدة تغطّيها.
   =========================================================================== */

@media (prefers-reduced-motion: reduce) {
  body *,
  body *::before,
  body *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  body :is(button, .user-btn, .btn):active {
    transform: none;
  }
}

/* ===========================================================================
   ٨) إشعار خفيف بديل عن alert() — مفارقة المستخدم النشط
   ---------------------------------------------------------------------------
   المصدر يطلب «تصميم بصري بسيط لعرض المعلومة» و«اعطاء مخرج واضح عند
   ظهور التعليمات». نافذة alert() تحجب الصفحة وتوقف التنفيذ وتخرج عن
   لغة الواجهة، فهذه بديلها في كل اللوحات الداخلية.
   =========================================================================== */

.tw-toast-stack {
  position: fixed;
  inset-block-end: calc(24px + var(--tw-toast-offset, 0px) + env(safe-area-inset-bottom, 0px));
  inset-inline-start: 24px;
  z-index: 10001;
  display: grid;
  gap: 8px;
  pointer-events: none;
}

.tw-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: min(380px, calc(100vw - 48px));
  padding: 11px 17px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.6;
  color: #ffffff;
  background: #127A8B;
  box-shadow: 0 10px 28px rgb(0 0 0 / 0.22);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 220ms ease, transform 220ms ease;
}

.tw-toast.is-visible { opacity: 1; transform: none; }
.tw-toast.is-leaving { opacity: 0; transform: translateY(12px); }

/* كلٌّ من هذه الألوان يحقّق ‎4.5:1‎ أو أعلى مع النص الأبيض. */
.tw-toast--success { background: #127A8B; }
.tw-toast--info    { background: #075D51; }
.tw-toast--warning { background: #92400e; }
.tw-toast--error   { background: #b91c1c; }

@media (max-width: 768px) {
  .tw-toast-stack {
    inset-inline: 12px;
    /* الإزاحة الافتراضية تفترض ألا شيء يشغل الركن السفلي. زرّ الدعم العائم
       يبدو كأنه يشغله، لكنه مُخفى فعليًا في لوحة المستخدم عبر
       lawyer-clone-workspace.css:383 ولا يُرسم في أي قشرة أخرى — فرفعُ
       الإشعار فوقه كان تفاديًا لشيء لا يظهر. إن أُعيد إظهاره يومًا،
       يُضبط ‎--tw-toast-offset‎ من القشرة بدل تعديل هذا الملف. */
    inset-block-end: calc(16px + var(--tw-toast-offset, 0px) + env(safe-area-inset-bottom, 0px));
  }
  .tw-toast { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tw-toast { transition: none; transform: none; }
}

/* ===========================================================================
   ٩) الطباعة — أهداف اللمس لا معنى لها على الورق
   ---------------------------------------------------------------------------
   نماذج المنصة (mof-*) تُطبع، فلا يجوز أن يوسّع حدٌّ أدنى للّمس صفوف
   الجدول المطبوع. نُعيد كل شيء إلى حجمه الطبيعي عند الطباعة.
   =========================================================================== */

@media print {
  body :is(button, [role="button"], a, input, select, textarea, summary, .user-btn, .btn) {
    min-height: 0 !important;
    min-width: 0 !important;
  }

  body :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: none;
    box-shadow: none;
  }
}
