/* ==========================================================================
   نظام تصميم مكين — طبقة المكوّنات
   المرجع: DESIGN.md. لا يُضاف صنف هنا قبل توثيقه هناك وعرضه في /dev/ui.

   القواعد الحاكمة:
   · كل قيمة من التوكنات — لا أرقام مباشرة داخل الأصناف
   · خصائص منطقية فقط — لا left/right
   · حلقة تركيز ظاهرة على كل عنصر تفاعلي
   · لا انتقال يتجاوز 150ms، وكلها تُلغى مع prefers-reduced-motion
   · لا أصناف مساعدة — أصناف مكوّنات مسمّاة فقط
   ========================================================================== */

/* --------------------------------------------------------------------------
   الخطوط — مستضافة ذاتياً (DESIGN.md §1.5)

   خطّان بدورين لا خطٌّ واحد بدورين:
   · Readex Pro  — العناوين والأرقام الكبيرة. هندسيٌّ يشبه خطّ الشعار،
                   ومتغيّر فملفٌ واحد يغطي 400–700.
   · IBM Plex    — المتن والجداول والحقول. أوضح في المقاسات الصغيرة،
                   وعليه بُنيت كثافة الجداول.
   وReadex كان مستضافاً لصفحة الهبوط وحدها بينما التطبيق على Plex — فكان
   الزائر يرى خطاً والمستخدم آخر. هذا يوحّدهما.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Readex Pro';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/ReadexPro-arabic.woff2') format('woff2');
  /* بلا هذا المدى تُطلب اللاتينية من الملف العربي فتسقط الأرقام إلى سيريف النظام */
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Readex Pro';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/ReadexPro-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/IBMPlexSansArabic-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/IBMPlexSansArabic-Medium.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/IBMPlexSansArabic-SemiBold.woff2') format('woff2');
}

/* --------------------------------------------------------------------------
   1. التوكنات (DESIGN.md §1)
   -------------------------------------------------------------------------- */
:root {
  /* 1.1 المسافات — سلّم مغلق */
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;

  /* 1.2 المقاسات النصية — ستة، بأسماء دلالية لا بأرقامها
     العربية تحتاج مقاساً أكبر من اللاتينية عند نفس الوزن البصري: نقاطها
     وحركاتها تسقط تحت 14px على شاشات المدارس. رُفع السلّم درجةً كاملة. */
  --text-xs: 12px;      /* تسميات · بيانات وصفية · رؤوس الجداول */
  --text-sm: 14px;      /* النص الأساسي · صفوف الجداول */
  --text-md: 16px;      /* نص بارز · قيم مهمة */
  --text-lg: 20px;      /* عنوان قسم أو بطاقة */
  --text-xl: 28px;      /* عنوان الصفحة — واحد لكل شاشة */
  --text-display: 40px; /* رقم المؤشر وحده — لا يُستعمل لنص */

  /* 1.2-أ العائلتان بدورَيهما — لا تُنادى أسماء الخطوط داخل الأصناف */
  --font-ui: 'IBM Plex Sans Arabic', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Readex Pro', 'IBM Plex Sans Arabic', system-ui, sans-serif;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;

  --leading-body: 1.7;
  --leading-doc: 2.2;   /* الوثيقة الرسمية تُقرأ متمهلاً وتُوقَّع */
  --leading-heading: 1.4;
  --leading-display: 1.15;  /* العنوان الكبير يضيق سطره وإلا تفكّك */

  --leading-flat: 1;

  /* 1.3 الزوايا والحدود */
  --radius-6: 6px;
  --radius-8: 8px;
  --radius-10: 10px;
  --radius-12: 12px;
  --radius-pill: 999px;  /* الشارة وحدها — حالةٌ تُقرأ، لا زرٌّ يُضغط */
  --border-width: 1px;

  /* سماكات لها معنى دلالي — لا تُكتب مباشرة داخل الأصناف */
  --indicator-width: 3px;   /* مؤشر العنصر النشط في القائمة */
  --underline-width: 2px;   /* حد التبويب النشط */
  --ring-width: 2px;        /* حلقة التركيز */
  --ring-offset: 2px;
  --ring-offset-tight: 1px; /* داخل الحقول: الحد نفسه يتلوّن فتكفي إزاحة أقل */
  --badge-padding-block: 3px;

  /* حدود دنيا للأعمدة المرنة */
  --col-min-stat: 160px;
  --col-min-search: 180px;
  /* حقل النموذج — عمودان على المكتب وعمود على الجوال (DESIGN.md §4.3).
     كان يستعير `--col-min-search` (180px) فيُخرج **خمسة** أعمدة عند 1050px
     وعمودين على جوالٍ بعرض 380 — عكسَ القاعدة في الطرفين. قِيس: 400px
     يعطي 2 فوق 832px و1 دونها. */
  --col-min-field: 400px;
  /* بلاطة «يحتاج إجراء» — قِيس: 280px يعطي 3 أعمدة على 1080px من عرض
     المحتوى، و2 دون 900، وواحداً على الجوال. وما دونها يقصّ العنوان
     («356 مهمة غياب مفتوحة») على سطرين ونصف. */
  --col-min-action: 280px;

  /* 1.4 الارتفاعات الثابتة */
  --h-row: 48px;
  --h-thead: 42px;
  --h-field: 44px;
  --h-btn: 44px;
  --h-btn-sm: 36px;
  --h-nav-item: 40px;
  --h-filter: 42px;

  /* شاشة البوابة وحدها — تُقرأ واقفاً على مسافة ذراع لا جالساً (§4.6).
     44px حدّ اللمس لمن يجلس؛ والحارس بيدٍ واحدة وقفّاز أحياناً. */
  --h-kiosk-field: 60px;
  --kiosk-name-size: 34px;
  --kiosk-verdict-size: 44px;

  /* الألوان — الهوية (MAKEEN-SAAS-PLAN §10.3) */
  --ink: #052a2b;
  --primary: #145C5E;
  --primary-hover: #0F4A4C;
  --link: #218387;
  --focus: #218387;

  --page: #F5F7F7;
  --surface: #FFFFFF;
  --surface-alt: #FAFBFB;
  --surface-selected: #F0F7F7;
  /* الكريم لون الشعار حرفياً — ودرجةً أدفأ من ورقنا القديم، فنُقل إليه */
  --cream: #f4ebd0;
  --paper: #EFE7DD;

  --border: #E3E7E7;
  --border-row: #EEF1F1;

  --text: #16211F;
  --text-2: #5A6664;
  --text-3: #8A9391;

  /* القائمة الجانبية (DESIGN.md §2.1)
     رُفع العرض من 186 إلى 218: بطاقة المدرسة أعلى والشعار كاملاً أسفل
     لا يقرآن دونه — و«مدرسة الأمير سلطان الثانوية» كانت تُقصّ عند 186. */
  --nav-width: 218px;
  --nav-item: #A9BFBF;
  --nav-group: #5F7B7A;
  --nav-active-text: var(--cream);
  --nav-divider: rgba(244, 235, 208, .13);

  /* 1.6 حالات — أربع نغمات لكل حالة (DESIGN.md §3.6)
     خلفية هادئة · حدّ · مشبع · نص. الحدّ هو ما يجعل الشارة تبدو مصمَّمة
     لا «div ملوّناً»، وهو ما كان ناقصاً. والنغمات الأربع كلها من أصلٍ
     واحد فلا تتنافر. */
  --ok:      #1F8A5F;  --ok-bg:     #E7F6EF;  --ok-bd:     #A9DFC6;  --ok-text:     #12613F;
  --warn:    #BC8100;  --warn-bg:   #FDF3DF;  --warn-bd:   #F1D89B;  --warn-text:   #7D5600;
  --danger:  #CE4A3E;  --danger-bg: #FDEDEB;  --danger-bd: #F3C4BE;  --danger-text: #8E2C22;
  --info:    #3D7DBF;  --info-bg:   #EAF2FB;  --info-bd:   #BFD6EE;  --info-text:   #255182;
  --neutral: #8A9391;  --muted-bg:  #EEF1F1;  --muted-bd:  #DFE5E4;  --muted-text:  #5A6664;
  --danger-hover: #A8382E;

  /* الطرف الفاتح لكل حالة — الرأس الأعلى في تدرّج الشارة والتنبيه وحدهما */
  --ok-lift: #F0FAF5;
  --warn-lift: #FEF9EC;
  --danger-lift: #FEF5F3;
  --info-lift: #F1F6FC;

  /* 1.7 العمق — ثلاث درجات لا رابعة (DESIGN.md §1.6)
     والقاعدة الحاكمة: لا ظلَّ على صفٍّ في جدول ولا على حقل. البطاقة
     تُظلَّل وما بداخلها مسطّح — وإلا صار الجدول حساءً وهذا سبب الحظر
     القديم. الظل هنا طبقتان: حدٌّ ملامس يعرّف الحافة، وانتشارٌ واسع
     خافت يرفع العنصر. */
  --e1: 0 1px 2px rgba(5, 42, 43, .05), 0 2px 8px rgba(5, 42, 43, .035);
  --e2: 0 2px 4px rgba(5, 42, 43, .05), 0 10px 24px rgba(5, 42, 43, .07);
  --e3: 0 8px 16px rgba(5, 42, 43, .10), 0 28px 56px rgba(5, 42, 43, .13);

  /* 1.8 التدرجات — بأدوار معلومة (DESIGN.md §1.7)
     أسطح الهوية · البطاقة · الأشرطة والرسوم · الزر. وممنوعة على صفوف
     الجداول وخلفيات الحقول: هناك يكسر التدرّجُ المسحَ الرأسي للعين. */
  --g-brand:   linear-gradient(168deg, #0b4143 0%, #052a2b 58%, #03201f 100%);
  --g-primary: linear-gradient(180deg, #1a6f71, #134f51);
  --g-danger:  linear-gradient(180deg, #d9564a, #c03a2f);
  --g-card:    linear-gradient(180deg, #ffffff 0%, #FBFDFC 100%);
  --g-head:    linear-gradient(180deg, #FCFEFD, #F8FBFA);
  --g-paper:   linear-gradient(150deg, #F7F3EC, #EFE7DD);
  --g-chip:    linear-gradient(160deg, #EDF3F2, #E2EBEA);

  --motion: 120ms;
  --ease: ease-out;
}

/* --------------------------------------------------------------------------
   2. الأساس
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  line-height: var(--leading-body);
  direction: rtl;
  -webkit-font-smoothing: antialiased;
}

/* العناوين على العائلة العرضية — وهي وحدها ما يُضيَّق تباعده */
h1, h2, h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
}
h1 { line-height: var(--leading-display); }
p { margin: 0; }

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

/* حلقة التركيز — إلزامية على كل عنصر تفاعلي (القاعدة 3) */
:focus-visible {
  outline: var(--ring-width) solid var(--focus);
  outline-offset: var(--ring-offset);
  border-radius: var(--radius-6);
}

/* الأرقام تصطف رأسياً في الجداول والقيم (DESIGN.md §7) */
.table, .stat-value, .pagination, [dir='ltr'] { font-variant-numeric: tabular-nums; }

/* القاعدة 4 — الحركة تأخير لا متعة */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* لقارئ الشاشة فقط — ليس صنفاً مساعداً بل جزء من عقد الوصولية */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. هيكل الصفحة (DESIGN.md §2)
   -------------------------------------------------------------------------- */
.shell {
  display: flex;
  min-height: 100vh;
}

.content {
  flex: 1;
  min-width: 0;
  padding: var(--space-16);
}

/* 3.1 القائمة الجانبية
   الترتيب مقصود: المدرسة أعلى لأنها ما يتحقق منه المستخدم يومياً — ومن
   يدير مدرستين يخطئ إن لم يرها أولاً. وشعار مكين أسفل توقيعاً: المساحة
   هناك فارغة أصلاً، والمنتج يوقّع ولا يتصدّر شاشة المدرسة. */
.sidebar {
  width: var(--nav-width);
  flex-shrink: 0;
  background: var(--g-brand);
  display: flex;
  flex-direction: column;
  padding: var(--space-12);
  position: relative;
}
/* خيط ضوء على الحافة الداخلية — يفصل القائمة عن الصفحة بلا حدٍّ صلب */
.sidebar::after {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(244, 235, 208, .18) 45%, transparent);
}

/* بطاقة المدرسة */
.school-card {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid rgba(244, 235, 208, .15);
  border-radius: var(--radius-12);
  background: linear-gradient(150deg, rgba(244, 235, 208, .13), rgba(244, 235, 208, .05));
}
.school-badge {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-10);
  background: linear-gradient(160deg, var(--cream), #dccfa6);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-md);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .22);
}
.school-name {
  min-width: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-xs);
  line-height: 1.35;
  color: #F2EEE3;
}
.school-period {
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
  color: #84A09F;
  margin-block-start: 3px;
}

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding-block-start: var(--space-8);
}

.nav-group {
  padding-inline: var(--space-8);
  margin-block: var(--space-12) var(--space-4);
  color: var(--nav-group);
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
}
.sidebar-nav > .nav-group:first-child { margin-block-start: var(--space-4); }

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--h-nav-item);
  padding-inline: var(--space-8);
  border-radius: var(--radius-8);
  color: var(--nav-item);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  position: relative;
  transition: background var(--motion) var(--ease), color var(--motion) var(--ease);
}
.nav-item:hover,
.nav-item.is-hover {
  background: rgba(244, 235, 208, .07);
  color: var(--nav-active-text);
  text-decoration: none;
}
/* النشط: تدرّج يخفت نحو الداخل + مؤشر على حافة القائمة لا على حافة العنصر */
.nav-item.is-active {
  background: linear-gradient(90deg, rgba(244, 235, 208, .15), rgba(244, 235, 208, .03));
  color: var(--nav-active-text);
}
.nav-item.is-active::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(-1 * var(--space-12));
  inset-block: var(--space-8);
  width: var(--indicator-width);
  border-radius: 0 var(--indicator-width) var(--indicator-width) 0;
  background: linear-gradient(180deg, var(--cream), #c9b98c);
}
.nav-item:focus-visible { outline-offset: calc(-1 * var(--ring-offset)); }
/* شارة العدد على عنصر القائمة — تذاكر مفتوحة تنتظر السوبر أدمن. تُدفع إلى
   الطرف بـ`auto`، ولونها كريميّ على القائمة الداكنة (نغمة الهوية النشطة) */
.nav-item .nav-badge {
  margin-inline-start: auto;
  min-inline-size: 20px;
  padding-inline: 6px;
  block-size: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--cream);
  color: var(--ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* بطاقة المستخدم أسفل القائمة */
.sidebar-user {
  padding: var(--space-12) var(--space-8) var(--space-8);
  border-block-start: var(--border-width) solid var(--nav-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}
.sidebar-user-name {
  color: var(--nav-active-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.sidebar-user-role {
  color: var(--nav-item);
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
}
.sidebar-signout {
  background: none;
  border: none;
  padding: var(--space-4);
  color: var(--nav-item);
  cursor: pointer;
  display: flex;
  transition: color var(--motion) var(--ease);
}
.sidebar-signout:hover { color: var(--nav-active-text); }

/* توقيع مكين — أسفل القائمة. الشعار كاملاً: عند 172px يُقرأ «MKEEN»
   ويُميَّز السطر العربي. أضيق من ذلك يصير السطران نسيجاً لا نصاً. */
.sidebar-sign {
  padding-block-start: var(--space-12);
  border-block-start: var(--border-width) solid var(--nav-divider);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}
.sidebar-sign img {
  width: 172px;
  max-width: 100%;
  height: auto;
  opacity: .92;
}
.sidebar-version {
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
  color: var(--nav-group);
}

/* 3.2 رأس الصفحة — نمط ملزم */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  flex-wrap: wrap;
  margin-block-end: var(--space-16);
}
.page-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
}
.page-context {
  color: var(--text-2);
  font-size: var(--text-xs);
  margin-block-start: var(--space-4);
}
.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
}

/* صفحة النموذج (DESIGN.md §4.3) — عمودان لسطح المكتب، وعمود على الجوال */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--col-min-field), 100%), 1fr));
  gap: 0 var(--space-16);
  margin-block-start: var(--space-12);
}
.form-section { margin-block-start: var(--space-16); }
.form-bar {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-8);
  margin-block-start: var(--space-16);
}

/* عنوان قسم داخل الصفحة */
.section-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  margin-block: var(--space-24) var(--space-12);
}

/* --------------------------------------------------------------------------
   4. الأزرار (DESIGN.md §3.1)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  min-height: var(--h-btn);
  padding-inline: var(--space-16);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-10);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-flat);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--motion) var(--ease),
              border-color var(--motion) var(--ease),
              transform var(--motion) var(--ease);
}
.btn:hover { text-decoration: none; }

/* ردّ الفعل عند الضغط لا عند الإفلات: الانتظار حتى الإفلات يُقرأ تأخّراً.
   مقياس خفيف ومدة قصيرة، ويُلغى مع تقليل الحركة. */
.btn:active,
.copy-tile:active { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) {
  .btn:active,
  .copy-tile:active { transform: none; }
}

