/* ==================================================================
   Syriana Connect — مكتبة المكوّنات
   مغلقة: لا يُنشأ نمط خارجها، ولا قيمة مكتوبة يدوياً داخلها.

   القيم منقولة حرفياً من components.css في نظام تصميم سيريانا
   (الطبقة .syr-*) بعد إعادة تسمية البادئة إلى sy- كما يفرض §1،
   وما لا يشحنه النظام الأم — Toggle · ProgressBar · Stepper ·
   EmptyState · Skeleton · Toast · Modal · Chart — مبنيّ هنا على
   التوكنز نفسها.

   ثلاث قواعد تسري على كل ما تحت:
     · لا left/right — خصائص منطقية فقط.
     · كل عنصر تفاعلي ≥ 44px في البعدين.
     · الحالة لا تُنقل بلون وحده — أيقونة أو كلمة معها دائماً.
   ================================================================== */

/* ═══════ Button ═══════════════════════════════════════════════════
   حجم واحد فقط بارتفاع 44px، لأن ستة أشكال أزرار هي ما نُصلحه.
   أربعة أدوار لا أكثر: أساسي · ثانوي · شبح · خطِر. */
.sy-btn{
  display:inline-flex;align-items:center;justify-content:center;
  gap:var(--space-2);
  min-block-size:var(--touch-min);
  min-inline-size:var(--touch-min);
  padding:0 var(--space-5);
  border:1px solid transparent;
  border-radius:var(--radius-card);
  font-family:inherit;
  font-size:var(--type-body-size);
  font-weight:var(--weight-semibold);
  line-height:var(--leading-tight);
  text-decoration:none;
  white-space:nowrap;
  cursor:pointer;
  transition:background-color var(--motion-fast) var(--motion-ease),
             color var(--motion-fast) var(--motion-ease),
             border-color var(--motion-fast) var(--motion-ease);
}
.sy-btn:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
/* زر معطّل يظل مقروءاً ويجب أن يُشفع بسبب مكتوب تحته — الزر الميت
   بلا تفسير هو العطل A7 نفسه. */
.sy-btn:disabled,
.sy-btn[aria-disabled='true']{cursor:not-allowed;opacity:.55}

.sy-btn--primary{background:var(--surface-action);color:var(--text-on-action)}
.sy-btn--primary:hover:not(:disabled){background:var(--surface-action-hover)}

.sy-btn--secondary{
  background:var(--surface-card);color:var(--text-strong);
  border-color:var(--surface-border);
}
.sy-btn--secondary:hover:not(:disabled){background:var(--surface-raised)}

.sy-btn--ghost{background:transparent;color:var(--text-link)}
.sy-btn--ghost:hover:not(:disabled){background:var(--surface-action-quiet)}

/* الفعل الهادم يُرى قبل أن يُقرأ: لون مستقل تماماً عن كل ما حوله،
   ولا يُبنى إلا خلف مودال تأكيد. */
.sy-btn--danger{
  background:var(--surface-destructive);color:var(--text-on-destructive);
}
.sy-btn--danger:hover:not(:disabled){background:var(--surface-destructive-hover)}

.sy-btn--block{inline-size:100%}

/* دوّارة داخل الزر أثناء التنفيذ. النص لا يُستبدل بل يُضاف إليه،
   فلا يتغيّر عرض الزر ولا يقفز ما حوله. */
.sy-btn[data-state='loading']{cursor:progress}
.sy-btn[data-state='loading'] .sy-btn__spin{
  inline-size:16px;block-size:16px;flex:none;
  border:2px solid currentColor;border-block-start-color:transparent;
  border-radius:var(--radius-pill);
  animation:sy-spin 700ms linear infinite;
}
@keyframes sy-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .sy-btn__spin{animation-duration:2s}
}

/* ═══════ Card ═══════════════════════════════════════════════════ */
.sy-card{
  background:var(--surface-card);
  border:1px solid var(--surface-border);
  border-radius:var(--radius-panel);
  box-shadow:var(--shadow-sm);
}
.sy-card__head{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--space-4);
  padding:var(--space-5);
  border-block-end:1px solid var(--surface-border);
}
.sy-card__title{font-size:var(--type-h3-size);font-weight:var(--type-h3-weight);
  color:var(--text-strong);line-height:var(--leading-tight)}
.sy-card__desc{margin-block-start:var(--space-1);
  font-size:var(--type-label-size);color:var(--text-muted)}
.sy-card__body{padding:var(--space-5);
  display:flex;flex-direction:column;gap:var(--space-4)}
.sy-card__foot{padding:var(--space-4) var(--space-5);
  border-block-start:1px solid var(--surface-border);
  display:flex;flex-wrap:wrap;gap:var(--space-3)}

/* ═══════ Field · Label · Help · Error ════════════════════════════
   لا حقل بلا <label> مرئي مرتبط به. الـplaceholder مثال لا تسمية —
   وهذا هو العطل C8 مصلحاً في بنية المكوّن لا بقاعدة تصحيح. */
