/* ---------- 0. الخط: مُستضاف ذاتيًا ----------
   كان يُحمَّل من fonts.googleapis.com بطلبٍ يحجب الرسم عبر الشبكة — تأخيرٌ حقيقي
   على شبكات الجوال، وتبعية طرف ثالث قد تُحجب في بعض الشبكات. الآن 4 ملفات
   woff2 مجزّأة على النطاق العربي (36KB كاملة) من نفس الأصل:
     • لا طلب خارجي، ولا preconnect، ولا تتبّع طرف ثالث
     • سياسة CSP صارت أضيق: لا fonts.googleapis ولا fonts.gstatic
     • swap + preload: الخط يصل قبل الرسم عمليًا فلا قفزة تبديل تُذكر
   الترخيص: Tajawal تحت OFL — الاستضافة الذاتية مسموحة. */
/* ملاحظة: Tajawal لا تملك وزن 600 إطلاقًا. كل font-weight:600 كان المتصفح
   يرقّيه إلى 700 ضمنًا، فجُعل صريحًا — لا تغيير بصري، وانتهى الغموض. */
@font-face { font-family: 'Tajawal'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/tajawal-400.woff2') format('woff2'); }
@font-face { font-family: 'Tajawal'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/tajawal-500.woff2') format('woff2'); }
@font-face { font-family: 'Tajawal'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/tajawal-700.woff2') format('woff2'); }
@font-face { font-family: 'Tajawal'; font-style: normal; font-weight: 800; font-display: swap;
  src: url('../fonts/tajawal-800.woff2') format('woff2'); }

/* ============================================================
   Be Great Academy Jo — نظام التصميم
   RTL-first · Mobile-first · بلا إطار عمل · بلا خطوة بناء
   ============================================================ */

/* ---------- 1. Tokens ---------- */
:root {
  /* ألوان العلامة — مُقاسة من بكسلات الشعار الرسمي نفسه (ملف 1536×1536)
     ثلاث نقاط ارتكاز حقيقية، والباقي سُلّم مشتق منها:
       #38ABE4  الأزرق السماوي في الحلقة والكتاب
       #1C78B9  الأزرق الأساسي في الكتاب والشخصية
       #134477  الكحلي في كلمة Be Great Academy
     كل زوج نص/خلفية أدناه مُختبَر على WCAG AA (انظر tests/contrast) */
  --brand-900: #134477;   /* ← من الشعار: لون الاسم */
  --brand-800: #15527F;
  --brand-700: #17629A;
  --brand-600: #1C78B9;   /* ← من الشعار: الأساسي — الأزرار والروابط */
  --brand-500: #2491CD;
  --brand-400: #38ABE4;   /* ← من الشعار: السماوي */
  --brand-300: #7BC7EE;
  --brand-200: #B2DDF6;
  --brand-100: #DBEFFB;
  --brand-50:  #F0F8FD;

  --ink-900: #0D1B2A;
  --ink-700: #29415A;
  --ink-500: #5B7186;
  --ink-300: #97A8B8;
  --ink-200: #CBD6E0;
  --ink-100: #E6ECF2;
  --ink-50:  #F5F8FA;
  --field-border: #7C8FA2; /* حدّ حقول النموذج — كان ink-200 عند 1.48:1، الآن 3.33:1 (P1-5) */
  --white:   #FFFFFF;

  --ok-600:   #16703F;   /* كان #1B7F4B (4.43:1 على ok-100 — راسب AA)؛ الآن 5.41:1 (P1-5) */
  --ok-100:   #E3F5EB;
  --warn-700: #8A5A00;
  --warn-100: #FDF3DC;
  --err-600:  #C02A2A;
  --err-100:  #FCEAEA;
  --wa-600:   #12833F;   /* أغمق من أخضر واتساب الأصلي ليحقق AA مع النص الأبيض */

  /* مقياس مسافات بأساس 4px */
  --s1: .25rem;  --s2: .5rem;   --s3: .75rem;  --s4: 1rem;
  --s5: 1.25rem; --s6: 1.5rem;  --s8: 2rem;    --s10: 2.5rem;
  --s12: 3rem;   --s16: 4rem;   --s20: 5rem;

  --r-sm: 8px; --r-md: 12px; --r-lg: 18px; --r-full: 999px;

  /* سلّم ارتفاع بظلال مصبوغة بلون العلامة لا بالرمادي المحايد —
     الظل الرمادي فوق سطح أزرق يبدو متسخًا، والمصبوغ يبدو جزءًا من الهوية. */
  --sh-1: 0 1px 2px rgba(19,68,119,.06), 0 2px 8px rgba(19,68,119,.05);
  --sh-2: 0 4px 12px rgba(19,68,119,.08), 0 12px 28px rgba(19,68,119,.07);
  --sh-3: 0 10px 24px rgba(19,68,119,.10), 0 24px 56px rgba(19,68,119,.10);
  --sh-brand: 0 6px 16px rgba(28,120,185,.28);

  /* منحنيات الحركة: خروج سريع ودخول هادئ — إحساس «مادي» لا آلي */
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --dur-1: .18s; --dur-2: .32s; --dur-3: .55s;

  --container: 1120px;
  --header-h: 68px;

  --font: 'Tajawal', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;

  /* هوية الأكاديمية فاتحة بقصد — الشعار والملصقات كلها على خلفية بيضاء.
     تثبيت color-scheme يمنع المتصفح من تلوين حقول النموذج وأشرطة التمرير
     بألوان الوضع الداكن فوق صفحة بيضاء عند مَن جهازه على الوضع الداكن. */
  color-scheme: light;
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  margin: 0;
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink-700);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}
img, svg { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4 { color: var(--ink-900); line-height: 1.35; margin: 0 0 var(--s3); font-weight: 800; }
h1, .as-h1 { font-size: clamp(1.75rem, 5vw, 2.85rem); letter-spacing: -.02em; }
h2 { font-size: clamp(1.4rem, 3.6vw, 2.1rem); letter-spacing: -.015em; }
h3 { font-size: clamp(1.1rem, 2.4vw, 1.3rem); }
p  { margin: 0 0 var(--s4); }
a  { color: var(--brand-700); text-decoration-thickness: 1px; text-underline-offset: 3px; }
ul { margin: 0 0 var(--s4); padding-inline-start: 1.25rem; }

/* ---------- 3. Layout ---------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--s5); }
.section   { padding-block: var(--s12); }
.section--tight { padding-block: var(--s10); }
.section--alt   { background: var(--brand-50); }
.stack > * + * { margin-top: var(--s4); }
.center { text-align: center; }
.muted  { color: var(--ink-500); }
.small  { font-size: .875rem; }
.skip-link {
  position: absolute; inset-inline-start: var(--s4); top: -100px;
  background: var(--brand-700); color: #fff; padding: var(--s3) var(--s5);
  border-radius: var(--r-sm); z-index: 200; font-weight: 700;
}
.skip-link:focus { top: var(--s3); }

.section-head { max-width: 58ch; margin-bottom: var(--s8); }
.section-head.center { margin-inline: auto; }
.eyebrow {
  display: inline-block; font-size: .8125rem; font-weight: 700; letter-spacing: .06em;
  /* brand-600 على brand-100 = 4.00:1 ويرسب في WCAG AA (المطلوب 4.5).
     brand-700 = 5.46:1 ويمرّ، ويبقى ضمن ألوان الشعار. */
  color: var(--brand-700); background: var(--brand-100);
  padding: var(--s1) var(--s3); border-radius: var(--r-full); margin-bottom: var(--s3);
}

/* حلقة تركيز واحدة للموقع كله: مرئية بوضوح على أي خلفية، ولا تزيح شيئًا
   لأنها outline لا border. الاعتماد على الحلقة الافتراضية يعطي مظهرًا مختلفًا
   في كل متصفح ويكاد يختفي فوق الأزرق. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--brand-600);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
.on-dark :where(a, button):focus-visible { outline-color: #fff; }

/* ---------- 4. Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.94); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--ink-100);
}
.site-header__inner { display: flex; align-items: center; gap: var(--s4); min-height: var(--header-h); }
.brand { display: flex; align-items: center; gap: var(--s3); text-decoration: none; margin-inline-end: auto; }
.brand__mark { width: 40px; height: 40px; flex: 0 0 40px; border-radius: var(--r-full); }
.brand__text { display: flex; flex-direction: column; line-height: 1.2; }
.brand__name { font-weight: 800; color: var(--ink-900); font-size: 1.0625rem; }
.brand__sub  { font-size: .6875rem; color: var(--ink-500); letter-spacing: .04em; }

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 1px solid var(--ink-200);
  background: var(--white); border-radius: var(--r-sm); cursor: pointer; color: var(--ink-900);
}
.nav-toggle:hover { background: var(--ink-50); }

.site-nav { display: none; }
.site-nav__list { display: flex; align-items: center; gap: var(--s2); list-style: none; margin: 0; padding: 0; }
.site-nav__link {
  display: block; padding: var(--s2) var(--s3); border-radius: var(--r-sm);
  color: var(--ink-700); text-decoration: none; font-weight: 700; font-size: .9375rem;
}
.site-nav__link:hover { background: var(--ink-50); color: var(--ink-900); }
.site-nav__link[aria-current="page"] { color: var(--brand-700); background: var(--brand-100); }

@media (min-width: 900px) {
  .nav-toggle { display: none; }
  .site-nav { display: block; }
}
/* لوحة الجوال */
@media (max-width: 899px) {
  .site-nav.is-open {
    display: block; position: absolute; inset-inline: 0; top: var(--header-h);
    background: var(--white); border-bottom: 1px solid var(--ink-100);
    box-shadow: var(--sh-2); padding: var(--s3) var(--s5) var(--s5);
  }
  .site-nav.is-open .site-nav__list { flex-direction: column; align-items: stretch; gap: var(--s1); }
  .site-nav.is-open .site-nav__link { padding: var(--s3); font-size: 1rem; }
  .site-nav.is-open .btn { margin-top: var(--s2); width: 100%; }
}

/* ---------- 5. Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 46px; padding: var(--s3) var(--s6);
  border-radius: var(--r-sm); border: 1px solid transparent;
  font-family: inherit; font-size: 1rem; font-weight: 700; line-height: 1;
  text-decoration: none; cursor: pointer; transition: background-color .15s, border-color .15s, color .15s;
}
.btn { transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
                   box-shadow var(--dur-2) var(--ease), transform var(--dur-1) var(--ease); }
.btn--primary {
  /* كان الأعلى brand-500 = 3.50:1 مع النص الأبيض (راسب AA)؛ الآن 4.73:1 (P1-5) */
  background: linear-gradient(180deg, var(--brand-600), var(--brand-700));
  color: #fff; border-color: transparent; box-shadow: var(--sh-brand);
}
.btn--primary:hover { background: linear-gradient(180deg, var(--brand-700), var(--brand-800));
  box-shadow: 0 8px 22px rgba(28,120,185,.34); transform: translateY(-1px); }
.btn--primary:active { background: var(--brand-800); transform: translateY(0); box-shadow: var(--sh-1); }
.btn--ghost { background: var(--white); color: var(--brand-700); border-color: var(--brand-500); }
.btn--ghost:hover { background: var(--brand-50); border-color: var(--brand-400); transform: translateY(-1px); }
.btn--ghost:active { transform: translateY(0); }
.btn--wa { background: var(--wa-600); color: #fff; border-color: transparent;
  box-shadow: 0 6px 16px rgba(18,131,63,.26); }
.btn--wa:hover { filter: brightness(1.06); transform: translateY(-1px); box-shadow: 0 8px 22px rgba(18,131,63,.32); }
.btn--wa:active { filter: brightness(.94); transform: translateY(0); }
/* زر فاتح فوق السطح الداكن */
.btn--light { background: #fff; color: var(--brand-800); border-color: transparent; box-shadow: var(--sh-2); }
.btn--light:hover { background: var(--brand-50); transform: translateY(-1px); }
.btn--outline-light { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.42); }
.btn--outline-light:hover { background: rgba(255,255,255,.16); border-color: #fff; transform: translateY(-1px); }
.btn--lg { min-height: 54px; padding-inline: var(--s8); font-size: 1.0625rem; }
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .6; cursor: not-allowed; pointer-events: none; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* ---------- 6. Hero ---------- */
/* ---------- شبكات عامة ---------- */
.grid { display: grid; gap: var(--s5); }
/* auto-fit مع minmax: الأعمدة تتكيّف مع العرض المتاح بلا نقاط توقّف يدوية،
   فلا تظهر بطاقة يتيمة في صفّ وحدها على المقاسات الوسطى. */
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
@media (min-width: 900px) { .grid { gap: var(--s6); } }

/* ---------- 5. Hero ----------
   سطح داكن مبني على كحلي الشعار نفسه. السبب ليس الذوق: الصفحة كلها بيضاء،
   فبقاء البطل أبيض يجعله يذوب فيما تحته ولا يمسك العين. السطح الداكن يمنح
   الصفحة نقطة ارتكاز واحدة، ويجعل الأزرق السماوي في الشعار يتوهّج بدل أن يبهت. */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  background: linear-gradient(155deg, #0C2B4A 0%, var(--brand-900) 38%, var(--brand-700) 100%);
  color: #fff;
  padding-block: var(--s12) var(--s16);
}
/* وهج ناعم يكسر مسطّح التدرّج ويوحي بالعمق */
.hero::before, .hero::after {
  content: ""; position: absolute; z-index: -1; border-radius: 50%; pointer-events: none;
}
.hero::before {
  width: 46rem; height: 46rem; inset-block-start: -22rem; inset-inline-start: -14rem;
  background: radial-gradient(circle, rgba(56,171,228,.30), transparent 64%);
}
.hero::after {
  width: 34rem; height: 34rem; inset-block-end: -18rem; inset-inline-end: -10rem;
  background: radial-gradient(circle, rgba(123,199,238,.18), transparent 66%);
}
.hero__grid { display: grid; gap: var(--s8); position: relative; }
.hero__title {
  color: #fff; margin-bottom: var(--s4);
  font-size: clamp(2rem, 6.2vw, 3.4rem); line-height: 1.18; letter-spacing: -.022em;
  text-wrap: balance;
}
/* كلمة واحدة تحمل الوعد — تُلوَّن بسماوي الشعار فتصير مرساة بصرية */
.hero__title .accent {
  background: linear-gradient(180deg, var(--brand-300), var(--brand-400));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero__lead { font-size: clamp(1.02rem, 2.4vw, 1.18rem); color: rgba(255,255,255,.92);
  max-width: 52ch; line-height: 1.85; }
.hero__points { list-style: none; padding: 0; margin: var(--s6) 0 var(--s8);
  display: grid; gap: var(--s3); }
.hero__points li { display: flex; align-items: flex-start; gap: var(--s3);
  font-weight: 500; color: rgba(255,255,255,.94); }
.hero__points svg { flex: 0 0 22px; color: var(--brand-300); margin-top: 3px; }

/* شارة الحالة داخل البطل */
.hero__badge {
  display: inline-flex; align-items: center; gap: var(--s2);
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.24);
  color: #fff; border-radius: var(--r-full); padding: var(--s2) var(--s4);
  font-size: .875rem; font-weight: 700; margin-bottom: var(--s5);
  backdrop-filter: blur(6px);
}

/* حجز مكان شارة الدوام قبل ملئها.
   ------------------------------------------------------------
   الحالة لحظية فلا تُخبَز في HTML — ستكذب بعد ساعة. فتُملأ بجافاسكربت،
   وكان ملؤها يدفع كل ما تحتها: هذه كانت الإزاحة الوحيدة الباقية في الموقع.

   حُجز مكانها أولًا بنصٍّ شبحي بطول أسوأ احتمال، فسقط لسببٍ بنيوي: نصّ
   الشارة كان يطول ويقصر بتغيّر اليوم والساعة، فأي حجزٍ ثابت يكون أكبر من
   صياغة وأصغر من أخرى — والإزاحة تُحسب صعودًا كما تُحسب هبوطًا. فقُصّر
   نصّ الشارة إلى الحالة وحدها (انظر statusText في app.js): سطرٌ واحد في
   كل صندوق وكل عرض، فصار الحجز مطابقًا لا مقاربًا.

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

   والمطابقة مضمونة باختبار لا بالنظر: tests/qa.js يقيس كل ما يمكن أن
   تقوله الشارة (statusVariants) في كل موضع وكل عرض، ويشترط ألّا يختلف
   ارتفاع أيٍّ منها عن الحجز ولو بكسلًا واحدًا.

   والشبح خارج شجرة الوصول ضمنًا: العنصر كله visibility:hidden فلا يُقرأ
   ولا يُرى. ومن لا جافاسكربت عنده لا يرى الفراغ أصلًا: لا شيء سيملؤه. */
[data-open-status]:empty::before {
  content: ""; display: inline-block; width: 9px; height: 9px;
  border-radius: 50%; margin-inline-end: var(--s2);
}
[data-open-status]:empty::after { content: "مغلق الآن"; }
.js  [data-open-status]:empty { visibility: hidden; }
html:not(.js) [data-open-status]:empty { display: none; }

/* البطاقة الزجاجية: الدوام اليوم فقط — الجدول الكامل مكانه قسم التواصل.
   جدول سبعة صفوف داخل البطل يزاحم الرسالة ويؤخّر العين عن زر التسجيل. */
.hero__card {
  /* زجاج داكن لا فاتح — والفرق ليس ذوقًا: الزجاج الفاتح يرفع سطوع الخلفية
     فيهبط تباين النص الأبيض فوقها، وقد رسبت النصوص الثانوية فعلًا في القياس
     (3.37:1 والمطلوب 4.5). التعتيم 30% يعطي 6.00:1 في أسوأ نقطة من التدرّج. */
  background: rgba(8,32,58,.30);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--r-lg); padding: var(--s6);
  backdrop-filter: blur(10px); box-shadow: var(--sh-3);
}
.hero__card h2 { color: #fff; font-size: 1.05rem; margin-bottom: var(--s4); }
.hero__today { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); padding-block: var(--s3); border-block-end: 1px solid rgba(255,255,255,.14); }
.hero__today:last-of-type { border-block-end: 0; }
.hero__today dt { color: rgba(255,255,255,.82); font-size: .9rem; }
.hero__today dd { margin: 0; font-weight: 700; color: #fff; }
.hero__note { color: rgba(255,255,255,.80); font-size: .85rem; line-height: 1.7;
  margin: var(--s4) 0 0; }
.hero__card .status-dot--closed { background: var(--brand-300); }
.hero [data-open-status] { color: #fff; }

@media (min-width: 900px) {
  .hero { padding-block: var(--s16) var(--s20); }
  .hero__grid { grid-template-columns: 1.2fr .8fr; align-items: center; gap: var(--s12); }
}

/* موجة تفصل البطل عمّا تحته بلا خط حادّ */
.hero__wave { display: block; width: 100%; height: 40px; margin-block-start: -1px; color: var(--white); }
.hero__wave path { fill: currentColor; }

.card {
  display: flex; flex-direction: column;
  background: var(--white); border: 1px solid var(--ink-100);
  border-radius: var(--r-md); padding: var(--s6);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.card--link:hover { border-color: var(--brand-200); box-shadow: var(--sh-2); transform: translateY(-2px); }
.card__icon {
  width: 48px; height: 48px; border-radius: var(--r-md);
  background: var(--brand-100); color: var(--brand-700);
  display: grid; place-items: center; margin-bottom: var(--s4);
}
.card__title { margin-bottom: var(--s2); }
.card__body { color: var(--ink-500); margin-bottom: var(--s4); flex: 1; }
.card__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); margin-top: auto; }

.meta-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.chip {
  display: inline-flex; align-items: center; gap: var(--s1);
  font-size: .8125rem; font-weight: 700; padding: var(--s1) var(--s3);
  border-radius: var(--r-full); background: var(--ink-50); color: var(--ink-700);
}
.chip--brand  { background: var(--brand-100); color: var(--brand-900); }
.chip--closed { background: var(--warn-100); color: var(--warn-700); }
.chip--open   { background: var(--ok-100);   color: var(--ok-600); }

/* فلاتر الفئات */
.filters { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s8); }
.filter {
  min-height: 42px; padding: var(--s2) var(--s5); border-radius: var(--r-full);
  border: 1px solid var(--ink-200); background: var(--white);
  font-family: inherit; font-size: .9375rem; font-weight: 700; color: var(--ink-700); cursor: pointer;
}
.filter:hover { border-color: var(--brand-400); color: var(--brand-700); }
.filter[aria-pressed="true"] { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

/* حالة فارغة */
.empty-state {
  text-align: center; padding: var(--s12) var(--s5);
  border: 1px dashed var(--ink-200); border-radius: var(--r-lg); background: var(--ink-50);
}
.empty-state__icon { width: 56px; height: 56px; margin: 0 auto var(--s4); color: var(--ink-300); }

/* ---------- 8. Forms ---------- */
.form { display: grid; gap: var(--s5); }
.field { display: grid; gap: var(--s2); }
.field__label { font-weight: 700; color: var(--ink-900); font-size: .9375rem; }
.field__req { color: var(--err-600); margin-inline-start: 2px; }
.field__hint { font-size: .8125rem; color: var(--ink-500); }
/* سطر الخطأ يشغل مساحته دائمًا، ممتلئًا كان أم فارغًا.
   ------------------------------------------------------------
   كانت الحالة الفارغة تحجز min-height وحدها، والحالة الممتلئة تضيف فوقها
   هامشًا علويًا كاملًا وخطًّا أكبر وشارةً — ثلاث زيادات غير محجوزة. فعند
   الضغط على «إرسال» بنموذج فارغ كان الزرّ نفسه يهبط ١٢٥ بكسلًا من تحت
   الإصبع، والضغطة الثانية — وهي ضغطة متوقّعة لأن فخّ الزمن يطلبها — تقع
   على ما انزلق مكانه.

   الحجز هنا بالمقاسات النهائية نفسها: الهامش والخطّ والوزن في القاعدة
   الأساس لا في حالة الامتلاء، وسطرٌ صفريّ العرض يعطي الصندوقَ الفارغَ
   ارتفاعَ السطر الممتلئ بالتعريف. تكلفته ~٨px لكل حقل، وثمنه صفر إزاحة
   عند اللحظة الوحيدة المهمة في الموقع.

   (المقياس الرسمي لا يرى هذه الإزاحة أصلًا: CLS يستثني ما يقع خلال ٥٠٠ms
   من إدخال المستخدم. كانت حقيقية ومقيسة وخارج التعريف.) */
.field__err {
  display: flex; align-items: center; gap: .4rem; margin-top: var(--s2);
  color: var(--err-600); font-size: .85rem; font-weight: 700; line-height: 1.5;
}
.field__err:empty::before { content: "\200B"; }

.input, .select, .textarea {
  width: 100%; min-height: 48px; padding: var(--s3) var(--s4);
  font-family: inherit; font-size: 1rem; color: var(--ink-900); background: var(--white);
  border: 1px solid var(--field-border); border-radius: var(--r-sm);
  transition: border-color .15s, box-shadow .15s;
}
.textarea { min-height: 110px; padding-block: var(--s3); resize: vertical; line-height: 1.7; }
.select {
  appearance: none; padding-inline-end: var(--s10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235B7186' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: left var(--s4) center;
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-300); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100);
}
/* P1-2/P1-3: outline:none أعلاه يُسقط الحلقة العامة (نفس الخصوصية، ويكسبها
   الأقدم بالترتيب). :focus-visible بعد :focus يعيدها لمستخدمي لوحة المفاتيح
   فقط — الفأرة تبقى بلا حلقة كما صُمِّم، وintentional. */
.input:focus-visible, .select:focus-visible, .textarea:focus-visible {
  outline: 3px solid var(--brand-600); outline-offset: 2px;
}
.input[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--err-600); box-shadow: 0 0 0 3px var(--err-100);
}
.input[type="tel"], .input[type="number"] { direction: ltr; text-align: right; }