.btn-sm {
  min-height: var(--h-btn-sm);
  padding-inline: var(--space-12);
  font-size: var(--text-xs);
}

/* الزر الأساسي وحده يحمل ظلاً ملوَّناً — هو الإجراء الواحد في الشاشة */
.btn-primary {
  background: var(--g-primary);
  border-color: transparent;
  color: var(--surface);
  box-shadow: 0 1px 2px rgba(5, 42, 43, .2), 0 5px 14px rgba(20, 92, 94, .25);
}
.btn-primary:hover,
.btn-primary.is-hover { background: var(--primary-hover); }

.btn-secondary {
  background: var(--g-card);
  border-color: var(--border);
  color: var(--text);
  box-shadow: var(--e1);
}
.btn-secondary:hover,
.btn-secondary.is-hover { background: var(--surface-alt); }

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

.btn-danger {
  background: var(--g-danger);
  border-color: transparent;
  color: var(--surface);
  box-shadow: 0 5px 14px rgba(206, 74, 62, .26);
}
.btn-danger:hover,
.btn-danger.is-hover { background: var(--danger-hover); }

.btn:disabled,
.btn.is-disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* حالة «جارٍ» — تعطيل مع دوّار، والنص يتغيّر في القالب */
.btn.is-loading { cursor: progress; opacity: .8; }
.btn.is-loading::before {
  content: '';
  width: var(--space-12);
  height: var(--space-12);
  border: var(--ring-width) solid currentColor;
  border-block-start-color: transparent;
  border-radius: 50%;
  animation: spin 600ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* الحذف لا يجاور الحفظ (DESIGN.md §3.1) */
.btn-detached { margin-inline-start: var(--space-24); }

/* --------------------------------------------------------------------------
   5. الحقول (DESIGN.md §3.2)
   -------------------------------------------------------------------------- */
.field { margin-block-end: var(--space-12); }

.field-label {
  display: block;
  margin-block-end: var(--space-4);
  color: var(--text-2);
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
}
.field-required { color: var(--danger); margin-inline-start: var(--space-4); }

.field-input,
.field-select,
.field-textarea {
  display: block;
  width: 100%;
  min-height: var(--h-field);
  padding-inline: var(--space-12);
  padding-block: var(--space-8);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  text-align: start;
  transition: border-color var(--motion) var(--ease);
}
.field-textarea { line-height: var(--leading-body); resize: vertical; }

.field-input:focus,
.field-select:focus,
.field-textarea:focus,
.field-input.is-focus {
  border-color: var(--focus);
  outline: var(--ring-width) solid var(--focus);
  outline-offset: var(--ring-offset-tight);
}

.field-input:disabled,
.field-select:disabled,
.field-textarea:disabled,
.field-input.is-disabled {
  background: var(--page);
  color: var(--text-3);
  cursor: not-allowed;
}

.field-hint {
  margin-block-start: var(--space-4);
  color: var(--text-2);
  font-size: var(--text-xs);
  line-height: var(--leading-heading);
}

.field.has-error .field-input,
.field.has-error .field-select,
.field.has-error .field-textarea { border-color: var(--danger); }

.field-error {
  margin-block-start: var(--space-4);
  color: var(--danger);
  font-size: var(--text-xs);
  line-height: var(--leading-heading);
}

/* --------------------------------------------------------------------------
   6. البطاقة (DESIGN.md §3.3)
   -------------------------------------------------------------------------- */
.card {
  background: var(--g-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  padding: var(--space-16);
  box-shadow: var(--e1);
}
.card-flush { padding: 0; overflow: hidden; }

/* نص شارح داخل بطاقة — لا عنوان ولا حقل */
.card-text {
  font-size: var(--text-sm);
  color: var(--text-2);
  line-height: var(--leading-body);
  margin-block: var(--space-4) var(--space-12);
}

/* قائمة تعداد داخل بطاقة (معاينة الاستيراد مثلاً) */
.list-plain {
  margin: 0;
  margin-block-start: var(--space-8);
  padding-inline-start: var(--space-24);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--text-2);
}

/* حقل اختيار واحد — التسمية بجانب المربع، ومساحة اللمس على السطر كله */
.field-check { margin-block-end: var(--space-16); }
.check-label {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--h-row);
  font-size: var(--text-sm);
  cursor: pointer;
}
.check-input { width: var(--space-16); height: var(--space-16); accent-color: var(--primary); }

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  border-block-end: var(--border-width) solid var(--border);
  background: var(--g-head);
}
.card-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}
.card-body { padding: var(--space-16); }

/* --------------------------------------------------------------------------
   7. الجدول (DESIGN.md §3.4)
   -------------------------------------------------------------------------- */
/* الجدول سطحٌ مرتفع من خارجه، مسطّحٌ من داخله. لا ظلَّ ولا تدرّج على صفٍّ
   ولا خلية: هناك يكسر التدرّجُ المسحَ الرأسي للعين — وهو سبب الحظر القديم
   ومحلُّ صحته الوحيد. */
.table-wrap {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
  /* `hidden` يُنشئ حاوية تمرير فيموت `sticky` على رأس الجدول — قِيس: بعد
     تمرير 900px نزل الرأس إلى top=-835 أي انزلق كاملاً. و`clip` يقصّ ولا
     يُنشئ حاوية، فيبقى الرأس ثابتاً. والسطران معاً تدرّجٌ آمن: من لا يعرف
     `clip` يبقى على `hidden` — يقصّ الزوايا ولا يكسر شيئاً. */
  overflow: hidden;
  overflow: clip;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.table thead th {
  position: sticky;
  inset-block-start: 0;
  /* فوق الصفوف: بلا z-index يمرّ الصفُّ المتحرك **فوق** الرأس الثابت */
  z-index: 2;
  height: var(--h-thead);
  padding-inline: var(--space-12);
  background: var(--g-head);
  border-block-end: var(--border-width) solid var(--border);
  color: var(--text-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-align: start;
  white-space: nowrap;
}

.table tbody td {
  height: var(--h-row);
  padding-inline: var(--space-12);
  /* الارتفاع أعلاه حدٌّ أدنى في تخطيط الجداول — والحشو يمنع التصاق
     الخلية ذات السطرين بالفاصل، ولا يزيد الصف المفرد شيئاً */
  padding-block: var(--space-8);
  border-block-end: var(--border-width) solid var(--border-row);
  color: var(--text);
  text-align: start;
}
.table tbody tr:last-child td { border-block-end: none; }

.table tbody tr:hover,
.table tbody tr.is-hover { background: var(--surface-alt); }
.table tbody tr.is-selected { background: var(--surface-selected); }

/* عمود إجراءات الصف — دائماً الأخير */
.table-actions { width: var(--space-48); text-align: end; }
/* إجراءات صفٍّ بارزةٌ مضمّنة — بديلُ `row_menu` حين تُقصّ قائمته أو حين يكون
   الإجراء حرجاً (اعتماد/رفض): أزرارٌ ظاهرةٌ لا تُدفَن ولا يقصّها `overflow`. */
.cell-actions { text-align: end; white-space: nowrap; }
.row-actions { display: inline-flex; gap: var(--space-8); justify-content: flex-end; }

/* عمود الفرز */
.table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.table-sort.is-active { color: var(--text); }

.table-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  min-height: var(--h-thead);
  padding-inline: var(--space-12);
  background: var(--surface-alt);
  border-block-start: var(--border-width) solid var(--border);
  color: var(--text-2);
  font-size: var(--text-xs);
}

/* شريط التحديد المتعدد */
.table-selection {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-8) var(--space-12);
  margin-block-end: var(--space-12);
  background: var(--surface-selected);
  border: var(--border-width) solid var(--primary);
  border-radius: var(--radius-8);
  font-size: var(--text-sm);
}
/* إجراءُ الشريط قد يكون نموذجاً (طباعةُ المحدَّد تُرسَل بـGET) — والنموذج
   ابنٌ مرن، فيُقفل بـ`flex: none` وإلا ضُغط زرُّه دون بقية الأزرار (§0.2) */
.table-selection form { margin: 0; flex: none; }

/* قائمة إجراءات الصف — «…» تفتح قائمة (DESIGN.md §3.4) */
.row-menu { position: relative; display: inline-block; }
.row-menu-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-btn-sm);
  height: var(--h-btn-sm);
  border-radius: var(--radius-6);
  color: var(--text-2);
  cursor: pointer;
  list-style: none;
}
.row-menu-trigger::-webkit-details-marker { display: none; }
.row-menu-trigger:hover { background: var(--muted-bg); color: var(--text); }

.row-menu-list {
  position: absolute;
  inset-block-start: calc(100% + var(--space-4));
  inset-inline-end: 0;
  z-index: 50;
  min-width: 160px;
  padding-block: var(--space-4);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  box-shadow: var(--e2);
  text-align: start;
}
.row-menu-item {
  display: block;
  width: 100%;
  padding: var(--space-8) var(--space-12);
  background: none;
  border: none;
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}
.row-menu-item:hover { background: var(--surface-alt); text-decoration: none; }
.row-menu-item.is-danger { color: var(--danger-text); }

/* بطاقة نافذة الاقتران — محايدة النبرة عمداً: إجراءٌ يُبدأ لا تنبيهٌ يُستجاب
   له، فلا تأخذ نغمة التحذير التي تخص الجهاز الطارق أدناه */
.device-pair { margin-block-end: var(--space-16); }
.device-pair form { margin: var(--space-12) 0 0; }

/* أجهزة البصمة المنتظِرة الاعتماد — تظهر تلقائياً، تُعتمَد بضغطة (بلا كتابة رقم) */
.device-pending {
  border-color: var(--warn-bd);
  background: var(--warn-bg);
  margin-block-end: var(--space-16);
}
.pending-list {
  list-style: none;
  margin: var(--space-12) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.pending-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-12);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
}
.pending-info { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.pending-serial { font-weight: 600; }
.pending-item form { margin: 0; flex: none; }

/* عمود التحديد المتعدد — أضيق ما يسع مربع الاختيار */
.table .table-check {
  width: var(--space-32);
  padding-inline: var(--space-8);
  text-align: center;
}
.table-check input { width: var(--space-16); height: var(--space-16); accent-color: var(--primary); }

/* عمود رقمي — يُوسَّط هو ورأسه لتُقرأ الأرقام رأسياً (الهويات · المسلسلات) */
.table .cell-num {
  text-align: center;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* رقم هوية أو مسلسل — يُقرأ عند الحاجة ولا يزاحم الاسم.
   يبقى في `cell-num` لمحاذاته، ويأخذ هذا فوقه لوزنه: الهوية بوزن الاسم
   نفسه تجعل الصف سطرين متساويين لا سطراً رئيساً وآخر مساعداً. */
.table .cell-id {
  font-size: var(--text-xs);
  color: var(--text-3);
}

/* مرساة الصف — حرفا الاسم في رقاقة. أربعون اسماً متشابه البنية لا تُمسح
   بالعين بلا نقطة ارتكاز، والحرفان يميّزان الصف قبل قراءة كلمته الأولى.
   زخرفةٌ لا معنى فيها ⇒ aria-hidden، والاسم بجوارها هو ما يُقرأ. */
.cell-person { display: flex; align-items: center; gap: var(--space-8); min-width: 0; }
.cell-avatar {
  flex: none;
  inline-size: 30px;
  block-size: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-8);
  background: var(--g-chip);
  color: var(--primary);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-xs);
}

/* سطر ثانٍ داخل الخلية — هوية أو تفصيل لا يستحق عموداً مستقلاً.
   ارتفاع الخلية حدٌّ أدنى لا ثابت، فالصف يتّسع لسطرين من نفسه. */
.table .cell-sub {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: var(--leading-heading);
  margin-block-start: 2px;
}

/* عدّادٌ جنب الاسم — أيامُ الغياب بلا عذر (DESIGN.md §3.5-أ).
   رقمٌ بين قوسين لا شارة: الشارة تزاحم الاسم في عمودٍ رئيسٍ، والرقم يُقرأ
   في لمحةٍ مع الاسم. و`ltr` لأن القوسين حول رقمٍ لاتينيٍّ ينقلبان في RTL
   فيصيران `(12` و`12)`. والمعنى لا يُحمَّل على اللون وحده — نصٌّ خفيٌّ
   للقارئ الشاشي، ولا يُعرض عند الصفر أصلاً فلا قوسان فارغان. */
.cell-count {
  display: inline-block;
  margin-inline-start: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--danger-text);
}

/* --------------------------------------------------------------------------
   8. الشارات (DESIGN.md §3.6)
   -------------------------------------------------------------------------- */
/* الحدّ هو الفرق بين شارةٍ مصمَّمة و«div ملوّن» — يعرّف حافتها على الأبيض
   وعلى صفّ الجدول معاً. والتدرّج طرفٌ أفتح أعلى، خافتٌ لا يُرى مفرداً
   ويُرى مجموعاً. والحلقة كاملة لأن الشارة تُقرأ حالةً لا زراً. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding-block: var(--badge-padding-block);
  padding-inline: var(--space-8);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
  white-space: nowrap;
}
.badge-ok      { background: linear-gradient(180deg, var(--ok-lift), var(--ok-bg));         border-color: var(--ok-bd);     color: var(--ok-text); }
.badge-warn    { background: linear-gradient(180deg, var(--warn-lift), var(--warn-bg));     border-color: var(--warn-bd);   color: var(--warn-text); }
.badge-danger  { background: linear-gradient(180deg, var(--danger-lift), var(--danger-bg)); border-color: var(--danger-bd); color: var(--danger-text); }
.badge-info    { background: linear-gradient(180deg, var(--info-lift), var(--info-bg));     border-color: var(--info-bd);   color: var(--info-text); }
.badge-muted   { background: var(--muted-bg);                                               border-color: var(--muted-bd);  color: var(--muted-text); }

/* --------------------------------------------------------------------------
   9. الحالة الفارغة (DESIGN.md §3.7)
   -------------------------------------------------------------------------- */
.empty {
  padding-block: var(--space-48);
  padding-inline: var(--space-16);
  text-align: center;
}
.empty-icon { color: var(--text-3); }
.empty-title {
  margin-block: var(--space-12) var(--space-4);
  color: var(--text);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
}
.empty-text { color: var(--text-2); font-size: var(--text-sm); }
.empty-action { margin-block-start: var(--space-16); }

/* --------------------------------------------------------------------------
   10. التنبيه (DESIGN.md §3.9)
   -------------------------------------------------------------------------- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-12);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
  font-size: var(--text-sm);
  margin-block-end: var(--space-16);
}
/* التدرّج قُطري هنا لا رأسي — التنبيه أعرض من الشارة، والرأسي فيه يُقرأ شريطاً */
.alert-ok     { background: linear-gradient(160deg, var(--ok-lift), var(--ok-bg));         border-color: var(--ok-bd);     color: var(--ok-text); }
.alert-warn   { background: linear-gradient(160deg, var(--warn-lift), var(--warn-bg));     border-color: var(--warn-bd);   color: var(--warn-text); }
.alert-danger { background: linear-gradient(160deg, var(--danger-lift), var(--danger-bg)); border-color: var(--danger-bd); color: var(--danger-text); }
.alert-info   { background: linear-gradient(160deg, var(--info-lift), var(--info-bg));     border-color: var(--info-bd);   color: var(--info-text); }
.alert-muted  { background: var(--muted-bg);                                               border-color: var(--muted-bd);  color: var(--muted-text); }

/* خانة توقيع فارغة في كشف التواقيع — سطر يُوقَّع عليه بعد الطباعة */
.sig-blank {
  display: block;
  min-width: 140px;
  border-block-end: var(--border-width) solid var(--text-3);
}

/* قائمة الإجراءات النظامية — نص اللائحة كما ورد */
.action-list {
  margin: 0;
  padding-inline-start: var(--space-24);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}
.action-list li { margin-block-end: var(--space-8); }

/* الخط الزمني الموحّد في ملف الطالب (الخطة §7) */
.tl-item {
  display: flex;
  gap: var(--space-12);
  align-items: flex-start;
  padding: var(--space-12);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  margin-block-end: var(--space-8);
}
.tl-icon { color: var(--text-2); display: flex; }
.tl-body { flex: 1; min-width: 0; }
.tl-title { font-size: var(--text-sm); }
.tl-meta { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-4); }

/* ملاحظة إرشاد — محتوى حسّاس يُقرأ على الشاشة ولا يُطبع ولا يُصدَّر */
.note-card {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  padding: var(--space-16);
  margin-block-end: var(--space-8);
}
.note-meta { font-size: var(--text-xs); color: var(--text-2); margin-block-end: var(--space-8); }
.note-body { font-size: var(--text-sm); line-height: var(--leading-body); white-space: pre-line; }

/* بطاقة الخطأ ذات الحد الأحمر (DESIGN.md §3.8) */
.error-card {
  padding: var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--danger);
  border-radius: var(--radius-10);
}
.error-card-title {
  color: var(--danger-text);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  margin-block-end: var(--space-8);
}

