/* بنية الصفحة: الأساسيات، الشريط العلوي، أقسام الصفحات، الاستجابة، الطباعة */

/* ===================== أساسيات ===================== */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:'IBM Plex Sans Arabic', system-ui, -apple-system, sans-serif;
  font-size:15px; line-height:1.85;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  transition:background .25s ease, color .25s ease;
}
::selection{background:rgba(61,201,176,.28)}
/* رموز المقررات والأرقام التقنية — حصريًا بخط المونو (قاعدة الهوية) */
.c-code, .m-code, .pr-chip, .mini-chip .cc, .c-hours,
#statDoneH, #statLeftH, #statProgText, .wi-hours-val{font-family:var(--mono)}
a{color:var(--interactive)}
button{font-family:inherit}
.container{max-width:1120px; margin-inline:auto; padding-inline:22px}
.i{width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round; flex:none}
.i-sm{width:16px; height:16px}
:focus-visible{outline:2px solid var(--ring); outline-offset:2px; border-radius:8px}
[hidden]{display:none !important}

/* ===================== الشريط العلوي ===================== */
.topbar{
  position:sticky; top:0; z-index:60;
  background:color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border-bottom:1px solid var(--border);
}
.topbar .container{display:flex; align-items:center; justify-content:space-between; height:64px}
.brand{display:flex; align-items:center; gap:12px; background:none; border:none; cursor:pointer; color:var(--text); padding:4px; text-decoration:none}
/* شعار مساري (issue #184): ملف واحد src/assets/masari-logo.svg بخلفيته المستديرة وألوانه
   الثابتة، فيصلح للوضعين بلا نسخة داكنة. يحل محل الشارة القديمة بالكامل لا داخلها.
   issue #203: خلفية الملف لون الهوية ‎--primary‎ نهاراً (#0E352C، غابة) بدل أخضر خارج الهوية،
   فيقرأ امتداداً لاسم «مساري» الداكن لا لطخة لونية، ويذوب ليلاً في الشريط القريب منه.
   الحلقة الرفيعة بـ‎--border-strong‎ كحدّ الشارة القديمة، بـ box-shadow لا border فلا تغيّر
   المقاس. نصف القطر نسبةً = rx 14 من 64 في الملف، فيطابق أي مقاس. الرسم نفسه يملأ ~86% من عرض المربع. */
.brand-badge{width:48px; height:48px; flex:none; display:block; border-radius:21.875%; box-shadow:0 0 0 1px var(--border-strong)}
.brand-name{font-size:20px; font-weight:700; letter-spacing:-.2px}
.brand-sub{font-size:13px; color:var(--muted); font-weight:500; letter-spacing:.2px}
.nav-actions{display:flex; align-items:center; gap:10px}

/* ===================== الصفحة الرئيسية ===================== */
.hero{position:relative; padding:76px 0 44px; text-align:center; background:var(--hero-tint)}
.hero-title{
  margin:0 auto; max-width:820px;
  font-size:clamp(30px, 5.4vw, 50px); font-weight:700; line-height:1.5;
  color:var(--brand-ink); letter-spacing:-.5px;
}
.hero-title .hl{
  background:linear-gradient(180deg, transparent 62%, color-mix(in srgb, var(--accent) 32%, transparent) 62%);
  border-radius:4px; padding:0 4px;
}
.hero-sub{margin:18px auto 0; max-width:640px; color:var(--muted); font-size:16.5px}