.field-row { display: grid; gap: var(--s5); }
@media (min-width: 640px) { .field-row--2 { grid-template-columns: 1fr 1fr; } }

/* مصيدة البوتات — مخفية عن البشر وعن قارئات الشاشة، ظاهرة للبوت */
.hp-field {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* البرنامج المختار */
.picked {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  background: var(--brand-50); border: 1px solid var(--brand-200);
  border-radius: var(--r-md); padding: var(--s4) var(--s5);
}
.picked__label { font-size: .8125rem; color: var(--brand-700); font-weight: 700; }
.picked__value { font-weight: 800; color: var(--ink-900); }

/* ---------- 9. Alerts & states ---------- */
.alert {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s4) var(--s5); border-radius: var(--r-md);
  border: 1px solid transparent; font-size: .9375rem;
}
.alert svg { flex: 0 0 20px; margin-top: 3px; }
.alert--info  { background: var(--brand-50); border-color: var(--brand-200); color: var(--brand-900); }
.alert--warn  { background: var(--warn-100); border-color: #EBD49A; color: var(--warn-700); }
.alert--err   { background: var(--err-100);  border-color: #F0BFBF; color: var(--err-600); }
.alert--ok    { background: var(--ok-100);   border-color: #B7E3CA; color: var(--ok-600); }

.spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2.5px solid rgba(255,255,255,.4); border-top-color: #fff;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.success-panel { text-align: center; padding: var(--s10) var(--s5); }
.success-panel__icon {
  width: 68px; height: 68px; margin: 0 auto var(--s5);
  border-radius: var(--r-full); background: var(--ok-100); color: var(--ok-600);
  display: grid; place-items: center;
}
.ref-code {
  display: inline-block; font-family: ui-monospace, 'Courier New', monospace;
  background: var(--ink-50); border: 1px solid var(--ink-200);
  padding: var(--s2) var(--s4); border-radius: var(--r-sm); font-weight: 700; direction: ltr;
}

/* ---------- 10. Contact / hours ---------- */
.info-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s4); }
.info-list li { display: flex; gap: var(--s3); align-items: flex-start; }
.info-list svg { flex: 0 0 20px; color: var(--brand-600); margin-top: 4px; }
.info-list a { color: var(--ink-900); text-decoration: none; font-weight: 700; }
.info-list a:hover { color: var(--brand-700); text-decoration: underline; }

.hours-table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
.hours-table th, .hours-table td { text-align: start; padding: var(--s3) 0; border-bottom: 1px solid var(--ink-100); }
.hours-table th { font-weight: 700; color: var(--ink-700); }
.hours-table td { color: var(--ink-500); text-align: end; white-space: nowrap; }
.hours-table tr:last-child th, .hours-table tr:last-child td { border-bottom: 0; }
.hours-table tr.is-today th { color: var(--brand-700); font-weight: 800; }
.hours-table tr.is-today td { color: var(--brand-700); font-weight: 700; }

/* الشارة تُملأ بجافاسكربت بعد الرسم (الوقت لا يُصيَّر مسبقًا — يتغيّر كل دقيقة).
   نحجز ارتفاع سطر واحد سلفًا فلا يهبط ما تحتها لحظة وصول النص. */
[data-open-status] { min-height: 1.5em; }
.status-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-inline-end: var(--s2); }
.status-dot--open   { background: var(--ok-600); }
.status-dot--closed { background: var(--ink-300); }