/* --------------------------------------------------------------------------
   11. الإشعار العابر (DESIGN.md §3.10)
   -------------------------------------------------------------------------- */
.toast {
  position: fixed;
  inset-block-end: var(--space-24);
  inset-inline-start: var(--space-24);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  box-shadow: var(--e2);
  font-size: var(--text-sm);
}
.toast-close {
  background: none;
  border: none;
  padding: var(--space-4);
  color: var(--text-2);
  cursor: pointer;
  display: flex;
}

/* في المعرض فقط: عرض الإشعار داخل التدفق لا معلّقاً */
.toast-static { position: static; display: inline-flex; }

/* --------------------------------------------------------------------------
   12. نافذة التأكيد (DESIGN.md §3.11) — عنصر dialog للحصر البؤري وEsc
   -------------------------------------------------------------------------- */
.modal {
  width: min(420px, calc(100vw - var(--space-32)));
  padding: var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  box-shadow: var(--e3);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
}
.modal::backdrop { background: rgba(5, 42, 43, .45); }

.modal-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  margin-block-end: var(--space-8);
}
.modal-body { color: var(--text-2); line-height: var(--leading-body); }
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-8);
  margin-block-start: var(--space-16);
}

/* خيارات بديلة تُتمّ الناقص قبل الحفظ (DESIGN.md §3.11) — **عمودٌ لا صفّ**:
   النافذة 420px، وأربعة أزرارٍ في سطرٍ واحد تتكسّر فيُقرأ ترتيبها عشوائياً.
   وكلٌّ منها بعرض النافذة فيُقرأ نصُّه كاملاً («احفظ وأكمل الباقي غياباً»). */
.modal-choices {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  margin-block-start: var(--space-16);
}

/* المعاينة الساكنة في المعرض */
.modal-static { position: static; display: block; }

/* نافذة إنشاء — أعرض من نافذة التأكيد لأنها تحمل حقولاً */
.modal-form { width: min(520px, calc(100vw - var(--space-32))); }
.modal-form .modal-body { color: var(--text); }

/* --------------------------------------------------------------------------
   13. بطاقة المؤشر (DESIGN.md §3.12)
   -------------------------------------------------------------------------- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--col-min-stat), 1fr));
  gap: var(--space-12);
  margin-block-end: var(--space-16);
}
/* نبض المدرسة — عددُ بطاقاته يتغيّر بالدور والبيانات (من اثنتين إلى ستّ)،
   وتسمياتها أطول من تسميات المؤشرات العادية.
   **ومرن لا شبكة**: الشبكة لا تملأ صفَّها الأخير — `auto-fit` لا يطوي
   مساراً إلا إذا خلا في كل الصفوف، فستُّ بطاقاتٍ في أربعة أعمدة تُخلّف
   فجوةً معلَّقة في الصفّ الثاني تُقرأ نقصاً. والمرن يوزّع الفائض على
   بطاقات السطر فيمتلئ كل سطرٍ مهما كان العدد.
   **وموضعه بعد `.stat-row` لا قبله**: الصنفان بنفس الأولوية، فالسابق منهما
   في الملف يخسر — والمُعدِّل الذي يسبق أصله لا يفعل شيئاً (§0.1). */
.stat-row-pulse {
  display: flex;
  flex-wrap: wrap;
}
/* `260px` أساسٌ لا عرضٌ ثابت: ثلاثٌ في سطر المكتب، واثنتان دون 900،
   وواحدة على الجوال — ويكبرن لملء السطر */
.stat-row-pulse > .stat { flex: 1 1 260px; }
/* الشريط الجانبي يحمل دلالة البطاقة قبل قراءة رقمها — واللون وحده لا يكفي،
   فالنص ملوَّن معه (DESIGN.md §3.12) */
.stat {
  position: relative;
  overflow: hidden;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--g-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
  padding: var(--space-12) var(--space-16);
}
/* شريط الدلالة — يخفت نحو الأسفل فلا يقطع البطاقة بخطٍّ صلب */
.stat::before {
  content: '';
  position: absolute;
  inset-block: var(--space-12);
  inset-inline-start: 0;
  inline-size: var(--indicator-width);
  border-radius: 0 var(--indicator-width) var(--indicator-width) 0;
  background: linear-gradient(180deg, var(--stat-accent, var(--neutral)), transparent);
}
/* وهجٌ خافت بلون الحالة في الزاوية — اللمسة التي تجعل البطاقة سطحاً لا مستطيلاً.
 *
 * **العنصر يملأ البطاقة والتدرّج هو المحدود، لا العكس.** كان العنصر مربّعاً
 * ثابتاً 130×70: يذوب في بطاقةٍ ضيقة، وفي صفٍّ ببطاقتين (البطاقة 520px) يظهر
 * حافّةً صلبة عند 130px فيُقرأ صندوقاً مُقحماً في الزاوية. والقياس هنا: صفّ
 * الأربع يُخفي منه اثنتان بـ`hideZero` فيتمدّد الباقيان — وهي الحال الشائعة.
 */
.stat::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(200px 110px at 12% 0%, var(--stat-glow, transparent), transparent);
  pointer-events: none;
}
.stat > * { position: relative; }
.stat-ok     { --stat-accent: var(--ok);      --stat-glow: rgba(31, 138, 95, .13); }
.stat-warn   { --stat-accent: var(--warn);    --stat-glow: rgba(201, 138, 0, .13); }
.stat-danger { --stat-accent: var(--danger);  --stat-glow: rgba(206, 74, 62, .13); }
.stat-info   { --stat-accent: var(--info);    --stat-glow: rgba(61, 125, 191, .13); }

/* الصفوف مقفلة الارتفاع — بها تقف الأرقام على خطٍّ واحد عبر البطاقات.
   flex:none إلزامي: الابن المرن يُضغط تحت ارتفاعه المعلن حين يضيق أبوه.
   والتسمية سطرٌ واحد بنقاطٍ عند الطول — سطرها الثاني يزيح رقمها وحده. */
.stat-label {
  flex: none;
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-flat);
  min-height: var(--space-16);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat-value {
  flex: none;
  margin-block-start: var(--space-8);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-flat);
  font-variant-numeric: tabular-nums;
}
.stat-value-text {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-heading);
}
.stat-value-ok     { color: var(--ok-text); }
.stat-value-warn   { color: var(--warn-text); }
.stat-value-danger { color: var(--danger-text); }
.stat-value-info   { color: var(--info-text); }

/* الاتجاه يُلوَّن بالدلالة لا بالإشارة (DESIGN.md §3.12) */
/* بطاقة مؤشر تفتح شاشتها — القراءة تُتبع بإجراء، والرقم الذي لا يُنقر
   يُقرأ ثم يُنسى. والحلقة على البطاقة كلها لا على نصٍّ فيها. */
.stat-link { text-decoration: none; color: inherit; }
.stat-link:hover { text-decoration: none; box-shadow: var(--e2); }
.stat-link:hover .stat-label { color: var(--text); }

.stat-trend {
  flex: none;
  font-size: var(--text-xs);
  margin-block-start: var(--space-4);
  min-height: var(--space-16);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat-trend-good { color: var(--ok-text); }
.stat-trend-bad  { color: var(--danger-text); }

/* --------------------------------------------------------------------------
   14. عنصر «يحتاج إجراء» (DESIGN.md §3.13)
   -------------------------------------------------------------------------- */
/* شبكة المهام — بلاطات متجاورة لا أسطر متتابعة.
   كان كلُّ عنصرٍ سطراً بعرض الصفحة: العنوان يميناً والزرّ يساراً وبينهما
   فراغُ 700 بكسل، وخمسةُ عناصر تملأ الشاشة بلا أن تملأ العين. والمهامّ
   تُمسح مسحاً لا تُقرأ سطراً سطراً. */
.action-grid {
  display: grid;
  /* `auto-fit`: البلاطات تتوسّع فتملأ صفَّها مهما كان عددها — والفجوة
     المعلَّقة في آخر الصفّ الأخير تُقرأ نقصاً لا ترتيباً */
  grid-template-columns: repeat(auto-fit, minmax(min(var(--col-min-action), 100%), 1fr));
  gap: var(--space-12);
}
/* عمودٌ نصّيٌّ واحد: الرقاقة عمودٌ، والعنوان والوصف والزرّ عمودٌ ثانٍ
   يبدأون جميعاً من حافةٍ واحدة. كان العنوان يُزاح خلف الرقاقة والوصفُ
   يبدأ من حافة البلاطة والزرُّ من ثالثة — ثلاثُ حوافَّ في بطاقةٍ واحدة
   تُقرأ اهتزازاً لا ترتيباً.
   والصفّ الأول `1fr` فيبتلع الفراغ ويهبط الزرّ إلى القاع: أزرارُ الصفّ
   تستوي مهما اختلف طول الوصف. */
.action-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  gap: var(--space-12);
  align-items: start;
  padding: var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
}
.action-item-body {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.action-item-title { font-size: var(--text-md); color: var(--text); }
.action-item-meta { font-size: var(--text-xs); color: var(--text-2); }
.action-item > .btn { grid-column: 2; grid-row: 2; justify-self: start; }

/* البلاطة الوجهة — التقارير: البلاطة كلها رابط، بلا زرّ «فتح» يكرّرها
   (القاعدة نفسها في §3.22: لا يُكرَّر «فتح الملف» بجانب اسمٍ يفتحه).
   وصفٌّ واحد: لا زرَّ يهبط، فالرقاقة تتوسّط النصّ والشيفرون عمودٌ ثالث. */
.action-item-link {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto;
  align-items: center;
  text-decoration: none;
  color: inherit;
}
.action-item-link:hover { border-color: var(--primary); background: var(--paper); }
.action-item-go { grid-column: 3; grid-row: 1; color: var(--text-3); }

/* رقاقة الأيقونة — خلفية الحالة الهادئة مع أيقونتها المشبعة.
   الرقاقة تسبق العنوان فتُقرأ الدلالة قبل النص، ومعها النص دائماً. */
.action-item-icon,
.icon-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  inline-size: var(--h-btn-sm);
  block-size: var(--h-btn-sm);
  border-radius: var(--radius-8);
  background: var(--chip-bg, var(--muted-bg));
  color: var(--chip-text, var(--muted-text));
}
.icon-chip-ok     { --chip-bg: var(--ok-bg);     --chip-text: var(--ok-text); }
.icon-chip-warn   { --chip-bg: var(--warn-bg);   --chip-text: var(--warn-text); }
.icon-chip-danger { --chip-bg: var(--danger-bg); --chip-text: var(--danger-text); }
.icon-chip-info   { --chip-bg: var(--info-bg);   --chip-text: var(--info-text); }

/* --------------------------------------------------------------------------
   15. التبويبات (DESIGN.md §3.14)
   -------------------------------------------------------------------------- */
.tabs {
  display: flex;
  gap: var(--space-16);
  border-block-end: var(--border-width) solid var(--border);
  margin-block-end: var(--space-16);
}
.tab {
  padding-block: var(--space-8);
  border-block-end: var(--underline-width) solid transparent;
  color: var(--text-2);
  font-size: var(--text-sm);
  text-decoration: none;
  transition: color var(--motion) var(--ease);
}
.tab:hover, .tab.is-hover { color: var(--text); text-decoration: none; }
.tab.is-active { color: var(--text); border-block-end-color: var(--primary); }

/* --------------------------------------------------------------------------
   16. الترقيم (DESIGN.md §3.15)
   -------------------------------------------------------------------------- */
.pagination { display: flex; align-items: center; gap: var(--space-4); }
.page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--h-btn-sm);
  height: var(--h-btn-sm);
  padding-inline: var(--space-8);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-6);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-xs);
  text-decoration: none;
  transition: background var(--motion) var(--ease);
}
.page-link:hover, .page-link.is-hover { background: var(--surface-alt); text-decoration: none; }
.page-link.is-active { background: var(--primary); border-color: var(--primary); color: var(--surface); }
.page-link.is-disabled { opacity: .5; pointer-events: none; }

/* --------------------------------------------------------------------------
   17. شريط الفلاتر (DESIGN.md §3.5)
   -------------------------------------------------------------------------- */
.filter-bar {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
  margin-block-end: var(--space-12);
}
.filter-search {
  flex: 1;
  min-width: var(--col-min-search);
  display: flex;
  align-items: center;
  gap: var(--space-8);
  height: var(--h-filter);
  padding-inline: var(--space-12);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
}
.filter-search:focus-within { border-color: var(--focus); }
.filter-search-icon { color: var(--text-3); display: flex; }
.filter-search-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
}
.filter-search-input:focus { outline: none; }

.filter-select {
  height: var(--h-filter);
  padding-inline: var(--space-12);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
}
.filter-select.is-applied {
  background: var(--surface-selected);
  border-color: var(--primary);
}

/* --------------------------------------------------------------------------
   18. منتقي حالة الحضور — خاص بشاشة الرصد
   لون + نص دائماً، ومساحة اللمس 44px لأنها تُستخدم على تابلت
   -------------------------------------------------------------------------- */
.status-picker { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.status-opt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  min-height: var(--h-row);
  min-width: 62px;
  padding-inline: var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  background: var(--surface);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--text-2);
  cursor: pointer;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
/* الدائرة تُخفى بصرياً وتبقى للتركيز والقارئ: الرقاقة نفسها هي الحالة،
   وأربعون صفاً × أربع دوائر = مئةٌ وستون علامةً تزاحم اللونَ الذي يدلّ */
.status-opt input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.status-opt:has(input:disabled) { opacity: .5; cursor: not-allowed; }
.status-opt:has(input:focus-visible) { outline: var(--ring-width) solid var(--focus); outline-offset: var(--ring-offset); }
.status-opt:hover { border-color: var(--text-3); }
.status-present:has(input:checked) { background: linear-gradient(180deg, var(--ok-lift), var(--ok-bg));         color: var(--ok-text);     border-color: var(--ok); }
.status-late:has(input:checked)    { background: linear-gradient(180deg, var(--warn-lift), var(--warn-bg));     color: var(--warn-text);   border-color: var(--warn); }
.status-absent:has(input:checked)  { background: linear-gradient(180deg, var(--danger-lift), var(--danger-bg)); color: var(--danger-text); border-color: var(--danger); }
.status-excused:has(input:checked) { background: linear-gradient(180deg, var(--info-lift), var(--info-bg));     color: var(--info-text);   border-color: var(--info); }

.late-input { width: 72px; }

/* 18-أ. كشف الرصد — الاكتمال ظاهرٌ دائماً (DESIGN.md §4.7)

   الطالب بلا سجل يُحسب حاضراً: نسبة الغياب بسطُها صفوف absent ومقامُها
   أيام الدراسة (م31/9). فالصفُّ المنسيّ غيابٌ مجاني لا يظهر في حرمانٍ ولا
   درجة مواظبة — ولذلك النقص يُشار إليه في الصف وفي الشريط معاً. */
/* المؤشر بـ ::before لا بـ box-shadow: الأخير لا يعرف المنطقي فيظهر على
   الحافة المقابلة في RTL — وهو ما وقع (DESIGN.md §0 · خصائص منطقية فقط) */
.mark-row > td:first-child { position: relative; }
.mark-row.is-unmarked > td:first-child::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block: 0;
  inline-size: var(--indicator-width);
  background: var(--warn);
}
.mark-row.is-unmarked .cell-primary { color: var(--warn-text); }

/* حقل الدقائق مع «متأخر» وحدها — أربعون صندوقاً فارغاً يُخفي المملوء.
   وبلا :has() يظهر دائماً، وهو التدهور الصحيح: يُعرض ولا يُفقد. */
.mark-row:not(:has(.status-late input:checked)) .mark-late .late-input {
  visibility: hidden;
}