.sy-field{display:flex;flex-direction:column;gap:var(--space-2)}
.sy-field__label{
  font-size:var(--type-label-size);font-weight:var(--type-label-weight);
  color:var(--text-strong);
}
.sy-field__req{color:var(--text-negative);margin-inline-start:var(--space-1)}
.sy-field__help{font-size:var(--type-label-size);color:var(--text-muted)}
/* الخطأ نص وأيقونة معاً، فيقرأه من لا يميّز الأحمر. */
.sy-field__error{
  display:flex;align-items:center;gap:var(--space-2);
  font-size:var(--type-label-size);font-weight:var(--weight-semibold);
  color:var(--text-negative);
}
.sy-field__error::before{content:'⚠';font-size:var(--type-body-size)}
/* الحقل يُنشئ عنصر خطئه فارغاً وقت البناء ويملؤه عند الخطأ وحده.
   بلا هذا السطر تظهر ⚠ وحدها بلا رسالة فوق كل حقل سليم — تحذيرٌ
   من لا شيء، وهو ما يمنعه العقد: لا حالة خاطئة تُقلب. */
.sy-field__error:empty{display:none}

.sy-input,.sy-select,.sy-textarea{
  inline-size:100%;
  min-block-size:var(--touch-min);
  padding:var(--space-2) var(--space-3);
  font-family:inherit;font-size:var(--type-body-size);
  color:var(--text-strong);
  background:var(--surface-card);
  /* حدّ التحكّم لا حدّ الزينة: هو الشيء الوحيد الذي يرسم حدود الحقل،
     فيخضع لـ3:1. #D9D9DB كان يقيس 1.41. */
  border:1px solid var(--surface-border-control);
  border-radius:var(--radius-control);
}
.sy-textarea{line-height:var(--leading-body);resize:vertical;min-block-size:96px}
.sy-input::placeholder,.sy-textarea::placeholder{color:var(--text-muted)}
.sy-input:focus-visible,.sy-select:focus-visible,.sy-textarea:focus-visible{
  outline:2px solid var(--focus-ring);outline-offset:2px;
}
.sy-input[aria-invalid='true'],
.sy-select[aria-invalid='true'],
.sy-textarea[aria-invalid='true']{border-color:var(--surface-destructive)}
.sy-input:disabled,.sy-select:disabled,.sy-textarea:disabled{
  background:var(--surface-raised);cursor:not-allowed;opacity:.6;
}
/* رقم أو مبلغ أو معرّف: لاتيني من اليسار داخل حقل عربي. */
.sy-input--ltr{direction:ltr;text-align:start;unicode-bidi:isolate}

/* السهم الأصلي للمتصفّح لا سهم مرسوم. background-position خاصية
   فيزيائية لا منطقية، فالسهم المرسوم يهاجر إلى الجهة الخطأ في RTL —
   ظهر نقطةً في زاوية الحقل في لقطة شاشة حقيقية. سهم النظام يعرف
   اتجاه الحقل وحده، ويرثه المستخدم كما اعتاده على جهازه. */
.sy-select{padding-inline-end:var(--space-6)}

/* ═══════ Checkbox ════════════════════════════════════════════════
   الصندوق 20px بصرياً لكن هدف اللمس 44px عبر ::before ممتدّ فوق
   الصف كلّه — العطل C7 لا يُصلح بتكبير المربّع بل بتوسيع الهدف. */
.sy-check{display:flex;flex-direction:column;gap:var(--space-1)}
.sy-check__row{
  position:relative;
  display:flex;align-items:center;gap:var(--space-3);
  min-block-size:var(--touch-min);
}
.sy-check__box{
  inline-size:20px;block-size:20px;flex:none;
  accent-color:var(--surface-action);cursor:pointer;
}
.sy-check__box:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.sy-check__label{font-size:var(--type-body-size);color:var(--text-strong);cursor:pointer}
.sy-check__label::before{content:'';position:absolute;inset:0}
.sy-check__hint{font-size:var(--type-label-size);color:var(--text-muted);
  padding-inline-start:calc(20px + var(--space-3))}

/* ═══════ Toggle ══════════════════════════════════════════════════
   المفتاح كامل الصف: هدف لمس 44px، وحالته مكتوبة بجانبه لا مستنتجة
   من موضع الكرة. */