/* ---------- 11. Footer ---------- */
.site-footer { background: var(--ink-900); color: var(--ink-200); padding-block: var(--s12) var(--s6); margin-top: var(--s16); }
/* عناوين أعمدة الفوتر هي h2 دلاليًا (لا h4) حتى لا يقفز التسلسل من h2 إلى h4،
   وحجمها يُضبط هنا فيبقى المظهر كما هو. */
.site-footer .footer-title { color: #fff; font-size: 1rem; margin-bottom: var(--s4);
  letter-spacing: 0; font-weight: 800; }
.site-footer a { color: var(--ink-200); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer__grid { display: grid; gap: var(--s8); }
@media (min-width: 780px) { .site-footer__grid { grid-template-columns: 1.4fr 1fr 1.2fr; } }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s2); }
.site-footer__bottom {
  margin-top: var(--s10); padding-top: var(--s5);
  border-top: 1px solid rgba(255,255,255,.12); font-size: .8125rem; color: var(--ink-300);
  display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: space-between;
}
.social { display: flex; gap: var(--s3); margin-top: var(--s5); }
.social a {
  width: 40px; height: 40px; border-radius: var(--r-sm);
  background: rgba(255,255,255,.08); display: grid; place-items: center; color: #fff;
}
.social a:hover { background: var(--brand-600); }