/* ===================== صفحة المسار ===================== */
.path-toolbar{padding:22px 0 6px}
.pt-row{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
/* ⚠️ عقد التخطيط (issue #121): العنوان وحده هو ما يتمدّد، ولا يشارك أبداً في قرار كسر السطر.
   في Flexbox يسبق توزيعُ العناصر على الأسطر انكماشَها: يوزّع المتصفح بحسب الحجم الافتراضي
   (flex-basis:auto = max-content) ثم يُطبّق flex-shrink داخل كل سطر بعد تكوينه. فـ min-width:0
   وحده لا يمنع الكسر — كان يمنع الانكماش فقط. ولذلك كان عرضُ العنوان الطبيعي يدفع
   «ماذا يحدث لو...» لسطر ثانٍ متى طال العنوان (خطة تقنية المعلومات: عجز 12.2px عن 1076px
   المتاحة، مقابل فائض 5.8px فقط لخطة علوم الحاسب — أي أن CS نجت بالصدفة لا بالتصميم).

   flex-basis:0 يجعل الحجم الافتراضي للعنوان صفراً فلا يُحتسب في قرار الكسر، ثم يتمدّد ليملأ
   ما تبقّى. و min-width هنا **ليس تفصيلاً**: المواصفة تَقصر الحجم الافتراضي بـ min/max، فتصير
   340px هي ما يُحتسب في قرار الكسر بدل عرض العنوان الطبيعي مهما طال. أي أن العنوان يقول
   «أحتاج 340px على الأقل» لا «أحتاج عرضي كاملاً»، فينتج سلوكان مقصودان:
     • مساحة كافية (حاوية 1076px): سطر أفقي واحد، والعنوان يتمدّد لـ 418px — يتّسع لأطول
       عنوان حقيقي (تقنية المعلومات 380.8px) بهامش مريح، وأي عنوان أطول يلتفّ داخل صندوقه.
     • مساحة ضيّقة (حاوية <977px): ينكسر الصف عمداً فينزل الزرّان لسطر ثانٍ ويبقى العنوان
       سطراً واحداً مقروءاً — أفضل من سحقه إلى ثلاثة أسطر داخل صف واحد.
   دون 640px يُصفَّر min-width في responsive.css (كتلة التكديس) لأن الشاشة نفسها قد تضيق
   عن 340px فتُحدث تجاوزاً أفقياً. يُتحقَّق من الحالتين آلياً: npm run check:layout */
.pt-titles{flex:1 1 0; min-width:340px}
.pt-title{margin:0; font-size:20px; font-weight:700; display:flex; align-items:center; gap:10px; overflow-wrap:anywhere}
.pt-sub{font-size:12.5px; color:var(--muted); font-weight:500; margin-top:2px; overflow-wrap:anywhere}
/* حقل البحث: أساس مرن أصغر من عرضه الطبيعي (298px) ليُفسح للعنوان مساحة أوسع قبل التفافه،
   مع أرضية 240px تُبقي نصّ الـ placeholder كاملاً — راجع check-layout.mjs */
.search{
  display:flex; align-items:center; gap:8px; background:var(--surface);
  border:1px solid var(--border-strong); border-radius:12px; padding:0 12px; height:42px;
  flex:0 1 auto; width:260px; min-width:240px;
  transition:border-color .2s ease, box-shadow .2s ease; color:var(--muted);
}
.search:focus-within{border-color:var(--interactive); box-shadow:0 0 0 3px color-mix(in srgb, var(--interactive) 15%, transparent)}
/* align-self:stretch يجعل مساحة اللمس كامل ارتفاع الحقل (42px) بدل 23px فقط */
.search input{border:none; outline:none; background:transparent; color:var(--text); font-family:inherit; font-size:14px; width:100%; min-width:0; align-self:stretch}
.search input::placeholder{color:var(--muted)}
/* نصّ الزرّين لا يلتفّ داخلهما مهما ضاق الصف — الالتفاف الداخلي يشوّه الشريط بلا فائدة */
#btnPrereqMap, #btnWhatIf{white-space:nowrap}

/* ===================== حركة الدخول ===================== */
@keyframes fadeUp{from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:none}}
.fadeup{animation:fadeUp .5s cubic-bezier(.22,.9,.36,1) both; animation-delay:var(--d, 0ms)}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important}
  html{scroll-behavior:auto}
}

/* ===================== استجابة الشاشات =====================
   قواعد العرض المتجاوب كلها في src/styles/responsive.css، لأنها تلمس محددات
   معرّفة في components.css بنفس التخصيص، فلا تكسب إلا إذا حُمّلت بعده. */

/* ===================== طباعة / تصدير PDF ===================== */
/* A4 هنا مقاسُ الطباعة المباشرة (Ctrl+P) وحدها. أما زرّ «تصدير PDF» فيستبدلها لحظتها بورقة
   واحدة متصلة: عرض ثابت وارتفاع بطول المحتوى — يحسبه `Paper` في src/lib/printOptions.js
   ويحقنه `applyPaperSize()` في <style id="prPageSize"> بعد هذا الملف، فيغلب عليها (Issue #136). */