/* الشريط الملتصق — العدّاد والإجراءان لا يُبحث عنهم بالتمرير */
.mark-bar {
  position: sticky;
  inset-block-end: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  flex-wrap: wrap;
  margin-block-start: var(--space-12);
  padding: var(--space-12) var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e2);
}
.mark-counts { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
.mark-actions { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
/* حدٌّ تحذيري على الشريط ما بقي غير مرصود — النقص حالةُ الشاشة لا رقمٌ فيها */
.is-incomplete .mark-bar { border-color: var(--warn-bd); }

/* --------------------------------------------------------------------------
   19. شاشة البوابة — كشك بغرض واحد (DESIGN.md §4.6)

   تُقرأ واقفاً على مسافة ذراع، بيدٍ واحدة، في شمس، وخلف الطالب صفٌّ ينتظر.
   فالشاشة **هي** النتيجة لا بطاقةٌ فيها نتيجة: اللون يملأ السطح كي يُقرأ
   الحكم قبل الاسم، والحقل شريطٌ ثابت أسفل لا يتحرك بين مسحٍ وآخر.

   وهي المكان الوحيد الذي يخرج فيه المقاس عن سلّم §1.2: 34px للاسم و64px
   للحكم. السلّم مكتوبٌ لمن يجلس أمام الشاشة بذراعٍ واحدة، والحارس لا يجلس.
   -------------------------------------------------------------------------- */
.kiosk {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  position: relative;
  background: var(--kiosk-bg, var(--g-paper));
  transition: background var(--motion) var(--ease);
}
.kiosk.is-present { --kiosk-bg: linear-gradient(160deg, var(--ok-lift), var(--ok-bg));         --kiosk-ink: var(--ok-text); }
.kiosk.is-late    { --kiosk-bg: linear-gradient(160deg, var(--warn-lift), var(--warn-bg));     --kiosk-ink: var(--warn-text); }
.kiosk.is-fail    { --kiosk-bg: linear-gradient(160deg, var(--danger-lift), var(--danger-bg)); --kiosk-ink: var(--danger-text); }
/* بعد التقادم يعود السطح محايداً: هالةٌ خضراء خلف طبقة «امسح من جديد»
   تبقى توحي بحكمٍ لمن يلمح الشاشة من بعيد. وترتيبه بعد الأنغام مقصود —
   التخصيص متساوٍ، فالأخير هو الفائز. */
.kiosk.is-stale { --kiosk-bg: var(--g-paper); }

/* اللوح الأعلى — يأخذ ما بقي من الشاشة ويُوسّط محتواه */
.kiosk-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  padding: var(--space-24) var(--space-16);
  text-align: center;
  color: var(--kiosk-ink, var(--text));
  position: relative;
}

/* حالة الانتظار — لا فراغ: دعوةٌ مصمَّمة (CLAUDE.md §8-أ) */
.kiosk-idle { color: var(--text-3); display: grid; justify-items: center; gap: var(--space-8); }
.kiosk-idle-title { font-family: var(--font-display); font-size: var(--text-xl); color: var(--text-2); }
.kiosk-idle-hint { font-size: var(--text-md); }

.kiosk-name {
  font-family: var(--font-display);
  font-size: var(--kiosk-name-size);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
}
.kiosk-class { font-size: var(--text-lg); opacity: .8; }

/* الحكم: أيقونة ونص — واللون ثالثهما لا وحده (DESIGN.md §3.6) */
.kiosk-verdict {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  margin-block-start: var(--space-16);
  font-family: var(--font-display);
  font-size: var(--kiosk-verdict-size);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
}
.kiosk-detail { font-size: var(--text-lg); opacity: .85; font-variant-numeric: tabular-nums; }

/* طبقة التقادم — تغطي النتيجة بعد مهلة فلا تُقرأ نتيجةُ سابقٍ حكماً لحاضر */
.kiosk-stale {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-12);
  /* شبه معتمة: الشبح يقول «كان هنا شيء»، والقراءة منه تُعيد الخطر نفسه */
  background: rgba(243, 246, 245, .975);
  color: var(--text-2);
  font-family: var(--font-display);
  font-size: var(--text-xl);
}
.kiosk-stale[hidden] { display: none; }

/* الاستئذان — مهمة مطابقة لا مهمة تسجيل، فلها لوحها ورقمها بمقاسه */
.kiosk-exit {
  margin: 0 var(--space-16) var(--space-12);
  padding: var(--space-16);
  border: var(--border-width) solid var(--info-bd);
  border-radius: var(--radius-12);
  background: linear-gradient(160deg, var(--info-lift), var(--info-bg));
  box-shadow: var(--e1);
  color: var(--info-text);
  text-align: center;
}
.kiosk-exit-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
}
.kiosk-exit-serial {
  font-variant-numeric: tabular-nums;
  opacity: .75;
  font-size: var(--text-sm);
}
.kiosk-exit-who {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  margin-block-start: var(--space-4);
}
/* الرقم كاملاً وبمقاسٍ يُقابَل ببطاقةٍ في اليد — لا يُقصّ ولا يُصغَّر */
.kiosk-exit-id {
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-display);
}
.kiosk-exit-foot { font-size: var(--text-sm); opacity: .85; margin-block-start: var(--space-8); }

/* الشريط الأسفل — ثابت، فلا تتبع اليدُ حقلاً يتحرك */
.kiosk-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-12);
  align-items: center;
  padding: var(--space-12) var(--space-16);
  background: var(--surface);
  border-block-start: var(--border-width) solid var(--border);
  box-shadow: 0 -2px 12px rgba(5, 42, 43, .06);
}
.kiosk-input {
  min-height: var(--h-kiosk-field);
  padding-inline: var(--space-16);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-variant-numeric: tabular-nums;
  text-align: center;
  letter-spacing: .12em;   /* أرقام لاتينية وحدها — dir=ltr على العنصر */
  width: 100%;
}
.kiosk-input::placeholder { font-family: var(--font-ui); font-size: var(--text-md); letter-spacing: normal; }
.kiosk-input:focus { outline: var(--ring-width) solid var(--focus); outline-offset: var(--ring-offset-tight); border-color: var(--focus); }
.kiosk-submit { min-height: var(--h-kiosk-field); padding-inline: var(--space-24); font-size: var(--text-md); }
.kiosk-meta {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-12);
  font-size: var(--text-sm);
  color: var(--text-3);
}
.kiosk-clock {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}
/* «المتأخر بعد 07:15» — قاعدةُ الحكم بجانب الساعة، أخفتُ منها: الوقت يُقرأ
   والقاعدة تُراجَع. وكان الصنف مكتوباً في القالب بلا قاعدةٍ هنا فيخرج بحجم
   المتن كأنه إعلان. */
.kiosk-rule {
  font-size: var(--text-xs);
  color: var(--text-3);
}
.kiosk-out {
  position: absolute;
  inset-block-start: var(--space-8);
  inset-inline-start: var(--space-8);
  display: flex;
  align-items: center;
  gap: var(--space-8);
}
/* رابط لوح الباب — بمساحة لمسٍ كاملة: يُضغط بإبهامٍ واقفاً، لا بمؤشّر */
.kiosk-exits {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--h-btn);
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.kiosk-exits:hover { background: var(--page); }
.link-button {
  background: none;
  border: none;
  padding: var(--space-8);
  min-height: var(--h-btn);
  color: var(--text-2);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}
.link-button:hover { color: var(--text); }

/* --------------------------------------------------------------------------
   20. الهيكل العظمي (DESIGN.md §3.8)
   -------------------------------------------------------------------------- */
.skeleton {
  display: block;
  background: var(--muted-bg);
  border-radius: var(--radius-6);
  animation: pulse 1.2s var(--ease) infinite;
}
.skeleton-text { height: var(--text-sm); margin-block-end: var(--space-8); }
.skeleton-title { height: var(--text-lg); width: 40%; margin-block-end: var(--space-12); }
.skeleton-row { height: var(--h-row); margin-block-end: var(--space-4); border-radius: var(--radius-8); }
@keyframes pulse { 50% { opacity: .55; } }

/* --------------------------------------------------------------------------
   19. الجوال — نقطة كسر وحيدة (DESIGN.md §5)
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
  .shell { flex-direction: column-reverse; }

  .sidebar {
    width: 100%;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
    padding: 0;
    position: sticky;
    inset-block-end: 0;
    z-index: 40;
  }
  .sidebar::after { display: none; }
  /* الشريط السفلي أيقونات وتسميات فقط — بطاقة المدرسة وتوقيع مكين يظهران
     في الرأس والدخول، وتكرارهما هنا يأكل نصف الشاشة على جوال الحارس */
  .school-card,
  .sidebar-user,
  .sidebar-sign,
  .nav-group { display: none; }
  .sidebar-nav {
    display: flex;
    flex: 1;
    padding-block-start: 0;
    overflow-x: auto;
  }
  .nav-item {
    flex-direction: column;
    gap: var(--space-4);
    min-height: var(--h-row);
    padding-inline: var(--space-12);
    border-radius: 0;
    border-block-start: var(--indicator-width) solid transparent;
    font-size: var(--text-xs);
  }
  /* المؤشر الجانبي يصير علوياً — والمطلق منه لا مكان له في شريطٍ أفقي */
  .nav-item.is-active::before { display: none; }
  .nav-item.is-active { border-block-start-color: var(--nav-active-text); }

  .page-header { flex-direction: column; }
  .page-actions { width: 100%; }
  .page-actions .btn { flex: 1; }

  /* الجدول يصير بطاقات — لا تمرير أفقي (DESIGN.md §5) */
  .table-cards thead { display: none; }
  .table-cards tbody tr {
    display: block;
    padding: var(--space-12);
    border-block-end: var(--border-width) solid var(--border-row);
  }
  .table-cards tbody td {
    display: block;
    height: auto;
    padding-inline: 0;
    border: none;
  }
  .table-cards .cell-primary { font-size: var(--text-md); font-weight: var(--weight-medium); }
  .table-cards .cell-secondary { color: var(--text-2); font-size: var(--text-xs); }
  .table-cards .cell-hidden { display: none; }

  .toast { inset-inline: var(--space-16); inset-block-end: calc(var(--h-row) + var(--space-16)); }
}

/* --------------------------------------------------------------------------
   الطباعة — نماذج اللائحة تُطبع وتُوقَّع (DESIGN.md §8)
   ورق أبيض · حبر داكن · بلا قائمة ولا أيقونات (CLAUDE.md §8-ب: الحالة تُطبع نصاً)
   -------------------------------------------------------------------------- */
.print-only,
.print-letterhead { display: none; }

.print-letterhead {
  align-items: flex-start;
  justify-content: space-between;
  border-block-end: 2px solid var(--ink);
  padding-block-end: var(--space-12);
  margin-block-end: var(--space-16);
}
.letterhead-school { display: flex; align-items: center; gap: var(--space-12); }
.letterhead-logo   { height: 58px; width: auto; flex: none; }
.letterhead-name  { font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--ink); }
.letterhead-title { font-size: var(--text-md); font-weight: var(--weight-medium); color: var(--ink); }
.letterhead-sub   { font-size: var(--text-xs); color: var(--text-2); }

/* طباعة A4 موحّدة لكل المستندات — هامشٌ متساوٍ يحفظ الحواف (وتك للحواف) */
@page { size: A4; margin: 16mm; }

.print-note {
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  margin-block: var(--space-16);
}
.sig-row {
  display: flex;
  gap: var(--space-32);
  margin-block-start: var(--space-48);
  font-size: var(--text-xs);
  color: var(--text-2);
}
/* المسمّى تحت الخط والتوقيع بالقلم فوقه — كنماذج الوزارة.
   السطر مقيّد بـ .sig-row: الصنف نفسه في كشف التواقيع سطرُ خليةٍ مصمت */
.sig-row .sig-blank { flex: 1; text-align: center; border-block-end: none; }
.sig-row .sig-blank::before {
  content: "";
  display: block;
  block-size: var(--space-48);
  border-block-end: 1px dotted var(--ink);
  margin-block-end: var(--space-8);
}

/* نموذج اللائحة المطبوع (م33/م34 — ص72–74): إطارٌ خارجي وجدولٌ كامل التحديد.
   **حدودٌ لا خلفيات**: المتصفح لا يطبع الخلفيات افتراضياً فتسقط صامتةً.
   الأنماط خارج @media print عمداً ليُعاين المكوّن في /dev/ui — إخفاؤه على
   الشاشة يتكفّل به غلاف `.print-only` لا هذه القواعد. */
.print-frame {
  border: 2px solid var(--ink);
  padding: var(--space-16) var(--space-24) var(--space-24);
  margin-block-start: var(--space-16);
}
.print-form-title {
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  color: var(--ink);
  margin-block: 0 var(--space-16);
}
.print-table {
  inline-size: 100%;
  border-collapse: collapse;
}
.print-table th,
.print-table td {
  border: 1px solid var(--ink);
  padding: var(--space-8) var(--space-12);
  text-align: start;
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink);
  vertical-align: middle;
}
.print-table th { inline-size: 34%; font-weight: var(--weight-medium); }
.print-note-box {
  border: 1px solid var(--ink);
  padding: var(--space-12) var(--space-16);
  margin-block: var(--space-16);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink);
}

/* ورقةٌ واحدة في مستندٍ متعدّد — إشعارات الغياب تُطبع دفعةً، ولكلِّ ولي أمرٍ
   ورقتُه بترويستها وتواقيعها. القطع في الطباعة وحدها، والشاشةُ معاينةٌ
   متتابعة بفاصلٍ بين الأوراق. */
.print-sheet + .print-sheet { margin-block-start: var(--space-32); }

/* كشفٌ يوميٌّ يُطبع ويُعلَّق — **جدولُ بيانات** بحدودٍ كاملة، غيرُ `.print-table`
   (نموذجُ عمودين: تسمية وقيمة). صفوفه كثيرة فالحشو أضيق والسطر أقرب، وحدودُه
   حبرٌ صريح: الوكيل يقرؤه من على اللوحة لا من الشاشة. */
.print-grid {
  inline-size: 100%;
  border-collapse: collapse;
  margin-block-start: var(--space-12);
}
.print-grid th,
.print-grid td {
  border: 1px solid var(--ink);
  padding: var(--space-4) var(--space-8);
  font-size: var(--text-sm);
  line-height: var(--leading-heading);
  color: var(--ink);
  text-align: start;
}
.print-grid thead th { font-weight: var(--weight-semibold); text-align: center; }
.print-grid .cell-num { text-align: center; }
/* رأسُ الحصة — فاصلٌ يُقرأ من بعيد. **حدٌّ لا خلفية**: المتصفح لا يطبع
   الخلفيات افتراضياً فتسقط صامتةً ويصير الكشف كتلةً واحدة */
.print-grid .grid-group td {
  font-weight: var(--weight-semibold);
  border-block-start: 2px solid var(--ink);
}
/* ما لم يُسند — نصّاً لا لوناً، فالورقة رمادية */
.print-grid .grid-none { font-style: italic; }
.print-summary {
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink);
  margin-block: var(--space-8) 0;
}

@media print {
  .sidebar,
  .no-print,
  .page-actions,
  .row-menu,
  .filter-bar,
  .pagination,
  svg { display: none !important; }

  body { background: #FFFFFF; color: var(--ink); }
  .shell { display: block; }
  .content { padding: 0; }
  .card { border: none; padding: 0; }

  .print-only { display: block; }
  .print-letterhead { display: flex; }

  /* والأخيرةُ بلا قطع — وإلا خرجت ورقةٌ بيضاء في ذيل كل دفعة */
  .print-sheet { break-after: page; margin-block-start: 0; }
  .print-sheet:last-of-type { break-after: auto; }

  /* الكشف الطويل ينقسم على ورقتين — فترويستُه تتكرر على الثانية، وإلا
     قُرئ نصفُه بلا عناوين أعمدة. والصفُّ لا ينقسم على ورقتين أبداً */
  .print-grid thead { display: table-header-group; }
  .print-grid tr { break-inside: avoid; }

  /* الإطار يملأ ورقته والتواقيعُ في أسفله.
     كانت `.sig-row` تطفو تحت النص بهامشٍ ثابت، فيختلف موضعُ التوقيع من طالبٍ
     لآخر بطول جدوله ويبقى ثلثُ الورقة أبيضَ تحته — ووثيقةٌ تُوقَّع يُتوقَّع
     موضعُ توقيعها. و200mm دون ارتفاع المساحة المطبوعة (297 - 32 هامشاً)
     بفارقٍ يتسع للترويسة، فلا يُدفع النموذجُ إلى ورقةٍ ثانية. */
  .print-frame {
    display: flex;
    flex-direction: column;
    min-block-size: 200mm;
  }
  .print-frame .sig-row { margin-block-start: auto; padding-block-start: var(--space-32); }

  /* الحالة لا تُمثَّل بلون على الورق — إطار ونص */
  .badge {
    border: var(--border-width) solid var(--ink);
    background: none !important;
    color: var(--ink) !important;
  }
  .table th, .table td { height: auto; padding-block: var(--space-8); }
}

/* رمز اقتران الواتساب — يُمسح بكاميرا جوال، فالحجم ليس زينة.
   240px هو أصغر ما يُمسح من مسافةٍ مريحة أمام الشاشة، والخلفية بيضاء صريحة
   لا شفافة: قارئُ الرمز يحتاج تبايناً، والشفافة تأخذ لون البطاقة. */
.qr-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-16);
  margin-block: var(--space-16);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-12);
}
/* لوحة الاقتران — الخطوات تُقرأ ثم الرمز يُمسح، فهي أولاً في اتجاه القراءة
   والرمز إلى جوارها. وكان الرمز تحتها بألف بكسل، فيُمرَّر إليه ولا يُرى مع
   تعليمته — والاثنان يُقرآن معاً أو لا معنى لأيهما. */
.pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 240px;
  gap: var(--space-24);
  align-items: start;
  margin-block: var(--space-16);
}
@media (max-width: 820px) {
  .pair { grid-template-columns: minmax(0, 1fr); }
}
.pair-qr { display: flex; flex-direction: column; align-items: center; gap: var(--space-8); }
.pair-note {
  font-size: var(--text-xs);
  color: var(--text-3);
  text-align: center;
  line-height: var(--leading-body);
}

/* مربّع الانتظار بمقاس الرمز نفسه — فلا تقفز الصفحة حين يصل.
   وحدُّه متقطّع: «هنا سيظهر شيء» لا «هنا شيءٌ فارغ». */