/* ---------- 12. Utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
[hidden] { display: none !important; }
/* ---------- 13. بطاقات بصور ---------- */
.card--media { padding: 0; overflow: hidden; }
.card--media .card__inner { padding: var(--s5); display: flex; flex-direction: column; flex: 1; }
/* ملصقات الأكاديمية مربّعة وكثيفة النص. عرضها بنسبتها الأصلية داخل البطاقة
   يجعلها تبتلع البطاقة ويُنافس نصُّها عنوانَها. نقصّها إلى شريط عريض يُظهر
   أعلى الملصق (عنوانه الفني) ويُبقي البطاقات متساوية الارتفاع وقابلة للمسح
   بالعين. الصورة كاملةً تبقى متاحة — لم تُقصَّ في الملف، فقط في العرض. */
.card__media { background: var(--brand-50); border-bottom: 1px solid var(--ink-100);
  position: relative; overflow: hidden; }

/* ---------- سطح الهوية في واجهة البطاقة ----------
   بديل الصورة (انظر categoryCard في app.js). ثلاث طبقات فوق بعضها:
   تدرّج قُطري من كحلي الشعار إلى أزرقه، وهجٌ ناعم من الزاوية العلوية،
   وحلقاتٌ متحدة المركز خلف الأيقونة توحي بالعمق بلا تفاصيل تُشتّت.
   النسبة 16/10 هي نسبة الصورة التي كانت هنا، فلم يتغيّر إيقاع الشبكة. */
