/* ============================================================================
   0. الخط — Noto Sans Arabic، ملفّ متغيّر واحد مستضاف محلياً

   لماذا تغيّر عن IBM Plex Sans Arabic: قِستُ ارتفاع جسم الحرف العربي
   نسبةً إلى الـem في خمسة خطوط، فكان Plex **أصغرها** (0.713 مقابل 0.775
   هنا). أي أنه عند نفس الـ13px يرسم حروفاً أصغر بـ9٪ — وهذا سبب شعور
   "الخط رفيع وغير مريح" في شاشة كثيفة تُقرأ ثماني ساعات. اخترتُه لأنه
   مميّز، وهذا حكم على الشكل لا على الاستعمال؛ الأداة تُقاس بالراحة.

   ووجدتُ عند القياس أن Plex **بلا tnum أصلاً**، فسطر tabular-nums كان
   بلا أثر — الأرقام كانت تصطفّ بالصدفة لا بالخاصية. هنا tnum حقيقية.

   وهو **متغيّر**: ملفّ واحد (181KB) يعطي الأوزان الأربعة كلها، بدل أربعة
   ملفات ثابتة كانت 300KB. أخفّ وأدقّ في الأوزان الوسيطة.

   مُشتقّ ومُقلَّم: محور العرض ثُبِّت، والمحارف قُصرت على العربي واللاتيني
   وما يستعمله النظام. الرخصة SIL OFL — static/fonts/
   ============================================================================ */
@font-face {
  font-family: "Noto Sans Arabic";
  src: url("../fonts/NotoSansArabic-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}


/* ==========================================================================
   Clinic ERP — Design System
   Identity: "Clinical Instrument" — cool cyan-blue primary, mint for healthy
   states, on blue-tinted paper. No external dependencies. Works offline.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces — ورقٌ دافئ مشتقّ من ذهب العلامة، لا رماديّ ولا مزرقّ

     كان الورق مزرقّاً (#eef4f8) يخدم لبنيّاً طبيّاً لم يعد لون النظام.
     بعد أن صار الأساسي كحليّ الهوية والتمييز ذهبها، الورق المزرقّ يشدّ
     اللوحة إلى عائلة لونية ثالثة لا تنتمي للعلامة. الدفء هنا مسحةٌ من
     الذهب نفسه بتشبّع منخفض جداً: تُقرأ "ورقاً" لا "أصفر"، وتُجانس
     الذهب حين يظهر، وتُريح العين أكثر من الأبيض الساطع في نهارٍ طويل. */
  --paper:        #f4f1ea;
  --surface:      #fffdf8;
  --surface-2:    #faf7f0;
  --surface-sunk: #ebe7dd;

  /* Ink — الحبر الأساسي هو لون اللوجو الداكن نفسه (#0f2333)، والدرجتان
     الأخفّ مشتقّتان منه بمسحة دافئة تُجانس الورق. */
  --ink:    #0f2333;
  --ink-2:  #55645f;
  --ink-3:  #8a9490;

  /* Lines — خطوط دافئة تنتمي للورق. المزرقّة السابقة كانت تُقرأ باردةً
     فوق ورقٍ دافئ فتبدو دخيلة. */
  --line:        #e4ded1;
  --line-strong: #cfc6b4;

  /* --------------------------------------------------------------------
     الرِّف — حيث تعيش الهوية

     لون العلامة ذهب على أسود، وكان ممنوعاً كلون واجهة لأن تباينه على
     الأبيض 1.62:1. لكنه على هذا الحبر 10.9:1 — فالمشكلة لم تكن في
     الذهب بل في الأبيض تحته. بدل حظر لون العلامة، أُعطي المكان الذي
     يصلح فيه: رِفٌّ داكن يمتدّ بارتفاع النظام. الهوية في الرِّف
     والبيانات على منضدة هادئة، وهي الجرأة الوحيدة في التصميم كله.

     الذهب **لا يظهر على الأبيض إطلاقاً**. من يريد استعماله في المتن
     يستعمل --primary.
     -------------------------------------------------------------------- */
  --rail:      #0b1623;
  --rail-2:    #131f31;
  --rail-line: #ffffff14;
  --rail-ink:  #a9becd;
  --rail-ink-2:#7e97a8;
  --gold:      #f7c51a;
  /* وردي فاتح للخطر **على الرِّف**: --rose معايَر على الورق الأبيض
     فيغمق على الداكن حتى يكاد يُقرأ. لون واحد لا يخدم خلفيتين. */
  --rail-danger: #ff9aa8;

  /* --------------------------------------------------------------------
     اللون الأساسي — مشتقّ من الذهب لا مجاور له

     اللبني القديم (#0a6e93) درجته 196° والذهب 46°: بينهما 150°. والمكمّل
     الحقيقي للذهب هو 226°. أي أن اللبني كان على بُعد 30° من المكمّل —
     وهي أسوأ منطقة: لا هي تناغم ولا هي تضادّ مقصود، فتُقرأ نشازاً.
     وتباينه مع الذهب كان 3.54 فقط، فلا يفصلهما شيء حين يلتقيان.

     الكحلي الحبريّ عند 220° هو المكمّل الطبيعي، وتباينه مع الذهب 6.5.
     والذهب مع الكحلي اقتران كلاسيكي راسخ يقرأ **فخامة**، وهو أنسب لعيادة
     تجميل من اللبني الطبي الذي يقرأ **مستشفى**.

     تشبّعه 56% لا 85%: الأزرق المشبع عند هذه الدرجة هو أزرق كل منصّات
     البرمجيات، والحبريّ الأهدأ يبقى مميّزاً ولا يزاحم الذهب.
     -------------------------------------------------------------------- */
  --primary:       #23407b;
  --primary-hover: #1b356a;
  --primary-soft:  #e8ecf5;
  --primary-ink:   #1b356a;
  --on-danger:     #ffffff;
  /* لون النصّ فوق الأساسي. كان مُعرَّفاً في الوضع الليلي وحده، فالوضع
     الفاتح يكتب `#fff` مباشرةً في تسعة مواضع — والأبيض صحيح هنا صدفةً
     لأن الأساسي كحليّ. يوم يصير الأساسي ذهبياً في الوضعين، يتحوّل كل
     زرّ إلى نصّ أبيض على ذهب بتباين 1.62 — غير مقروء. التوكن يجعل
     التغيير مكاناً واحداً. */
  --on-primary:    #ffffff;

  /* Semantic — mint reads "healthy", not generic green */
  --mint:      #0f7a60;
  --mint-soft: #dcf3ec;
  /* كهرماني محروق: القديم (#a56212) كان قريباً من ذهب العلامة فيتنافسان
     على المعنى — أيّهما "تحذير" وأيّهما "هوية"؟ الآن لا لبس. */
  --amber:     #8a4f0b;
  --amber-soft:#fbebd6;
  --rose:      #bb2d43;
  --rose-soft: #fce4e7;
  --violet:    #4c4bb0;
  --violet-soft:#e8e8fa;

  /* Geometry */
  --r-sm: 8px;
  --r:    12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* Elevation */
  --sh-1: 0 1px 2px rgba(15,35,51,.05);
  --sh-2: 0 1px 3px rgba(15,35,51,.06), 0 6px 18px rgba(15,35,51,.06);
  --sh-3: 0 12px 40px rgba(15,35,51,.14);

  /* Layout */
  --side-w:  254px;
  --topbar-h: 62px;

  /* Type */
  --font-ui: "Noto Sans Arabic", "Segoe UI", "Dubai", "Geeza Pro",
             Tahoma, system-ui, sans-serif;
  --font-mono: "Cascadia Mono", "SF Mono", "Consolas", "DejaVu Sans Mono", monospace;

  /* ------------------------------------------------------------------
     سُلّم المقاسات
     كان في الملف 18 مقاساً، خمسة منها داخل 2px من بعضها (13 · 13.5 · 14
     · 14.5 · 15). لا عين تفرّق بينها؛ هي تراكم "زوّدها نصّ بكسل" على مدى
     شهور، لا قرارات. سبع درجات تكفي شاشة كثيفة، وكل درجة لها عمل:
       11 وسوم دقيقة · 12 ثانوي · 13 نصّ الجداول · 14 نصّ أساسي
       16 عناوين اللوحات · 20 عناوين الشاشات · 26 و34 للأرقام الكبيرة
     ------------------------------------------------------------------ */
  --fs-3xs: 11px;
  --fs-2xs: 12px;
  --fs-xs:  13px;
  --fs-sm:  14px;
  --fs-md:  16px;   /* يُستعمل أيضاً لحقول الهاتف: 16px يمنع تكبير iOS */
  --fs-lg:  20px;
  --fs-xl:  26px;
  --fs-2xl: 34px;

  /* أربعة أوزان بدل سبعة: الفرق بين 600 و650 لا يُرى، وكان لكلٍّ منهما
     عشرات الاستخدامات — أي مستوى بصري واحد باسمين. */
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semi:   600;
  --fw-bold:   700;

  /* ------------------------------------------------------------------
     سُلّم المسافات — كان 32 قيمة px مختلفة وصفر توكن.
     أساس 4px: كل قيمة مضاعف له، فتصطفّ العناصر رأسياً بلا ضبط يدوي.
     ------------------------------------------------------------------ */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  24px;
  --sp-6:  32px;
  --sp-7:  48px;

  /* ارتفاعات العناصر التفاعلية: ثلاثة فقط، وإلا اختلفت أطوال الأزرار
     والحقول في نفس الصف بلا سبب. */
  --h-sm: 28px;
  --h-md: 36px;
  --h-lg: 44px;
  /* درجتان للهاتف: --h-touch حدّ اللمس المريح (يساوي --touch)، و--h-chip
     لعناصر العرض الصغيرة (chip الموعد) التي تُلمَس لكنها ليست حقلاً. */
  --h-touch: 44px;
  --h-chip:  32px;
  --h-btn-mobile: 40px;   /* الزرّ الصغير على الهاتف: أكبر للمس، أصغر من الحقل */

  /* مقاس شارة الأيقونة — ليس ارتفاع عنصر تفاعلي، ولذلك درجة مستقلّة:
     كانت 28 و30 و34 في سبعة مواضع بلا سبب يميّزها، فتبدو الشارات
     المتجاورة غير مصطفّة. درجتان تكفيان: عادية وصغيرة. */
  --ico:    30px;
  --ico-sm: 28px;
  --ico-lg: 52px;   /* شعار شاشة الدخول — مقاس فريد مقصود، لا يتكرّر */
  --box:    24px;   /* مربّع الاختيار: مقاس نظام لا يُشتقّ من الارتفاعات */

  /* ------------------------------------------------------------------
     نقاط الكسر

     كانت خمساً بلا سلّم (560 · 700 · 760 · 980 · 1100)، فشاشتان
     متجاورتان تنكسران عند عرضين مختلفين بلا سبب. ثلاث درجات تكفي:

       bp-sm  الهاتف — عمود واحد، الجداول تصير بطاقات
       bp-md  اللوحي — القائمة تنطوي، الشبكات عمودان
       bp-lg  فوقه سطح مكتب كامل

     CSS لا يقبل var() داخل @media، فالأرقام مكتوبة في الاستعلامات
     نفسها — هذه التوكنات مرجعٌ واحد يُقاس عليه عند إضافة أي استعلام
     جديد، لا مصدرٌ تقرؤه المتصفحات.
     ------------------------------------------------------------------ */
  --bp-sm: 600px;
  --bp-md: 900px;
  --bp-lg: 1200px;

  /* أصغر هدف لمس مريح. 44px توصية معتمدة في إرشادات الوصول، وأقلّ منها
     يجعل الإصبع يخطئ الزرّ على شاشة يُعمَل عليها واقفاً. */
  --touch: 44px;

  --speed: .16s;
}

/* ============================================================================
   الطبقة الدلالية

   الفرق بينها وبين الطبقة الأولى هو النواة كلها: الأولى تقول "ما اللون"،
   وهذه تقول "لماذا". القالب الذي يكتب style="border-color:var(--rose)"
   يصف **شكلاً**؛ الذي يكتب class="tone-danger" يصف **معنى** — فيتغيّر لون
   الخطر لاحقاً من مكان واحد بدل تسعة قوالب.
   ============================================================================ */
:root {
  --tone-info-line:   var(--primary);
  --tone-info-bg:     var(--primary-soft);
  --tone-info-ink:    var(--primary-ink);

  --tone-ok-line:     var(--mint);
  --tone-ok-bg:       var(--mint-soft);
  --tone-ok-ink:      var(--mint);

  --tone-warn-line:   var(--amber);
  --tone-warn-bg:     var(--amber-soft);
  --tone-warn-ink:    var(--amber);

  --tone-danger-line: var(--rose);
  --tone-danger-bg:   var(--rose-soft);
  --tone-danger-ink:  var(--rose);

  /* عروض الحقول: كانت 17 مرة max-width بالإيد في القوالب، أي أن النظام
     لم يكن فيه عرض معياري فاخترعه كل قالب لنفسه. */
  --w-xs:  110px;
  --w-sm:  160px;
  --w-md:  220px;
  --w-lg:  320px;

  /* ألوان الطباعة: الورق الأبيض لا سطوح ولا وضع ليلي، فرمادي الطباعة
     قيمة مستقلة لا مشتقّة من اللوحة. */
  --print-fill: #f0f0f0;
  --auth-deep:  #071a25;   /* أعمق من الحبر: خلفية شاشة الدخول وحدها */
  --chart-mint-dark: #6fe3c4;  /* مِنت فاتح للرسوم على الوضع الليلي */
}

/* Dark mode — أسود شبه خالص، والذهب لونُ تمييزٍ حقيقي لا زينة

   تغيّر عن الكحلي الداكن السابق (#0c1620) إلى شبه أسود: العيادة تعمل
   ليلاً والشاشة تُقرأ ساعات، والداكن العميق أرحم. لم نبلغ #000 الحالك
   عمداً — الأسود التامّ مع نصٍّ أبيض يُحدث هالةً حول الحروف (halation)
   تُتعب في القراءة الطويلة؛ المسحة الزرقاء الخفيفة (‎#080b0f‎) تلغيها
   وتبقى العين مرتاحة.

   والمكسب الأهم: الذهب على هذا العمق تباينه 12.2:1 — أي أنه صار لوناً
   صالحاً للنصّ لا للشارات فقط. فالهوية حاضرة في المتن هنا، لا محبوسةً
   في الرِّف كما في الوضع الفاتح حيث تباينه على الأبيض 1.6:1 فقط. */
[data-theme="dark"] {
  --paper:        #080b0f;
  --surface:      #101519;
  --surface-2:    #171e24;
  --surface-sunk: #05080b;

  --ink:    #e8edf2;
  --ink-2:  #a3b2c0;
  --ink-3:  #6f8092;

  --line:        #1e262e;
  --line-strong: #2e3a45;

  /* الرِّف يذوب في الخلفية هنا: في الوضع الفاتح كان الرِّف الداكن هو
     موطن الهوية لأنه الوحيد الذي يحتمل الذهب. في الأسود كل الشاشة تحتمله،
     فلا داعي لرِفٍّ متمايز — يكفي خطّ فاصل. */
  --rail:      #05080b;
  --rail-2:    #0d1216;
  --rail-line: #ffffff10;
  --rail-ink:  #a3b2c0;
  --rail-ink-2:#6f8092;

  /* الأساسي ذهبٌ صريح لا لبنيّ دخيل. اللبني السابق (#3aaed6) كان بقيّة
     لوحةٍ قديمة، فكان الوضعان يحملان هويّتين مختلفتين. الآن واحدة. */
  --primary:       #f7c51a;
  --primary-hover: #ffd644;
  --primary-soft:  #2a2208;
  --primary-ink:   #f7c51a;
  /* الحبر الذي يعلو سطحاً ملؤه الأساسي: الذهب فاتح، فما فوقه داكن.
     أبيض عليه تباينه 1.62 — غير مقروء. هذا 9.9. */
  --on-primary:    #0f2333;
  /* الأحمر الليلي أفتح من نظيره النهاري، فالأبيض عليه يبقى مقروءاً —
     لكن التوكن يُعرَّف صراحةً لا يُترك يسقط إلى `initial`. توكنٌ ناقص في
     وضع لا يرفع خطأ: يرث النصّ لون أبيه فيبدو «شبه صحيح». */
  --on-danger:     #16121a;

  --mint:      #3dbf9c;
  --mint-soft: #0a2820;
  --amber:     #d9a047;
  --amber-soft:#2b2110;
  --rose:      #e8778a;
  --rose-soft: #2e1519;
  --violet:    #8f8ee0;
  --violet-soft:#1c1a35;

  --sh-1: 0 1px 2px rgba(0,0,0,.5);
  --sh-2: 0 1px 3px rgba(0,0,0,.55), 0 6px 18px rgba(0,0,0,.45);
  --sh-3: 0 12px 40px rgba(0,0,0,.7);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 { margin: 0; font-weight: var(--fw-bold); letter-spacing: -.01em; }

/* Icons carry no intrinsic size: the macro emits a bare <svg> with only a
   viewBox. Without a default, an icon dropped into a context that has no
   sizing rule (a hint paragraph, a new component) stretches to the full
   width of its container. This is that default — every specific rule below
   simply overrides it.

   Scoped to class-less <svg> on purpose. A blanket `svg:not([width])` also
   caught decorative graphics that size themselves through their own class
   (the login pulse trace is 200% wide), collapsing them to 1em. */
svg:not([width]):not([class]) { width: 1em; height: 1em; flex-shrink: 0; }

.hint svg, p svg, .muted svg, .faint svg {
  width: 15px;
  height: 15px;
  vertical-align: -2px;
  stroke: currentColor;
}

/* Numbers must align in financial tables */
/* أرقام جدولية بنفس عائلة الخط بدل خطّ mono ثانٍ: المال يصطفّ رأسياً
   دون إدخال شخصية طباعية ثانية إلى الصفحة. Plex فيه tnum حقيقية. */
.num, td.num, .kpi-v, .money, .settle-cell strong, .sc b, .stat b {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -.01em;
}

.mono { font-family: var(--font-mono); font-size: .92em; letter-spacing: -.02em; }

::selection { background: var(--primary-soft); color: var(--primary-ink); }

/* Visible keyboard focus everywhere — accessibility floor */
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. Shell
   -------------------------------------------------------------------------- */
.app {
  display: grid;
  grid-template-columns: var(--side-w) 1fr;
  min-height: 100vh;
  transition: grid-template-columns var(--speed) ease;
}
/* Fully closed: the column collapses to zero and the panel slides out,
   so the content gets the entire viewport width. */
.app.nav-closed { grid-template-columns: 0 1fr; }

/* ---- Sidebar ---- */
/* الرِّف: السطح الوحيد الداكن في النظام، وفيه وحده يظهر ذهب العلامة. */
.side {
  background: var(--rail);
  border-inline-end: 1px solid var(--rail-line);
  color: var(--rail-ink);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  z-index: 40;
}

.side-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--rail-line);
  min-height: var(--topbar-h);
}