.qr-wait {
  inline-size: 240px;
  block-size: 240px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed var(--border);
  border-radius: var(--radius-8);
  color: var(--text-3);
}

.qr-img {
  inline-size: 240px;
  block-size: 240px;
  flex: none;
  background: #FFFFFF;
  padding: var(--space-8);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  image-rendering: pixelated;   /* الرمز شبكةُ مربّعات — التنعيم يُذيب حوافها */
}

/* مفتاح الجهاز — يُعرض مرة واحدة، فيُقرأ ويُنسخ بلا التباس بين الحروف */
.key-once {
  font-family: ui-monospace, 'Courier New', monospace;
  font-size: var(--text-md);
  word-break: break-all;
  margin-block-start: var(--space-8);
}

/* نص طويل داخل خلية — سطر واحد ينتهي بحذف، والكامل في مصدره لا في الجدول */
.cell-clamp {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* شجرة الهيكل الدراسي — صف واحد لكل صف دراسي وفصوله شارات */
.tree-row {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  flex-wrap: wrap;
  padding-block: var(--space-8);
  border-block-start: var(--border-width) solid var(--border-row);
}
.tree-name { font-size: var(--text-sm); font-weight: var(--weight-medium); min-width: 120px; }
.tree-tags { display: flex; gap: var(--space-4); flex-wrap: wrap; flex: 1; }

/* --------------------------------------------------------------------------
   الأسطح العامة — الدخول · بوابة ولي الأمر · الصفحات التعريفية
   ورق كريمي في شاشة الدخول وحدها (CLAUDE.md §8-أ)
   -------------------------------------------------------------------------- */
.auth-page {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--g-paper);
  padding: var(--space-16);
}
.auth-card {
  background: var(--surface);
  border: var(--border-width) solid rgba(5, 42, 43, .09);
  border-radius: var(--radius-12);
  box-shadow: var(--e2);
  padding: var(--space-32);
  width: 100%;
  max-width: 400px;
}
/* الشعار كاملاً — هنا تتّسع المساحة فيُقرأ سطراه الصغيران، بخلاف القائمة */
.auth-brand {
  display: flex;
  justify-content: center;
  margin-block-end: var(--space-24);
}
.auth-brand img {
  width: 250px;
  max-width: 100%;
  height: auto;
}
/* فاصل يخفت طرفاه — الحدّ الصلب على الورق يقطعه، وهذا يقسّمه */
.auth-rule {
  block-size: 1px;
  border: 0;
  margin-block: 0 var(--space-24);
  background: linear-gradient(90deg, transparent, rgba(5, 42, 43, .16), transparent);
}
.auth-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  text-align: center;
  margin-block-end: var(--space-8);
}
.auth-sub {
  font-size: var(--text-sm);
  color: var(--text-2);
  text-align: center;
  margin-block-end: var(--space-24);
}
.auth-foot { text-align: center; margin-block-start: var(--space-16); font-size: var(--text-sm); }

/* الأيقونة التي تدلّ على اتجاه القراءة تنعكس في RTL — السهم والشيفرون والردّ
   والتراجع وأبواب الدخول والخروج (CLAUDE.md §8-ب). ولا تنعكس الساعة ولا
   الصح ولا العدسة ولا الشعار.
   وكانت `icon-flip` تُطبع من `icon()` **بلا قاعدة تقابلها في هذا الملف**:
   الصنف يخرج في الصفحة ولا يفعل شيئاً، فيمرّ من كل فحصٍ صامتاً.
   والقيد على `[dir="rtl"]` لا على الصنف وحده: في لغةٍ تُقرأ يساراً إلى يمين
   يبقى الرمز كما رُسم، فتكون الإنجليزية ترجمةً لا إعادة بناء (§8-ج). */
[dir="rtl"] .icon-flip { transform: scaleX(-1); }

/* ── الدعم والتواصل ────────────────────────────────────────────────────────
   **لا زرَّ عائماً هنا.** كان «؟» يثبت في `inset-inline-end: 24px` أسفل
   الشاشة — وهو بعينه موضعُ شريط حفظ الحضور الملتصق، فيغطّي «حفظ» و«بقية
   الطلاب غائبون» فلا يجدهما المحضِّر ويظنّهما غير موجودين. والعائمُ يفعلها
   في كل شاشةٍ لها شريطٌ سفليّ. فصار الدعم عنصراً في القائمة الجانبية
   (`Nav::groups`) — موضعٌ لا يقع خلفه شيء، ومعه نصُّه لا رمزُه وحده. */

/* شبكة صفحة الدعم: الأسئلة عمودٌ رئيس أوسع، والنموذج عمودٌ جانبيٌّ ألصق.
   عمودان على المكتب (‏1.6fr للأسئلة، والنموذج ثابتٌ يلتصق أعلى الشاشة)،
   وعمودٌ واحد حين تضيق الشاشة — لا `1fr 1fr` جامد. */
.help-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(320px, 1fr);
  gap: var(--space-24);
  align-items: start;
}
@media (max-width: 900px) {
  .help-grid { grid-template-columns: 1fr; }
}

/* فئات الأسئلة — كلٌّ عنوانها بأيقونةٍ ثم أقسامها المطوية تحتها. */
.help-faq { display: flex; flex-direction: column; gap: var(--space-24); }
.help-cat { display: flex; flex-direction: column; gap: var(--space-8); }
.help-cat-head {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin: 0;
  padding-block-end: var(--space-8);
  border-block-end: 1px solid var(--border);
  font-family: var(--font-display);
  font-size: var(--text-md);
  color: var(--ink);
}
.help-cat-head svg { color: var(--link); flex: none; }

/* النموذج الجانبي يلتصق أعلى الشاشة على المكتب فيبقى مرئياً مع تصفّح الأسئلة. */
.help-aside { position: sticky; top: var(--space-24); }
@media (max-width: 900px) {
  .help-aside { position: static; }
}

/* نتائج البحث عن المدرسة (‎/p) — صفٌّ قابلٌ للنقر كاملاً لا اسمٌ برابط:
   الشاشة على جوال وليّ أمر، ومساحة اللمس 44px لا سطرُ نصّ. */
.find-list {
  list-style: none;
  margin-block: var(--space-16) 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.find-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  min-block-size: 44px;
  padding: var(--space-12) var(--space-16);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
}
.find-item:hover { background: var(--paper); border-color: var(--primary); }
.find-item svg { color: var(--text-3); flex: none; }
.btn-block { display: flex; width: 100%; }

.public-page {
  background: var(--paper);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
.public-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-12);
  padding: var(--space-16) var(--space-24);
  background: var(--ink);
}
.public-brand {
  color: var(--surface);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}
.public-nav { display: flex; align-items: center; gap: var(--space-16); }
.public-nav a { color: var(--surface); text-decoration: none; font-size: var(--text-md); }
.public-main { flex: 1; padding: var(--space-32) var(--space-24); }
.public-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-16) var(--space-24);
  border-block-start: var(--border-width) solid var(--border);
  color: var(--text-2);
  font-size: var(--text-sm);
  text-align: center;
}
.footer-nav { display: flex; gap: var(--space-16); flex-wrap: wrap; justify-content: center; }
.footer-nav a { color: var(--link); }

/* حُذف هنا بلوكُ `.hero` و`.hero-title` و`.hero-text` و`.features`
   و`.feature-*`: بقايا صفحةٍ عامة قديمة، صارت كلها على أصناف `.lp-*` في
   `landing.css`. ولم يكن ميتاً بلا أثر — `.hero` كانت **معرّفة مرتين**،
   فورثت لوحةُ المعلومات منها `text-align: center` و`max-width: 640px`
   بلا قصد. (DESIGN.md §0.1 — والاصطدام لا ينكشف إلا في تركيبته) */
.legal-card {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  padding: var(--space-32);
  max-width: 720px;
  margin-inline: auto;
  line-height: var(--leading-body);
}

/* --------------------------------------------------------------------------
   الصفحة الرئيسية — خطاب رسمي: الترويسة والرقم الصادر والختم
   المقاسات مسنودة إلى سلّم DESIGN.md (11·13·15·17·22) لا إلى مقاسات حرة
   -------------------------------------------------------------------------- */
.letter {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  max-width: 760px;
  margin-inline: auto;
  margin-block: var(--space-24) var(--space-32);
  overflow: hidden;
}
.letter-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-16);
  padding: var(--space-24) var(--space-32) var(--space-16);
  border-block-end: 2px solid var(--ink);
}
.letter-logo {
  display: block;
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.letter-sub { font-size: var(--text-sm); color: var(--text-2); }
.letter-meta {
  text-align: start;
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: var(--leading-body);
}
.letter-body { position: relative; padding: var(--space-32); }
.letter-title {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  max-width: 480px;
  margin-block-end: var(--space-12);
}
.letter-lede {
  color: var(--text-2);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  max-width: 520px;
  margin-block-end: var(--space-24);
}
.letter-actions {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  flex-wrap: wrap;
}

/* الختم — العنصر الموقّع للصفحة: دائري مفرّغ بحبر داكن، مائل كختم حقيقي */
.letter-stamp {
  position: absolute;
  inset-inline-end: var(--space-32);
  inset-block-end: var(--space-24);
  width: 148px;
  height: 148px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  padding: var(--space-12);
  transform: rotate(-8deg);
  opacity: .85;
}
.letter-stamp::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: var(--border-width) solid var(--ink);
  border-radius: 50%;
}
.stamp-name { font-size: var(--text-xl); font-weight: var(--weight-semibold); }

.roster { max-width: 760px; margin-inline: auto; margin-block-end: var(--space-32); }
.roster-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-12);
  margin-block-end: var(--space-12);
}
.roster-title { font-size: var(--text-xl); font-weight: var(--weight-semibold); color: var(--ink); }
.roster-desc { color: var(--text-2); font-size: var(--text-sm); }

.pledges {
  max-width: 760px;
  margin-inline: auto;
  margin-block-end: var(--space-32);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-16);
}
.pledge { border-block-start: 2px solid var(--ink); padding-block-start: var(--space-12); }
.pledge-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  margin-block-end: var(--space-8);
}
.pledge-text { font-size: var(--text-sm); color: var(--text-2); line-height: var(--leading-body); }

@media (max-width: 640px) {
  .letter-head { flex-direction: column; align-items: flex-start; }
  .letter-stamp { position: static; margin-inline: auto; margin-block-start: var(--space-24); }
}
.auth-card-wide { max-width: 520px; }
.auth-center { text-align: center; }

/* بلاطات البوابة — مؤشرات ولي الأمر */
.portal-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-8);
  margin-block-end: var(--space-24);
}
.portal-tile {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  padding: var(--space-12);
  text-align: center;
}
.portal-num { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.portal-label { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-4); }

/* السلوك والمواظبة في البوابة — درجتان بأرقامٍ كبيرة، ومخالفاتٌ بمسمّاها.
   شفافية (ب): لا سلّم ولا سوابق ولا notes — الحارس في ParentConductRepo. */
.portal-section { margin-block-end: var(--space-24); }
.portal-scores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: var(--space-8);
  margin-block-end: var(--space-12);
}
.portal-score-card {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  padding: var(--space-16);
  text-align: center;
}
.portal-score {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-medium);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.portal-score-out { font-size: var(--text-sm); color: var(--text-3); }
.portal-score-na { font-size: var(--text-lg); color: var(--text-3); }

.portal-violations { display: flex; flex-direction: column; gap: var(--space-8); }
.portal-vio {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
}
.portal-vio-name { font-size: var(--text-sm); color: var(--ink); }
.portal-vio-meta { display: inline-flex; align-items: center; gap: var(--space-8); flex: none; }
.portal-vio-date { font-size: var(--text-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.portal-empty {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-3);
}

.portal-excuse-days { display: flex; flex-direction: column; gap: var(--space-8); }
.portal-excuse-day {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
}
.portal-excuse-date { font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.portal-excuse-state {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-xs);
}
.portal-excuse-state.is-ok     { color: var(--ok-text); }
.portal-excuse-state.is-open   { color: var(--warn-text); }
.portal-excuse-state.is-closed { color: var(--text-3); }

/* تعاميم المدرسة في البوابة — بطاقاتٌ تُقرأ، بلا إجراء. */
.portal-circulars { display: flex; flex-direction: column; gap: var(--space-8); margin-block-end: var(--space-24); }
.portal-circular {
  border: var(--border-width) solid var(--border);
  border-inline-start: 3px solid var(--link);
  border-radius: var(--radius-10);
  padding: var(--space-12) var(--space-16);
}
.portal-circular-title { font-size: var(--text-md); font-weight: var(--weight-semibold); margin: 0 0 var(--space-4); }
.portal-circular-body { color: var(--text); margin: 0; white-space: pre-wrap; }
.portal-circular-meta { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-8); }

/* --------------------------------------------------------------------------
   تبويبات البوابة وبطاقات الطلب (DESIGN.md §3.25 · §3.26)
   -------------------------------------------------------------------------- */

/* البوابة صفحةٌ طويلةٌ داخل `.auth-page` المُوسِّطة رأسياً — والتوسيط المرن
   (`align-items: center`) **يقصّ أعلى ما يفوق الشاشة فلا يُمرَّر إليه**.
   `margin-block: auto` يوسّط ما قصُر ويترك ما طال يبدأ من أوله. وحشوة 32px
   تبتلع عرض الجوال الضيّق، فتُخفَّض دون 420px. */
.portal-shell { margin-block: auto; }
@media (max-width: 420px) {
  .portal-shell { padding: var(--space-16); }
}

/* رأس البوابة — الاسمان متقاربان، والطالب بأيقونته فلا يلتبس باسم المدرسة */
.portal-head { margin-block-end: var(--space-16); }
.portal-head .auth-sub {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

/* شريط التبويبات — **روابطُ خادم** لا تبديلٌ بجافاسكربت: الجوال الضعيف يفتحها،
   وزرُّ الرجوع يعمل، والرابط يُشارَك على تبويبه. مساحة اللمس 44px، والأيقونة
   مع نصّها دائماً (لا شريطَ أيقوناتٍ مجرّدة — CLAUDE.md §8-ب).
   وليس `sticky`: هو داخل بطاقةٍ ذات حشوة، فيمرّ المحتوى من جانبيه تحت الحشوة. */
.portal-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  padding: var(--space-4);
  margin-block-end: var(--space-16);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
}
.portal-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  min-block-size: 44px;
  padding: var(--space-8) var(--space-4);
  border-radius: var(--radius-8);
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: background var(--motion) var(--ease), color var(--motion) var(--ease);
}
.portal-tab:hover, .portal-tab.is-hover { color: var(--ink); text-decoration: none; }
.portal-tab.is-active {
  background: var(--g-primary);
  color: var(--cream);
}
.portal-tab-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* عدّاد المعلّق — شارةٌ صغيرةٌ على التبويب: «عندك طلبٌ ينتظر» قبل أن يفتحه */
.portal-tab-count {
  flex: none;
  min-inline-size: 18px;
  padding-inline: 5px;
  border-radius: var(--radius-pill);
  background: var(--warn);
  color: #FFFFFF;
  font-size: var(--text-xs);
  line-height: 18px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.portal-tab.is-active .portal-tab-count { background: var(--cream); color: var(--ink); }

/* نغمة بلاطة حالة اليوم — الحدّ إلزاميّ مع اللون، والنصّ يقول الحالة أصلاً */
.portal-tile-ok     { border-color: var(--ok-bd);     background: var(--ok-bg);     color: var(--ok-text); }
.portal-tile-warn   { border-color: var(--warn-bd);   background: var(--warn-bg);   color: var(--warn-text); }
.portal-tile-danger { border-color: var(--danger-bd); background: var(--danger-bg); color: var(--danger-text); }
.portal-tile-info   { border-color: var(--info-bd);   background: var(--info-bg);   color: var(--info-text); }
.portal-tile-ok .portal-label,
.portal-tile-warn .portal-label,
.portal-tile-danger .portal-label,
.portal-tile-info .portal-label { color: inherit; opacity: .8; }

/* بطاقة الطلب — للعذر والاستئذان معاً. الحدّ الجانبيّ يحمل الحالة لوناً،
   والشارة تحملها نصّاً وأيقونة (لا لونَ وحده). */
.portal-reqs { display: flex; flex-direction: column; gap: var(--space-12); }
.portal-req {
  border: var(--border-width) solid var(--border);
  border-inline-start: 3px solid var(--neutral);
  border-radius: var(--radius-12);
  padding: var(--space-12) var(--space-16);
  background: var(--surface);
}
.portal-req-ok     { border-inline-start-color: var(--ok); }
.portal-req-warn   { border-inline-start-color: var(--warn); }
.portal-req-danger { border-inline-start-color: var(--danger); }
.portal-req-muted  { border-inline-start-color: var(--neutral); }

.portal-req-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-8);
  margin-block-end: var(--space-8);
}
.portal-req-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  margin: 0;
  min-inline-size: 0;
  overflow-wrap: anywhere;
}
.portal-req-head .badge { flex: none; }