@page{size:A4; margin:12mm}
@media print{
  :root, [data-theme="dark"]{
    --bg:#fff; --surface:#fff; --surface2:#f4f4f0; --text:#17251F; --muted:#666;
    --border:#ddd; --border-strong:#ccc; --brand-ink:#0E352C; --accent-ink:#0F8A74;
    --ok-ink:#0F8A74; --info-ink:#2A6E96; --warn-ink:#8A6D14; --danger-ink:#B4472A; --pink-ink:#CE2C73;
    --shadow:none; --shadow-lift:none; --hero-tint:none;
    /* الزجاج المطفي بلا معنى على الورق (issue #112): بطاقات معتمة بحدّ رمادي */
    --glass-bg:#fff; --glass-border:#ddd;
  }
  .topbar, .path-toolbar, .whatif, .simbar, .legend, .footer, .toast, .modal-ov, .analyze, .pmap-ov, .nc-bar{display:none !important}
  /* البطاقات معتمة على الورق. تُكتب القيم على المحدِّد نفسه لا عبر المتغيّرات أعلاه: قواعد
     dark-mode.css تُحمَّل بعد هذا الملف وبنفس تخصيص [data-theme="dark"]، و@media لا يرفع
     التخصيص — فتغلب تعريفاتها الداكنة على تعريفات الطباعة هنا وتبقى البطاقة شبه شفافة. */
  .stat{
    background:#fff !important; border-color:#ddd !important;
    backdrop-filter:none !important; -webkit-backdrop-filter:none !important;
  }
  #printHead{display:block !important}

  /* خيارات نافذة الطباعة (issue #134): أصناف تُوضع على <body> قبل window.print() وتُزال
     بعدها. غيابها كلها = الطباعة الكاملة كما كانت — وهو ما يحدث مع Ctrl+P المباشر. */
  body.pr-no-head .ph-plan{display:none}
  body.pr-no-head #printHead{padding:0; margin:0; border-bottom:none}
  body.pr-no-stats .statbar{display:none !important}
  /* «المنجزة فقط»: يبقى قسم «مقررات منجزة» وحده — بحالته على الشاشة (مفتوحاً أو مطوياً)،
     فلا يفتح النظام ولا يطوي شيئاً نيابةً عن الطالب. ويسقط معه تقرير التحليل وتحذيرات
     الجدولة، فكلاهما عن فصول لم تعد تُطبع. */
  body.pr-done-only #termsWrap > *:not(#completedWrap){display:none}
  body.pr-req #printReq{display:block}

  /* المحتوى يملأ منطقة الورقة كاملةً — هامشا @page هما التنفيس البصري الوحيد المطلوب.
     وثبات هذا العرض شرطٌ لصحة قياس ارتفاع الورقة قبل الطباعة: القياس يجري على نفس العرض
     بالضبط (Paper.contentWidthPx)، فلو بقيت حشوة الحاوية لاختلف الالتفاف عن الناتج (#136). */
  .container{max-width:none; padding-inline:0}

  .term-wrap::before{display:none}
  .term-wrap{padding-inline-start:0}
  .term-node{display:none}
  .term-card{break-inside:avoid; box-shadow:none}
  body{background:#fff}
}
#printHead{display:none; padding:6px 0 14px; border-bottom:2px solid var(--primary); margin-bottom:16px}
#printHead .ph-plan{display:grid; grid-template-columns:auto 1fr; column-gap:12px; align-items:center}
#printHead .ph-logo{grid-row:span 2; width:40px; height:40px; border-radius:10px}
#printHead .ph-title{font-size:20px; font-weight:700; color:var(--primary)}
#printHead .ph-sub{font-size:12px; color:#666; margin-top:4px}
/* سطر هوية الطالب (issue #134) — يُملأ من نافذة الخيارات، ويبقى بلا ارتفاع حين يُترك فارغاً */
#printHead .ph-id{font-size:12.5px; font-weight:700; color:var(--text); margin-top:8px}
#printHead .ph-id:empty{display:none}

/* صفحة «المتطلبات» في ملف PDF (issue #134) — تُرسم لحظة الطباعة وتظل مخفية عن الشاشة دائماً.
   بلا خلفيات ملوّنة عمداً: خيار «طباعة خلفيات الصفحة» مطفأ افتراضياً في المتصفحات، فالتمييز
   هنا بالحدود وسماكة الخط وحدهما حتى يخرج الجدول صحيحاً بلا ضبط إضافي من الطالب. */
#printReq{display:none; break-before:page}
.pr-req-title{font-size:18px; font-weight:700; color:var(--primary); margin:0 0 14px;
  padding-bottom:8px; border-bottom:2px solid var(--primary)}
.pr-pkg{break-inside:avoid; margin:0 0 18px}
.pr-pkg h3{margin:0 0 7px; font-size:14px; font-weight:700; display:flex; gap:9px; align-items:baseline; flex-wrap:wrap}
.pr-pkg-rule{font-size:11px; font-weight:600; color:#666}
.pr-tbl{width:100%; border-collapse:collapse; font-size:11.5px; line-height:1.6}
.pr-tbl thead{display:table-header-group}   /* الرؤوس تتكرر حين تنقسم الحزمة على صفحتين */
.pr-tbl th, .pr-tbl td{border:1px solid #ccc; padding:4px 8px; text-align:start}
.pr-tbl th{font-weight:700; border-bottom-width:2px}
/* الرمز والساعات والحالة بعرض محتواها (width:1%) فيبقى الفائض كله لاسم المقرر — بلا ذلك
   يتقاسم الرمزُ والاسمُ العرضَ مناصفةً فيظهر عمود الرمز فارغاً بمعظمه */
.pr-tbl .pr-c-code{font-family:var(--mono); direction:ltr; text-align:right; white-space:nowrap; width:1%}
.pr-tbl .pr-c-h, .pr-tbl .pr-c-st{white-space:nowrap; width:1%; text-align:center}
.pr-tbl tr.is-done td, .pr-tbl tr.is-sel td{font-weight:700}