.sy-toggle{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--space-4);
  min-block-size:var(--touch-min);
  inline-size:100%;padding:0;
  background:none;border:0;font-family:inherit;
  font-size:var(--type-body-size);color:var(--text-strong);
  text-align:start;cursor:pointer;
}
.sy-toggle__text{display:flex;flex-direction:column;gap:var(--space-1);min-inline-size:0}
.sy-toggle__hint{font-size:var(--type-label-size);color:var(--text-muted)}
.sy-toggle__track{
  position:relative;flex:none;
  inline-size:52px;block-size:32px;
  border-radius:var(--radius-pill);
  background:var(--surface-track-off);
  /* المفتاح المطفأ لا يمكن أن يكون داكناً — يُقرأ عندها مشتعلاً. لكن
     أرضيته الفاتحة تقيس 1.86 على البطاقة، وWCAG 1.4.11 تطلب 3:1 لحدّ
     عنصر التحكّم. الحلّ حدّ لا تعبئة: الأرضية تبقى تقول «مطفأ»،
     والحدّ يرسم أين يبدأ المفتاح وأين ينتهي. */
  border:1px solid var(--surface-border-control);
  transition:background-color var(--motion-base) var(--motion-ease);
}
.sy-toggle[aria-checked='true'] .sy-toggle__track{
  border-color:var(--surface-track-on);
}
.sy-toggle__knob{
  /* 3px لا 4px: الإزاحة تُقاس من داخل الحدّ. */
  position:absolute;inset-block-start:3px;inset-inline-start:3px;
  inline-size:24px;block-size:24px;
  border-radius:var(--radius-pill);background:var(--color-neutral-0);
  box-shadow:var(--shadow-sm);
  transition:translate var(--motion-base) var(--motion-ease);
}
.sy-toggle[aria-checked='true'] .sy-toggle__track{background:var(--surface-track-on)}
/* translate المنطقي: 20px نحو نهاية السطر، فيعمل في الاتجاهين. */
.sy-toggle[aria-checked='true'] .sy-toggle__knob{translate:20px 0}
[dir='rtl'] .sy-toggle[aria-checked='true'] .sy-toggle__knob{translate:-20px 0}
.sy-toggle:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.sy-toggle[aria-busy='true']{cursor:progress;opacity:.7}

/* ═══════ StatusBadge ═════════════════════════════════════════════
   شريحة الحالة كلمة ولون معاً، ولا تُستخدم كزر أبداً. */
.sy-badge{
  display:inline-flex;align-items:center;gap:var(--space-1);
  padding:var(--space-1) var(--space-3);
  border-radius:var(--radius-pill);
  font-size:var(--type-label-size);font-weight:var(--weight-semibold);
  line-height:var(--leading-tight);
  white-space:nowrap;
}
.sy-badge__dot{inline-size:8px;block-size:8px;border-radius:var(--radius-pill);
  background:currentColor;flex:none}
/* --text-body لا --text-muted: الخافت على المرتفع يقيس 3.50 في الوضع
   الداكن. */
.sy-badge--neutral{background:var(--surface-raised);color:var(--text-body)}
.sy-badge--positive{background:var(--state-positive-surface);color:var(--state-positive-text)}
.sy-badge--caution{background:var(--state-caution-surface);color:var(--state-caution-text)}
.sy-badge--negative{background:var(--state-negative-surface);color:var(--state-negative-text)}
.sy-badge--info{background:var(--state-informative-surface);color:var(--state-informative-text)}

/* ═══════ ProgressBar ═════════════════════════════════════════════
   يمتلئ من بداية السطر — أي من اليمين في العربية — عبر transform
   منطقي. الرقم مكتوب دائماً فوقه: الشريط وحده ليس معلومة. */
.sy-progress{display:flex;flex-direction:column;gap:var(--space-2)}
.sy-progress__row{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--space-3);font-size:var(--type-label-size)}
.sy-progress__value{font-weight:var(--weight-semibold);color:var(--text-strong)}
.sy-progress__track{
  block-size:10px;inline-size:100%;
  background:var(--surface-raised);
  border-radius:var(--radius-pill);
  overflow:hidden;
}
.sy-progress__fill{
  block-size:100%;inline-size:100%;
  background:var(--surface-fill);
  border-radius:inherit;
  transform-origin:inline-start;
  scale:var(--sy-progress,0) 1;
  transition:scale var(--motion-slow) var(--motion-ease);
}
.sy-progress[data-level='caution'] .sy-progress__fill{background:var(--state-caution-text)}
.sy-progress[data-level='danger'] .sy-progress__fill{background:var(--surface-fill-danger)}

/* ═══════ Stepper ═════════════════════════════════════════════════
   الخطوة المنجزة تحمل ✓ لا رقمها — العطل A8. والملخّص الثابت الذي
   يبقي المبلغ ظاهراً حتى النهاية هو .sy-stepper__summary. */
.sy-stepper{display:flex;flex-direction:column;gap:var(--space-4)}
.sy-stepper__list{display:flex;align-items:center;gap:var(--space-2)}
.sy-stepper__step{display:flex;align-items:center;gap:var(--space-2);
  font-size:var(--type-label-size);color:var(--text-muted)}
.sy-stepper__mark{
  display:flex;align-items:center;justify-content:center;
  inline-size:24px;block-size:24px;flex:none;
  border-radius:var(--radius-pill);
  border:1px solid var(--surface-border);
  background:var(--surface-card);color:var(--text-muted);
  font-size:var(--type-label-size);font-weight:var(--weight-semibold);
}
.sy-stepper__step[data-state='done'] .sy-stepper__mark{
  background:var(--state-positive-surface);color:var(--state-positive-text);
  border-color:var(--state-positive-text);
}
.sy-stepper__step[data-state='now'] .sy-stepper__mark{
  background:var(--surface-step-now);color:var(--text-on-action);
  border-color:var(--surface-step-now);
}
.sy-stepper__step[data-state='now']{color:var(--text-strong);font-weight:var(--weight-semibold)}
.sy-stepper__sep{block-size:1px;inline-size:var(--space-6);
  background:var(--surface-border);flex:none}