/* Signature: the pulse mark. Grounded in the subject, used in exactly
   two places (sidebar + login) so it stays a signature, not decoration. */
.mark {
  width: var(--h-md); height: var(--h-md);
  flex: 0 0 34px;
  border-radius: 10px;
  background: linear-gradient(150deg, var(--primary) 0%, var(--mint) 130%);
  display: grid;
  place-items: center;
  box-shadow: var(--sh-2);
}
.mark svg { width: 21px; height: 21px; stroke: #fff; }

.wordmark { display: flex; flex-direction: column; min-width: 0; }
.wordmark b { font-size: var(--fs-sm); font-weight: var(--fw-bold); letter-spacing: -.015em; white-space: nowrap; color: #fff; }
.wordmark span {
  font-size: var(--fs-3xs); color: var(--rail-ink-2); font-weight: var(--fw-semi);
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}

.nav { flex: 1; overflow-y: auto; padding: var(--sp-3) var(--sp-2); display: flex; flex-direction: column; gap: 2px; }
.nav::-webkit-scrollbar { width: 6px; }
.nav::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }

.nav a {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--rail-ink);
  font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
  white-space: nowrap;
  transition: background var(--speed), color var(--speed);
}
.nav a svg { width: 18px; height: 18px; flex: 0 0 18px; stroke: currentColor; opacity: .9; }
.nav a:hover { background: #ffffff0d; color: #fff; }
/* المؤشّر الذهبي: خطّ رفيع على الحافّة لا خلفية كاملة — لون العلامة
   يقول "أنت هنا" بأقلّ ما يمكن، ولا يصرخ في كل زيارة. */
.nav a.active {
  background: #ffffff12;
  color: #fff;
  font-weight: var(--fw-semi);
  box-shadow: inset -2.5px 0 0 var(--gold);
}
[dir="ltr"] .nav a.active { box-shadow: inset 2.5px 0 0 var(--gold); }
.nav a.active svg { opacity: 1; }

/* --------------------------------------------------------------------------
   Collapsible nav groups
   The headings used to be inert text with every link always visible, so the
   sidebar was one long list of nineteen items. A group is a button now, and
   the one containing the current page opens itself — you never land on a
   page whose own entry is folded away.
   -------------------------------------------------------------------------- */
.nav-group { border-top: 1px solid var(--rail-line); margin-top: var(--sp-1); padding-top: var(--sp-1); }
.nav-group:first-of-type { border-top: 0; }

.nav-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ink-2);
  font-family: inherit;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: .02em;
  cursor: pointer;
  text-align: start;
  transition: background var(--speed), color var(--speed);
}
.nav-head:hover { background: #ffffff0d; color: #fff; }
.nav-head svg { flex: 0 0 auto; width: 17px; height: 17px; }
.nav-head .lbl { flex: 1; min-width: 0; }

.nav-caret {
  flex: 0 0 auto;
  display: inline-flex;
  width: 15px; height: 15px;
  color: var(--ink-3);
  transition: transform var(--speed);
}
.nav-caret svg { width: 15px; height: 15px; }
.nav-group.is-open .nav-caret { transform: rotate(180deg); }

.nav-items {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--speed);
}
.nav-group.is-open .nav-items { grid-template-rows: 1fr; }
/* The inner wrapper is what actually clips; grid-template-rows animates
   only when the content sits in a min-height:0 track. */
.nav-items > * { min-height: 0; }
.nav-items { overflow: hidden; }
.nav-items > a { margin-inline-start: var(--sp-2); }

/* A group carrying the current page is marked even while folded, so the
   sidebar still says where you are. */
.nav-group:not(.is-open):has(a.active) .nav-head { color: var(--gold); }

.side-foot {
  border-top: 1px solid var(--rail-line);
  padding: var(--sp-3) var(--sp-2);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.who {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2) var(--sp-2);
  min-width: 0;
}
.avatar {
  width: var(--h-md); height: var(--h-md); flex: 0 0 var(--h-md); border-radius: 50%;
  background: var(--gold); color: var(--rail);
  display: grid; place-items: center;
  font-weight: var(--fw-bold); font-size: var(--fs-xs);
}
.who-txt { min-width: 0; }
.who-txt b { display: block; font-size: var(--fs-xs); font-weight: var(--fw-semi); color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-txt span { font-size: var(--fs-2xs); color: var(--rail-ink-2); white-space: nowrap; }

.side-foot a {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--rail-ink);
  white-space: nowrap;
  transition: background var(--speed), color var(--speed);
}
.side-foot a svg { width: 16px; height: 16px; flex: 0 0 16px; stroke: currentColor; }
.side-foot a:hover { background: #ffffff0d; color: #fff; }
.side-foot a.danger:hover { background: #ffffff14; color: var(--rail-danger); }

/* Closed state (desktop). Scoped to wide screens so it can never fight the
   mobile drawer, which is driven by .side.open instead. */
@media (min-width: 981px) {
  .side { transition: transform var(--speed) cubic-bezier(.2,.9,.3,1); }
  .app.nav-closed .side {
    transform: translateX(-100%);
    border-inline-end-color: transparent;
  }
  [dir="rtl"] .app.nav-closed .side { transform: translateX(100%); }
  /* Keep it out of the tab order while hidden */
  .app.nav-closed .side { visibility: hidden; }
}

/* ---- Main ---- */
.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  min-height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-5);
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--line);
}
@supports not (backdrop-filter: blur(2px)) { .topbar { background: var(--paper); } }

.topbar h1 { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.topbar .crumb { font-size: var(--fs-2xs); color: var(--ink-3); font-weight: var(--fw-semi); letter-spacing: .05em; text-transform: uppercase; }

/* أدوات الشريط العلوي.

   الموضع ينقلب مع اللغة تلقائياً: `justify-content: space-between` على
   `.topbar` يضع العنوان في بداية السطر والأدوات في نهايته، و"البداية"
   و"النهاية" تتبعان `dir` — فالعربية تعطي العنوان يميناً والأدوات
   يساراً، والإنجليزية العكس. لا قاعدة `left/right` فيزيائية في الشريط
   كلّه، وأي واحدة تُضاف ستكسر أحد الاتجاهين بلا أن يُلاحَظ في الآخر. */
.tools {
  display: flex; align-items: center; gap: var(--sp-2);
  flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end;
}
/* فاصل رفيع بين ضوابط النطاق وأدوات الصفحة: الأولى تسأل "أي بيانات؟"
   والثانية "افعل ماذا بها؟" — سؤالان مختلفان في شريط واحد. */
.tools .scopebar { padding-inline-end: var(--sp-2); border-inline-end: 1px solid var(--line); margin-inline-end: var(--sp-1); }

/* أدوات النظام (السمة واللغة) تبقى في أقصى النهاية مهما أضافت الشاشة
   من أزرار: هي ثابتة عبر الشاشات، فمكانها الثابت يجعلها تُوجد بالعادة
   لا بالبحث. `order` يفصل الترتيب البصري عن ترتيب DOM الذي يخدم
   قارئ الشاشة. */
.tools > [data-theme-toggle],
.tools > .seg { order: 9; }
.tools .sysgap { order: 8; width: 1px; align-self: stretch; background: var(--line); margin-inline: var(--sp-1); }

/* إيقاع الصفحة: مسافة واحدة بين الكتل. كانت الفواصل تتراوح بين 14 و26
   بكسل بحسب من كتب الشاشة، فتبدو الصفحات من أنظمة مختلفة. */
.content { padding: var(--sp-5) var(--sp-5) var(--sp-7); max-width: 1320px; width: 100%; }
:where(.content) > * + * { margin-top: var(--sp-4); }
:where(.content) > .print-head + * { margin-top: 0; }

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-weight: var(--fw-semi);
  font-size: var(--fs-xs);
  line-height: 1.3;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--speed), border-color var(--speed), color var(--speed), box-shadow var(--speed);
}
.btn svg { width: 16px; height: 16px; stroke: currentColor; flex-shrink: 0; }
.btn:hover { background: var(--surface-2); border-color: var(--primary); color: var(--primary-ink); }

/* الضغط يُحسّ لا يُرى فقط.
   `translateY` وحده يحرّك الزرّ فيبدو كأنه انزلق؛ إضافة تصغير طفيف تجعله
   يبدو **مضغوطاً**. الفرق بينهما هو ما يميّز واجهة تستجيب من واجهة
   تتحرّك — والاستقبال يضغط هذه الأزرار مئات المرات يومياً. */
.btn:active { transform: translateY(1px) scale(.985); }

/* حلقة التركيز على الزرّ بلونه لا بلون عامّ.
   القاعدة العامة `:focus-visible` تضع حلقة بالأساسي على كل شيء — وعلى
   زرّ خطر أحمر تبدو الحلقة الزرقاء غريبة وتُضعف إشارة الخطر. */
.btn:focus-visible { outline-color: var(--primary); }
.btn-danger:focus-visible { outline-color: var(--rose); }

/* الزرّ المعطَّل: لا يُشار إليه بالشفافية وحدها.
   `opacity` يجعل النصّ باهتاً فيصعب قراءة **سبب** التعطيل المكتوب عليه.
   خلفية مسطّحة وحبر أخفت أوضح، ومؤشّر المنع يقول القصة قبل القراءة. */
/* `is-busy` أُزيلت من هنا: كانت ترث `not-allowed` و`pointer-events: none`
   من قاعدة المعطَّل، فيبدو الزرّ المشغول ممنوعاً — والفرق هو كل المعنى.
   قاعدته المستقلّة أدناه. */
.btn[disabled] {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--ink-3);
  cursor: not-allowed;
  opacity: 1;
  pointer-events: none;
}
.btn-primary[disabled] { background: var(--surface-2); color: var(--ink-3); }

.btn-primary {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
  /* بلا ظلّ.
     كان `rgba(11,126,168,.24)` — ظلاً أزرق من اللوحة القديمة بقي بعد
     تحويل الهوية للذهب، فالظلّ تحت الزرّ بلون لا وجود له في النظام.
     وحاولتُ استبداله بـ`--sh-1` فأسقط الحارس: القاعدة أن الظلّ محجوز لما
     يطفو فعلاً، والزرّ لا يطفو — يُميَّز بلونه المصمت لا بارتفاعه.
     الحدّ الشعري والتباين يكفيان، وهو ما تفعله الأنظمة الحديثة. */
}
.btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--on-primary); }

.btn-danger { border-color: var(--rose); color: var(--rose); background: var(--surface); }
.btn-danger:hover { background: var(--rose); border-color: var(--rose); color: var(--on-danger); }

.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--surface-2); border-color: transparent; }

.btn-sm { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-2xs); border-radius: var(--r-sm); }
.btn-sm svg { width: 14px; height: 14px; }

.btn-icon { padding: var(--sp-2); width: var(--h-md); height: var(--h-md); }
.btn-icon svg { width: 17px; height: 17px; }

/* الزرّ المشغول يختلف عن المعطَّل: المعطَّل لا يُضغط، والمشغول **ضُغط
   للتوّ**. توحيد مظهرهما يجعل الموظف يظنّ أن ضغطته لم تُسجَّل فيضغط
   مجدداً — وهو ما يمنعه القفل ولا يمنع قلقه.

   فيُبقي المشغول ألوانه ويضيف دوّاراً، والمعطَّل يبهت بلا دوّار. */
.btn.is-busy {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
  cursor: progress;
  /* يُمنع النقر بلا مؤشّر المنع: الضغطة الثانية لا تُسجَّل، والمؤشّر
     يقول «انتظر» لا «ممنوع». */
  pointer-events: none;
}
.btn.is-busy:not(.btn-primary) {
  background: var(--surface-2);
  border-color: var(--line-strong);
  color: var(--ink-2);
}
.btn.is-busy::after {
  content: ""; width: 13px; height: 13px;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: 50%; animation: spin .6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Segmented control — language switch */
.seg {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface);
}
.seg a {
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  color: var(--ink-2);
  transition: background var(--speed), color var(--speed);
}
.seg a:hover { background: var(--surface-2); color: var(--ink); }
.seg a.on { background: var(--primary); color: #fff; }

/* --------------------------------------------------------------------------
   5. Cards & panels
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: var(--sp-4); }
.cards { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* بطاقات الأرقام: خطّ شعرة لا ظلّ، ولا ارتفاع عند المرور. الظلّ يعني
   "هذا يطفو فوق الصفحة" وهي لا تطفو — والارتفاع عند المرور يوحي بأنها
   قابلة للنقر وأغلبها ليس كذلك. */
.kpi {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-4);
  overflow: hidden;
}

/* The "vital rail" — polarity encoded structurally, not decoratively */
/* ------------------------------------------------------------------------
   شارة الأيقونة — حيث يدخل اللون إلى المنضدة

   كان اللون كلّه في الرِّف، وخيطٌ بعرض 3px على حافّة البطاقة هو كلّ ما
   يصل المحتوى — فتبدو الصفحة رمادية بلا حياة. الشارة تعطي اللون مساحة
   يُرى فيها، وتبقى مقيّدة: خلفية باهتة وأيقونة مشبعة، لا بطاقة ملوّنة
   بالكامل. اللون هنا يقول **ماذا يعني الرقم** لا "انظر إليّ".
   ------------------------------------------------------------------------ */
.kpi::before { content: none; }
.kpi-k::before {
  content: "";
  order: -1;
}
.kpi.pos  .kpi-k svg { background: var(--mint-soft);    color: var(--mint); }
.kpi.neg  .kpi-k svg { background: var(--rose-soft);    color: var(--rose); }
.kpi.warn .kpi-k svg { background: var(--amber-soft);   color: var(--amber); }
.kpi.info .kpi-k svg { background: var(--primary-soft); color: var(--primary); }

/* نفس الشارة في رؤوس اللوحات، فتُقرأ الصفحة كنظام واحد لا كقطع متجاورة */
.panel-head > h2 > svg:first-child,
.panel-head > h3 > svg:first-child {
  width: var(--ico-sm); height: var(--ico-sm); padding: var(--sp-2);
  border-radius: var(--r-sm);
  background: var(--primary-soft);
  color: var(--primary);
  box-sizing: content-box;
  margin-inline-end: var(--sp-1);
}

.kpi-k {
  display: flex; align-items: center; gap: var(--sp-3);
  font-size: var(--fs-2xs); color: var(--ink-2); font-weight: var(--fw-medium);
  margin-bottom: var(--sp-3);
}
.kpi-k svg { stroke: currentColor; opacity: 1; }
.kpi-v { font-size: var(--fs-xl); font-weight: var(--fw-bold); letter-spacing: -.02em; line-height: 1.15; }
.kpi-v.pos { color: var(--mint); }
.kpi-v.neg { color: var(--rose); }
.kpi-sub { font-size: var(--fs-2xs); color: var(--ink-3); margin-top: var(--sp-1); }
.kpi-cur { font-size: .62em; font-weight: var(--fw-semi); color: var(--ink-3); margin-inline-start: var(--sp-1); }