.card__media--brand {
  /* النسبة تحكم الشكل، والسقف يحكم الطول: بطاقتان فقط في الشبكة فتتّسع كل
     واحدة إلى نصف الحاوية (~530px)، ونسبةٌ وحدها كانت تعطيها لوحًا بطول
     300px يبتلع البطاقة ويزيح عنوانها تحت الطيّة. السقف يحوّل اللوح إلى
     شريط هادئ على الشاشات العريضة ويتركه على حاله في الضيقة. */
  aspect-ratio: 16 / 9; max-block-size: 200px;
  display: grid; place-items: center;
  border-bottom: 0; color: #fff;
  background:
    radial-gradient(120% 150% at 82% -20%, rgba(255,255,255,.22), transparent 58%),
    linear-gradient(140deg, var(--tone-a, var(--brand-900)), var(--tone-b, var(--brand-600)));
}
/* الحلقات: دوائر شفافة متتابعة. مرسومة بتدرّج لا بعناصر — لا وسمَ زائدًا
   في الصفحة ولا طلبَ شبكة، وتتكيّف مع أي مقاس بطاقة. */
.card__media--brand::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-radial-gradient(circle at 50% 50%,
    rgba(255,255,255,.085) 0 1px, transparent 1px 26px);
  mask-image: radial-gradient(circle at 50% 50%, #000 35%, transparent 78%);
}
.card__media--brand[data-tone="sky"]  { --tone-a: var(--brand-800); --tone-b: var(--brand-400); }
.card__media--brand[data-tone="deep"] { --tone-a: var(--brand-900); --tone-b: var(--brand-600); }