.sy-stepper__summary{
  display:flex;flex-wrap:wrap;align-items:baseline;
  gap:var(--space-2) var(--space-4);
  padding:var(--space-3) var(--space-4);
  background:var(--surface-action-quiet);
  border-radius:var(--radius-card);
  font-size:var(--type-label-size);
}
.sy-stepper__summary strong{font-size:var(--type-body-size);color:var(--text-strong)}

/* ═══════ Table + EmptyState ══════════════════════════════════════
   الجدول يتمرّر داخل .sy-scroll-x وحده — الصفحة لا تتمرّر أفقياً.
   الفجوة بين الأعمدة مسافة حقيقية لا شرطة: «000031» و«مدفوعة»
   لا يلتصقان (C10)، والخلية الفارغة تُترك فارغة بنص بديل للقارئ. */
.sy-table{inline-size:100%;border-collapse:collapse;
  font-size:var(--type-body-size);text-align:start}
.sy-table thead tr{border-block-end:1px solid var(--surface-border)}
.sy-table th{
  padding:var(--space-3) var(--space-4);
  text-align:start;white-space:nowrap;
  font-size:var(--type-label-size);font-weight:var(--weight-semibold);
  color:var(--text-muted);
}
.sy-table td{padding:var(--space-4);vertical-align:middle;
  border-block-end:1px solid var(--surface-border)}
.sy-table tbody tr:last-child td{border-block-end:0}
.sy-table td.is-strong{font-weight:var(--weight-semibold);color:var(--text-strong)}
.sy-table td.is-numeric{font-variant-numeric:tabular-nums;white-space:nowrap}

.sy-empty{
  display:flex;flex-direction:column;align-items:center;
  gap:var(--space-3);
  padding:var(--space-12) var(--space-6);
  text-align:center;color:var(--text-muted);
}
.sy-empty__title{font-size:var(--type-h3-size);font-weight:var(--type-h3-weight);
  color:var(--text-strong)}
.sy-empty__body{max-inline-size:44ch}

/* حالة الخطأ. القسم يبقى ظاهراً ولا يختفي — القسم المختفي بصمت
   يقرأه المشترك على أنه عطل في خطّه. */
.sy-error{
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-3);
  padding:var(--space-4);
  background:var(--state-negative-surface);color:var(--state-negative-text);
  border-radius:var(--radius-card);
  font-size:var(--type-body-size);
}

/* صفّ قائمة غير مقروء. الكلمة («غير مقروء») هي الحالة؛ الأرضية
   تسندها للمسح السريع بالعين ولا تنقلها وحدها. */
.sy-card__body li[data-sy-unread]{
  background:var(--accent-quiet);
  border-radius:var(--radius-card);
  padding:var(--space-3) var(--space-4);
}

/* ═══════ Skeleton ════════════════════════════════════════════════
   بأبعاد المحتوى النهائي بالضبط، فلا إزاحة عند وصول البيانات.
   ولا يُعرض قط محتوى بحالة خاطئة ثم يُقلب — السكيلتون يبقى حتى
   تتأكّد الحالة (A5 · A6). */
.sy-skel{
  background:var(--surface-raised);
  border-radius:var(--radius-control);
  position:relative;overflow:hidden;
}
.sy-skel::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,
    color-mix(in srgb,var(--surface-card) 60%,transparent),transparent);
  animation:sy-sheen 1.4s ease-in-out infinite;
}
@keyframes sy-sheen{from{translate:-100% 0}to{translate:100% 0}}
@media (prefers-reduced-motion:reduce){.sy-skel::after{animation:none}}
.sy-skel--line{block-size:1em;margin-block:.35em}
.sy-skel--title{block-size:var(--type-h2-size)}
.sy-skel--btn{block-size:var(--touch-min);inline-size:140px;
  border-radius:var(--radius-card)}
.sy-skel--card{block-size:120px;border-radius:var(--radius-panel)}

/* ═══════ Toast ═══════════════════════════════════════════════════ */
.sy-toasts{
  position:fixed;inset-inline:var(--space-4);inset-block-end:var(--space-4);
  z-index:1000;display:flex;flex-direction:column;gap:var(--space-2);
  align-items:center;pointer-events:none;
}
.sy-toast{
  pointer-events:auto;
  display:flex;align-items:center;gap:var(--space-3);
  max-inline-size:var(--container-max);
  padding:var(--space-3) var(--space-4);
  border-radius:var(--radius-card);
  box-shadow:var(--shadow-lg);
  font-size:var(--type-body-size);
  background:var(--surface-card);color:var(--text-strong);
  border:1px solid var(--surface-border);
}
.sy-toast--success{background:var(--state-positive-surface);
  color:var(--state-positive-text);border-color:currentColor}
.sy-toast--error{background:var(--state-negative-surface);
  color:var(--state-negative-text);border-color:currentColor}
.sy-toast__action{margin-inline-start:auto}

/* ═══════ Modal ═══════════════════════════════════════════════════
   يُبنى على <dialog> فيأتي حبس التركيز وEsc والطبقة العلوية من
   المتصفّح نفسه بلا سطر JS. */