/* ------------------------------------------------------------------------
   انضباط الارتفاع

   كانت كل لوحة تحمل ظلاً، فكانت الصفحة كومة صناديق متطابقة الأهمية —
   ولو كان كل شيء مرتفعاً فلا شيء مرتفع. القاعدة الآن:

     أسطح المحتوى  → خطّ شعرة، بلا ظلّ.
     ما يطفو فعلاً → ظلّ: المودال، البوب-أب، شريط اليوم.

   هذا وحده يغيّر إحساس كل شاشة أكثر من أي لون.
   ------------------------------------------------------------------------ */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
.panel + .panel, .grid + .panel, .panel + .grid { margin-top: var(--sp-4); }

.panel-head {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  background: var(--surface);
}
.panel-head h2 { font-size: var(--fs-sm); font-weight: var(--fw-bold); display: flex; align-items: center; gap: var(--sp-2); }
.panel-head h2 svg { width: 17px; height: 17px; stroke: var(--ink-2); }
.panel-head .count {
  font-size: var(--fs-2xs); color: var(--ink-2); font-weight: var(--fw-semi);
  background: var(--surface-sunk); padding: 2px var(--sp-2); border-radius: var(--r-pill);
}
.panel-body { padding: var(--sp-4); }
.panel-foot {
  padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--line);
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   6. Tables
   -------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap::-webkit-scrollbar { height: 8px; }
.table-wrap::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 4px; }

table { width: 100%; border-collapse: collapse; }

th, td {
  padding: var(--sp-3) var(--sp-4);
  text-align: start;
  font-size: var(--fs-xs);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-2);
  color: var(--ink-2);
  font-weight: var(--fw-semi);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: .055em;
  white-space: nowrap;
  border-bottom: 1px solid var(--line-strong);
}

tbody tr { transition: background var(--speed); }
tbody tr:hover { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: none; }

/* ---- ما يُحسّ في الجداول الطويلة ---- */

/* الأرقام تُقرأ عمودياً لا أفقياً.
   المحاسب يقارن خانة الآحاد بخانة الآحاد. بخطّ متناسب العرض ينزلق العمود
   فيصير الفرق بين 1,200 و11,200 غير مرئي بنظرة. */
td.num, th.num { font-variant-numeric: tabular-nums; text-align: end; }

/* ترقيم الصفوف بتظليل خفيف: العين تفقد السطر في جدول بعشرين عموداً،
   فتقرأ رقم صفّ مع اسم صفّ آخر. أخفت من أن يُرى كزخرفة، وكافٍ ليمسك
   البصر السطر. */
tbody tr:nth-child(even) { background: var(--surface-sunk); }
tbody tr:nth-child(even):hover { background: var(--surface-2); }

/* الصفّ المقروء الآن يُميَّز بحدّ جانبي لا بلون وحده — من يستعمل
   الكيبورد يحتاج أن يعرف أين هو في الجدول. */
tbody tr:focus-within {
  background: var(--primary-soft);
  outline: none;
}
tbody tr:focus-within > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--primary);
}

/* الرأس اللاصق يحتاج خطاً يفصله عند التمرير: بدونه تلتصق العناوين
   بالصفوف فتبدو صفّاً منها. */
thead th { box-shadow: inset 0 -1px 0 0 var(--line-strong); }

/* Sortable headers */
th[data-sort] { cursor: pointer; user-select: none; padding-inline-end: var(--sp-5); position: sticky; }
th[data-sort]::after {
  content: "";
  position: absolute;
  inset-inline-end: 9px;
  top: 50%;
  margin-top: -5px;
  width: 8px; height: 10px;
  opacity: .3;
  background: currentColor;
  clip-path: polygon(50% 0, 100% 40%, 0 40%, 50% 0, 50% 100%, 100% 60%, 0 60%);
  transition: opacity var(--speed);
}
th[data-sort]:hover::after { opacity: .6; }
th[data-sort].asc::after  { opacity: 1; clip-path: polygon(50% 0, 100% 70%, 0 70%); }
th[data-sort].desc::after { opacity: 1; clip-path: polygon(50% 100%, 100% 30%, 0 30%); }

/* Toolbar above a table: search + actions */
.tbl-tools { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
/* الحقل والزرّ صندوقان متجاوران — انظر تعليق الماكرو في `_ui.html`.
   العرض انتقل من الحقل إلى الغلاف: الغلاف صار يضمّ الاثنين، فقياسه من
   الحقل وحده كان يُخرج الزرّ خارج الحدود المرصودة له. */
.search {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  width: 210px;
}
/* زرّ العدسة: نفس شكل `.datefield-btn` ليقرأ الاثنان كعائلة واحدة */
.search-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-md);
  height: var(--h-md);
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: background var(--speed), border-color var(--speed), color var(--speed);
}
.search-btn svg { width: 15px; height: 15px; stroke: currentColor; }
.search-btn:hover {
  border-color: var(--primary);
  color: var(--primary-ink);
  background: var(--surface-2);
}
.search > input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: var(--h-md);
}

.row-hidden { display: none !important; }

/* --------------------------------------------------------------------------
   7. Tags
   -------------------------------------------------------------------------- */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  white-space: nowrap;
  background: var(--surface-sunk);
  color: var(--ink-2);
  line-height: 1.5;
}
.tag::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.tag.plain::before { display: none; }

.tag.ok, .tag.mint     { background: var(--mint-soft);    color: var(--mint); }
.tag.low, .tag.danger  { background: var(--rose-soft);    color: var(--rose); }
.tag.warn, .tag.billable_supply { background: var(--amber-soft); color: var(--amber); }
.tag.info, .tag.consumable      { background: var(--violet-soft); color: var(--violet); }
.tag.blue              { background: var(--primary-soft); color: var(--primary-ink); }

/* --------------------------------------------------------------------------
   8. Forms
   -------------------------------------------------------------------------- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
}

.field { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.field > label, .fld {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  color: var(--ink-2);
  display: block;
}
.field .hint { font-size: var(--fs-2xs); color: var(--ink-3); }

/* One list, every text-like field. datetime-local, time and search were
   missing from it, so the browser drew them with its own chrome — a
   different height, border and font sitting next to our styled fields.
   That was the "date and time box doesn't look like the rest" report. */
input[type=text], input[type=date], input[type=number],
input[type=password], input[type=email], input[type=tel],
input[type=datetime-local], input[type=time], input[type=month],
input[type=search], input[type=url],
select, textarea {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  height: var(--h-md);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-xs);
  background: var(--surface);
  color: var(--ink);
  transition: border-color var(--speed), box-shadow var(--speed);
}
textarea { height: auto; min-height: 78px; padding: var(--sp-2) var(--sp-3); resize: vertical; }

/* WebKit gives search fields a pill shape and its own clear button */
input[type=search] { appearance: none; -webkit-appearance: none; }
input[type=search]::-webkit-search-decoration,
input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ------------------------------------------------------------------------
   حقول التاريخ والوقت

   المتصفح يرسم أيقونة المنتقي بنفسه، ونتركه يرسمها.

   حاولتُ استبدالها بأيقونة من عندي لتطابق سهم القوائم، فوقعت الأيقونة
   **فوق النص**: هذه الحقول تحمل dir="ltr" لضمان ترتيب يوم/شهر/سنة، بينما
   الصفحة rtl — فذهبت الحشوة إلى جهة والأيقونة إلى الأخرى. المتصفح وحده
   يعرف أين يضع أيقونته لأنه هو من يعرف اتجاه محتوى الحقل.

   نلوّنها فقط: filter لأن العنصر داخل shadow DOM ولا يقبل color.
   ------------------------------------------------------------------------ */
/* حشوة متساوية واسعة على الجهتين، وعرض أدنى يسع "dd/mm/yyyy" وأيقونته.

   السبب: هذه الحقول تحمل dir="ltr" (لترتيب يوم/شهر/سنة) والصفحة rtl،
   والمتصفحات تختلف في أي طرف تضع أيقونة المنتقي — فأي حشوة على جهة
   واحدة تصطدم بالأيقونة على أحد المتصفحين. ضبطُها على الجهتين يجعل
   النتيجة صحيحة أياً كانت الجهة، بثمن بضعة بكسلات من العرض. حاولتُ
   تخمين الجهة مرّتين وأخطأتُ مرّتين. */
/* حشوة متساوية واسعة على الجهتين، وعرض أدنى يسع "dd/mm/yyyy" وأيقونته.

   السبب: هذه الحقول تحمل dir="ltr" (لترتيب يوم/شهر/سنة) والصفحة rtl،
   والمتصفحات تختلف في أي طرف تضع أيقونة المنتقي — فأي حشوة على جهة
   واحدة تصطدم بالأيقونة على أحد المتصفحين. ضبطُها على الجهتين يجعل
   النتيجة صحيحة أياً كانت الجهة.

   الحشوة رُفعت إلى sp-5 (بدل sp-6 الأصلية المبالغة، وأوسع من sp-3): تفصل
   الأيقونة عن الأرقام بوضوح على كل المتصفحات دون توسيع الحقل زيادة —
   وهو ما طلبه المستخدم: فصلٌ واضح لا تراكب. */
/* الحشوة عادية على الجهتين: أيقونة المتصفح صارت مخفيّة وزرّ التقويم خارج
   الحقل، فلم يعد هناك ما يزاحم الأرقام داخل الصندوق — ولا داعي للحشوة
   الواسعة التي كانت تحجز مكاناً لأيقونة لم تعد موجودة. */
input[type=date], input[type=datetime-local],
input[type=time], input[type=month] {
  padding-inline: var(--sp-3);
  min-width: 132px;
  text-align: left;
}
.scopebar input[type=date],
.scope-dates input[type=date] { min-width: 120px; }

input[type=date]::-webkit-calendar-picker-indicator,
input[type=datetime-local]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator,
input[type=month]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: .55;
  transition: opacity var(--speed);
}
input[type=date]:hover::-webkit-calendar-picker-indicator,
input[type=datetime-local]:hover::-webkit-calendar-picker-indicator,
input[type=time]:hover::-webkit-calendar-picker-indicator,
input[type=month]:hover::-webkit-calendar-picker-indicator { opacity: 1; }

[data-theme="dark"] input[type=date]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type=datetime-local]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type=time]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type=month]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(1.6);
}

/* النصّ داخلها بخطّ الواجهة لا بخطّ المتصفح الافتراضي */
input[type=date]::-webkit-datetime-edit,
input[type=datetime-local]::-webkit-datetime-edit,
input[type=time]::-webkit-datetime-edit { font-family: inherit; color: inherit; }


input::placeholder, textarea::placeholder { color: var(--ink-3); }

input:hover, select:hover, textarea:hover { border-color: var(--primary); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

select {
  appearance: none;
  padding-inline-end: var(--sp-6);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2352697d' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 15px;
  background-position: right 9px center;
}
[dir="rtl"] select { background-position: left 9px center; }
[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239db1c2' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

/* Checkbox / radio */
input[type=checkbox], input[type=radio] {
  width: 16px; height: 16px;
  accent-color: var(--primary);
  cursor: pointer;
  margin: 0;
}

.check {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--ink);
  cursor: pointer;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  transition: border-color var(--speed), background var(--speed);
}
.check:hover { border-color: var(--primary); background: var(--surface-2); }
.check:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-ink); }

.check-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ضوابط الشاشة ليست محتوى: كانت لوحةً كاملة بظلّ وحدود، فتقرأ كقرين
   للجدول الذي تتحكّم فيه — صندوقان لشيء واحد. الآن صفٌّ خفيف بخطّ سفلي
   يربطه بما تحته، والصفحة تبدأ بالبيانات لا بأدواتها. */
.filters {
  display: flex;
  gap: var(--sp-3);
  align-items: end;
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
  padding: 0 var(--sp-1) var(--sp-3);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
}
.filters .field { min-width: 150px; }

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   9. Empty states — an invitation to act, not a dead end
   -------------------------------------------------------------------------- */
.empty { padding: var(--sp-7) var(--sp-5); text-align: center; }
.empty svg {
  width: var(--ico); height: var(--ico);
  stroke: var(--ink-3);
  opacity: .55;
  margin-bottom: var(--sp-3);
}
.empty b { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semi); margin-bottom: var(--sp-1); }
.empty p { margin: 0; font-size: var(--fs-xs); color: var(--ink-2); }

/* --------------------------------------------------------------------------
   10. Toasts

   Centred at the top rather than pinned to a corner: a rule violation is
   the answer to what the user just did, so it belongs on their line of
   sight. Corner placement in an RTL layout also collided with the sidebar
   and forced the text to wrap badly.
   -------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   Toasts
   ---------------------------------------------------------------------------
   They used to sit centred at the top of the page, full width, with a
   draining progress bar underneath. Three problems, all of them felt on
   every single screen:

     • centred-top lands on the page header — the toast covered the very
       controls the user had just used;
     • a progress bar is motion in the corner of the eye. It repeats after
       every action, and motion that repeats becomes noise;
     • the bold title ("Done") above the message ("Password changed")
       said the same thing twice.

   Now: anchored to the bottom inline-end corner, compact, no bar, and the
   title only where it adds something — errors and warnings, where knowing
   the severity before reading matters.
   --------------------------------------------------------------------------- */
.toasts {
  position: fixed;
  bottom: var(--sp-4);
  inset-inline-end: var(--sp-4);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  cursor: pointer;                /* the whole card dismisses */
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  max-width: 380px;
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--sh-3);
  font-size: var(--fs-xs);
  animation: toast-in .2s cubic-bezier(.2,.9,.3,1);
}

/*  يدخل من الأسفل لا من الأعلى: الحركة تأتي من حافة الشاشة التي ظهر
    عندها، فتُقرأ كقدوم لا كقفزة في منتصف الصفحة. */
@keyframes toast-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.toast.out {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .18s, transform .18s;
}

/*  من يُعطّل الحركة في نظامه يُعطّلها هنا أيضاً — والتنبيه يظهر ويختفي
    بلا انزلاق. */
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
  .toast.out { transition: opacity .1s; transform: none; }
}

.toast-ico {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface-sunk);
  color: var(--ink-2);
}
.toast-ico svg { width: 14px; height: 14px; stroke: currentColor; }

.toast-txt { min-width: 0; }
.toast-title {
  display: block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  margin-bottom: 1px;
}
/*  «تم» فوق «تم تغيير كلمة السر» تكرار. العنوان يبقى للخطأ والتحذير
    وحدهما، حيث تُعرف الخطورة قبل قراءة النصّ. */
.toast.success .toast-title,
.toast.info .toast-title { display: none; }

.toast-msg {
  display: block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--ink);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.toast.error .toast-msg,
.toast.warning .toast-msg { color: var(--ink-2); }

.toast button {
  align-self: center;
  background: none; border: 0; cursor: pointer;
  padding: var(--sp-1); margin: calc(var(--sp-1) * -1);
  border-radius: 6px;
  color: var(--ink-3);
  line-height: 0;
  opacity: 0;
  transition: opacity .15s;
}
.toast:hover button, .toast:focus-within button { opacity: 1; }
.toast button svg { width: 15px; height: 15px; stroke: currentColor; }
.toast button:hover { color: var(--ink); background: var(--surface-2); }

/*  على الشاشة الضيّقة: عرض كامل أسفل الصفحة — الزاوية هناك ضيّقة،
    والبطاقة المقصوصة أسوأ من بطاقة ممتدّة. */
@media (max-width: 640px) {
  .toasts { inset-inline: var(--sp-3); bottom: var(--sp-3); align-items: stretch; }
  .toast { max-width: none; }
  .toast button { opacity: 1; }      /* لا تحويم على اللمس */
}

.toast.success { border-color: color-mix(in srgb, var(--mint) 40%, var(--line)); }
.toast.success .toast-ico { background: var(--mint-soft); color: var(--mint); }

.toast.error { border-color: color-mix(in srgb, var(--rose) 45%, var(--line)); }
.toast.error .toast-ico { background: var(--rose-soft); color: var(--rose); }
.toast.error .toast-title { color: var(--rose); }

.toast.warning { border-color: color-mix(in srgb, var(--amber) 45%, var(--line)); }
.toast.warning .toast-ico { background: var(--amber-soft); color: var(--amber); }
.toast.warning .toast-title { color: var(--amber); }

.toast.info { border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.toast.info .toast-ico { background: var(--primary-soft); color: var(--primary-ink); }

@media print { .toasts { display: none !important; } }

/* --------------------------------------------------------------------------
   11. Charts (pure SVG, drawn by app.js)
   -------------------------------------------------------------------------- */
.chart { width: 100%; display: block; overflow: visible; }
.chart .axis  { stroke: var(--line); stroke-width: 1; }
.chart .glabel, .chart .vlabel { font-size: var(--fs-3xs); font-weight: var(--fw-semi); fill: var(--ink-2); font-family: var(--font-ui); }
.chart .vlabel { font-size: var(--fs-3xs); fill: var(--ink-3); }
.chart .bar { transition: opacity var(--speed); }
.chart .bar:hover { opacity: .78; }
.chart .grid-line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 4; }

.legend { display: flex; gap: var(--sp-4); flex-wrap: wrap; font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--ink-2); }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; margin-inline-end: var(--sp-1); }

/* --------------------------------------------------------------------------
   12. Auth screen
   -------------------------------------------------------------------------- */
.auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
  background:
    radial-gradient(1100px 520px at 80% -10%, rgba(18,135,107,.20), transparent 60%),
    radial-gradient(900px 480px at 10% 110%, rgba(247,197,26,.10), transparent 60%),
    var(--auth-deep);
  position: relative;
  overflow: hidden;
}

/* Signature, second (and last) appearance: an ambient trace behind the card */
.auth-trace {
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  width: 200%;
  height: 130px;
  transform: translateY(-50%);
  opacity: .13;
  pointer-events: none;
}
.auth-trace path {
  fill: none;
  stroke: var(--chart-mint-dark);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1400;
  stroke-dashoffset: 1400;
  animation: trace 5.5s linear infinite;
}
@keyframes trace { to { stroke-dashoffset: -1400; } }

.auth-card {
  overflow: hidden;
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 372px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-6) var(--sp-6) var(--sp-5);
  box-shadow: 0 24px 70px rgba(0,0,0,.34);
  border: 1px solid var(--line);
}
.auth-head { text-align: center; margin-bottom: var(--sp-5); }
.auth-head .mark { width: var(--ico-lg); height: var(--ico-lg); flex-basis: 52px; margin: 0 auto var(--sp-3); border-radius: 15px; }
.auth-head .mark svg { width: var(--ico); height: var(--ico); }
.auth-head h1 { font-size: var(--fs-lg); margin-bottom: var(--sp-1); }
.auth-head p { margin: 0; font-size: var(--fs-xs); color: var(--ink-2); }
.auth-card .field { margin-bottom: var(--sp-4); }
.auth-card .btn-primary { width: 100%; padding: var(--sp-3); font-size: var(--fs-sm); margin-top: var(--sp-1); }
.auth-foot { margin-top: var(--sp-4); text-align: center; font-size: var(--fs-2xs); color: var(--ink-3); }

/* --------------------------------------------------------------------------
   13. Error page
   -------------------------------------------------------------------------- */
.err { max-width: 470px; margin: var(--sp-6) auto; text-align: center; padding: var(--sp-6) var(--sp-5); }
.err .code {
  font-size: var(--fs-2xl); font-weight: var(--fw-bold); line-height: 1;
  letter-spacing: -.04em;
  background: linear-gradient(150deg, var(--primary), var(--mint));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-bottom: var(--sp-2);
}
.err p { font-size: var(--fs-sm); color: var(--ink-2); margin: 0 0 var(--sp-5); }

/* --------------------------------------------------------------------------
   14. Utilities
   -------------------------------------------------------------------------- */
.muted { color: var(--ink-2); }
.faint { color: var(--ink-3); }
.pos   { color: var(--mint); }
.neg   { color: var(--rose); }
.bold  { font-weight: var(--fw-semi); }
.nowrap{ white-space: nowrap; }
.text-end { text-align: end; }
.text-center { text-align: center; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: var(--sp-2); }
.mt-2 { margin-top: var(--sp-4); } .mt-3 { margin-top: var(--sp-5); }
.mb-2 { margin-bottom: var(--sp-4); }
.flex { display: flex; align-items: center; gap: var(--sp-2); }
.flex-wrap { flex-wrap: wrap; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.gap-sm { gap: var(--sp-1); }
.w-full { width: 100%; }
.hidden { display: none !important; }

.subhead {
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .07em;
  margin: var(--sp-4) 0 var(--sp-2);
  display: flex; align-items: center; gap: var(--sp-2);
}
.subhead::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.scrim {
  position: fixed; inset: 0; z-index: 39;
  background: rgba(8,22,32,.45);
  backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--speed);
}
.scrim.on { opacity: 1; pointer-events: auto; }

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */
.burger { display: none; }

@media (max-width: 980px) {
  .app, .app.nav-closed { grid-template-columns: 1fr; }

  .side {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    width: var(--side-w);
    transform: translateX(-100%);
    transition: transform .22s cubic-bezier(.2,.9,.3,1);
    box-shadow: var(--sh-3);
  }
  [dir="rtl"] .side { transform: translateX(100%); }
  .side.open, [dir="rtl"] .side.open { transform: translateX(0); }

  /* On mobile the drawer is the pattern — the desktop close button is hidden
     and the sidebar must stay visible so .side.open can slide it in. */
  .app.nav-closed .side { visibility: visible; transform: translateX(-100%); }
  [dir="rtl"] .app.nav-closed .side { transform: translateX(100%); }
  .app.nav-closed .side.open, [dir="rtl"] .app.nav-closed .side.open { transform: translateX(0); }

  .burger { display: inline-flex; }
  .nav-toggle { display: none !important; }

  .topbar { padding: var(--sp-2) var(--sp-4); }
  .content { padding: var(--sp-4) var(--sp-4) var(--sp-6); }
  .topbar h1 { font-size: var(--fs-md); }
  .search { width: 150px; }
}