.card__media-glyph {
  position: relative; display: grid; place-items: center;
  width: 84px; height: 84px; border-radius: var(--r-full);
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.30);
  backdrop-filter: blur(2px);
  transition: transform var(--dur-3) var(--ease-out);
}
.card--link:hover .card__media-glyph { transform: scale(1.06); }

/* ---------- 14. الموقع والخريطة ---------- */
.map-grid { display: grid; gap: var(--s6); align-items: start; }
@media (min-width: 900px) { .map-grid { grid-template-columns: 1.25fr .75fr; gap: var(--s8); } }

.map-frame {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  border: 1px solid var(--ink-200); border-radius: var(--r-md);
  overflow: hidden; background: var(--ink-50);
}
@media (min-width: 640px) { .map-frame { aspect-ratio: 16 / 10; } }
.map-frame iframe { width: 100%; height: 100%; display: block; }
/* الخريطة تعلو البديل بالطبقات لا بحذفه: يبقى البديل موجودًا فإن لم يُرسم
   الإطارُ شيئًا (حجب أو انقطاع) ظهر ما تحته بدل بياضٍ يبدو عطلًا. */
.map-frame__live { position: relative; z-index: 1; }
.map-frame__ph {
  position: absolute; inset: 0; z-index: 0; display: grid; place-items: center;
  color: var(--brand-500); /* كان brand-300 = 1.74:1 على خلفيته؛ الآن 3.25:1 (P1-5) */
  background:
    radial-gradient(circle at 50% 45%, rgba(28,120,185,.10), transparent 62%),
    repeating-linear-gradient(0deg,  var(--ink-100) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, var(--ink-100) 0 1px, transparent 1px 34px),
    var(--brand-50);
}

.map-actions { display: grid; gap: var(--s3); margin-top: var(--s5); }
@media (min-width: 520px) { .map-actions { grid-auto-flow: column; grid-auto-columns: 1fr; } }

.pluscode {
  font-family: ui-monospace, 'Courier New', monospace; font-weight: 700;
  background: var(--ink-50); border: 1px solid var(--ink-200);
  padding: 2px var(--s2); border-radius: 6px;
}

/* ---------- 15. شريط المنح ---------- */
.ribbon {
  background: var(--brand-900); color: #fff;
  border-radius: var(--r-md); padding: var(--s4) var(--s5);
  font-size: .9375rem; text-align: center;
}
.ribbon strong { color: var(--brand-200); }

/* يُخفي حقل البرنامج قبل الرسم حين يصل الزائر من بطاقة برنامج محدَّد.
   القرار يتخذه assets/js/early.js في <head> — راجع تعليقه للسبب. */
.has-preselected-program #f-program-wrap { display: none; }


/* ---------- 13. الحركة ----------
   الإخفاء مشروط بصنف motion-ready الذي يضعه motion.js بعد تأكّده أنه قادر
   على الإظهار. بلا هذا الشرط يختفي المحتوى نهائيًا عن كل زائر تعطّلت عنده
   الجافاسكربت — وهو الخطأ الأشهر في حركات الكشف. */
.motion-ready .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out);
  will-change: opacity, transform;
}
.motion-ready .reveal.is-revealed { opacity: 1; transform: none; will-change: auto; }

/* رأس ثابت يكتسب عمقًا بعد التمرير */
.site-header { transition: box-shadow var(--dur-2) var(--ease), background var(--dur-2) var(--ease); }
.site-header.is-stuck { box-shadow: var(--sh-2); }

/* البطاقات ترتفع قليلًا عند المرور — دعوة للنقر لا زخرفة */
.card { transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease),
                    border-color var(--dur-2) var(--ease); }
.card--link:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.card--media .card__media { overflow: hidden; }

/* الشرائح والفلاتر */
.filter { transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
                      border-color var(--dur-1) var(--ease); }

@media (prefers-reduced-motion: reduce) {
  /* إلغاء لا إبطاء: من طلب تقليل الحركة لا يريدها أبطأ، يريدها ألّا تكون. */
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
}


/* ---------- 15. ارتقاء البطاقات والعناوين ----------
   جدار بطاقات بيضاء متطابقة لا يُقرأ — العين لا تجد فيه إيقاعًا ولا تعرف
   أين تبدأ. ثلاث إضافات تحلّ ذلك بلا زخرفة: شريط لوني رفيع يُعلن هوية
   البطاقة، وارتفاعات متساوية بزرّ مثبّت في الأسفل، وشرائح أوضح. */