/* الحقائق — عمودان على الجوال فلا تصير قائمةً طويلة، وثلاثةٌ فوق ذلك */
.portal-req-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: var(--space-8);
  margin: 0;
}
.portal-req-fact { min-inline-size: 0; }
.portal-req-key { font-size: var(--text-xs); color: var(--text-3); }
.portal-req-val {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.portal-req-note {
  margin: var(--space-8) 0 0;
  font-size: var(--text-sm);
  color: var(--text-2);
  white-space: pre-wrap;
}

/* سبب الرفض — «مرفوض» بلا سببٍ تفتح اتصالاً بالمدرسة، فالسبب في البطاقة */
.portal-req-verdict {
  margin-block-start: var(--space-12);
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid var(--danger-bd);
  border-radius: var(--radius-8);
  background: var(--danger-bg);
}
.portal-req-verdict-key {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--danger-text);
}
.portal-req-verdict-text {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--danger-text);
  white-space: pre-wrap;
}
/* ما يُفعل بعد القرار — «مرفوض» تقول ما حدث، وهذه تقول ما العمل */
.portal-req-hint {
  margin: var(--space-8) 0 0;
  font-size: var(--text-xs);
  color: var(--text-2);
}
.portal-req-foot { margin-block-start: var(--space-12); }

/* «متى» في نموذج الاستئذان — يومٌ ونافذةٌ **يُقرآن ولا يُختاران**: الطلب لليوم
   حصراً، فحقلُ تاريخٍ يَعِد باختيارٍ لا يقبله الخادم. */
.portal-exit-when {
  padding: var(--space-8) var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  margin-block-end: var(--space-12);
}

/* بطاقة مشاركة رابط البوابة في لوحة المعلومات — نصٌّ ورقاقة نسخ متجاورتان */
.dash-share { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-16); }
.dash-share-tile { flex: 1 1 320px; max-inline-size: 540px; }

/* رقاقة نسبة المشاهدة — رابطٌ إلى قائمة القرّاء */
.seen-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--link);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.seen-pill:hover { text-decoration: underline; }
.seen-pill-of { color: var(--text-2); font-size: var(--text-xs); }

/* رمز التحقق — يُقرأ رقماً رقماً على الجوال */
.otp-input {
  font-size: var(--text-xl);
  text-align: center;
  letter-spacing: .3em;
  font-variant-numeric: tabular-nums;
}
.legal-card h2 {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--ink);
  margin-block: var(--space-24) var(--space-8);
}
.legal-card p { color: var(--text-2); font-size: var(--text-sm); }
.legal-list {
  color: var(--text-2);
  font-size: var(--text-sm);
  list-style: disc;
  padding-inline-start: var(--space-24);
  margin-block: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.legal-note {
  color: var(--text-3);
  font-size: var(--text-sm);
  margin-block: var(--space-8) var(--space-16);
}
.legal-controller {
  margin-block-start: var(--space-32);
  padding-block-start: var(--space-16);
  border-block-start: 1px solid var(--border);
}
.legal-controller p {
  color: var(--text-2);
  font-size: var(--text-sm);
  margin-block: var(--space-4);
}
.legal-controller-mail { unicode-bidi: plaintext; }

/* وثيقة قانونية كاملة (سياسة الخصوصية) — عناوين فرعية وجداول ونصّ مؤكَّد */
.legal-meta { color: var(--text-3); font-size: var(--text-sm); margin-block: var(--space-4); }
.legal-card h3 {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--ink);
  margin-block: var(--space-16) var(--space-8);
}
.legal-doc strong { color: var(--ink); font-weight: var(--weight-medium); }
ol.legal-list { list-style: decimal; }
.legal-table-wrap { overflow-x: auto; margin-block: var(--space-8) var(--space-16); }
.legal-card table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.legal-card th,
.legal-card td {
  border: 1px solid var(--border);
  padding: var(--space-8);
  text-align: start;
  vertical-align: top;
  color: var(--text-2);
}
.legal-card th { background: var(--surface-alt); color: var(--ink); font-weight: var(--weight-medium); }

/* --------------------------------------------------------------------------
   وثيقة المساءلة — الورق الكريمي. مقفولة الشكل بقرار المالك: تُنقل كما هي.
   -------------------------------------------------------------------------- */
.doc-paper {
  background: var(--paper);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  padding: var(--space-32);
  max-width: 760px;
  color: var(--ink);
}
.doc-paper .print-letterhead { display: flex; border-block-end-color: var(--ink); }
.doc-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-12) var(--space-32);
  margin-block-end: var(--space-24);
  padding-block-end: var(--space-16);
  border-block-end: var(--border-width) solid rgba(5, 42, 43, .2);
}
.doc-fields dt { font-size: var(--text-xs); color: var(--text-2); margin-block-end: 2px; }
.doc-fields dd { margin: 0; font-size: var(--text-md); font-weight: var(--weight-medium); }
.doc-flag {
  font-size: var(--text-sm);
  border-inline-start: 3px solid var(--ink);
  padding-inline-start: var(--space-12);
  margin-block-end: var(--space-16);
}
.doc-body {
  line-height: var(--leading-doc);
  font-size: var(--text-md);
  white-space: pre-line;
  max-width: 62ch;
}
.doc-section {
  margin-block-start: var(--space-24);
  padding-block-start: var(--space-16);
  border-block-start: var(--border-width) solid rgba(5, 42, 43, .2);
}
.doc-section h3 {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  margin-block-end: var(--space-8);
}
.doc-section p { font-size: var(--text-md); margin-block-end: var(--space-4); }
.doc-sign-meta { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-8); }
.doc-signatures {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-32);
  margin-block-start: var(--space-48);
}
.doc-serial-head { font-size: var(--text-md); color: var(--text-2); font-weight: var(--weight-regular); }
.doc-actions { max-width: 760px; margin-block-start: var(--space-16); }
.doc-actions h2 { font-size: var(--text-md); font-weight: var(--weight-semibold); }
.doc-actions form { margin-block-end: var(--space-16); }
.doc-actions form:last-child { margin-block-end: 0; }

/* بطاقة مساءلة في قائمة الموظف */
.letter-card {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  padding: var(--space-16);
  margin-block-end: var(--space-16);
  max-width: 680px;
}
.letter-card--action { border-inline-start: 3px solid var(--primary); }
.letter-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-12);
  flex-wrap: wrap;
}
.letter-subject { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.letter-serial { font-size: var(--text-xs); color: var(--text-3); margin-block-start: var(--space-4); }
.letter-deadline {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
  margin-block: var(--space-12);
}
.letter-read {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--h-row);
  font-size: var(--text-sm);
}

@media print {
  /* الوثيقة الرسمية تُطبع على أبيض بحبر داكن — لا خلفية كريمية */
  .doc-paper { background: none; border: none; padding: 0; max-width: none; }
  .doc-body { max-width: none; }
  .doc-signatures { margin-block-start: var(--space-48); }
}

/* عنوان قسم داخل صفحة — «ما ينتظر رداً» ثم «الأرشيف» */
.section-lead {
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  margin-block: var(--space-24) var(--space-12);
}
.section-lead:first-of-type { margin-block-start: 0; }

/* الكشف التدريجي — نموذج الرد مطوي حتى يقرر الموظف الرد */
.reply-block {
  border-block-start: var(--border-width) solid var(--border);
  margin-block-start: var(--space-12);
  padding-block-start: var(--space-12);
}
.reply-toggle {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-row);
  padding-inline: var(--space-16);
  border: var(--border-width) solid var(--primary);
  border-radius: var(--radius-8);
  color: var(--primary);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.reply-toggle::-webkit-details-marker { display: none; }
.reply-toggle:hover { background: var(--page); }
.reply-block[open] .reply-toggle { margin-block-end: var(--space-16); }

/* صندوق التوقيع — إجراء لا رجعة فيه، فيُفصَل بصرياً عن كتابة النص */
.sign-box {
  background: var(--paper);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  padding: var(--space-16);
  margin-block: var(--space-16);
}
.sign-title {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.sign-note {
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: var(--leading-body);
  margin-block: var(--space-4) var(--space-12);
}
.sign-box .field { margin-block-end: 0; }
.sig-slot { text-align: center; }
.sig-role { font-size: var(--text-xs); color: var(--text-2); }
.sig-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  margin-block: var(--space-4) var(--space-32);
}
.sig-line { border-block-end: var(--border-width) solid var(--ink); }
.sig-date { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-4); }

/* صف أزرار متجاور */
.btn-row { display: flex; gap: var(--space-8); flex-wrap: wrap; align-items: center; }

/* ترويسة الطباعة — كتلة المدرسة وكتلة الوثيقة */
.letterhead-school { display: flex; align-items: center; gap: var(--space-12); }
.letterhead-meta { text-align: end; }

/* صف فصل دراسي — رقمه ثم تاريخاه، وينهار عمودياً على الجوال */
.term-row {
  display: grid;
  grid-template-columns: 90px 1fr 1fr;
  gap: var(--space-12);
  align-items: start;
  padding-block: var(--space-8);
  border-block-start: var(--border-width) solid var(--border-row);
}
.term-no {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  padding-block-start: var(--space-24);
}
@media (max-width: 640px) {
  .term-row { grid-template-columns: 1fr; }
  .term-no { padding-block-start: 0; }
}

/* اسم في خلية يفتح الملف — الوصول المباشر أسرع من قائمة الصف */
.cell-link { color: inherit; text-decoration: none; }
.cell-link:hover { color: var(--link); text-decoration: underline; }

/* قائمة تُصفَّى بالكتابة — لائحة المخالفات 128 بنداً لا تُتصفَّح بالتمرير */
.combo { display: flex; flex-direction: column; gap: var(--space-8); }
.combo-search { margin-block-end: 0; }

/* --------------------------------------------------------------------------
   صفحة التفصيل — عمود هوية ثابت (DESIGN.md §4.2)
   الوكيل يفتح الملف وهو على الهاتف مع ولي الأمر: «من» يبقى ظاهراً
   بينما يتغيّر «ماذا».
   -------------------------------------------------------------------------- */
/* حُذفت هنا `.detail-layout` و`.detail-side` و`.identity-*` و`.stat-mini`:
   ألغى تخطيطا §4.2 الجديدان العمودَ الجانبي القديم — لم يكن يقول «من هو»
   بوضوح (كان يعيد ما في المتن حرفاً بحرف) ولا يعين على الفعل. */

/* حقل مصدره خارجي (نور) — يُعرض ولا يُعدَّل */
.locked-field .field-input,
.locked-field .field-select {
  background: var(--page);
  color: var(--text-2);
  cursor: not-allowed;
}
.locked-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-3);
  margin-inline-start: var(--space-4);
}

/* الخط الزمني الموحّد — تيار واحد لكل ما جرى للسجل */
.timeline { margin: 0; }
/* أيقونةٌ ثم تاريخ ثم الحدث: أربعون سطراً متطابق البنية لا تُمسح بالعين
   بلا نقطة ارتكاز، ورمز النوع يميّز الغياب من المخالفة قبل قراءة كلمة. */
.tl-row {
  display: grid;
  grid-template-columns: 30px 108px minmax(0, 1fr);
  gap: var(--space-12);
  align-items: center;
  padding-block: var(--space-12);
  border-block-end: var(--border-width) solid var(--border-row);
}
.tl-row:last-child { border-block-end: none; }
/* 108px لا 74: «23 صفر 1448هـ» كانت تنكسر سطرين فيتضاعف ارتفاع الصف */
.tl-date {
  font-size: var(--text-xs);
  color: var(--text-2);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tl-body { min-width: 0; }
.tl-head { font-size: var(--text-sm); }
/* رقاقة النوع — بلون حالته، مفرّغة كبقية الأيقونات */
.tl-icon {
  inline-size: 30px;
  block-size: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-8);
  flex: none;
}
.tl-icon-ok     { background: var(--ok-bg);     color: var(--ok); }
.tl-icon-warn   { background: var(--warn-bg);   color: var(--warn); }
.tl-icon-danger { background: var(--danger-bg); color: var(--danger); }
.tl-icon-info   { background: var(--info-bg);   color: var(--info); }
.tl-icon-muted  { background: var(--muted-bg);  color: var(--neutral); }
.tl-sub { font-size: var(--text-xs); color: var(--text-2); margin-block-start: var(--space-4); }

@media (max-width: 1024px) {
  /* الصف يصير سطرين: الأيقونة يمينَ التاريخ، والحدث تحته */
  .tl-row { grid-template-columns: 30px minmax(0, 1fr); }
  .tl-date { grid-column: 2; }
  .tl-body { grid-column: 2; }
}

/* --------------------------------------------------------------------------
   تنقّل فرعي داخل مجموعة شاشات (إعدادات المدرسة) — DESIGN.md §3.24
   يختلف عن .tabs: التبويب يبدّل محتوى الصفحة، وهذا ينقل بين صفحات.
   -------------------------------------------------------------------------- */
.subnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-end: var(--space-16);
}
.subnav-item {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-btn-sm);
  padding-inline: var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--text-sm);
  text-decoration: none;
}
.subnav-item:hover { color: var(--text); border-color: var(--primary); text-decoration: none; }
.subnav-item.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--surface);
  font-weight: var(--weight-medium);
}
/* عدّاد المعلّق على التبويب — «كم ينتظر هنا» قبل أن يفتحه، ويظهر فوق الصفر
   فقط. على التبويب النشط ينقلب إلى الكريميّ ليُقرأ على خلفية الهوية. */
.subnav-count {
  margin-inline-start: var(--space-8);
  min-inline-size: 18px;
  padding-inline: 5px;
  border-radius: var(--radius-pill);
  background: var(--warn);
  color: #FFFFFF;
  font-size: var(--text-xs);
  line-height: 18px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.subnav-item.is-active .subnav-count { background: var(--cream); color: var(--ink); }

/* --------------------------------------------------------------------------
   خطوات مرقّمة — إجراء يُنفَّذ بالترتيب (ربط جهاز، تهيئة سنة) — §3.23
   الرقم يحمل معنى: لا تُستعمل لقائمة غير مرتّبة.
   -------------------------------------------------------------------------- */
.steps { counter-reset: step; }
.step {
  display: grid;
  grid-template-columns: var(--space-24) minmax(0, 1fr);
  gap: var(--space-12);
  padding-block: var(--space-8);
  border-block-start: var(--border-width) solid var(--border-row);
}
.step:first-child { border-block-start: none; padding-block-start: 0; }
.step::before {
  counter-increment: step;
  content: counter(step);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--space-24);
  height: var(--space-24);
  border-radius: 50%;
  background: var(--primary);
  color: var(--surface);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
/* خطوةٌ تمّت وخطوةٌ الآن — والحالة **لا تُقال باللون وحده**: المنتهية
   تحمل صحّاً بدل رقمها، والحالية يثقُل عنوانها. فالمكفوف لوناً يقرأ الفرق. */
.step-done::before { content: '\2713'; background: var(--ok); }
.step-now::before { box-shadow: 0 0 0 3px var(--info-bg); }
.step-now .step-title { font-weight: var(--weight-semibold); }
.step-done .step-title { color: var(--text-2); }
/* الخطوة غير الحالية عنوانٌ وحده — شرحُ ما فُرغ منه أو ما لم يحن ضجيجٌ دائم.
   فالبطاقة تنكمش كلما تقدّم التركيب، والتعليماتُ تخدم من يحتاجها الآن. */
.step:not(.step-now) .step-text { display: none; }
.step:not(.step-now) { padding-block: var(--space-4); }

.step-title { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.step-text {
  font-size: var(--text-sm);
  color: var(--text-2);
  line-height: var(--leading-body);
  margin-block-start: var(--space-4);
}
/* قيمة تُنسخ كما هي إلى الجهاز — تُقرأ حرفاً حرفاً فلا تلتبس */
.step-value {
  display: inline-block;
  font-family: ui-monospace, 'Courier New', monospace;
  font-size: var(--text-sm);
  background: var(--page);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-6);
  padding: 2px var(--space-8);
  margin-block-start: var(--space-4);
  direction: ltr;
}

/* رمز المصادقة المربّع — يُرسم في المتصفح (app.js + qrcode.js المحلية).
   **الخلفية بيضاء صريحة والحشو هو المنطقة الهادئة**: الماسح يحتاج إطاراً
   فارغاً بعرض أربع وحداتٍ حول الرمز، والحشو الأبيض يؤدّيها — فلا هامش
   داخل الـSVG نفسه (margin: 0 عند التوليد). */
.tfa-qr {
  inline-size: 180px;
  padding: var(--space-12);
  margin-block-start: var(--space-8);
  background: #FFFFFF;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
}
.tfa-qr svg { display: block; inline-size: 100%; block-size: auto; }


/* --------------------------------------------------------------------------
   شبكة الجدول الدراسي — أيام × حصص. تُمرَّر أفقياً داخل حاويتها لا بالصفحة.
   -------------------------------------------------------------------------- */
.grid-scroll { overflow-x: auto; }
.grid-table { min-width: 720px; }
.grid-table th:first-child { position: sticky; inset-inline-start: 0; background: var(--surface); }
.grid-select, .grid-input {
  min-width: 120px;
  height: var(--h-btn-sm);
  font-size: var(--text-xs);
  padding-inline: var(--space-8);
}
/* إسناد داخل صف الجدول — قائمة وزر متجاوران */
.inline-assign { display: flex; gap: var(--space-4); align-items: center; }

/* --------------------------------------------------------------------------
   31. القيمة المنسوخة والدليل بعمودين — `.copy-grid` (DESIGN.md §3.25)
   -------------------------------------------------------------------------- */
/* الفنّي واقف أمام الجهاز يكتب على لوحة أرقام صغيرة. الاسم الإنجليزي أولاً
   لأنه ما يبحث عنه في شاشة الجهاز، والعربي شرحٌ له لا العكس.
   والمربّع كلّه زر — سطرٌ للقيمة وآخر للزر يهدر عرضاً لا يحتاجه أحد. */
.copy-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-8);
}
.copy-tile {
  display: block;
  inline-size: 100%;
  text-align: start;
  font-family: inherit;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  padding: var(--space-8) var(--space-12);
  cursor: pointer;
  transition: border-color var(--motion) var(--ease), background var(--motion) var(--ease),
              transform var(--motion) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .copy-tile:hover { background: var(--surface-alt); border-color: var(--link); }
}
.copy-tile.is-hover { background: var(--surface-alt); border-color: var(--link); }
.copy-tile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}
.copy-tile-key {
  font-family: ui-monospace, 'Courier New', monospace;
  font-size: var(--text-xs);
  color: var(--text-2);
  direction: ltr;
}
.copy-tile-icon { display: flex; color: var(--text-3); }
.copy-tile-value {
  display: block;
  font-family: ui-monospace, 'Courier New', monospace;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  line-height: var(--leading-heading);
  direction: ltr;
  unicode-bidi: isolate;
  overflow-wrap: anywhere;
}
.copy-tile-gloss { display: block; font-size: var(--text-xs); color: var(--text-2); }