@media (max-width: 560px) {
  .cards { grid-template-columns: 1fr 1fr; }
  .kpi-v { font-size: var(--fs-lg); }
  th, td { padding: var(--sp-2) var(--sp-3); }
  .form-grid { grid-template-columns: 1fr; }
  .toasts { inset-inline: 12px; max-width: none; }
  .tbl-tools { width: 100%; }
  .search, .search input { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* --------------------------------------------------------------------------
   16. Print — clinics live on paper. Invoices and session sheets must
   come out clean on A4 with no chrome.
   -------------------------------------------------------------------------- */
@media print {
  @page { size: A4; margin: 14mm 12mm; }

  :root {
    --paper: #fff; --surface: #fff; --surface-2: #fff; --surface-sunk: #fff;
    --ink: #000; --ink-2: #333; --ink-3: #555;
    --line: #bbb; --line-strong: #888;
  }

  body { background: #fff; font-size: 11pt; }

  .side, .topbar, .toasts, .scrim, .filters,
  .no-print, .btn, form.no-print, .tbl-tools,
  .panel-foot, .burger { display: none !important; }

  .app { display: block; }
  .main { display: block; }
  .content { padding: 0; max-width: none; }

  .print-head { display: block !important; }

  .panel, .kpi {
    box-shadow: none !important;
    border: 1px solid #bbb;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .panel + .panel { margin-top: 10mm; }

  .kpi::before { display: none; }
  .cards { grid-template-columns: repeat(4, 1fr); gap: 6mm; }

  thead th {
    position: static;
    background: var(--print-fill) !important;
    color: #000;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  tr { break-inside: avoid; page-break-inside: avoid; }
  thead { display: table-header-group; }

  .tag {
    border: 1px solid #999;
    background: #fff !important;
    color: #000 !important;
  }
  .tag::before { display: none; }

  a[href]::after { content: ""; }
  .table-wrap { overflow: visible; }
}

/* Print-only masthead — hidden on screen */
.print-head { display: none; }
.print-head .ph-row { display: flex; justify-content: space-between; align-items: flex-end; border-bottom: 2px solid #000; padding-bottom: var(--sp-1); margin-bottom: 8mm; }
.print-head h1 { font-size: 16pt; }
.print-head .ph-meta { font-size: 9pt; color: #444; text-align: end; }

/* --------------------------------------------------------------------------
   17. Cases module — steps, calendar, invoice, tiles
   -------------------------------------------------------------------------- */

/* Numbered steps for the bulk-load flow */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--sp-4); }
.step { display: flex; gap: var(--sp-3); align-items: flex-start; }
.step-n {
  flex: 0 0 26px; width: var(--ico-sm); height: var(--ico-sm);
  border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-ink);
  display: grid; place-items: center;
  font-weight: var(--fw-bold); font-size: var(--fs-xs);
}
.step b { display: block; font-size: var(--fs-xs); margin-bottom: var(--sp-1); }
.step p { margin: 0; font-size: var(--fs-2xs); color: var(--ink-2); }
.step input[type=file] {
  font-size: var(--fs-2xs); padding: var(--sp-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface-2); cursor: pointer;
}
.step input[type=file]:hover { border-color: var(--primary); }

/* Month calendar */
.cal-head, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal-head {
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.cal-head span {
  padding: var(--sp-2) var(--sp-1); text-align: center;
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .05em;
}
.cal-cell {
  min-height: 104px;
  padding: var(--sp-1);
  border-inline-end: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: var(--sp-1);
  overflow: hidden;
}
.cal-cell:nth-child(7n) { border-inline-end: none; }
.cal-cell.blank { background: var(--surface-2); }
.cal-cell.today { background: var(--primary-soft); }
.cal-cell.today .cal-day {
  background: var(--primary); color: #fff;
  border-radius: var(--r-pill); padding: 1px var(--sp-2);
}
.cal-day { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--ink-2); align-self: flex-start; }
.cal-ev {
  display: block;
  font-size: var(--fs-2xs); line-height: 1.35;
  padding: var(--sp-1) var(--sp-1); border-radius: 5px;
  background: var(--surface-sunk); color: var(--ink);
  border-inline-start: 2px solid var(--primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background var(--speed);
}
.cal-ev:hover { background: var(--primary-soft); }
.cal-ev b { font-variant-numeric: tabular-nums; margin-inline-end: var(--sp-1); }
.cal-ev.completed { border-inline-start-color: var(--mint); }
.cal-ev.cancelled { border-inline-start-color: var(--rose); opacity: .55; text-decoration: line-through; }

/* --------------------------------------------------------------------------
   Invoice screen — a fast entry form, not a printed document.

   The previous layout put identity, items, payments, totals and actions in
   one panel separated only by small headings, so nothing grouped visually
   and the totals floated mid-page. It is now three blocks in the order the
   work happens: who → what was provided → how it was paid → commit.
   -------------------------------------------------------------------------- */

/* 1. identity strip */
.inv-bar {
  display: flex;
  align-items: stretch;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--primary);
  border-radius: var(--r);
}

.inv-bar-ref {
  display: flex; flex-direction: column; justify-content: center;
  padding-inline-end: var(--sp-4);
  border-inline-end: 1px solid var(--line);
  min-width: 96px;
}
.inv-bar-ref span {
  font-size: var(--fs-3xs); font-weight: var(--fw-bold); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .07em;
}
.inv-bar-ref b { font-size: var(--fs-lg); line-height: 1.15; letter-spacing: -.02em; }

.inv-bar-facts {
  display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; flex: 1;
}
.fact { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fact i {
  font-style: normal; font-size: var(--fs-3xs); font-weight: var(--fw-bold); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.fact b { font-size: var(--fs-sm); font-weight: var(--fw-semi); white-space: nowrap; }
.fact span { font-size: var(--fs-2xs); }

.inv-bar-state {
  display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap;
  margin-inline-start: auto;
}

/* 2. line table — fixed column widths stop inputs from drifting */
.inv-lines th.c-type   { width: 130px; }
.inv-lines th.c-qty    { width: 92px; }
.inv-lines th.c-price  { width: 118px; }
.inv-lines th.c-total  { width: 110px; }
.inv-lines th.c-del    { width: 46px; }
.inv-lines td { padding: var(--sp-2) var(--sp-3); vertical-align: middle; }
.inv-lines td input, .inv-lines td select { height: var(--h-md); }
.inv-lines td:nth-child(3) input,
.inv-lines td:nth-child(4) input { text-align: end; }
.inv-lines tbody tr:hover { background: transparent; }

.foot-total { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink-2); }
.foot-total strong { font-size: var(--fs-lg); color: var(--ink); margin-inline: var(--sp-2) var(--sp-1); }

/* 3. payment rows — one grid so the columns line up down the stack */
.pay-rows { display: flex; flex-direction: column; gap: var(--sp-2); }
.pay-row {
  display: grid;
  grid-template-columns: 190px 170px 34px;
  gap: var(--sp-2);
  align-items: center;
}
.pay-row input { text-align: end; }

/* settlement verdict */
.settle {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--fs-xs);
}
.settle-ico { display: grid; place-items: center; width: var(--ico-sm); height: var(--ico-sm);
  flex: 0 0 28px; border-radius: 50%; background: var(--surface-sunk); color: var(--ink-2); }
.settle-ico svg { width: 16px; height: 16px; }
.settle-text { font-weight: var(--fw-semi); }

.settle-nums { margin-inline-start: auto; display: flex; gap: var(--sp-4); }
.settle-nums span { display: flex; flex-direction: column; gap: 1px; }
.settle-nums i {
  font-style: normal; font-size: var(--fs-3xs); font-weight: var(--fw-bold); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.settle-nums b { font-size: var(--fs-sm); }

.settle.ok  { background: var(--mint-soft); }
.settle.ok .settle-ico  { background: rgba(18,135,107,.18); color: var(--mint); }
.settle.ok .settle-text { color: var(--mint); }
.settle.due { background: var(--amber-soft); }
.settle.due .settle-ico  { background: rgba(165,98,18,.18); color: var(--amber); }
.settle.due .settle-text { color: var(--amber); }
/* تبرير تعطيل زر الإقفال — نصّ مرئي لا تلميح.
   الزر المعطَّل عليه `pointer-events: none` فلا يظهر `title` أصلاً،
   والموبايل بلا hover من الأساس. مبرِّرٌ لا يُقرأ إلا بالفأرة ليس
   مبرِّراً.

   بلا ظلّ: الظلّ في هذا النظام محجوز لما يطفو فعلاً (المودالات)، وأسطح
   المحتوى تُحدَّد بخطّ شعرة — انظر test_content_surfaces_carry_no_shadow. */
/* الشبكة اليومية — أعمدة للأطباء وصفوف للوقت.
   الارتفاع ثابت والمواضع بالنسبة المئوية، فتتناسب الكتلة مع مدة الموعد
   بلا حساب في القالب. */
.daygrid {
  /* يُعاد تعريفه من القالب بعدد أطباء اليوم. التعريف هنا ليس زينة:
     متغيّر يُستعمل بلا تعريف يسقط بصمت إلى `initial` — فتنهار الشبكة إلى
     عمود واحد بلا خطأ يشير إلى السبب. */
  --cols: 1;
  display: grid;
  grid-template-columns: 3.5rem repeat(var(--cols), minmax(7rem, 1fr));
  gap: var(--sp-1);
  height: 32rem;
  overflow: auto;
}
.dg-times { position: relative; }
.dg-hour {
  position: absolute; inset-inline-end: var(--sp-1);
  transform: translateY(-50%);
  font-size: var(--fs-3xs); color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.dg-col { display: flex; flex-direction: column; min-width: 0; }
.dg-head {
  position: sticky; top: 0; z-index: 1;
  padding: var(--sp-1) var(--sp-2);
  background: var(--surface); border-bottom: 1px solid var(--line);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dg-track {
  position: relative; flex: 1;
  border-inline-start: 1px solid var(--line);
}
/* خطّ الساعة شعرة لا ظلّ: الظلّ في هذا النظام محجوز لما يطفو فعلاً. */
.dg-line {
  position: absolute; inset-inline: 0; height: 1px;
  background: var(--line);
}
.dg-block {
  position: absolute; inset-inline: 2px;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  border-inline-start: 3px solid var(--primary);
  background: var(--primary-soft); color: var(--primary-ink);
  font-size: var(--fs-3xs); line-height: 1.25;
  overflow: hidden; text-decoration: none;
  min-height: 1.1rem;
}
.dg-block b { font-variant-numeric: tabular-nums; }
.dg-block span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dg-block.cancelled {
  border-inline-start-color: var(--ink-3);
  background: var(--surface-2); color: var(--ink-3);
  text-decoration: line-through;
}
.dg-block.att-attended { border-inline-start-color: var(--tone-ok-line); }
.dg-block.att-no_show  { border-inline-start-color: var(--tone-danger-line); }

@media (max-width: 720px) {
  /* على الموبايل الأعمدة تضيق حتى تصير غير مقروءة: نُبقيها قابلة للتمرير
     أفقياً بعرض أدنى بدل ضغطها. */
  .daygrid { grid-template-columns: 3rem repeat(var(--cols), 8rem); height: 26rem; }
}

/* تذييل الإصدار — يُقرأ عند الحاجة ويُتجاهَل يومياً.
   `--ink-3` أخفت درجات النصّ: المعلومة مرجعية لا محتوى. */
.app-foot {
  padding: var(--sp-4) var(--sp-4) var(--sp-5);
  text-align: center;
  color: var(--ink-3);
  font-size: var(--fs-3xs);
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}
.auth-foot { padding-block: var(--sp-3); }

/*  التذييل سطران: الإصدار وحقوق الملكية.
    يتجاوران على الشاشة العريضة ويتكدّسان على الموبايل — لا سطر واحد
    يُقَصّ ولا سطران يأكلان مساحة الشاشة الصغيرة.
    الاتجاه ltr على نصّ الحقوق وحده لأنه لاتيني: تركه للاتجاه العربي
    ينقل علامة @ إلى آخر السطر فيصير "Amr omran@copyrights". */
.app-foot { display: flex; flex-wrap: wrap; justify-content: center;
            align-items: center; gap: var(--sp-1) var(--sp-3); }
.foot-rights { color: var(--ink-3); }
.foot-rights::before { content: "·"; margin-inline-end: var(--sp-3);
                       opacity: .55; }
@media (max-width: 640px) {
  .app-foot { flex-direction: column; gap: var(--sp-1); }
  .foot-rights::before { content: none; margin: 0; }
}

.settle-why {
  margin: 0 0 var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  /* التوكنات الدلالية لا الألوان المباشرة: الوضع الليلي يعيد تعريفها
     (‎#d9a047 على ‎#2b2110)، فيتبعه التبرير تلقائياً بلا قاعدة ثانية. */
  border-inline-start: 3px solid var(--tone-warn-line);
  background: var(--tone-warn-bg);
  color: var(--tone-warn-ink);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  border-radius: var(--r-sm);
}
.settle-why[hidden] { display: none; }

.btn.is-blocked { opacity: .55; }

.settle.over { background: var(--rose-soft); }
.settle.over .settle-ico  { background: rgba(187,45,67,.18); color: var(--rose); }
.settle.over .settle-text { color: var(--rose); }

/* 4. commit bar */
.inv-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
  margin-top: var(--sp-4); padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.inv-actions .hint { margin: 0; max-width: 460px; }

@media (max-width: 700px) {
  .inv-bar-ref { border-inline-end: none; padding-inline-end: 0; }
  .inv-bar-state { margin-inline-start: 0; }
  .settle-nums { margin-inline-start: 0; width: 100%; justify-content: space-between; gap: var(--sp-2); }
  .pay-row { grid-template-columns: 1fr 1fr 34px; }
  .inv-actions { flex-direction: column; align-items: stretch; }
  .inv-actions .flex { justify-content: flex-end; }
}

/* Settings tiles */
.tile {
  display: block;
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color var(--speed), box-shadow var(--speed), transform var(--speed);
}
.tile:hover { border-color: var(--primary); box-shadow: var(--sh-2); transform: translateY(-1px); }
.tile-ico {
  display: grid; place-items: center;
  width: var(--h-lg); height: var(--h-lg); border-radius: 11px;
  background: var(--primary-soft); color: var(--primary-ink);
  margin-bottom: var(--sp-3);
}
.tile-ico svg { width: 21px; height: 21px; stroke: currentColor; }
.tile b { display: block; font-size: var(--fs-sm); margin-bottom: var(--sp-1); }
.tile p { margin: 0; font-size: var(--fs-2xs); color: var(--ink-2); line-height: 1.5; }

@media (max-width: 700px) {
  .cal-cell { min-height: 74px; padding: var(--sp-1); }
  .cal-ev { font-size: var(--fs-3xs); padding: 2px var(--sp-1); }
  .cal-head span { font-size: var(--fs-3xs); padding: var(--sp-2) 2px; }
}

@media print {
  .cal-cell { min-height: 78px; }
  .tile:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   18. Modal
   -------------------------------------------------------------------------- */
/* align-items:start rather than center: a dialog taller than the viewport
   would otherwise be centred and have its top clipped beyond reach. */
.modal {
  position: fixed; inset: 0; z-index: 120;
  display: grid; justify-items: center; align-items: start;
  padding: var(--sp-4);
  overflow-y: auto;
}
.modal[hidden] { display: none; }
.modal-scrim {
  position: absolute; inset: 0;
  background: rgba(8,22,32,.5);
  backdrop-filter: blur(2px);
  animation: fade-in .16s ease;
}
.modal-box {
  position: relative;
  width: 100%; max-width: 560px;
  max-height: calc(100vh - 40px);
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-3);
  animation: modal-in .2s cubic-bezier(.2,.9,.3,1);
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line);
}
.modal-head h2 { font-size: var(--fs-sm); display: flex; align-items: center; gap: var(--sp-2); }
.modal-head h2 svg { width: 17px; height: 17px; stroke: var(--ink-2); }
/* The <form> sits between the box and the body, so it is the real flex item.
   Without it stretching and shrinking, the body cannot scroll and the footer
   is pushed past the bottom of the screen — the buttons become unreachable. */
.modal-box > form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
}

/* min-height:0 is the part that matters: a flex item defaults to min-height
   auto, which refuses to shrink below its content, so overflow never kicks in. */
.modal-body {
  padding: var(--sp-4);
  overflow-y: auto;
  min-height: 0;
  flex: 1 1 auto;
  overscroll-behavior: contain;
}
.modal-foot {
  display: flex; justify-content: flex-end; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  flex: 0 0 auto;          /* never shrink: this holds Save */
}
.modal-head { flex: 0 0 auto; }
@keyframes fade-in { from { opacity: 0; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }

/* --------------------------------------------------------------------------
   19. Scope bar — one filter surface shared by every module
   -------------------------------------------------------------------------- */
/* شريط النطاق صار في الشريط العلوي: كان لوحة كاملة بعرض الشاشة أعلى كل
   صفحة لشيء يُغيَّر مرّة في اليوم، تدفع المحتوى لأسفل الطيّة. الآن ضوابط
   مضغوطة في مكان الأدوات، والصفحة تبدأ بما جاء المستخدم لأجله. */
.scopebar {
  display: flex; align-items: center; gap: var(--sp-1);
  margin: 0; padding: 0; background: none; border: 0;
}
.scopebar .scope-dates { gap: var(--sp-1); }
.scopebar input[type=date] { height: var(--h-sm); font-size: var(--fs-2xs); }
.scopebar .btn { height: var(--h-sm); }
@media (max-width: 1100px) { .scopebar .scope-dates { display: none; } }

.scope-pick { position: relative; }
.scope-pick > summary {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  cursor: pointer; list-style: none; white-space: nowrap;
}
.scope-pick > summary::-webkit-details-marker { display: none; }
.scope-pick > summary:hover { border-color: var(--primary); color: var(--primary-ink); }
.scope-pick > summary svg { width: 16px; height: 16px; stroke: currentColor; }
.scope-pick[open] > summary { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-ink); }

.scope-menu {
  position: absolute; z-index: 60; top: calc(100% + 6px); inset-inline-start: 0;
  min-width: 230px; max-height: 300px; overflow-y: auto;
  padding: var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  box-shadow: var(--sh-3);
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.scope-menu-head { display: flex; gap: var(--sp-1); padding-bottom: var(--sp-1); border-bottom: 1px solid var(--line); margin-bottom: var(--sp-1); }
.scope-menu .check { border-color: transparent; }

.scope-dates { display: flex; align-items: center; gap: var(--sp-2); }
.scope-dates .datefield { width: auto; }
.scope-dates input { width: 100%; height: var(--h-sm); }

@media (max-width: 700px) {
  .scopebar { gap: var(--sp-2); }
  .scope-dates { width: 100%; }
  .scope-dates .datefield { flex: 1; width: auto; }
}

@media print { .scopebar { display: none !important; } }

/* --------------------------------------------------------------------------
   20. Date inputs

   Two separate problems, two separate fixes:

   (a) ORDER. Chrome lays the segments out inside its own shadow DOM. In an
       RTL page the Arabic hint يوم/شهر/سنة comes out reversed as
       ةنس/رهش/موي. Setting direction on the <input> is not enough — the
       inner ::-webkit-datetime-edit wrapper has to be forced LTR too.

   (b) WORDING. Chrome takes the placeholder text from the *browser's*
       locale and ignores the element's lang attribute, so an Arabic Chrome
       always writes Arabic there. The only reliable way to show dd/mm/yyyy
       is to hide Chrome's text while the field is empty and paint our own.
       Once a date is picked the field shows digits, which read the same in
       both languages.
   -------------------------------------------------------------------------- */
input[type="date"],
input[type="datetime-local"],
input[type="time"],
input[type="month"] {
  direction: ltr;
  font-variant-numeric: tabular-nums;
}
/* المحاذاة يسار حتى في صفحة rtl: محتوى الحقل dd/mm/yyyy إنجليزيّ ltr،
   ودفعُه يميناً كان يضعه في بقعة أيقونة التقويم فيتراكبان. يساراً يبقى
   نطاق الأرقام ونطاق الأيقونة منفصلين تماماً. */
[dir="rtl"] input[type="date"],
[dir="rtl"] input[type="datetime-local"],
[dir="rtl"] input[type="time"],
[dir="rtl"] input[type="month"] { text-align: left; }

/* (a) force the inner editor LTR so segments never reverse */
input[type="date"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit,
input[type="month"]::-webkit-datetime-edit,
input[type="date"]::-webkit-datetime-edit-fields-wrapper,
input[type="datetime-local"]::-webkit-datetime-edit-fields-wrapper {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: left;
}

/* (b) our own placeholder, shown only while the field has no value */
/* الغلاف صفٌّ أفقي: الحقل ثم زرّ التقويم، صندوقان متجاوران لا متراكبان.
   هذا هو الفصل المادّي: لا يمكن لأحدهما أن يدخل مساحة الآخر لأنهما
   عنصران مستقلّان في التخطيط لا طبقتان في صندوق واحد. */
.datefield {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  width: 100%;
}
.datefield > input { width: 100%; min-width: 0; flex: 1 1 auto; }

/* أيقونة المتصفح تُخفى تماماً — صار لها بديلٌ خارج الحقل. إخفاؤها هو ما
   يحرّر مساحة الحقل للأرقام وحدها. */
.datefield > input::-webkit-calendar-picker-indicator {
  display: none;
  -webkit-appearance: none;
  appearance: none;
}

/* زرّ التقويم: هدف لمس مستقلّ بمساحته الخاصة */
.datefield-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-md);
  height: var(--h-md);
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: background var(--speed), border-color var(--speed), color var(--speed);
}
.datefield-btn svg { width: 17px; height: 17px; stroke: currentColor; }
.datefield-btn:hover { border-color: var(--primary); color: var(--primary-ink); background: var(--surface-2); }
/* في شريط النطاق المضغوط يصغر الزرّ مع الحقل */
.scopebar .datefield-btn, .scope-dates .datefield-btn {
  width: var(--h-sm); height: var(--h-sm);
}
.scopebar .datefield-btn svg, .scope-dates .datefield-btn svg { width: 15px; height: 15px; }

.datefield[data-empty="true"] > input::-webkit-datetime-edit {
  color: transparent;      /* hide Chrome's localized hint */
}
/* موضع النائب: يُحسب من حافة الحقل لا من حافة الغلاف.

   الغلاف صار يضمّ الحقل والزرّ معاً، فقياس النائب منه كان يخرجه عن حدود
   الحقل ليركب على الزرّ. نجعل الحقل نفسه مرجع التموضع: نائبٌ داخل صندوق
   الأرقام دائماً، والزرّ في صندوقه — فلا تلامس.

   يُثبَّت يساراً لا بـ inset-inline-start: محتواه "dd/mm/yyyy" إنجليزيّ
   ltr ومكانه الطبيعي اليسار، بينما inset-inline-start يتبع اتجاه الصفحة
   (rtl) فيقذفه يميناً. */
.datefield { --ph-inset: var(--sp-3); }
.datefield[data-empty="true"]::before {
  content: attr(data-hint);
  position: absolute;
  left: var(--ph-inset);
  right: auto;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--ink-3);
  font-size: var(--fs-xs);
  font-family: var(--font-ui);
  direction: ltr;
  white-space: nowrap;
  z-index: 1;
}
/* الزرّ يسبق الحقل في الصفّ، فالنائب يُزاح بعرض الزرّ وفجوته ليقع داخل
   صندوق الأرقام لا فوق الزرّ. */
.datefield[data-empty="true"] { --ph-inset: calc(var(--h-md) + var(--sp-1) + var(--sp-3)); }
.scopebar .datefield[data-empty="true"],
.scope-dates .datefield[data-empty="true"] {
  --ph-inset: calc(var(--h-sm) + var(--sp-1) + var(--sp-3));
}
/* While typing, Chrome's segments must be visible again */
.datefield[data-empty="true"] > input:focus::-webkit-datetime-edit { color: var(--ink); }
.datefield[data-empty="true"]:focus-within::before { display: none; }

/* --------------------------------------------------------------------------
   21. Page-level primary action
   -------------------------------------------------------------------------- */
.page-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); }

.btn-lg {
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  border-radius: var(--r);
  gap: var(--sp-2);
}
.btn-lg svg { width: 19px; height: 19px; }
/* الزرّ الكبير لا يشذّ عن القاعدة: الظلّ محجوز لما يطفو، والزرّ يُميَّز
   بلونه ومساحته لا بارتفاعه. وظلّه القديم كان كحلياً على زرّ ذهبي. */

@media (max-width: 560px) {
  .page-actions .btn-lg { width: 100%; }
}
@media print { .page-actions { display: none !important; } }

/* --------------------------------------------------------------------------
   22. Password field with reveal toggle
   -------------------------------------------------------------------------- */
.pwfield { position: relative; display: block; }
.pwfield > input {
  width: 100%;
  /* room for the eye button on the trailing side */
  padding-inline-end: var(--sp-6);
}

.pw-toggle {
  position: absolute;
  inset-inline-end: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: var(--ico);
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: color var(--speed), background var(--speed);
}
.pw-toggle svg { width: 17px; height: 17px; }
.pw-toggle:hover { color: var(--primary); background: var(--surface-2); }
.pw-toggle[aria-pressed="true"] { color: var(--primary); }

/* The browser's own reveal control would sit on top of ours */
.pwfield > input::-ms-reveal,
.pwfield > input::-ms-clear { display: none; }

@media print { .pw-toggle { display: none !important; } }


.settle {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding: var(--sp-3) var(--sp-3);
  border-radius: var(--r);
  border: 1px solid var(--line);
  border-inline-start-width: 3px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
}
.settle .settle-ico { display: inline-flex; }
.settle svg { width: 18px; height: 18px; stroke: currentColor; }

/* Only one of the two icons shows, depending on state */
.settle.ok    { background: var(--mint-soft); border-inline-start-color: var(--mint); color: var(--mint); }
.settle.due   { background: var(--rose-soft); border-inline-start-color: var(--rose); color: var(--rose); }
.settle.over  { background: var(--amber-soft); border-inline-start-color: var(--amber); color: var(--amber); }
.settle.ok  .settle-ico svg:first-child { display: none; }
.settle.due .settle-ico svg:last-child,
.settle.over .settle-ico svg:last-child { display: none; }

@media (max-width: 560px) {
}

/* --------------------------------------------------------------------------
   23. Fixed (non-editable) value shown in place of a form control
   -------------------------------------------------------------------------- */
.fixed-val {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--h-md);
  padding: var(--sp-2) var(--sp-3);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  color: var(--ink);
}
.fixed-val .tag { font-weight: var(--fw-semi); }

/* --------------------------------------------------------------------------
   24. Accounting ledgers
   Accounting screens read as columns of figures, so they get tighter rows,
   tabular numerals everywhere, and account-type colour coding.
   -------------------------------------------------------------------------- */

/* Balance verdict banner — the first thing to read on a trial balance */
.ledger-check {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--mint);
  background: var(--surface);
}
.ledger-check.bad { border-inline-start-color: var(--rose); background: var(--rose-soft); }
.ledger-check b { display: block; font-size: var(--fs-sm); }
.ledger-check p { margin: 2px 0 0; font-size: var(--fs-2xs); color: var(--ink-2); }

.lc-ico {
  display: grid; place-items: center;
  width: var(--h-md); height: var(--h-md); flex: 0 0 var(--h-md);
  border-radius: 50%;
  background: var(--mint-soft); color: var(--mint);
}
.lc-ico svg { width: 19px; height: 19px; }
.ledger-check.bad .lc-ico { background: var(--rose-soft); color: var(--rose); }

.lc-nums { margin-inline-start: auto; display: flex; gap: var(--sp-5); }
.lc-nums span { display: flex; flex-direction: column; gap: 2px; }
.lc-nums i {
  font-style: normal; font-size: var(--fs-3xs); font-weight: var(--fw-semi); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.lc-nums b { font-size: var(--fs-md); }

/* Account type chips */
.tag.acct-asset     { background: var(--primary-soft); color: var(--primary-ink); }
.tag.acct-liability { background: var(--amber-soft);   color: var(--amber); }
.tag.acct-equity    { background: var(--violet-soft);  color: var(--violet); }
.tag.acct-revenue   { background: var(--mint-soft);    color: var(--mint); }
.tag.acct-expense   { background: var(--rose-soft);    color: var(--rose); }

/* Totals row */
tfoot .tfoot-total td {
  background: var(--surface-sunk);
  font-weight: var(--fw-bold);
  border-top: 2px solid var(--line-strong);
  border-bottom: none;
}

/* Opening-balance row in a ledger */
.row-opening td {
  background: var(--surface-2);
  font-weight: var(--fw-semi);
  color: var(--ink-2);
  font-size: var(--fs-2xs);
}

/* Journal: each entry is a self-contained block, not a flat row */
.jentry { border-bottom: 1px solid var(--line); }
.jentry:last-child { border-bottom: none; }

.jentry-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  font-size: var(--fs-xs);
}

.jentry-lines { width: 100%; }
.jentry-lines td {
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-xs);
  border-bottom: 1px dashed var(--line);
}
.jentry-lines tr:last-child td { border-bottom: none; }
/* A credit line is indented so the debit/credit shape is visible at a glance */
.jentry-lines td:nth-child(2) { padding-inline-start: var(--sp-4); }