.sy-modal{
  max-inline-size:min(560px,calc(100vw - var(--space-8)));
  inline-size:100%;
  padding:0;border:0;
  border-radius:var(--radius-panel);
  background:var(--surface-card);color:var(--text-body);
  box-shadow:var(--shadow-lg);
}
.sy-modal::backdrop{background:rgb(11 11 11 / .55)}
.sy-modal__head{padding:var(--space-5) var(--space-5) 0}
.sy-modal__title{font-size:var(--type-h2-size);font-weight:var(--type-h2-weight);
  color:var(--text-strong)}
.sy-modal__body{padding:var(--space-4) var(--space-5);
  display:flex;flex-direction:column;gap:var(--space-3)}
.sy-modal__foot{
  display:flex;flex-wrap:wrap;gap:var(--space-3);
  padding:var(--space-4) var(--space-5) var(--space-5);
}
.sy-modal__foot .sy-btn{flex:1 1 auto}
/* تأكيد فعل هادم: العنوان يسمّي الفعل، والنص يشرح النتيجة والمدة
   بالعربية البسيطة، والزر يسمّي الفعل لا «موافق». */
.sy-modal--danger .sy-modal__title{color:var(--text-negative)}

/* ═══════ Chart ═══════════════════════════════════════════════════
   SVG مرسوم بأيدينا — لا مكتبة رسوم. المحاور والتسميات والمقياس
   جزء من المكوّن لا زينة، ولكل رسم بديل جدولي مكافئ (C9). */
.sy-chart{display:flex;flex-direction:column;gap:var(--space-3)}
.sy-chart__plot{inline-size:100%;block-size:auto;overflow:visible}
.sy-chart__grid{stroke:var(--chart-grid);stroke-width:1}
.sy-chart__axis{fill:var(--chart-axis);font-size:12px;font-family:var(--font-sans)}
.sy-chart__bar{transition:opacity var(--motion-fast) var(--motion-ease)}
.sy-chart__legend{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-4);
  font-size:var(--type-label-size)}
.sy-chart__key{display:flex;align-items:center;gap:var(--space-2)}
.sy-chart__swatch{inline-size:12px;block-size:12px;flex:none;
  border-radius:var(--radius-control)}
/* البديل النصي مطويّ تحت <details> — متاح دائماً وغير مزاحم. */
.sy-chart__table summary{
  min-block-size:var(--touch-min);display:flex;align-items:center;
  cursor:pointer;color:var(--text-link);font-size:var(--type-label-size);
}
.sy-chart__s1{fill:var(--chart-1)}
.sy-chart__s2{fill:var(--chart-2)}
.sy-chart__s3{fill:var(--chart-3)}
.sy-chart__s4{fill:var(--chart-4)}
.sy-chart__s5{fill:var(--chart-5)}
.sy-chart__s6{fill:var(--chart-6)}

/* ==================================================================
   جداول UCRM الأصلية في «بياناتي»
   ------------------------------------------------------------------
   صفحات الإعدادات كانت تُشحن من UISP بصنف الوضع الداكن على <body>،
   وألوان جداولها مكتوبة لتلك الخلفية السوداء. الصنف أُفرغ في
   client_zone/settings/account.html.twig — الوضع عندنا اختيار
   المشترك في data-theme — فبقيت الألوان معلّقة فوق خلفيتنا الفاتحة.

   مقيس بمتصفّح حقيقي على 390 و1280، لا مُقدَّراً: اثنان وعشرون عنصراً
   تحت 4.5، أسوأها **1.06**. وتسميات بيانات المشترك نفسه — الاسم
   والبريد والهاتف والعنوان واسم المستخدم والمعرّف وتاريخ التسجيل
   ونوع الزبون — كانت `rgb(255,255,255)` فوق `rgb(247,247,248)`:
   أبيض على أبيض. المشترك لا يرى ما اسم الحقل الذي يقرأ قيمته.

   ولا !important هنا ولا في reset-uisp.css: القاعدة المُبطَلة
   `.client-zone-account th` نوعيتها (0,1,1) وطبقتنا تُحمَّل بعد
   main.min.css، فالتعادل في النوعية يحسمه الترتيب. وهذا هو الشرط
   الثاني في عقد ذلك الملف حرفياً.
   ================================================================== */
.client-zone-account th{color:var(--text-muted)}

/* وقيم الحقول نفسها: `td` في الجدول ذاته، ‎rgb(169,169,169)‎ فوق
   ‎#f7f7f8‎ = 2.2. أوّل محاولة لي كتبتها تحت
   `.settings-card__content` — وهو ليس سلفها أصلاً، فلم تُطابق شيئاً
   ولم يتغيّر الرقم. القياس بعد كل قاعدة هو ما كشف ذلك، لا القراءة. */
.client-zone-account td{color:var(--text-body)}

/* سجلّ الدخول: البطاقة نفسها تُطلي `rgb(30,30,30)` — خلفية الوضع
   الداكن في UISP — فيقع تحتها نصّ داكن: `rgb(35,35,35)` على
   `rgb(30,30,30)` = **1.06**، ونصّ العنوان 1.59. الخطأ في الخلفية لا
   في النصّ، فتُصحَّح الخلفية وحدها ويعود النصّان مقروءَين بلا لمسهما.

   وهي ليست داخل `.client-zone-account` بل شقيقتها في `.sy-stack` —
   خطأٌ ثانٍ في محاولتي الأولى، كشفه تتبّع سلسلة الآباء الحقيقية. */