.card { position: relative; }
/* شريط علوي يظهر عند المرور — إشارة «هذه قابلة للنقر» بلا نصّ إضافي */
.card--link::before {
  content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; height: 3px;
  background: linear-gradient(90deg, var(--brand-400), var(--brand-600));
  transform: scaleX(0); transform-origin: inline-end;
  transition: transform var(--dur-2) var(--ease-out);
  border-start-start-radius: var(--r-lg); border-start-end-radius: var(--r-lg);
}
.card--link:hover::before, .card--link:focus-within::before { transform: scaleX(1); }

/* بطاقة البرنامج: الزرّ في الأسفل دائمًا مهما اختلف طول الوصف،
   فتصطفّ الأزرار أفقيًا وتصير المقارنة بين البرامج ممكنة بلمحة. */
.card article, article.card { display: flex; flex-direction: column; }
.card__foot { margin-top: auto; padding-top: var(--s4); }
.card__body ul { margin: var(--s3) 0 0; padding-inline-start: var(--s5); }
.card__body li { margin-bottom: var(--s1); }

/* الشرائح: خلفية أوضح وحدود ألطف */
.chip {
  border-radius: var(--r-full); padding: .3rem .7rem; font-size: .8125rem; font-weight: 700;
  background: var(--ink-50); color: var(--ink-700); border: 1px solid var(--ink-100);
  display: inline-flex; align-items: center; gap: .35rem;
}
.chip--brand { background: var(--brand-50); color: var(--brand-800); border-color: var(--brand-100); }
.chip--open  { background: var(--ok-100); color: var(--ok-600); border-color: transparent; }
.chip--closed{ background: var(--ink-100); color: var(--ink-700); border-color: transparent; }
.meta-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s3); }

/* رأس القسم: خط قصير فوق العنوان يعطي الأقسام إيقاعًا متكرّرًا */
.section-head h2 { text-wrap: balance; }
/* الخطّ المائل تحت كلمة القسم.
   كان ::after على الشارة نفسها، وهي inline-block بخلفية ملوّنة — فابتلعت
   الخلفيةُ الخطَّ وتمدّدت الشارة إلى كتلة بيضاوية طويلة بدل حبّة مضغوطة.
   مكانه الصحيح قبل العنوان: عنصر في السياق نفسه بلا إحداثيات ولا أرقام
   سحرية، والشارة تعود إلى حجمها. */
.section-head.center h2::before {
  content: ""; display: block; width: 2.5rem; height: 3px;
  margin: 0 auto var(--s4); border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--brand-400), var(--brand-600));
}

/* عنوان البطاقة في صفحة البرامج h2 — نضبط حجمه بصريًا دون المساس بالدلالة */
.card__title { font-size: clamp(1.08rem, 2.2vw, 1.25rem); line-height: 1.4; }


/* ---------- 16. صفحة التسجيل ----------
   النموذج كان يطفو على بياض ونصفُ الشاشة فارغ على الديسكتوب. اللوحة المرتفعة
   تمنحه حدودًا، والعمود المجاور يجيب السؤال الذي يمنع الناس من الإرسال:
   «ماذا سيحدث ببياناتي بعد الضغط؟» — وهو أكبر سبب لترك النماذج. */
.form-layout { display: grid; gap: var(--s8); align-items: start; }
@media (min-width: 980px) {
  .form-layout { grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); gap: var(--s10); }
  .form-aside { position: sticky; top: calc(var(--header-h) + var(--s6)); }
}
.form-panel {
  background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-lg);
  padding: var(--s6); box-shadow: var(--sh-2);
}
@media (min-width: 700px) { .form-panel { padding: var(--s8); } }

.form-aside { display: grid; gap: var(--s5); }
.aside-card {
  background: var(--brand-50); border: 1px solid var(--brand-100);
  border-radius: var(--r-lg); padding: var(--s6);
}
.aside-card__title { font-size: 1.05rem; margin-bottom: var(--s4); }
.steps-mini { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); }
.steps-mini li { display: flex; gap: var(--s3); align-items: flex-start; }
.steps-mini__n {
  flex: 0 0 28px; height: 28px; border-radius: 50%;
  background: var(--brand-600); color: #fff; font-weight: 800; font-size: .85rem;
  display: grid; place-items: center;
}
.steps-mini strong { display: block; font-size: .95rem; margin-bottom: 2px; }
.steps-mini p { margin: 0; font-size: .875rem; color: var(--ink-500); line-height: 1.7; }

/* ---------- 17. حالات الحقول ----------
   الحالة تُقرأ بلونٍ وأيقونة ونص — لا باللون وحده، فمن لا يميّز الألوان
   يجب أن يعرف أن الحقل خاطئ. */
.field__label { display: block; font-weight: 700; margin-bottom: var(--s2); font-size: .95rem; }
.input, .select, textarea.input {
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease);
}
.input:hover, .select:hover { border-color: var(--brand-300); }
.input:focus, .select:focus, textarea.input:focus {
  border-color: var(--brand-500); box-shadow: 0 0 0 4px rgba(28,120,185,.14); outline: none;
}
.input:focus-visible, .select:focus-visible, textarea.input:focus-visible {
  outline: 3px solid var(--brand-600); outline-offset: 2px;
}
.input[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--err-600); background: #FFFCFC;
}
.input[aria-invalid="true"]:focus, .select[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 4px rgba(192,42,42,.14);
}
.field__err:not(:empty)::before { content: "!"; flex: 0 0 16px; height: 16px;
  border-radius: 50%; background: var(--err-600); color: #fff;
  font-size: .7rem; display: grid; place-items: center; }

/* زر الإرسال أثناء العمل: دوّارة صغيرة لا تغيّر مقاس الزر فلا يقفز التخطيط */
.spinner {
  width: 18px; height: 18px; border-radius: 50%; display: inline-block;
  border: 2.5px solid rgba(255,255,255,.35); border-top-color: #fff;
  animation: spin .7s linear infinite; vertical-align: -3px; margin-inline-end: .5rem;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; opacity: .8; } }