@media (max-width: 700px) {
  .lc-nums { margin-inline-start: 0; width: 100%; justify-content: space-between; }
  .jentry-head { font-size: var(--fs-2xs); }
}

@media print {
  .ledger-check { box-shadow: none; border: 1px solid #bbb; }
  .jentry { break-inside: avoid; page-break-inside: avoid; }
  .jentry-head { background: var(--print-fill) !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}


.lane {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
/* The primary lane is marked structurally, not just by colour */
.lane-primary { border-color: var(--primary); box-shadow: var(--sh-2); }

.lane-head { display: flex; align-items: flex-start; gap: var(--sp-3); }
.lane-head b { display: block; font-size: var(--fs-sm); }
.lane-head p { margin: var(--sp-1) 0 0; font-size: var(--fs-2xs); color: var(--ink-2); line-height: 1.45; }

.lane-ico {
  display: grid; place-items: center;
  width: var(--h-md); height: var(--h-md); flex: 0 0 var(--h-md);
  border-radius: 10px;
  background: var(--primary-soft); color: var(--primary-ink);
}
.lane-ico svg { width: 18px; height: 18px; }
.lane-ico.alt { background: var(--surface-sunk); color: var(--ink-2); }

.lane-body { display: flex; gap: var(--sp-2); align-items: center; margin-top: auto; }
.lane-body input { flex: 1; min-width: 0; }
.lane-body .btn { flex-shrink: 0; }

@media (max-width: 560px) {
  .lane-body { flex-wrap: wrap; }
  .lane-body .btn { width: 100%; }
}
@media print { .entry-lanes { display: none !important; } }

/* The booking lookup is the only lane left, so it spans the row */
.lane-solo { margin-bottom: var(--sp-4); }
.lane-solo .lane-body { display: block; }

.bk-field { position: relative; }
.bk-field > input[type=search] { width: 100%; }

.bk-results {
  position: absolute;
  inset-inline: 0;
  top: calc(100% + 6px);
  z-index: 40;
  max-height: 340px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-1);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  box-shadow: var(--sh-3);
}
.bk-results[hidden] { display: none; }

/*  حقل البحث يحتاج موضعاً نسبياً حتى تنسدل نتائجه تحته لا تحت الصفحة. */
.field.lookup { position: relative; }

.bk-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.bk-row:hover, .bk-row.is-active { background: var(--primary-soft); }

.bk-no {
  flex: 0 0 auto;
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  color: var(--primary-ink);
}
.bk-mid { flex: 1; min-width: 0; }
.bk-name {
  display: block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bk-sub {
  display: block;
  font-size: var(--fs-2xs);
  color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bk-right {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: var(--sp-2);
  text-align: end;
}
.bk-due { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--rose); white-space: nowrap; }

.bk-note {
  padding: var(--sp-4) var(--sp-3);
  text-align: center;
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

@media (max-width: 560px) {
  .bk-right { flex-direction: column; align-items: flex-end; gap: var(--sp-1); }
  .bk-sub { white-space: normal; }
}
@media print { .lane-solo { display: none !important; } }

/* --------------------------------------------------------------------------
   26. Brand identity — Dr. Yehia Taher

   The gold (#F7C51A) is the clinic's signage colour, but it fails contrast
   badly as UI text: roughly 1.7:1 on white, where 4.5:1 is the floor. It is
   also already spoken for semantically — amber means "warning" throughout
   this system (pending collection, low stock, outstanding balance).

   So the gold is used for identity surfaces only: the login screen, the
   logo itself, and thin accents. The medical blue stays the working colour
   of the interface, and warnings keep their amber.
   -------------------------------------------------------------------------- */
:root {
  --brand-gold: #f7c51a;
  --brand-gold-deep: #886b00;   /* 4.56:1 on paper, 5.06:1 on white — clears AA */
  --brand-black: #0b0b0b;
}

/* --- sidebar lockup --- */
.brand {
  display: grid;
  place-items: center;
  width: var(--h-lg);
  height: var(--h-lg);
  flex: 0 0 40px;
  border-radius: 10px;
}
.brand img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* الرِّف داكن دائماً، فالنسخة الذهبية من اللوجو هي الصحيحة في الوضعين —
   لا تبديل بحسب السمة بعد اليوم. */
.brand .brand-ink { display: none; }
.brand .brand-gold { display: block; }

/* الخيط الذهبي تحت اللوجو لم يعد ضرورياً: الذهب صار في مؤشّر الصفحة
   النشطة وفي الصورة الرمزية، وتكراره تحت اللوجو يجعله زينة لا إشارة. */
.side-head { border-bottom: 1px solid var(--rail-line); position: relative; }

/* --- login --- */
.auth {
  background:
    radial-gradient(900px 480px at 82% -12%, rgba(247,197,26,.14), transparent 62%),
    /* كان أزرق من اللوحة القديمة بجوار الذهب في نفس التدرّج — خلفيةٌ
       نصفها هوية جديدة ونصفها قديمة، وهو ما يُقرأ «غير مضبوط» بلا أن
       يعرف الناظر السبب. */
    radial-gradient(900px 500px at 8% 112%, rgba(15,35,51,.30), transparent 62%),
    var(--auth-deep);
}
/* Brand band: the logo keeps its own black backing, so the gold is read at
   12:1 instead of the 1.6:1 it would get against the white card. */
.auth-brand {
  margin: -32px -30px 20px;
  padding: var(--sp-5) var(--sp-4) var(--sp-5);
  background: var(--brand-black);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  border-bottom: 3px solid var(--brand-gold);
  text-align: center;
}
.auth-brand img { width: 128px; height: auto; display: inline-block; }
.auth-trace path { stroke: var(--brand-gold); }

/* --- print masthead --- */
.print-head .ph-logo { width: 90px; height: auto; }
.print-head .ph-row { border-bottom: 2px solid var(--brand-black); }

/* --- accents that use gold without hurting legibility --- */
.tag.brand { background: rgba(247,197,26,.18); color: var(--brand-gold-deep); }
[data-theme="dark"] .tag.brand { background: rgba(247,197,26,.16); color: var(--brand-gold); }

@media print {
}

/* --------------------------------------------------------------------------
   27. Error detail — the cause, not just an apology
   -------------------------------------------------------------------------- */
.err-hint {
  display: flex; align-items: center; gap: var(--sp-2); justify-content: center;
  margin: 0 0 var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--amber-soft);
  color: var(--amber);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
}
.err-detail {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--surface-sunk);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-align: start;
  direction: ltr;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 160px;
  overflow: auto;
}

/* --------------------------------------------------------------------------
   28. Scheduling — day agenda and denser month cells

   A month cell showed every booking at equal weight, so a day with eight
   appointments looked like a day with one and the cell overflowed. Cells now
   show three and link the rest into the day view, and the day number carries
   a count so load is visible at a glance.
   -------------------------------------------------------------------------- */
.cal-day {
  display: flex; align-items: center; gap: var(--sp-1);
  align-self: flex-start;
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--ink-2);
  border-radius: var(--r-pill);
  padding: 1px var(--sp-1);
}
.cal-day:hover { background: var(--primary-soft); color: var(--primary-ink); }

.cal-count {
  display: inline-grid; place-items: center;
  min-width: 17px; height: 17px; padding: 0 var(--sp-1);
  border-radius: var(--r-pill);
  background: var(--primary); color: #fff;
  font-size: var(--fs-3xs); font-weight: var(--fw-bold);
}
.cal-cell.has-events { background: color-mix(in srgb, var(--primary-soft) 40%, transparent); }
.cal-cell.today.has-events { background: var(--primary-soft); }

.cal-more {
  font-size: var(--fs-3xs); font-weight: var(--fw-semi); color: var(--primary-ink);
  padding: 1px var(--sp-1); border-radius: 5px;
}
.cal-more:hover { background: var(--primary-soft); }

/* --- day agenda --- */
.agenda { display: flex; flex-direction: column; }
.agenda-head {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--fs-sm);
}

/* ---------- العرض الأسبوعي ----------
   سبعة أيام متتالية بنفس سطر الموعد (`.slot`) المستعمل في العرض اليومي.
   اليوم الفارغ يُعرض فارغاً ولا يُطوى: الفراغ هو المعلومة التي يبحث
   عنها الاستقبال، وطيُّه يخفي ما جاء المستخدم ليراه. */
.agenda-week { display: flex; flex-direction: column; }

.wk-day + .wk-day { border-top: 2px solid var(--line); }

.wk-day-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  background: var(--surface-2);
  font-size: var(--fs-sm);
}
.wk-day-head b { color: var(--ink); }
.wk-day-head a { color: var(--ink-3); text-decoration: none; }
.wk-day-head a:hover { color: var(--primary-ink); text-decoration: underline; }

/* شريط على حافّة اليوم الحالي — علامةٌ تُلتقط بالطرف لا لونُ خلفية
   يتنازع مع ألوان حالات المواعيد داخله. */
.wk-day.is-today .wk-day-head {
  box-shadow: inset 3px 0 0 var(--primary);
}

.wk-empty {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
}

.slot {
  display: grid;
  grid-template-columns: 92px 1fr auto auto;
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  border-inline-start: 3px solid var(--primary);
}
.slot:last-child { border-bottom: none; }
.slot.cancelled { border-inline-start-color: var(--rose); opacity: .6; }
.slot.completed { border-inline-start-color: var(--mint); }
.slot.no-show   { border-inline-start-color: var(--amber); background: var(--amber-soft); }

.slot-time { display: flex; flex-direction: column; line-height: 1.25; }
.slot-time b { font-size: var(--fs-sm); }
.slot-time span { font-size: var(--fs-2xs); }

.slot-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.slot-body b { font-size: var(--fs-sm); }
.slot-body span { font-size: var(--fs-2xs); }

.slot-actions { display: flex; gap: var(--sp-1); flex-wrap: wrap; }
.slot-actions form { display: inline; }

@media (max-width: 700px) {
  .slot { grid-template-columns: 74px 1fr; row-gap: var(--sp-2); }
  .slot-state, .slot-actions { grid-column: 1 / -1; }
}
@media print {
  .slot-actions { display: none !important; }
  .slot { break-inside: avoid; }
}

/* --------------------------------------------------------------------------
   29. Doctor working days — a branch and its days read as one unit
   -------------------------------------------------------------------------- */
.branch-days { display: flex; flex-direction: column; gap: var(--sp-2); }

.bd-row {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}
/* The days only matter once the branch is ticked — dim them until then. */
.bd-row:has(.bd-branch input:not(:checked)) .bd-days { opacity: .45; }
.bd-row:has(.bd-branch input:checked) {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.bd-branch { min-width: 165px; border-color: transparent; background: transparent; }
.bd-days { display: flex; gap: var(--sp-1); flex-wrap: wrap; }

.daychip { position: relative; cursor: pointer; }
.daychip input {
  position: absolute; opacity: 0; width: 0; height: 0;
}
.daychip span {
  display: grid; place-items: center;
  min-width: 42px; padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--ink-2);
  transition: background var(--speed), color var(--speed), border-color var(--speed);
}
.daychip:hover span { border-color: var(--primary); color: var(--primary-ink); }
.daychip input:checked + span {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.daychip input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }

@media (max-width: 560px) {
  .bd-row { flex-direction: column; align-items: stretch; }
  .daychip span { min-width: 38px; }
}

/* --------------------------------------------------------------------------
   30. System rule switches
   -------------------------------------------------------------------------- */
.flagrow {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color var(--speed), background var(--speed);
}
.flagrow + .flagrow { margin-top: var(--sp-2); }
.flagrow:hover { border-color: var(--primary); }
.flagrow input { position: absolute; opacity: 0; width: 0; height: 0; }

.flagbox {
  flex: 0 0 42px; width: 42px; height: var(--box);
  margin-top: 2px;
  border-radius: var(--r-pill);
  background: var(--line-strong);
  position: relative;
  transition: background var(--speed);
}
.flagbox::after {
  content: "";
  position: absolute; top: 3px; inset-inline-start: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff;
  transition: transform var(--speed);
}
.flagrow input:checked ~ .flagbox { background: var(--mint); }
.flagrow input:checked ~ .flagbox::after { transform: translateX(18px); }
[dir="rtl"] .flagrow input:checked ~ .flagbox::after { transform: translateX(-18px); }
.flagrow input:focus-visible ~ .flagbox { outline: 2px solid var(--primary); outline-offset: 2px; }

.flagtext b { display: block; font-size: var(--fs-sm); }
.flagtext span { font-size: var(--fs-2xs); color: var(--ink-2); line-height: 1.5; }

/* --------------------------------------------------------------------------
   31. Searchable selects
   The native <select> stays in the DOM as the single source of truth — it
   still submits, still validates, still gets read and written by the rest of
   the JS. What changes is only what the eye sees: the select is laid flat and
   made transparent underneath a button that shows the current label, and one
   shared popup does the filtering for every field on the page.

   Rendering it transparent rather than display:none is deliberate: a hidden
   required control makes the browser refuse to submit with "not focusable",
   and the constraint bubble loses its anchor.
   -------------------------------------------------------------------------- */
.sselect { position: relative; display: block; width: 100%; }

.sselect > select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
  background: none;
}

.sselect-face {
  width: 100%;
  height: var(--h-md);
  padding: var(--sp-2) var(--sp-3);
  padding-inline-end: var(--sp-6);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-xs);
  text-align: start;
  cursor: text;
  transition: border-color var(--speed), box-shadow var(--speed);

  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2352697d' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 15px;
  background-position: right 9px center;
}
[dir="rtl"] .sselect-face { background-position: left 9px center; }
[data-theme="dark"] .sselect-face {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239db1c2' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* The prompt ("Choose a doctor…") is a placeholder now, not a value:
   leaving it as real text means the first keystroke has to delete it. */
.sselect-face::placeholder { color: var(--ink-3); opacity: 1; }
.sselect.is-open .sselect-face { cursor: text; }

.sselect-face:hover { border-color: var(--primary); }
.sselect-face:focus,
.sselect.is-open .sselect-face {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}
.sselect.is-invalid .sselect-face { border-color: var(--rose); }
.sselect.is-invalid .sselect.is-invalid .sselect-face:focus { box-shadow: 0 0 0 3px var(--rose-soft); }

/* رسالة خطأ القائمة. لا تُضمّ إليها .sselect-face.is-empty: تلك حالةُ
   حقلٍ فارغ لا رسالةَ خطأ، وضمُّها يمنحها display:block ولوناً أحمر
   ومقاس خطٍّ أصغر فينهار تنسيق الواجهة. */
.sselect-err {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  color: var(--rose);
}

/* ---- the shared popup ---------------------------------------------------- */
.sspop {
  position: fixed;
  z-index: 120;
  display: flex;
  flex-direction: column;
  max-height: 320px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  box-shadow: var(--sh-3);
  overflow: hidden;
}
.sspop[hidden] { display: none; }

.sspop-list {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-1);
  margin: 0;
  list-style: none;
  -webkit-overflow-scrolling: touch;
}

.sspop-opt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sspop-opt:hover,
.sspop-opt.is-active { background: var(--primary-soft); color: var(--primary-ink); }
.sspop-opt.is-picked { font-weight: var(--fw-bold); }
.sspop-opt.is-picked::after {
  content: "";
  flex: 0 0 14px;
  height: 14px;
  margin-inline-start: auto;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
}

.sspop-group {
  padding: var(--sp-2) var(--sp-2) var(--sp-1);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
  letter-spacing: .3px;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sspop-none {
  padding: var(--sp-4) var(--sp-3);
  text-align: center;
  font-size: var(--fs-xs);
  color: var(--ink-3);
}
.sspop-count[hidden] { display: none; }
.sspop-count {
  flex: 0 0 auto;
  padding: var(--sp-1) var(--sp-2);
  border-top: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  text-align: center;
}

/* Phones: a bottom sheet beats a 200px popup pinned to a tiny field */
.sspop.is-sheet {
  inset-inline: 8px;
  bottom: 8px;
  top: auto;
  width: auto !important;
  max-height: 62vh;
  border-radius: var(--r-lg);
}

.sspop-veil {
  position: fixed;
  inset: 0;
  z-index: 119;
  background: transparent;
}
.sspop-veil[hidden] { display: none; }
.sspop-veil.is-dim { background: rgba(15, 35, 51, .28); }

/* ---- fitting into the layouts that used to size a <select> --------------- */
.inv-lines td .sselect-face { height: var(--h-md); }
.pay-row .sselect-face { height: var(--h-md); }

@media print {
  .sspop, .sspop-veil { display: none !important; }
  .sselect-face {
    border-color: var(--line);
    background-image: none;
    padding-inline-end: var(--sp-3);
  }
}


/* --------------------------------------------------------------------------
   32. Settlement grid — one cell per account the money belongs to
   Money in the drawer, money Valu owes and money the case owes are three
   different balances closing three different accounts. One merged figure
   was what let a 5,000 invoice report 8,000 paid.
   -------------------------------------------------------------------------- */
.settle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--sp-2);
}
.settle-cell {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line-strong);
  border-radius: var(--r);
}
.settle-cell span { font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--ink-2); }
.settle-cell strong { font-size: var(--fs-lg); }
.settle-cell.ok  { border-inline-start-color: var(--mint); }
.settle-cell.warn { border-inline-start-color: var(--amber); background: var(--amber-soft); }
.settle-cell.bad { border-inline-start-color: var(--rose); background: var(--rose-soft); }