.sy-main .settings-card{
  background-color:var(--surface-card);
  color:var(--text-body);
  /* والبطاقة نفسها تحمل `ml-n-32 mr-n-32` — هامشان سالبان بُنيا
     لتخطيط UCRM ذي العمودين الذي لم يعد يُرسم. أثرهما المقيس على
     1280: عرض 1024 داخل عمود 960، و**ثماني بكسلات** تمرير أفقي
     للصفحة كلها. وعلى 390 يُلغيهما `mh-xs-0` فلا يظهر شيء — ولهذا
     ظهر العطل على الشاشة الكبيرة وحدها. */
  margin-inline:0;
}

/* ==================================================================
   رمادي UCRM ‎#7E8190‎ وأخضره ‎#39CC64‎ فوق خلفيتنا
   ------------------------------------------------------------------
   بقيّة كتل UCRM الأصلية في «خطي» و«عروض الأسعار» ترث لونين مقيسين:
     rgb(126,129,144) = **3.87** — تحت 4.5
     rgb(57,204,100)  = **2.10** — كلمة «فعّالة» تكاد لا تُرى

   والبديلان من رموزنا، ونسبتهما مقيسة لا مُقدَّرة:
     --text-muted        ‎#666666‎  = 5.74 على الأبيض · 5.36 على ‎#f7f7f8‎
     --text-body         ‎#3E3F43‎  = 10.52
     --color-success-700 ‎#0A6B4D‎  = 6.52

   ولا !important: القواعد المُبطَلة نوعيتها (0,1,1) و(0,1,0)، وطبقتنا
   تُحمَّل بعد main.min.css، فالتعادل يحسمه الترتيب.
   ================================================================== */
.sy-main .client-zone-table th{color:var(--text-muted)}
.sy-main .client-zone-table td{color:var(--text-body)}
.sy-main .empty-screen__description{color:var(--text-muted)}

/* كتلة الخدمة: القيم التي يقرؤها المشترك — اسم الباقة والسرعة والسعر. */
.sy-main #service-container strong,
.sy-main #service-container td,
.sy-main #service-container th{color:var(--text-body)}

/* حالة الخدمة: اللون يحمل المعنى، فيبقى أخضر ويصير مقروءاً.

   وأوّل صياغة لي كتبتها `--color-success-700` — لونٌ ثابت لا يتبع السمة.
   فصار في الوضع الليلي أخضر داكناً على خلفية داكنة: **2.29**. والرمز
   `--state-positive-text` يقلب مع السمة أصلاً، فهو الصواب. */
.sy-main .service-status-text--success{color:var(--state-positive-text)}

/* ==================================================================
   شبكة UCRM (appTable.grid-table) داخل بطاقاتنا — الوضع الليلي
   ------------------------------------------------------------------
   ألوان الشبكة مكتوبة بقيَم ثابتة لا برموز، فلا تتبع data-theme.
   مقيس في الوضع الليلي على صفحة «بياناتي»:
     ترويسة الأعمدة  rgb(82,84,97) فوق rgb(38,39,42) = 1.99
     عدّاد الصفحات   rgb(35,35,35) فوق rgb(38,39,42) = **1.05**
   داكن على داكن — لا يُقرأ إطلاقاً. وهو عطلٌ سابق لتغييري: خلفية
   البطاقة كانت rgb(30,30,30) والنسبة 1.06، أي هو هو.
   ================================================================== */
/* النوعية هنا مقصودة: قاعدة UISP المُبطَلة هي
   `.grid .appTable.grid-table thead th:not(.column--custom) span`
   ونوعيتها (0,4,2)، فمحاولتي الأولى بـ(0,3,2) خسرت وبقي الرقم 1.99
   كما هو. القياس بعد كل قاعدة هو ما كشف ذلك. */
.sy-main .grid .appTable.grid-table thead th:not(.column--custom),
.sy-main .grid .appTable.grid-table thead th:not(.column--custom) span,
.sy-main .appTable.grid-table thead th,
.sy-main .appTable.grid-table thead th span{color:var(--text-muted)}
.sy-main .appTable.grid-table tbody td{color:var(--text-body)}
.sy-main .pagination,
.sy-main .pagination__counter,
.sy-main .pagination label,
.sy-main .select2-container--unifi .select2-selection__rendered,
.sy-main .select2-selection__rendered{color:var(--text-body)}

/* قائمة «عناصر في الصفحة» (select2 بترميز UISP): rgb(82,84,97) فوق
   rgb(38,39,42) = 1.99 في الوضع الليلي. سلسلة أصنافها طويلة، فرُفعت
   النوعية إلى (0,4,0) — ولا !important. */
.sy-main .pagination__items-per-page .select2-container--unifi .select2-selection__rendered{
  color:var(--text-body);
}