/* تم النسخ — الأيقونة تتبدّل والحد يتلوّن، بلا إزاحة في التخطيط */
.copy-tile .copy-icon-done { display: none; }
.copy-tile.is-copied .copy-icon-copy { display: none; }
.copy-tile.is-copied .copy-icon-done { display: block; }
.copy-tile.is-copied { border-color: var(--ok); }
.copy-tile.is-copied .copy-tile-icon { color: var(--ok); }

/* --------------------------------------------------------------------------
   دليل التركيب — `.guide` (DESIGN.md §3.25)
   -------------------------------------------------------------------------- */
/* مرجعٌ قصير يُنسخ منه بجانب خطوات طويلة تُقرأ بالترتيب. تحت بعضهما يمدّان
   الصفحة طولاً بلا سبب: المساحة تُعطى على قدر المحتوى. */
.guide {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-16);
  align-items: start;
}
.guide-side { display: grid; gap: var(--space-12); align-content: start; }
@media (max-width: 1024px) {
  .guide { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   32. القسم المطوي — `.collapse` (DESIGN.md §3.26)
   -------------------------------------------------------------------------- */
/* الدليل يُقرأ مرة عند التركيب ثم يزاحم المراقبة اليومية طول العمر. */
.collapse { margin-block-start: var(--space-24); }
.collapse-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--h-btn);
  color: var(--text);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.collapse-toggle::-webkit-details-marker { display: none; }
.collapse-toggle:hover { color: var(--link); }
.collapse-hint {
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  color: var(--text-2);
}
/* مغلق: يشير إلى اتجاه القراءة · مفتوح: لأسفل */
.collapse-caret {
  display: flex;
  color: var(--text-2);
  transform: rotate(90deg);
  transition: transform var(--motion) var(--ease);
}
.collapse[open] .collapse-caret { transform: none; }
.collapse-body { margin-block-start: var(--space-12); }


/* الغلاف الممتد — الصفحة التسويقية تتولى حشوها بنفسها */
.public-main-flush { flex: 1; }


/* --------------------------------------------------------------------------
   لوحة المعلومات (DESIGN.md §3.28)

   الرسوم هنا SVG داخل الصفحة — لا مكتبة رسوم: سياسة المحتوى تمنع سكربتاً
   خارجياً، وخطٌّ واحد لا يستحق 90 كيلوبايت. والقيم تُرسم من الخادم فتظهر
   بلا جافاسكربت وتُطبع كما تُعرض.

   وألوان الحالة الأربعة من DESIGN.md ولا خامس، **ومع كل لونٍ نصُّه ورقمه**
   في مفتاح تحت الرسم — فالحالة لا تُعرف باللون وحده (§3.6).
   -------------------------------------------------------------------------- */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-16);
  margin-block-end: var(--space-24);
}

/* الرقم البطل — نسبة الحضور: رقمٌ واحد يُقرأ من الباب */
.hero {
  display: flex;
  align-items: baseline;
  gap: var(--space-8);
  margin-block: var(--space-8) var(--space-4);
}
.hero-value {
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  direction: ltr;
}
.hero-unit { font-size: var(--text-lg); color: var(--text-2); }
.hero-note { font-size: var(--text-sm); color: var(--text-2); }

/* شريط تركيبة اليوم — SVG: النسبة عددٌ متصل لا صنفٌ في ورقة الأنماط */
.compo {
  inline-size: 100%;
  block-size: var(--space-16);
  display: block;
  margin-block: var(--space-12) var(--space-8);
}
.compo-seg-present { fill: var(--ok); }
.compo-seg-late    { fill: var(--warn); }
.compo-seg-absent  { fill: var(--danger); }
.compo-seg-excused { fill: var(--info); }

/* ونقاط المفتاح تأخذ اللون خلفيةً لا حشواً */
.compo-present { background: var(--ok); }
.compo-late    { background: var(--warn); }
.compo-absent  { background: var(--danger); }
.compo-excused { background: var(--info); }

/* المفتاح: نقطة اللون واسمه وعدده — الثلاثة معاً دائماً */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8) var(--space-16);
  margin-block-start: var(--space-12);
  font-size: var(--text-sm);
  color: var(--text-2);
}
.legend-item { display: flex; align-items: center; gap: var(--space-4); }
/* على اللوح الداكن يرث المفتاح لونه — لا لونَ نصٍّ فاتحاً مكرراً في كل عنصر */
.dash-hero .legend { color: #9DB6B5; }
.dash-hero .legend-n { color: var(--cream); }
/* «لم يُرصد بعدُ» يقف خارج المفتاح **بلا لون**: نقصُ رصدٍ لا نتيجةَ رصد،
   وإعطاؤه لوناً يجعله حالةً خامسة (م31/9 — الطالب بلا سجل يُحسب حاضراً) */
.legend-rest { margin-inline-start: auto; opacity: .85; }
.legend-dot {
  inline-size: 10px;
  block-size: 10px;
  border-radius: 3px;
  flex: none;
}
.legend-n {
  color: var(--ink);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
}

/* منحنى الاتجاه — سلسلة واحدة فلا مفتاح لها، والعنوان يسمّيها */
.chart { inline-size: 100%; block-size: auto; display: block; }
.chart-grid   { stroke: var(--border); stroke-width: 1; }
.chart-line   { fill: none; stroke: var(--primary); stroke-width: 2;
                stroke-linejoin: round; stroke-linecap: round; }
.chart-area   { fill: var(--primary); opacity: .07; }
/* النقطة بحلقة بلون السطح كي لا تذوب في الخط عند التقارب */
.chart-dot    { fill: var(--primary); stroke: var(--surface); stroke-width: 2; }
/* **`direction: ltr` على النصوص الرقمية وحدها** لا على `.chart text` كلها:
   الوثيقة RTL و`text-anchor` منطقيٌّ لا مكانيّ، فـ`end` تمدّ النصّ يميناً
   ويُقصّ آخرُ رقمٍ عند الإطار. لكنّ تعميمها على كل نصوص الرسم يقلب
   التلميحة — وفيها عربيةٌ وأرقام — إلى «20 2.2 · صفر1448هـ%».
   والمُخصِّص `.chart text` (0-1-1) يغلب `.chart-tip-text` (0-1-0) فلا
   ينفع ردُّها بصنفٍ بعده (§0.1). */
.chart-label,
.chart-value { direction: ltr; }
.chart-label { fill: var(--text-3); font-size: 10px; }

/* شارة آخر قيمة — داخل الرسم دائماً، بخلفيةٍ تفصلها عن الخط تحتها */
.chart-value-bg { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
.chart-value    { fill: var(--ink); font-size: 12px; font-weight: 700; }

/* التلميحة: يوم النقطة ونسبته بالمرور — وعمودُ الإمساك بعرض المسافة بين
   نقطتين، فاليوم يُلتقط في كل مكانٍ فوقه لا على نقطةٍ نصفُ قطرها 3px */
/* `transparent` لا `none`: الشفّاف يلتقط الفأرة والمعدوم لا يلتقطها */
.chart-hit { fill: transparent; }
.chart-pt { outline: none; }
.chart-pt:focus-visible .chart-dot { stroke: var(--ink); stroke-width: 3; }
.chart-tip { opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.chart-pt:hover .chart-tip,
.chart-pt:focus-within .chart-tip { opacity: 1; }
.chart-pt:hover .chart-dot { r: 5; }
.chart-tip-bg   { fill: var(--ink); }
/* `isolate` يفصل الرقمَ عن العربية فلا تتشابك اتجاهاتهما داخل السطر */
.chart-tip-text { fill: var(--cream); font-size: 11px; unicode-bidi: isolate; }

@media (prefers-reduced-motion: reduce) {
  .chart-tip { transition: none; }
}

/* حُذفت `.mini*`: صارت موجزات اللوحة بطاقاتِ `.stat` — الرقم هو الرسالة،
   وسطرٌ نصفُه تسمية ونصفه رقم يجعل الخمسة تُقرأ جدولاً صغيراً. */

/* اللوح البطل — سطح هوية بعرض الشاشة (DESIGN.md §4.10).
   نسبة اليوم سؤالُ الصباح الأول، ومساواتها ببقية البطاقات تجعلها واحدةً
   منها. ووهجٌ أخضر خلفها يفصلها عن الداكن بلا حدٍّ صلب. */
.dash-hero {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-32);
  align-items: center;
  padding: var(--space-24);
  margin-block-end: var(--space-16);
  border-radius: var(--radius-12);
  background: var(--g-brand);
  box-shadow: var(--e2);
  color: var(--cream);
  position: relative;
  overflow: hidden;
}
.dash-hero::before {
  content: '';
  position: absolute;
  inset-block: -60%;
  inset-inline-start: -80px;
  inline-size: 420px;
  background: radial-gradient(circle at 35% 50%, rgba(31, 138, 95, .30), transparent 66%);
  pointer-events: none;
}
.dash-hero > * { position: relative; }
.dash-hero-label { font-size: var(--text-xs); color: #9DB6B5; }
.dash-hero-value {
  font-family: var(--font-display);
  font-size: var(--kiosk-verdict-size);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
  font-variant-numeric: tabular-nums;
  margin-block-start: var(--space-4);
}
.dash-hero-unit { font-size: var(--text-lg); color: #9DB6B5; margin-inline-start: 2px; }
.dash-hero-note { font-size: var(--text-xs); color: #9DB6B5; max-width: 260px; margin-block-start: var(--space-4); }
.dash-hero-compo { min-width: 0; }

@media print {
  .dash-grid { display: block; }
  /* الداكن لا يُطبع: حبرٌ يُهدر ونصٌّ كريمي يختفي على الورق */
  .dash-hero { background: none; color: var(--text); box-shadow: none; border: var(--border-width) solid var(--border); }
  .dash-hero::before { display: none; }
  .dash-hero-label, .dash-hero-note, .dash-hero-unit { color: var(--text-2); }
}

@media (max-width: 768px) {
  .dash-hero { grid-template-columns: 1fr; gap: var(--space-16); }
  .dash-hero-note { max-width: none; }
}

/* --------------------------------------------------------------------------
   سلّم التقدير 1–5 (DESIGN.md §3.27) — رصد تقييم الأداء
   خمسة أزرار متجاورة، نقرةٌ واحدة. مبنيّ على `input[type=radio]` لا على JS:
   المتصفح يعطي تنقّل الأسهم والاختيار الواحد وحالة `:checked` مجاناً، ويعمل
   بلا جافاسكربت.
   -------------------------------------------------------------------------- */
.rate-set {
  display: inline-flex;
  gap: var(--space-4);
  border: 0;
  padding: 0;
  margin: 0;
}
.rate-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.rate-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  /* 44px مساحة لمس — الرصد يجري على الجوال في الميدان كما على المكتب */
  inline-size: var(--h-field);
  block-size: var(--h-field);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-8);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  cursor: pointer;
  user-select: none;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease),
              color var(--motion) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .rate-pill:hover { border-color: var(--primary); color: var(--text); }
}
.rate-input:checked + .rate-pill {
  background: var(--primary);
  border-color: var(--primary);
  color: #FFFFFF;
}
/* حلقة التركيز واجبة: التنقّل بالأسهم لا يُرى بلا علامة */
.rate-input:focus-visible + .rate-pill {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}
.rate-set:disabled .rate-pill { opacity: .45; cursor: not-allowed; }
.rate-pill:active { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) {
  .rate-pill { transition: none; }
  .rate-pill:active { transform: none; }
}

/* شريط التوزيع — `<meter>` الأصلي: قيمته في بنيته لا في سمة نمط،
   ويقرؤه قارئ الشاشة عدداً. والعدد مكتوبٌ بجانبه دائماً (DESIGN.md §3.6). */
.meter {
  inline-size: 100%;
  min-inline-size: 80px;
  block-size: var(--space-8);
  border: 0;
  border-radius: var(--radius-8);
  background: var(--surface-alt);
  appearance: none;
}
.meter::-webkit-meter-bar {
  background: var(--surface-alt);
  border: 0;
  border-radius: var(--radius-8);
}
.meter::-webkit-meter-optimum-value,
.meter::-webkit-meter-suboptimum-value,
.meter::-webkit-meter-even-less-good-value {
  background: var(--primary);
  border-radius: var(--radius-8);
}
.meter::-moz-meter-bar { background: var(--primary); border-radius: var(--radius-8); }

/* --------------------------------------------------------------------------
   33. معرض /dev/ui وحده — عيّنات الهوية

   أصناف الصفحة الداخلية التي تُغلق قبل الإطلاق. لا تُستعمل في شاشة منتج،
   ووجودها هنا لا في القالب لأن القاعدة الحاكمة لا تُستثنى لصفحة أدوات
   (DESIGN.md §0).
   -------------------------------------------------------------------------- */
.ui-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-16);
  margin-block-end: var(--space-16);
}
.ui-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-12);
  margin-block-start: var(--space-12);
}
.ui-swatch {
  padding: var(--space-12);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-10);
  background: var(--surface);
}
.ui-swatch .stat-label { margin-block-start: var(--space-8); }

.ui-depth {
  padding: var(--space-16);
  border-radius: var(--radius-12);
  background: var(--surface);
  font-size: var(--text-xs);
}
.ui-depth-1 { box-shadow: var(--e1); }
.ui-depth-2 { box-shadow: var(--e2); }
.ui-depth-3 { box-shadow: var(--e3); }

.ui-grad {
  min-block-size: 64px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-10);
  border: var(--border-width) solid var(--border);
  font-size: var(--text-xs);
}
.ui-grad-brand   { background: var(--g-brand);   color: var(--cream); border-color: transparent; }
.ui-grad-primary { background: var(--g-primary); color: var(--surface); border-color: transparent; }
.ui-grad-paper   { background: var(--g-paper);   color: var(--ink); }
.ui-grad-card    { background: var(--g-card);    color: var(--text-2); }

.ui-solid {
  display: inline-block;
  inline-size: var(--space-48);
  block-size: var(--space-16);
  border-radius: var(--radius-6);
}
.ui-solid-ok     { background: var(--ok); }
.ui-solid-warn   { background: var(--warn); }
.ui-solid-danger { background: var(--danger); }
.ui-solid-info   { background: var(--info); }
.ui-solid-muted  { background: var(--neutral); }

/* --------------------------------------------------------------------------
   34. شريط الجاهزية — `.setup-gaps` (CLAUDE.md §3 «التهيئة تسبق كل شيء»)

   يظهر حين تنقص السنة أو الفصول أو أيام التقويم، ويختفي تماماً عند
   الاكتمال: شريطُ «كل شيء تمام» دائمُ الظهور يُقرأ زينةً ثم لا يُقرأ حين
   يتغيّر. والأثر مكتوبٌ بجانب النقص لا تحته — «لا فصول» لا تُقلق أحداً،
   و«وحدة السلوك كلها معطّلة» تُقلق.
   -------------------------------------------------------------------------- */
.setup-list {
  margin: var(--space-4) 0 0;
  padding-inline-start: var(--space-16);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}