/* --------------------------------------------------------------------------
   33. Menu contents — the admin's control over what the sidebar shows
   -------------------------------------------------------------------------- */
.menu-tree { display: grid; gap: var(--sp-3); }
.menu-grp {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2);
}
.menu-grp > .flagrow > .flagtext b { display: flex; align-items: center; gap: var(--sp-2); }
.menu-grp > .flagrow > .flagtext b svg { width: 16px; height: 16px; color: var(--ink-2); }

.menu-kids {
  display: grid;
  gap: 2px;
  margin-top: var(--sp-2);
  padding-inline-start: var(--sp-5);
  border-inline-start: 2px solid var(--line);
}
.menu-kids .flagrow { padding: var(--sp-1) var(--sp-2); }
.menu-kids .flagrow .flagtext b { font-weight: var(--fw-semi); font-size: var(--fs-xs); }
/* A screen the admin cannot open is still listed and still toggleable —
   they decide what the clinic's menu shows, not only their own. */
.flagrow.is-muted .flagtext b { color: var(--ink-3); }

/* Always-on modules: shown, explained, and not toggleable — the settings
   screen is what turns the others back on, so it cannot turn itself off. */
.flagrow.is-locked { opacity: .72; }
.flagrow.is-locked .flagbox { border-style: dashed; cursor: not-allowed; }


/* ============================================================================
   34. النبرة والمقاسات — الطبقة الثالثة

   كل كلاس هنا وُلد من `style=` مكتوب بالإيد في قالب. الـ93 التي كانت في
   القوالب لم تكن كسلاً: كل واحدة بلاغ عن أداة ناقصة في النظام، فمن كتبها
   لم يجد الأداة فاخترع واحدة. هذه هي الأدوات.
   ============================================================================ */

/* ---- النبرة: تصف المعنى لا الشكل ------------------------------------- */
/* القالب كان يقول style="border-color:var(--rose)" — وصفُ لون. يقول الآن
   class="tone-danger" — وصفُ معنى، فيتغيّر لون الخطر من مكان واحد. */
.tone-info,
.tone-ok,
.tone-warn,
.tone-danger { border-color: var(--tone-line); }
.tone-info   { --tone-line: var(--tone-info-line);   --tone-fill: var(--tone-info-bg);   --tone-text: var(--tone-info-ink); }
.tone-ok     { --tone-line: var(--tone-ok-line);     --tone-fill: var(--tone-ok-bg);     --tone-text: var(--tone-ok-ink); }
.tone-warn   { --tone-line: var(--tone-warn-line);   --tone-fill: var(--tone-warn-bg);   --tone-text: var(--tone-warn-ink); }
.tone-danger { --tone-line: var(--tone-danger-line); --tone-fill: var(--tone-danger-bg); --tone-text: var(--tone-danger-ink); }

/* الحشوة الملوّنة تُطلب صراحةً: لوحة بنبرة خطر ليست بالضرورة ملوّنة
   الخلفية، والجمع بينهما تلقائياً يجعل كل تحذير صرخة. */
.tone-fill { background: var(--tone-fill); }

/* ---- عروض معيارية ----------------------------------------------------- */
/* كانت 17 مرة max-width بالإيد بقيم 110 و120 و130 و150 و170 و190 و220
   و240 — أي أن حقلين متجاورين بنفس الغرض يختلفان بعشرين بكسل بلا سبب. */
.w-xs { max-width: var(--w-xs); }
.w-sm { max-width: var(--w-sm); }
.w-md { max-width: var(--w-md); }
.w-lg { max-width: var(--w-lg); }
.w-grow { flex: 1; min-width: var(--w-md); }
.w-full { width: 100%; }

/* ---- ترتيب الصفوف ----------------------------------------------------- */
/* align-items:flex-end تكرّرت 6 مرات — كلها صفُّ حقول ينتهي بزرّ، والزرّ
   يجب أن يحاذي أسفل الحقول لا منتصفها. هذا نمط، فليكن له اسم. */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: flex-end;
}

/* ---- الجداول الطويلة --------------------------------------------------- */
.scroll-md { max-height: 420px; overflow-y: auto; }

/* ---- حاشية أسفل اللوحة ------------------------------------------------- */
/* padding:0 16px 14px تكرّرت 4 مرات: نصّ توضيحي تحت نموذج داخل لوحة. */
.panel-note { padding: 0 var(--sp-4) var(--sp-3); }

/* ---- بقيّة الأنماط المتكرّرة في القوالب ------------------------------- */
/* لوحة نموذج بعرض قراءة مريح — تكرّرت 3 مرات كـ max-width:760px */
.form-page { max-width: 760px; }
.auth-page { max-width: 460px; }

/* حشوة صفٍّ داخل لوحة (14px 16px تكرّرت) */
.pad-row { padding: var(--sp-3) var(--sp-4); }
.pad-row-top { border-top: 1px solid var(--line); }

/* نصّ مساعد صغير داخل خليّة أو وسم */
.txt-2xs { font-size: var(--fs-2xs); }
.txt-xs  { font-size: var(--fs-xs); }
.txt-md  { font-size: var(--fs-md); }

/* عيّنة لون في مفتاح الرسوم — اللون نفسه يأتي من متغيّر يضبطه القالب */
.key-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--dot); }

.stack   { display: flex; flex-direction: column; gap: var(--sp-2); }
.center-row { display: flex; justify-content: center; gap: var(--sp-6); flex-wrap: wrap; }
.inline  { display: inline; }
.no-top  { margin-top: 0; }
.sunk    { background: var(--surface-2); }

/* شبكة بطاقات تتكيّف مع العرض — تكرّرت في شاشتين */
.auto-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--sp-3); }
/* صفّ نبرة: شريط ملوّن أعلى لوحة، بمحتوى يلتفّ */
.tone-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; background: var(--tone-fill); }
/* ملخّص <details> قابل للنقر بنبرة */
.tone-summary { padding: var(--sp-3) var(--sp-4); cursor: pointer; font-weight: var(--fw-bold); color: var(--tone-line); }
.w-2xs { max-width: 90px; }
.txt-3xs { font-size: var(--fs-3xs); }
.txt-lg  { font-size: var(--fs-lg); }
.center-block { display: flex; width: fit-content; margin-inline: auto; }


/* ============================================================================
   35. الحالة بشكل ولون معاً

   اللون وحده يسقط في حالتين واقعيتين: الطباعة بالأبيض والأسود (وتقارير
   هذا النظام تُطبع)، ومن لا يميّز الأحمر من الأخضر — ثمانية بالمئة من
   الرجال. النقطة تحمل الشكل: دائرة لِما تمّ، مربّع لِما ينتظر، معيّن
   لِما تأخّر. تُقرأ الحالة بلا لون أصلاً.
   ============================================================================ */
.tag::before {
  content: "";
  width: 6px; height: 6px;
  flex: 0 0 6px;
  background: currentColor;
  border-radius: 50%;            /* تمّ */
}
.tag.warn::before  { border-radius: 1px; }              /* ينتظر: مربّع */
.tag.low::before,
.tag.danger::before { border-radius: 0; transform: rotate(45deg); }  /* تأخّر: معيّن */
.tag.plain::before,
.tag.info::before  { border-radius: 50%; opacity: .55; }
.tag { display: inline-flex; align-items: center; gap: var(--sp-1); }


/* ============================================================================
   36. شريط اليوم — البطل الوحيد على الشاشة

   نفس حبر الرِّف: البطل ينتمي إلى الهوية لا إلى المنضدة، فيقرأ كقطعة
   واحدة مع الرِّف بينما تبقى الجداول تحته هادئة.
   ============================================================================ */
.daystrip {
  background: var(--rail);
  color: var(--rail-ink);
  border-radius: var(--r-lg);
  padding: var(--sp-5) var(--sp-5);
  box-shadow: var(--sh-2);
  margin-bottom: var(--sp-4);
}
.daystrip-top { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.daystrip-top h2 {
  margin: 0; color: #fff;
  font-size: var(--fs-lg); font-weight: var(--fw-semi);
}
.chip-dark {
  display: inline-flex; align-items: center;
  padding: 2px var(--sp-3); border-radius: var(--r-pill);
  background: #ffffff14; color: var(--rail-ink);
  font-size: var(--fs-2xs);
}
.daystrip-grid {
  display: grid; grid-template-columns: minmax(220px, 1fr) 1.4fr;
  gap: var(--sp-5); margin-top: var(--sp-4);
}
.daystrip-k {
  display: block; font-size: var(--fs-2xs);
  color: var(--rail-ink-2); margin-bottom: var(--sp-1);
}
/* المقاس الوحيد بهذا الحجم في النظام كله — محجوز لهذا الرقم وحده. */
.daystrip-money {
  font-size: var(--fs-2xl); font-weight: var(--fw-semi); color: #fff;
  line-height: 1.05; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.daystrip-money small {
  font-size: var(--fs-sm); font-weight: var(--fw-medium);
  color: var(--rail-ink-2); margin-inline-start: var(--sp-1);
}
.daystrip-note { font-size: var(--fs-2xs); color: var(--rail-ink-2); margin-top: var(--sp-1); }
.daystrip-list { display: grid; gap: var(--sp-1); }
.daystrip-item {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); color: var(--rail-ink);
}
.daystrip-item i { width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%; }
.dot-ok   { background: var(--mint); }
.dot-warn { background: var(--gold); border-radius: 1px !important; }
.dot-bad  { background: var(--rail-danger); border-radius: 0 !important; transform: rotate(45deg); }
.daystrip-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); flex-wrap: wrap; }

/* الزرّ الذهبي: الفعل الرئيسي لليوم، وعلى الداكن وحده. */
.btn-gold {
  background: var(--gold); border-color: var(--gold); color: var(--rail);
  font-weight: var(--fw-semi);
}
.btn-gold:hover { filter: brightness(1.06); background: var(--gold); color: var(--rail); }
.btn-on-dark { background: #ffffff14; border-color: #ffffff26; color: #fff; }
.btn-on-dark:hover { background: #ffffff26; color: #fff; border-color: #ffffff33; }

@media (max-width: 760px) { .daystrip-grid { grid-template-columns: 1fr; } }
@media print { .daystrip { display: none; } }


/* ============================================================================
   37. الجداول — سطح العمل الحقيقي

   أغلب وقت المستخدم يمرّ في جدول، لا في نموذج ولا لوحة تحكّم. لذلك
   يستحق أدقّ الضبط.
   ============================================================================ */
/* رأس ثابت: جدول يتجاوز الشاشة تُنسى أعمدته عند التمرير، فيصير الرقم
   بلا اسم — وهو أسوأ ما يحدث في جدول مالي. */
.table-wrap { position: relative; }
.table-wrap thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2);
  box-shadow: inset 0 -1px 0 var(--line);
  border-bottom: 0;
}
thead th {
  font-size: var(--fs-3xs);
  font-weight: var(--fw-semi);
  color: var(--ink-3);
  letter-spacing: .02em;
  white-space: nowrap;
  padding-top: var(--sp-2);
  padding-bottom: var(--sp-2);
}
/* آخر صفّ بلا خطّ: الحدّ السفلي للوحة يؤدّي عمله. */
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background var(--speed); }
tbody tr:hover { background: var(--surface-2); }

/* المال في عمود ثابت المحاذاة: العين تمسح عموداً لأسفل لا صفّاً بعرض
   الشاشة، والأرقام لا تصطفّ إلا بمحاذاة واحدة. */
td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; }
[dir="rtl"] td.num, [dir="rtl"] th.num { text-align: left; }
td.num.bold, td .money { font-weight: var(--fw-semi); }


/* ============================================================================
   39. رأس اللوحة والحالة الفارغة
   ============================================================================ */
.panel-head {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.panel-head h2, .panel-head h3 {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
}

/* الحالة الفارغة تعليمة لا زينة: أيقونة هادئة، جملة تقول ما العمل. */
.empty {
  display: grid; place-items: center; gap: var(--sp-2);
  padding: var(--sp-7) var(--sp-4);
  text-align: center;
}
.empty svg { width: var(--ico); height: var(--ico); color: var(--ink-3); opacity: .55; }
.empty b { font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.empty p { margin: 0; font-size: var(--fs-xs); color: var(--ink-2); max-width: 46ch; }

/* الحقول داخل شريط الضوابط أصغر: هي أدوات لا مدخلات بيانات. */
.filters .field { margin: 0; min-width: 150px; }
.filters .field > label { font-size: var(--fs-3xs); color: var(--ink-3); margin-bottom: 2px; }
.filters select, .filters .sselect-face, .filters input { height: var(--h-sm); font-size: var(--fs-2xs); }
/* الشرح ينزاح لآخر الصفّ ولا يزاحم الضوابط */
.filters .hint {
  margin-inline-start: auto;
  align-self: center;
  max-width: 44ch;
  font-size: var(--fs-2xs);
  color: var(--ink-3);
}


/* ============================================================================
   40. ضبط أخير — تفاصيل تُقرأ ولا تُلاحَظ
   ============================================================================ */
/* الأزرار: ارتفاع موحّد من السُّلّم، وحدّ لا يختفي على المرور. */
.btn { height: var(--h-md); }
.btn-sm { height: var(--h-sm); font-size: var(--fs-2xs); }
.btn-lg { height: var(--h-lg); }
.btn-primary { box-shadow: none; }
.btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

/* الوسوم أصغر قليلاً: هي تعليق على صفّ لا عنوان له. */
.tag { font-size: var(--fs-3xs); padding: 2px var(--sp-2); }

/* الحقول: الليبل أقرب لحقله، والمسافة بين الحقول أكبر من المسافة بين
   الليبل وحقله — وإلا انتمى الليبل بصرياً للحقل الذي فوقه. */
.field { display: flex; flex-direction: column; gap: var(--sp-1); }
.field > label { font-size: var(--fs-2xs); font-weight: var(--fw-medium); color: var(--ink-2); }
.form-grid { gap: var(--sp-4) var(--sp-3); }

/* شريط التمرير: رفيع وبلون الخطوط — لا يسرق الانتباه من الجدول. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--r-pill); }
::-webkit-scrollbar-track { background: transparent; }

/* المودال والبوب-أب: هذه هي التي تطفو فعلاً، فلها الظلّ وحدها. */
.modal-box { box-shadow: var(--sh-3); }


/* ============================================================================
   41. الهاتف — الجدول يصير بطاقات

   الجدول على شاشة 360px يمرّر أفقياً: تقرأ اسم المريضة ثم تسحب لتعرف
   المبلغ، فتفقد أيّ صفٍّ كنت فيه. الحلّ ليس تصغير الخطّ — بل تغيير
   الشكل: كل صفّ يصير بطاقة، وكل خليّة سطراً باسم عموده أمامه.

   الاسم مأخوذ من data-label الذي يضعه القالب على كل خليّة. الجداول
   التي لم تُوسَم بعد تُبقي السلوك القديم (تمرير أفقي) — لا تنكسر، بل
   تتحسّن حين تُوسَم.
   ============================================================================ */
@media (max-width: 600px) {
  .cards-on-mobile thead { display: none; }
  .cards-on-mobile,
  .cards-on-mobile tbody,
  .cards-on-mobile tr,
  .cards-on-mobile td { display: block; width: 100%; }

  .cards-on-mobile tr {
    border: 1px solid var(--line);
    border-radius: var(--r);
    margin-bottom: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    background: var(--surface);
  }
  .cards-on-mobile tr:hover { background: var(--surface); }

  .cards-on-mobile td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--sp-3);
    padding: var(--sp-2) 0;
    border-bottom: 1px solid var(--line);
    text-align: start;
  }
  .cards-on-mobile td:last-child { border-bottom: 0; }

  /* اسم العمود أمام قيمته — بدونه تصير البطاقة أرقاماً بلا معنى */
  .cards-on-mobile td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    color: var(--ink-3);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-medium);
  }
  /* خليّة بلا اسم عمود (أزرار الإجراءات) تأخذ العرض كاملاً */
  .cards-on-mobile td:not([data-label])::before { content: none; }
  .cards-on-mobile td:not([data-label]) { justify-content: flex-end; }

  /* المال يبقى محاذياً للنهاية ولا ينقلب مع تغيّر الشكل */
  .cards-on-mobile td.num { justify-content: space-between; }

  /* الصفّ الفارغ يبقى صفاً واحداً لا بطاقة فارغة */
  .cards-on-mobile td[colspan] { display: table-cell; text-align: center; }
  .cards-on-mobile td[colspan]::before { content: none; }
}

/* ============================================================================
   42. الهاتف — بقيّة الشاشة

   المبدأ: ما يُلمس يكبر، وما يُقرأ يبقى، وما يزاحم يُخفى.
   ============================================================================ */