/* اتجاه الرسم مثبَّت لا موروث. text-anchor في SVG يُحسب بالاتجاه لا
   بالشاشة: مع rtl تصير 'start' حافة النصّ اليمنى و'end' اليسرى.
   الرسوم مكتوبة على هذا المعنى صراحةً، فلو ورث الرسم اتجاهاً آخر من
   جدّ بعيد انقلبت كل تسمية إلى خارج الإطار — وهو العطل الذي وقع
   فعلاً: 14 تسمية من 17 خارج الإطار، منها اسم خدمة يخرج 238 بكسل
   على 1280. التثبيت هنا يجعل الافتراض عقداً لا حظاً. */
.sy-chart__plot{direction:rtl}

/* مفتاح رسم UISP الأصلي («تنزيل» / «رفع») في تبويب «خطي»:
   rgb(164,167,181) على أبيض = **2.39**.

   ولم يظهر في مسحي الأوّل الذي قال «صفر» — لا لأنه لم يكن، بل لأن المفتاح
   يُرسم بجافاسكربت UCRM بعد تحميل الصفحة، ومسحي كان ينتظر 1800 مللي ثانية
   فيقيس صفحة لم تكتمل. القياس المتسرّع يقول «سليم» بنفس ثقة القياس الصحيح. */
.sy-main .chart-legend__item__label{color:var(--text-muted)}

/* ==================================================================
   نصّان لم يقسهما مسبارنا أصلاً
   ------------------------------------------------------------------
   الأداة كانت تُسقط كل نصّ أطول من ستّين حرفاً — وهو شكل نصوص المساعدة
   العربية — ولا تقرأ `placeholder` إطلاقاً لأن `textContent` للحقل فارغ.
   فقالت «صفر» وفيهما إخفاقان حقيقيان. أُصلحت الأداة أوّلاً، ثم هذان:

     ‏`::placeholder` على حقولنا  rgb(164,167,181) = **2.39**
     ‏`.appInputHelp` من UCRM     rgb(150,155,163) = **2.61**

   والرمز `--text-muted` يحسب `#666666` صحيحاً (5.74) — لكن قاعدتنا
   ‏(0,1,0) كانت تخسر أمام قاعدة UISP. رُفعت إلى (0,2,0) بـ`.sy-main`،
   ولا !important.
   ================================================================== */
.sy-main .sy-input::placeholder,
.sy-main .sy-textarea::placeholder,
.sy-main input::placeholder,
.sy-main textarea::placeholder{color:var(--text-muted);opacity:1}

/* نصّ المساعدة تحت الحقل: شرحٌ يحتاجه المشترك ليُتمّ العملية، لا زخرفة. */
.sy-main .appInputHelp{color:var(--text-body)}

/* ==================================================================
   مكوّنات UCRM الأصلية في الوضع الليلي
   ------------------------------------------------------------------
   ألوانها مكتوبة لخلفية فاتحة ولا تتبع `data-theme`. مقيس على الإحدى
   عشرة لوحة في الوضعين — والادّعاء السابق «صفر في الوضعين» لم يكن قد
   قاس إلا لوحتين:

     عناوين وأوصاف UCRM   rgb(82,84,97)  على rgb(38,39,42) = 1.99
     ألسنة «عروض الأسعار» rgb(28,30,45)  على rgb(11,11,11) = **1.19**
     تسميات كلمة المرور   rgb(35,35,35)  على rgb(11,11,11) = 1.25
     رابط بطاقة الائتمان  rgb(11,124,175) على rgb(38,39,42) = 3.21
     وقت الإشعار          rgb(147,149,152) على rgb(5,59,84) = 3.97

   الرموز أدناه تقلب مع السمة، فالقاعدة واحدة للوضعين ولا تُكرَّر.
   ================================================================== */
.sy-main .client-zone-heading,
.sy-main .client-zone-heading *,
.sy-main #service-container .appLabel,
.sy-main .appLabel,
.sy-main .appInputLabel,
.sy-main label{color:var(--text-body)}

.sy-main .page-header__navigation a,
.sy-main .page-header__navigation span,
.sy-main .dropdown-unifi__label{color:var(--text-body)}

.sy-main .page-header__navigation .is-active,
.sy-main .page-header__navigation [aria-current]{color:var(--text-strong)}

/* روابط UCRM: أزرقها ثابت ولا يفتَح ليلاً. */
.sy-main .appLink,
.sy-main a.unifi-link,
.sy-main .settings-card a{color:var(--text-link)}

/* وقت الإشعار فوق بطاقة ملوّنة — النصّ الخافت لا يكفي هناك. */
.sy-main .sy-notice time,
.sy-main .sy-notice__time{color:var(--text-body)}

/* الأصناف الأربعة الباقية — أسماؤها الحقيقية مقروءة من الشجرة لا مُخمَّنة.
   ثلاثة من محدّداتي السابقة كانت قريبة وخاطئة: اللون على `strong` داخل
   الزرّ لا على الزرّ، والصنف `page-header__navigation__menu__item` لا
   `page-header__navigation`، و«إضافة بطاقة» زرّ لا رابط. */
.sy-main .dropdown-unifi__label strong,
.sy-main .dropdown-unifi__label span{color:var(--text-body)}

.sy-main .page-header__navigation__menu__item a{color:var(--text-body)}
.sy-main .page-header__navigation__menu__item.selected a{color:var(--text-strong)}