.setup-list li { margin-block-end: var(--space-4); }
.setup-list li:last-child { margin-block-end: 0; }
.setup-blocks {
  display: block;
  font-size: var(--text-xs);
  opacity: .85;
}
.setup-fix {
  display: inline-block;
  margin-block-start: 2px;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: inherit;
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   35. الملف الشخصي — تخطيطان بأطروحتين (DESIGN.md §4.2)

   ألغى كلاهما العمود الجانبي القديم: لم يكن يقول «من هو» بوضوح — كان يعيد
   ما في المتن حرفاً بحرف — ولا يعين على الفعل.

   · `.pb` + `.rail`  ملف **الطالب**: شريط هوية نحيف، والعمود يقول **ما تفعله**
   · `.ph`            ملف **الموظف**: رأسٌ عريض يقول «من هو» مرةً، والمتن يتحرّر

   والفرق أطروحةٌ لا ذوق: ملف الطالب يُفتح **للفعل** — اتصالٌ بوليّه أو رصدُ
   مخالفة أو فتحُ مؤشر حرمان. وملف الموظف يُفتح **للقراءة والمراجعة**.
   -------------------------------------------------------------------------- */

/* ── أ. الرأس العريض — ملف الموظف ───────────────────────────────────────── */
.ph {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-24);
  align-items: center;
  padding: var(--space-16) var(--space-24);
  margin-block-end: var(--space-16);
  background: var(--g-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
  position: relative;
  overflow: hidden;
}
/* شريط الحالة على الحافة — اللون يُقرأ قبل الاسم */
.ph::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 4px;
  background: linear-gradient(180deg, var(--ph-accent, var(--neutral)), transparent);
}
.ph-ok      { --ph-accent: var(--ok); }
.ph-warn    { --ph-accent: var(--warn); }
.ph-danger  { --ph-accent: var(--danger); }
.ph-info    { --ph-accent: var(--info); }
.ph-muted   { --ph-accent: var(--neutral); }

.ph-face {
  inline-size: 68px;
  block-size: 68px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-12);
  background: var(--g-chip);
  color: var(--primary);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-xl);
}
.ph-name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
}
.ph-line,
.ph-contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  font-size: var(--text-sm);
  color: var(--text-2);
}
.ph-line { margin-block-start: var(--space-4); }
.ph-contact { margin-block-start: var(--space-8); }
.ph-sep { color: var(--text-3); }
.ph-num { font-variant-numeric: tabular-nums; }

.ph-scores { display: flex; gap: var(--space-24); }
.ph-score { text-align: center; min-inline-size: 92px; }
.ph-score-v {
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-flat);
  font-variant-numeric: tabular-nums;
}
/* عنوان الرقم تحته — وكان بلا قاعدة، فيخرج بحجم المتن ولون الحبر تحت رقمٍ
   بحجم 40 فيتنازعانه. والمؤشّر رقمُه هو الخبر واسمُه هو التسمية */
.ph-score-l {
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-flat);
}

/* ── ب. شريط الهوية والسكة — ملف الطالب ─────────────────────────────────── */
.pb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  margin-block-end: var(--space-16);
  background: var(--g-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
}
.pb-face {
  inline-size: var(--space-48);
  block-size: var(--space-48);
  display: grid;
  place-items: center;
  border-radius: var(--radius-10);
  background: var(--g-chip);
  color: var(--primary);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
}
.pb-name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}
.pb-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-inline-start: auto;
  font-size: var(--text-sm);
  color: var(--text-2);
}

/* السكة — ترتيبها ترتيب القرار: أعرف ← أُنذر ← أتصل ← أرصد */
.pw {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 264px;
  gap: var(--space-16);
  align-items: start;
}
.rail { position: sticky; top: var(--space-16); display: grid; gap: var(--space-12); }
.rail-card {
  padding: var(--space-16);
  background: var(--g-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
}
.rail-title { font-size: var(--text-xs); color: var(--text-3); margin-block-end: var(--space-8); }
.rail-who { font-size: var(--text-sm); }
.rail-phone {
  font-size: var(--text-sm);
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
  margin-block: 2px var(--space-12);
}
.rail-acts { display: grid; gap: var(--space-8); }
.rail-acts .btn { width: 100%; justify-content: flex-start; }

/* لوح الخطر — يُرى من طرف العين والقراءةُ في المتن */
.rail-risk {
  border-color: var(--danger-bd);
  background: linear-gradient(160deg, var(--danger-lift), var(--danger-bg));
  color: var(--danger-text);
}
.rail-risk .rail-title { color: inherit; opacity: .8; }
.rail-risk-h { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-md); }
.rail-risk-m { font-size: var(--text-xs); margin-block: var(--space-4) var(--space-12); }

/* الدرجة ومقياسها — يخدمان التخطيطين */
.gauge { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-8); }
.gauge-l { font-size: var(--text-sm); color: var(--text-2); }
.gauge-v {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-flat);
  font-variant-numeric: tabular-nums;
}
/* SVG لا عرضٌ في سمة نمط: النسبة عددٌ متصل، و`style=""` ممنوع في القوالب
   (DESIGN.md §0). وسمة `width` على `rect` بنيةٌ لا نمط — كشريط اللوحة. */
.bar { display: block; inline-size: 100%; block-size: 6px; margin-block: var(--space-8) var(--space-16); }
.bar:last-child { margin-block-end: 0; }
.bar-track { fill: var(--border-row); }
.bar-ok     { fill: var(--ok); }
.bar-warn   { fill: var(--warn); }
.bar-danger { fill: var(--danger); }
.bar-info   { fill: var(--info); }
.ph-score .bar { margin-block: var(--space-8) 0; }

@media (max-width: 1024px) {
  .pw { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}
@media (max-width: 900px) {
  .ph { grid-template-columns: auto minmax(0, 1fr); }
  .ph-scores { grid-column: 1 / -1; justify-content: flex-start; }
  .pb-meta { margin-inline-start: 0; width: 100%; }
}
@media print {
  /* السكة إجراءات — والورقة لا تُنقر */
  .rail, .pb-face, .ph-face { display: none; }
  .pw { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   36. البنية الأكاديمية — تعديل الفصل من رقاقته (DESIGN.md §4.3-ب)
   -------------------------------------------------------------------------- */
/* الفصل رقاقةٌ تُنقر لا شارةٌ ساكنة — بلا هذا لا سبيل إلى تعديل اسمه ولا حذفه */
.tag-edit {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--motion) var(--ease), color var(--motion) var(--ease);
}
.tag-edit:hover { border-color: var(--primary); color: var(--primary); text-decoration: none; }
.tag-edit svg { opacity: .55; }
.tag-edit:hover svg { opacity: 1; }

.tree-head-acts { display: flex; align-items: center; gap: var(--space-8); }

/* ── ارتباط مزوّدٍ في شاشة ربط الرسائل — `.conn` ───────────────────────────
   للمدرسة ارتباطاتٌ عدّةٌ محفوظةٌ على القناة الواحدة (الترحيل 057)، فكلٌّ
   قسمٌ مطويّ: عنوانه اسمُ المزوّد وحالُه، وتفاصيلُه ومفاتيحُه تحته.
   والطيّ لأن المقروء يومياً هو **من يرسل**، لا حقولُ مفاتيحَ أُدخلت مرة. */
.conn {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  margin-block-start: var(--space-12);
  padding: var(--space-12);
}
/* لا ظلَّ ولا تدرّج: بطاقةٌ داخل بطاقة تُميَّز بالحدّ لا بعمقٍ ثانٍ (§8-أ) */
.conn[open] { background: var(--surface-alt); }
.conn-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  flex-wrap: wrap;
  min-block-size: 44px;          /* مساحة لمسٍ كاملة على الجوال */
  cursor: pointer;
  list-style: none;
}
.conn-head::-webkit-details-marker { display: none; }
.conn-name {
  font-family: var(--font-display);
  font-size: var(--text-md);
  color: var(--ink);
}
.conn-tags { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
.conn-head:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
/* الشيفرون ينقلب عند الفتح — دورانٌ لا `.icon-flip`: تلك لانعكاس RTL،
   وهذا يدلّ على «مفتوح/مطويّ» فيدور رأسياً في الاتجاهين معاً */
.conn-name { display: inline-flex; align-items: center; gap: var(--space-8); }
.conn-name svg { color: var(--text-3); flex: none; transition: transform var(--motion) var(--ease); }
.conn[open] > .conn-head .conn-name svg { transform: rotate(180deg); }

/* الحذف على حدةٍ أسفل القسم — الإجراء المدمّر لا يجاور المُشغِّل (§3.11) */
.conn-danger {
  margin-block-start: var(--space-16);
  padding-block-start: var(--space-12);
  border-block-start: var(--border-width) solid var(--border);
  display: flex;
  justify-content: flex-start;
}

/* «أضف منصّة» — **زرٌّ يُفتح** لا نموذجٌ قائمٌ دائماً (كشفٌ تدريجيّ).
   `summary` يحمل أصناف الزرّ، فيبدو زرّاً ويعمل بلا سطر JS. */
.conn-add {
  margin-block-start: var(--space-16);
  padding-block-start: var(--space-16);
  border-block-start: var(--border-width) solid var(--border);
}
.conn-add-btn {
  display: inline-flex;
  list-style: none;
  cursor: pointer;
}
.conn-add-btn::-webkit-details-marker { display: none; }
.conn-add[open] > .conn-add-btn { margin-block-end: var(--space-16); }

/* ── «من يرسل الآن؟» — شريطُ حالٍ لا شارةٌ في الرأس ────────────────────────
   سؤالُ الصفحة الأول، وجوابُه كان شارةً صغيرةً تُلتمس بين أخواتها. وأربع
   نغماتٍ لكل حال: خلفيةٌ وحدٌّ ونصّ (§8-أ) — والحدّ إلزاميّ، وبدونه يسبح
   الشريط في البطاقة. والحالة نصٌّ وأيقونةٌ لا لونٌ وحده. */
.chan-status {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  margin-block-end: var(--space-16);
  padding: var(--space-12);
  border-radius: var(--radius-8);
  border: var(--border-width) solid transparent;
}
.chan-status svg { flex: none; }
.chan-status > div { flex: 1 1 auto; min-inline-size: 0; }
.chan-status strong { display: block; font-size: var(--text-sm); }
.chan-status p {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-flat);
  color: var(--text-2);
}
.chan-status-live {
  background: var(--ok-bg);
  border-color: var(--ok-bd);
  color: var(--ok-text);
}
.chan-status-off {
  background: var(--warn-bg);
  border-color: var(--warn-bd);
  color: var(--warn-text);
}

/* الحذف داخل النافذة — على حدةٍ أسفلها، مفصولاً عن «حفظ» بحدٍّ ومسافة:
   الإجراء المدمّر لا يجاور الحافظ (DESIGN.md §3.11) */
.modal-danger {
  margin-block-start: var(--space-16);
  padding-block-start: var(--space-12);
  border-block-start: var(--border-width) solid var(--border);
  display: flex;
  justify-content: flex-start;
}

/* --------------------------------------------------------------------------
   لوح الباب — مستأذنو اليوم كما يراها الحارس على جواله

   الشاشة الوحيدة في النظام التي تُقرأ **واقفاً بيدٍ واحدة**: فبطاقةٌ لكل
   مستأذن لا صفٌّ في جدول (الجدول يحتاج تمريراً أفقياً على جوال)، ومساحاتُ
   اللمس واسعة، والمقاسات أكبر درجةً من مثيلاتها في شاشات المكتب.
   -------------------------------------------------------------------------- */
.gate {
  min-block-size: 100dvh;
  background: var(--page);
  padding: var(--space-16) var(--space-16) var(--space-32);
}

.gate-head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
  align-items: center;
  justify-content: space-between;
  margin-block-end: var(--space-16);
}
.gate-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
  margin: 0;
}
.gate-sub { font-size: var(--text-sm); color: var(--text-2); margin: var(--space-4) 0 0; }

/* عمودٌ على الجوال، وشبكةٌ على الشاشات الأوسع — الوكيل يفتحها من مكتبه */
.gate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--space-12);
}

.gate-card {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  box-shadow: var(--e1);
  padding: var(--space-16);
}
/* من حان وقته يُميَّز بحدٍّ لا بلونٍ وحده — ومعه شارةٌ نصّية في رأسه */
.gate-due { border-color: var(--ok-bd); border-inline-start: 4px solid var(--ok); }

.gate-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  margin-block-end: var(--space-8);
}
.gate-time {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* اسم الطالب هو البطل — به يُنادى، ويُقرأ من مسافة ذراع */
.gate-name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
  margin: 0;
}
.gate-class { font-size: var(--text-sm); color: var(--text-2); margin: var(--space-4) 0 var(--space-12); }

/* الحقائق شبكةٌ لا سطرٌ طويل: العين تلتقط القيمة تحت عنوانها */
.gate-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-8) var(--space-12);
  margin: 0 0 var(--space-12);
  padding-block-end: var(--space-12);
  border-block-end: var(--border-width) solid var(--border-row);
}
.gate-facts-wide { grid-column: 1 / -1; }
.gate-facts dt {
  font-size: var(--text-xs);
  color: var(--text-3);
  margin-block-end: 2px;
}
.gate-facts dd {
  margin: 0;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* لوح المطابقة — سبب وجود الشاشة كلها: طالبٌ يُسلَّم لغير من أُذن له خطأٌ
   لا يُصلَح بعد الباب. فله سطحه ولونه، والهوية بمقاسٍ يُقارَن ببطاقةٍ في يد. */
.gate-receiver {
  display: grid;
  gap: 2px;
  background: var(--info-bg);
  border: var(--border-width) solid var(--info-bd);
  border-radius: var(--radius-8);
  padding: var(--space-12);
}
.gate-receiver-solo { background: var(--warn-bg); border-color: var(--warn-bd); }
.gate-receiver-label {
  font-size: var(--text-xs);
  color: var(--text-2);
}
.gate-receiver-name {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
}
.gate-receiver-id {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
/* التباعد على الأرقام اللاتينية وحدها وبقيد `[dir="ltr"]` (CLAUDE.md §8-أ):
   الهوية تُقارَن خانةً خانةً ببطاقةٍ في يد، والتباعد يفصلها للعين */
.gate-receiver-id[dir="ltr"] { letter-spacing: .04em; }
.gate-receiver-note { font-size: var(--text-xs); color: var(--text-2); }

.gate-empty {
  display: grid;
  justify-items: center;
  gap: var(--space-8);
  padding: var(--space-32) var(--space-16);
  color: var(--text-3);
  text-align: center;
}
.gate-empty-title { font-size: var(--text-md); color: var(--text-2); margin: 0; }
.gate-empty-text { font-size: var(--text-sm); margin: 0; max-width: 36ch; }

.gate-foot {
  font-size: var(--text-xs);
  color: var(--text-3);
  text-align: center;
  margin-block-start: var(--space-24);
}

/* --------------------------------------------------------------------------
   جدولي — جدول الموظف نفسه (DESIGN.md §3.34)

   **لا شبكةَ يومٍ × حصة.** خمسةُ أيامٍ في ثمانية أعمدةٍ تخرج عن شاشة الجوال
   أفقياً أو تُقصّ، والمعلم يقرأ جدوله على جواله لا على مكتب. فالوحدةُ بطاقةُ
   يومٍ تُقرأ وحدها: عمودٌ واحدٌ على الجوال وخمسةُ أعمدةٍ على الشاشة الكبيرة،
   بلا تمريرٍ أفقيّ في الحالين.
   -------------------------------------------------------------------------- */
.sched-week {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-12);
}
@media (min-width: 900px) {
  /* `minmax(0, 1fr)` لا `1fr`: اسم الفصل الطويل يوسّع العمود ويكسر التساوي */
  .sched-week { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.sched-day {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-12);
  padding: var(--space-12);
  box-shadow: var(--e1);
}
.sched-day-h {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text);
  margin: 0 0 var(--space-8);
}

/* صفُّ حصة — والبطاقةُ هي المُظلَّلة وما بداخلها مسطّح (DESIGN.md §1.6) */
.sched-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-8);
  padding-block: var(--space-8);
  border-block-start: var(--border-width) solid var(--border-row);
}
.sched-row:first-of-type { border-block-start: 0; }

.sched-period {
  flex: none;
  min-width: 22px;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}
.sched-class   { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text); }
.sched-subject { font-size: var(--text-xs); color: var(--text-2); }
.sched-free    { font-size: var(--text-xs); color: var(--text-3); }

/* الانتظار — حدٌّ جانبيٌّ ملوّن **ومعه نصٌّ دائماً**: الحالة لا تُمثَّل باللون
   وحده (CLAUDE.md §8-أ)، فالصفُّ يقول «انتظار» ولا يُترك للون يقولها */
.sched-row-standby {
  border-inline-start: var(--indicator-width) solid var(--warn);
  padding-inline-start: var(--space-8);
}

.sched-today { margin-block-end: var(--space-16); }
.sched-today .sched-row:first-of-type { border-block-start: var(--border-width) solid var(--border-row); }