@media (max-width: 600px) {
  /* أهداف اللمس: 44px توصية وصول معتمدة. الإصبع ليس مؤشّر فأرة، وزرّ
     بارتفاع 28px على شاشة تُستعمل واقفاً يُخطئ أكثر مما يُصيب. */
  .btn, .btn-sm, .btn-icon,
  input, select, textarea, .sselect-face {
    min-height: var(--touch);
  }
  .btn-sm { font-size: var(--fs-xs); }

  /* حقل بعرض نصف الشاشة على الهاتف يجبر الكتابة في مساحة ضيقة بلا سبب:
     العمود الواحد هو الافتراض هنا، لا الاستثناء. */
  .form-grid,
  .settle-grid,
  .grid.cards,
  .auto-cards { grid-template-columns: 1fr; }

  .field, .filters .field { min-width: 0; max-width: none; width: 100%; }
  .w-xs, .w-sm, .w-md, .w-lg, .w-2xs { max-width: none; }

  /* الشريط العلوي: العنوان وحده يبقى، والأدوات تنزل سطراً بدل أن تُزاحمه */
  .topbar { flex-wrap: wrap; padding: var(--sp-2) var(--sp-3); }
  .tools { width: 100%; justify-content: flex-start; }
  .tools .scopebar { border-inline-end: 0; padding-inline-end: 0; }

  .content { padding: var(--sp-3) var(--sp-3) var(--sp-6); }

  /* شريط اليوم: الرقم الكبير يبقى كبيراً — هو سبب وجود الشريط. */
  .daystrip { padding: var(--sp-4); border-radius: var(--r); }
  .daystrip-actions .btn { flex: 1; justify-content: center; }

  /* النوافذ المنبثقة تملأ الشاشة: نافذة صغيرة داخل شاشة صغيرة تضيّق
     المتاح مرتين. */
  .modal-box {
    max-width: 100%;
    width: 100%;
    max-height: 92vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    margin-top: auto;
  }
  .modal { align-items: flex-end; }

  /* الطباعة من الهاتف نادرة، والزرّ يزاحم ما يُستعمل يومياً */
  [data-print] { display: none; }
}

/* اللوحي: القائمة تنطوي والشبكات عمودان — لا عمود واحد كالهاتف ولا
   أربعة كسطح المكتب. */
@media (min-width: 601px) and (max-width: 900px) {
  .grid.cards, .auto-cards { grid-template-columns: repeat(2, 1fr); }
  .settle-grid { grid-template-columns: repeat(2, 1fr); }
}


/* ============================================================================
   REFINEMENT LAYER · 2026 — طبقة تطوير التجربة البصرية

   تُضاف في الآخر عمداً: لا تُعيد كتابة النظام المدروس أعلاه، بل تصقله.
   كل قاعدة هنا ترفع مستوى واحداً من: نعومة الخط، وضوح الأزرار، راحة
   اللمس على الهاتف، وتغطية المديولات على الشاشات الصغيرة — مع الحفاظ
   التام على الهوية (كحلي + ذهب على ورق مزرقّ).
   ============================================================================ */

/* --------------------------------------------------------------------------
   1. الخط — تفعيل خصائص OpenType وتنعيم الحواف

   Noto Sans Arabic المتغيّر يحمل خصائص لم تكن مفعّلة: kerning حقيقي،
   وligatures سياقية تحسّن اتصال الحروف العربية. تفعيلها يجعل النص أنعم
   وأوضح دون تغيير الخط نفسه. والوزن الأساسي يُرفع درجة (400→420 عبر
   المحور المتغيّر ليس ممكناً بـ font-weight، لكن تحسين التنعيم يعطي نفس
   الإحساس بجسم أوضح على الشاشات الكثيفة).
   -------------------------------------------------------------------------- */
body {
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  font-kerning: normal;
  -moz-osx-font-smoothing: grayscale;
  letter-spacing: -.003em;   /* إحكام طفيف: النص العربي يتنفّس أفضل قليلاً */
}

/* العناوين تكسب وزناً بصرياً أوضح دون تكبير — تحسين التباين الطباعي بين
   العنوان ومتنه، وهو ما يميّز الأنظمة الحديثة. */
h1, .topbar h1 { letter-spacing: -.018em; }
h2, .panel-head h2 { letter-spacing: -.012em; }

/* الأرقام المالية: تفعيل الكسور الطولية للأرقام (lining) صراحةً، فلا
   تنزل الأصفار تحت السطر في بعض السياقات. */
.num, td.num, .kpi-v, .money { font-feature-settings: "tnum" 1, "lnum" 1; }


/* --------------------------------------------------------------------------
   2. الأزرار — لمسة تفاعل أوضح عند الضغط

   لا ظلّ ثابت على الزرّ: فلسفة النظام أن الظلّ لما يطفو فعلاً لا للزينة.
   لكن ردّ الفعل عند الضغط يصير أوضح — إحساس مادي بالنقر دون ثِقل بصري.
   -------------------------------------------------------------------------- */
.btn {
  transition: background var(--speed), border-color var(--speed),
              color var(--speed), box-shadow var(--speed),
              transform .08s ease;
}
.btn:active { transform: translateY(1px) scale(.99); }

/* الزرّ الأساسي وحده يطفو قليلاً — هو النداء للفعل، ومن حقّه أن يُرى
   أعلى من محيطه. هذا اتساق مع الفلسفة لا خرق لها: الزرّ الأساسي عنصر
   فاعل بارز، لا سطح محتوى ساكن. */
.btn-primary {
  box-shadow: 0 1px 2px rgba(35,64,123,.28), 0 2px 8px rgba(35,64,123,.14);
}
.btn-primary:hover {
  box-shadow: 0 2px 5px rgba(35,64,123,.32), 0 6px 18px rgba(35,64,123,.20);
}
.btn-primary:active { box-shadow: 0 1px 2px rgba(35,64,123,.28); }

/* الزرّ الأساسي يكتسب حلقة تركيز ذهبية — ربط بصري بالهوية. */
.btn-primary:focus-visible { outline-color: var(--gold); }


/* --------------------------------------------------------------------------
   3. الحقول — حلقة تركيز أوضح
   -------------------------------------------------------------------------- */
/* الانتقال على background-color لا على background المختصرة.

   المختصرة تشمل background-image، وذكرُها هنا كان يُعيد تعيينها إلى none
   على كل حقلٍ يطابق المحدِّد — ومن بينها .sselect-face التي ترسم سهم
   القائمة بصورة خلفية. فاختفى السهم من كل القوائم. خطأٌ مني، هذا إصلاحه. */
.field input, .field select, .field textarea,
input[type="text"], input[type="tel"], input[type="number"],
input[type="date"], input[type="search"], select, textarea {
  transition: border-color var(--speed), box-shadow var(--speed),
              background-color var(--speed);
}
.field input:focus, .field select:focus, .field textarea:focus,
input:focus, select:focus, textarea:focus {
  box-shadow: 0 0 0 3px var(--primary-soft);
  border-color: var(--primary);
  outline: none;
}


/* --------------------------------------------------------------------------
   4. الجداول — تحويم الصف أوضح على الشاشة العريضة
   الأسطح تبقى محدَّدة بخطّ شعرة لا بظلّ — احتراماً لفلسفة الارتفاع.
   -------------------------------------------------------------------------- */
tbody tr:hover { background: var(--primary-soft); }


/* ============================================================================
   MOBILE COVERAGE · 2026 — تغطية الهاتف الشاملة على كل المديولات

   القاعدة الحاكمة: على الهاتف، كل ما يُلمَس ≥ 44px (توكن --touch الموجود
   أصلاً لكنه لم يُطبَّق باطّراد). واللمس بالإبهام، فالأزرار المتلاصقة
   تتباعد، والحقول تكبر، والأشرطة الأفقية المزدحمة تتكدّس رأسياً.
   ============================================================================ */

@media (max-width: 980px) {
  /* --- أهداف اللمس: كل زرّ وحقل ورابط تفاعلي --- */
  .btn,
  .field input, .field select, .field textarea,
  input[type="text"], input[type="tel"], input[type="number"],
  input[type="date"], input[type="search"], select, textarea {
    min-height: var(--touch);
    font-size: var(--fs-sm);   /* ≥16px يمنع iOS من التكبير التلقائي عند التركيز */
  }
  /* الحقول النصية 16px تحديداً: أقلّ من ذلك يجعل Safari يقفز ويكبّر الصفحة */
  input, select, textarea { font-size: var(--fs-md); }

  /* الزرّ الصغير يكبر للمس لكن يبقى مضغوطاً بصرياً */
  .btn-sm { min-height: var(--h-btn-mobile); padding: var(--sp-2) var(--sp-3); font-size: var(--fs-xs); }
  .btn-sm svg { width: 16px; height: 16px; }

  /* زرّ الأيقونة يصير هدف لمس كامل */
  .btn-icon { width: var(--touch); height: var(--touch); }
  .btn-icon svg { width: 20px; height: 20px; }

  /* --- الأشرطة الأفقية تتكدّس: أزرار الإجراءات تملأ العرض ---
     أزرار الشاشة تعيش مباشرةً في .tools (لا في غلاف)، فنستهدفها هناك. */
  .tools {
    flex-wrap: wrap;
    gap: var(--sp-2);
    row-gap: var(--sp-2);
  }
  .topbar-actions, .page-actions {
    display: flex; flex-wrap: wrap; gap: var(--sp-2);
  }
  .topbar-actions .btn, .page-actions .btn { flex: 1 1 auto; }

  /* --- الفلاتر: عمود واحد، كل حقل بعرض كامل --- */
  .filters { flex-direction: column; align-items: stretch; gap: var(--sp-3); }
  .filters .field, .filters .field select, .filters .field input {
    min-width: 0; width: 100%;
  }

  /* --- أدوات الجدول: البحث بعرض كامل فوق، الأزرار تحته --- */
  .tbl-tools { width: 100%; flex-wrap: wrap; gap: var(--sp-2); }
  .tbl-tools .search { flex: 1 1 100%; }

  /* --- النماذج داخل الجداول (كروت الموبايل): الأزرار تتباعد وتكبر --- */
  .cards-on-mobile td form { width: 100%; }
  .cards-on-mobile td .btn { flex: 1 1 auto; justify-content: center; }
  .cards-on-mobile td .flex { flex-wrap: wrap; gap: var(--sp-2); width: 100%; }

  /* --- القوائم المنسدلة القابلة للبحث: تملأ العرض --- */
  .sselect-pop { min-width: 0; width: calc(100vw - 32px); max-width: 420px; }

  /* --- شريط النطاق: يتكدّس بدل أن يزدحم --- */
  .scopebar { flex-wrap: wrap; gap: var(--sp-2); }
  .scopebar > * { flex: 1 1 auto; }

  /* --- الكروت الرقمية (KPI): تبقى مقروءة، رقمان في الصف --- */
  .kpi { padding: var(--sp-3) var(--sp-4); }
}

/* الهاتف الضيّق: تبسيط أكثر */
@media (max-width: 560px) {
  /* عنوان الشاشة يبقى واضحاً ولا يُزاحَم بالأزرار */
  .topbar { flex-wrap: wrap; row-gap: var(--sp-2); }
  .topbar h1 { font-size: var(--fs-md); }

  /* أزرار الإجراءات: صفّان بحدّ أقصى، كل زرّ ≥ نصف العرض */
  .topbar-actions .btn, .page-actions .btn { flex: 1 1 calc(50% - var(--sp-2)); }

  /* الكروت الرقمية عمود واحد على الشاشة الضيّقة جداً — الرقم أهمّ من الكثافة */
  .cards { grid-template-columns: 1fr 1fr; gap: var(--sp-3); }

  /* اللوحات تلتصق بحواف الشاشة أقل، فالمحتوى يتنفّس */
  .panel { border-radius: var(--r); }

  /* النماذج: حقل واحد في الصف دائماً */
  .form-grid, .form-grid.mt-2 { grid-template-columns: 1fr; }

  /* المودال: يملأ العرض ويرتفع من الأسفل (سلوك ورقة الهاتف) */
  .modal-box { border-radius: var(--r-lg) var(--r-lg) 0 0; }

  /* الجداول ككروت: البطاقة تكسب مسافة داخلية أوضح */
  .cards-on-mobile tr { padding: var(--sp-3); margin-bottom: var(--sp-3); }
  .cards-on-mobile td { padding: var(--sp-2) 0; }

  /* التبويبات والأزرار المقسّمة تكبر للمس */
  .seg a { padding: var(--sp-2) var(--sp-3); min-height: var(--h-btn-mobile); display: flex; align-items: center; }
}

/* الكالندر — أهمّ شاشة تُفتح من الهاتف (الاستقبال).
   الشبكة الشهرية تصغر خلاياها على الهاتف، فنكبّر أهداف اللمس فيها. */
@media (max-width: 700px) {
  .cal-cell, .cal-day { min-height: 56px; }
}


/* ============================================================================
   الوضع الليلي — تصحيحات تتبع تحوّل الأساسي إلى الذهب

   حين صار --primary ذهباً، ورثت العناصر التي تكتب #fff فوق الأساسي نصّاً
   أبيض على ذهب: تباينه 1.62:1، أي غير مقروء. الذهب لونٌ فاتح، فما يعلوه
   يجب أن يكون داكناً — لا أبيض. القاعدة: كل سطح ملؤه --primary في الوضع
   الليلي يحمل حبراً داكناً.
   ============================================================================ */
/* `--on-primary` صار توكناً في الوضعين، فالقواعد التي كانت تفرض الحبر
   الداكن ليلاً لم تعد لازمة: `.btn-primary` و`.seg a.on` تقرأ التوكن
   مباشرةً. أُبقيت هنا العناصر التي تكتب لوناً صريحاً ولم تُحوَّل بعد. */
[data-theme="dark"] .btn-primary svg { stroke: var(--on-primary); }

[data-theme="dark"] .tag.on,
[data-theme="dark"] .badge-primary,
[data-theme="dark"] .nav-item.is-active .pill { color: var(--on-primary); }


/* ============================================================================
   مفتاح الوضع الليلي/النهاري — يُرى كزرّ لا كأيقونة زينة

   كان btn-ghost: بلا حدّ ولا خلفية، فيُقرأ رسماً لا ضابطاً — والمستخدم
   لا يعرف أنه قابل للضغط أصلاً. الآن له حدٌّ وخلفية كبقية الأزرار، ويحمل
   لون الحالة التي سينتقل إليها: قمرٌ كحليّ في النهار، شمسٌ ذهبية ليلاً —
   فيقول بشكله ما سيفعله.
   ============================================================================ */
[data-theme-toggle] {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-2);
}
[data-theme-toggle]:hover {
  border-color: var(--primary);
  color: var(--primary-ink);
  background: var(--surface-2);
}
[data-theme-toggle] svg { stroke: currentColor; }

/* ليلاً: الشمس ذهبية — لون الهوية نفسه، ونداءٌ واضح للعودة إلى النهار */
[data-theme="dark"] [data-theme-toggle] {
  color: var(--gold);
  border-color: var(--line-strong);
}
[data-theme="dark"] [data-theme-toggle]:hover {
  background: var(--primary-soft);
  border-color: var(--gold);
  color: var(--gold);
}

/* العنصر المخفي من الأيقونتين لا يشغل مساحة فيبقى الزرّ مربّعاً */
[data-theme-toggle] .hidden { display: none; }


/* ============================================================================
   سهم القائمة المنسدلة — تثبيت حاسم

   .sselect-face هي <input type="text"> فتطابقها قاعدة الحقول العامة التي
   تكتب `background: var(--surface)` بالصيغة المختصرة؛ والمختصرة تُصفّر
   background-image ضمناً. لأن العنصر يطابق القاعدتين ويتساويان عملياً في
   الحسم، كانت النتيجة غير مستقرّة — واختفى السهم.

   نحسمها هنا صراحةً: لون السطح وصورة السهم كخاصّيتين مفردتين لا مختصرة،
   مع !important لأن هذا هو الموضع الوحيد الذي يقرّر مظهر السهم، فلا يبقى
   لترتيب القواعد أثر عليه.
   ============================================================================ */
.sselect-face {
  background-color: var(--surface) !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2352697d' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-size: 15px 15px !important;
  background-position: right 9px center !important;
}
[dir="rtl"] .sselect-face {
  background-position: left 9px center !important;
}
[data-theme="dark"] .sselect-face {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3b2c0' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") !important;
}
/* الطباعة تبقى بلا سهم */
@media print {
  .sselect-face { background-image: none !important; }
}

/* Live search: the results being replaced dim slightly — the field stays
   fully live, so typing continues while the answer is on its way. */
[data-live-region][aria-busy="true"] {
  opacity: .6;
  transition: opacity var(--speed);
}

/* A wrapper that exists for scripts, not for layout (e.g. a live-search
   region around buttons that already sit in a flex row). */
.contents { display: contents; }

/* ── حضور شاشة الفاتورة ─────────────────────────────────────────────
   تحذيرٌ لا منع: شريط هادئ فوق الفاتورة يقول من يعمل عليها معك الآن.
   يختفي بلا أثر حين لا يكون معك أحد — لا فراغ محجوز ولا سطر صامت. */
.presence {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--amber-soft);
  color: var(--amber);
  font-size: var(--fs-sm);
}
.presence.is-idle { display: none; }