.sy-main .empty-screen__heading{color:var(--text-strong)}
.sy-main .empty-screen__description{color:var(--text-muted)}

.sy-main .unifi-button--secondary{color:var(--text-link)}

/* ═══════ Chart · خطّ ═══════════════════════════════════════════════
   منحنى الإشارة: سلسلة زمنية واحدة تُرسم <path> لا أعمدة. الأعمدة
   تجيب «كم لكلٍّ»، والمنحنى وحده يجيب «إلى أين يتّجه» — وهو السؤال
   الوحيد الذي يستحقّ أن يُسأل عن صحن.

   fill:none إلزامي: مسارٌ مفتوح بلا هذه القاعدة يُغلقه المتصفّح
   ويملؤه، فيصير المنحنى مساحة سوداء تغطّي الشبكة والتسميات معاً.
   وسمك 1 مثل الشبكة يجعل الخطّ لا يُميَّز عن خطوطها، فهو 2 — الرقم
   بوحدات viewBox كسمك .sy-chart__grid تماماً، لا بالبكسل. */
.sy-chart__line{
  fill:none;stroke:var(--chart-1);stroke-width:2;
  stroke-linejoin:round;stroke-linecap:round;
}

/* ═══════ عمود مثبَّت داخل الجدول المتمرّر ══════════════════════════
   العطل الذي أوجب هذه القاعدة، مقيساً على 390 بكسل:

     /invoices          clientWidth 356 · scrollWidth 751 → 395 مخفيّة
                        روابط PDF الأربعة عند left = ‎-379 — **كلّها**
                        خارج الشاشة.
     /support           658 → 302 مخفيّة، «افتح المحادثة» عند ‎-286.
     /account-statement 475 → 119 مخفيّة، وعمود «الرصيد» كلّه خارجها.

   الحاوية `.sy-scroll-x` مقصودة والصفحة لا تتمرّر أفقياً — هذا سليم.
   غير السليم أن يكون **الفعل الأهمّ في الصفحة** غير مرئيّ افتراضياً:
   من فتح «الفواتير» على هاتفه جاء ليأخذ فاتورته، والزرّ الوحيد الذي
   يعطيها إيّاه كان يحتاج تمريراً جانبياً لا شيء في المشهد يدلّ عليه.

   لماذا التثبيت لا إعادة الترتيب: نقل عمود الفعل إلى أوّل الجدول كان
   يُظهره، لكنه يقلب ترتيب القراءة — رقم الفاتورة يسبق زرّها — ويضيّع
   عمود «الرصيد» في كشف الحساب لأنه عمود خلاصة لا فعل، مكانه الأخير.
   والتثبيت يُبقي الترتيب كما هو ويُبقي العمود مرئياً معاً.

   ولماذا `position:sticky` لا وسيلة أخرى: هي الوحيدة التي تعمل حين
   يوجد فائض وتختفي أثره تماماً حين لا يوجد. على 1280 لا فائض في هذه
   الجداول، فلا يتحرّك شيء ولا يُخفى شيء.

   الأرضية إلزامية لا زينة: بلا لون صريح يمرّ المحتوى المتمرّر **تحت**
   الخلية فيُقرأ رقمان فوق بعضهما. وهي `--surface-card` أي لون البطاقة
   نفسه الذي تحتها، فلا يتغيّر مظهر شيء ولا قياس تباين واحد.

   الحدّ على الجهة الداخلية يقول للعين أين ينتهي المثبَّت ويبدأ ما
   ينزلق تحته. */
.sy-table .is-pinned{
  position:sticky;inset-inline-end:0;z-index:1;
  background:var(--surface-card);
  border-inline-start:1px solid var(--surface-border);
}

/* ═══════ صورة حالة «محلولة» في التذاكر ═════════════════════════════
   طلبٌ واحد يردّ 404 على صفحة محادثة تذكرة محلولة، مقيساً:

     GET /crm/uploads/assets/images/ticketing/ticket-status-circle__solved.svg
     → 404 وصفحةُ خطأ CRM بترميز HTML مكان صورة SVG.

   سببه أن القاعدة تعيش في `custom.css` المولَّد بـrtlcss، وفيه
   `url(../assets/…)` منقولةً كما هي من `main.min.css`. والملفّان في
   عمقين مختلفين: من `/crm/dist/` تعني `..` جذر `/crm/` فتصحّ، ومن
   `/crm/uploads/customization/` تعني `/crm/uploads/` فتضيع.

   الملفّ موجود وسليم على `/crm/assets/images/ticketing/…` — العنوان
   وحده هو الخاطئ. ويُصحَّح هنا لا هناك: `custom.css` مولَّد آلياً
   وأيّ تصليح فيه يمحوه أوّل توليد. وهذه الطبقة تُحمَّل بعده فتغلبه.

   والمسار نسبيّ من موضع هذا الملفّ (uploads/customization/portal/)
   لا مكتوباً من الجذر: البوابة قد تُركَّب على مسار آخر عند إعادة
   بيعها، والنسبيّ يتبعها والمطلق يكسر. */
.ticket-detail-panel__conversation__avatar__circle--solved{
  background-image:url(../../../assets/images/ticketing/ticket-status-circle__solved.svg);
}