/* ---------- 18. رأس الصفحات الداخلية ----------
   الرئيسية لها بطل داكن، والداخليتان كانتا بيضاوين تمامًا — فيبدو الموقع
   صفحاتٍ متفرّقة لا منتجًا واحدًا. شريط مُعلَّم خفيف يحمل الهوية نفسها بلا
   أن ينافس البطل الداكن ولا أن يدفع المحتوى بعيدًا عن أعلى الصفحة. */
.page-head {
  position: relative; isolation: isolate; overflow: hidden;
  background: linear-gradient(180deg, var(--brand-50), var(--white) 88%);
  border-block-end: 1px solid var(--brand-100);
  padding-block: var(--s10) var(--s8);
  margin-block-end: var(--s10);
}
.page-head::before {
  content: ""; position: absolute; z-index: -1; border-radius: 50%;
  width: 30rem; height: 30rem; inset-block-start: -19rem; inset-inline-start: -8rem;
  background: radial-gradient(circle, rgba(56,171,228,.16), transparent 68%);
  pointer-events: none;
}
/* النصف الفارغ من الشريط.
   النصّ يبدأ من جهة القراءة فيبقى النصف الآخر خاليًا على الشاشات العريضة —
   وخلاءٌ بلا سبب يبدو صفحةً لم تكتمل. الحلقات هنا هي حلقات سطح البطاقات
   نفسها بالضبط، فيقرأ الشريطُ والبطاقاتُ كلغة واحدة لا كزخرفتين. وتختفي
   دون 900px حيث لا نصف فارغ أصلًا. */
.page-head::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none; display: none;
  /* المركز خارج الشاشة عمدًا: الدوائر الكاملة تُقرأ رسمًا هندسيًا يسرق
     الانتباه، والأقواس وحدها تُقرأ نسيجًا يملأ الفراغ ولا ينافس العنوان. */
  inset-block: -60%; inset-inline-end: -20rem; width: 44rem;
  background: repeating-radial-gradient(circle at 50% 50%,
    rgba(28,120,185,.075) 0 1px, transparent 1px 24px);
  mask-image: radial-gradient(circle at 50% 50%, #000 26%, transparent 66%);
}
@media (min-width: 900px) { .page-head::after { display: block; } }
.page-head h1 { margin-bottom: var(--s3); }
.page-head nav[aria-label="مسار التنقل"] { margin-bottom: var(--s4); }
@media (min-width: 900px) { .page-head { padding-block: var(--s12) var(--s10); } }


/* ---------- 19. أدوات صغيرة ----------
   كل قاعدة هنا كانت style="..." داخل الوسوم. نقلُها إلى أصناف ليس ترتيبًا
   فحسب: هو ما سمح بإزالة 'unsafe-inline' من style-src في _headers، فصارت
   سياسة الأمان تمنع أي نمط يُحقن في الصفحة بدل أن تسمح به. */
.u-center      { text-align: center; }
.u-center-x    { margin-inline: auto; }
.u-narrow      { max-width: 46ch; }
.u-narrower    { max-width: 40ch; }
.u-flush       { margin: 0; }
.u-mt-2        { margin-block-start: var(--s4); }
.u-mt-3        { margin-block-start: var(--s6); }
.u-mt-4        { margin-block-start: var(--s8); }
.u-mb-2        { margin-block-end: var(--s4); }
.u-mb-3        { margin-block-end: var(--s6); }
.u-mb-0        { margin-block-end: 0; }
.u-dim         { color: var(--ink-300); }
.u-link-quiet  { text-decoration: none; }
.u-row-center  { justify-content: center; }
.u-col         { flex-direction: column; }
.u-pt-0        { padding-block-start: 0; }
.u-strong-brand{ color: var(--brand-700); font-weight: 700; }
.u-accent-link { color: var(--brand-300); font-weight: 700; }
.u-title-sm    { font-size: 1.05rem; }
.u-frameless   { border: 0; }
.u-bold        { font-weight: 700; }
/* زرّ يبدو رابطًا: الفعل ليس تنقّلًا (لا عنوان يقود إليه) فلا يجوز أن يكون
   <a>، لكن مظهره يجب أن يقول «اضغطني» بلا ثقل زرٍّ ثالث في لوحة النجاح. */
.linkish {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--brand-700); font-weight: 700; text-decoration: underline;
  text-underline-offset: 3px;
}
.linkish:hover { color: var(--brand-900); }
.u-bare-list { list-style: none; padding: 0; margin: 0; }
.u-ink { color: var(--ink-900); }


/* ---------- 20. أهداف اللمس ----------
   روابط الفوتر والقوائم كانت بارتفاع 14px — أصغر من أن تُنقر بإصبع، وقياسُها
   أظهر 12 هدفًا دون الحدّ. WCAG 2.2 يطلب 24×24 كحدّ أدنى، والممارسة الجيدة 44.
   الحشو الرأسي يوسّع منطقة اللمس بلا أن يغيّر حجم الخط ولا يفكّ التخطيط. */
@media (pointer: coarse), (max-width: 860px) {
  .site-footer ul a,
  .site-nav__link,
  [data-tel-link], [data-phone-text] {
    display: inline-flex; align-items: center; min-height: 44px;
  }
  .site-footer ul li { margin-block: 0; }
  .brand { min-height: 44px; }
  /* أزرار الفلاتر كانت 42px — أقلّ بقليل من الحدّ، وتُنقر كثيرًا */
  .filter { min-height: 44px; }
  /* روابط مسار التنقّل: نصّ صغير يُنقر بإصبع */
  nav[aria-label="مسار التنقل"] a { display: inline-flex; align-items: center; min-height: 44px; }
  /* «جدول الأسبوع كامل» رابط داخل فقرة — يستثنيه WCAG 2.2 من حدّ المقاس
     لأن توسيعه يكسر تدفّق السطر. يبقى كما هو بقصد. */
  .info-list a { min-height: 44px; display: inline-flex; align-items: center; }
}
/* أيقونات التواصل الاجتماعي: 40 → 44 */
.social a { width: 44px; height: 44px; }

/* القائمة المفتوحة طبقة فوق المحتوى لا امتداد له — الظل يقول ذلك بلا كلام */
.site-nav.is-open { box-shadow: var(--sh-2); border-block-end: 1px solid var(--ink-100); }
