/* ==========================================================================
   SlotWise — גיליון הסגנון היחיד של האפליקציה
   SlotWise — the single stylesheet.

   כללי היסוד:
   1. אין שום בקשה חיצונית. אין @import, אין CDN, אין גופן שנטען מהרשת —
      רק גופני מערכת. האפליקציה עובדת גם בלי חיבור לאינטרנט.
      No external requests at all: no @import, no CDN, no webfonts.
   2. כל צבע מוגדר קודם כטוקן על ‎:root‎ (מצב בהיר מלא), ורק אחר כך נדרס
      בגוש הכהה. אין צבע שקיים רק במצב אחד.
      Every colour is defined on bare :root first; the dark blocks ONLY override tokens.
      יש **שני** גושים כהים והם חייבים להישאר זהים: אחד למצב "לפי המערכת"
      (בתוך ‎prefers-color-scheme‎) ואחד לבחירה מפורשת בכהה (‎[data-theme]‎).
      ‏CSS אינו יודע לצרף תנאי מדיה ותנאי סלקטור לכלל אחד, ולכן זו כפילות
      מכוונת — משנים בשניהם או בכלל לא.
   3. כיווניות: ‎dir="rtl"‎ על ‎<html>‎. משתמשים במאפיינים לוגיים
      (inline-start / inline-end) כדי שהפריסה תהיה נכונה מימין לשמאל.
   ========================================================================== */

/* ==========================================================================
   1. טוקנים — הפלטה הבהירה המלאה
   ========================================================================== */
:root {
  color-scheme: light dark;

  /* ---- משטחים וטקסט ---- */
  --bg: #f3eee4;
  --panel: #fffdf9;
  --panel-2: #f7f1e5;
  --chip: #ece4d3;
  --ink: #2b241d;
  --muted: #5f5245;
  --line: #e2d8c6;
  --line-strong: #8f7b62;

  /* ---- צבע ראשי ---- */
  --accent: #a33b1c;
  --accent-ink: #fffdf9;
  --accent-soft: #f8e3d7;
  --focus: #a33b1c;

  /* ---- מצבים ---- */
  --info-bg: #e9eef6;  --info-line: #4d74ad;  --info-ink: #1f4576;
  --ok-bg:   #e7f0dc;  --ok-line:   #4a8a3c;  --ok-ink:   #24501a;
  --warn-bg: #fbf0d5;  --warn-line: #8a5a12;  --warn-ink: #5d3a05;
  --err-bg:  #fbe3e8;  --err-line:  #ad2c48;  --err-ink:  #8a1030;

  /* ---- סימוני טבלת המרצים ---- */
  --pin-bg: #e7f0dc;
  --pin-line: #366e2b;
  --tie-line: #6d4fa6;
  --dead-line: #7d1533;

  /* ---- מידות ---- */
  --slot-h: 22px;          /* גובה משבצת של 15 דקות */
  --time-col: 4.6rem;      /* רוחב עמודת השעות */
  --day-min: 8.5rem;       /* רוחב מינימלי לעמודת יום — מתחת לזה הרשת נגללת */
  --radius: 10px;
  --radius-sm: 6px;
  --gap: 14px;
  --shadow: 0 1px 0 rgba(74, 56, 38, .05), 0 2px 6px rgba(74, 56, 38, .09);
  --shadow-sm: 0 1px 2px rgba(74, 56, 38, .10);

  /* ---- עשרה צבעי קורס נגישים ----
     כל שילוב רקע/טקסט נבדק: יחס ניגודיות ‎>= 9:1‎ במצב בהיר ובמצב כהה כאחד
     (הדרישה היא 7:1). מיפוי הקוד לצבע זהה ל-src/render.py. */
  --course-0: #f3d4c9;  --course-0-bd: #d9613e;  --course-0-fg: #681a04;
  --course-1: #fbecd7;  --course-1-bd: #ae660f;  --course-1-fg: #623804;
  --course-2: #f8e5a1;  --course-2-bd: #b18b0c;  --course-2-fg: #4a3b03;
  --course-3: #cfe5bb;  --course-3-bd: #5a952e;  --course-3-fg: #1b4003;
  --course-4: #d9efe2;  --course-4-bd: #2b885c;  --course-4-fg: #03492b;
  --course-5: #a9dde2;  --course-5-bd: #229ba9;  --course-5-fg: #03373e;
  --course-6: #c1d2eb;  --course-6-bd: #3e74ce;  --course-6-fg: #042c6a;
  --course-7: #e9ddf1;  --course-7-bd: #a177ca;  --course-7-fg: #4d079f;
  --course-8: #faf0f4;  --course-8-bd: #c850a0;  --course-8-fg: #84055e;
  --course-9: #f6cdd3;  --course-9-bd: #db6780;  --course-9-fg: #6c051d;

  /* ======================================================================
     ‏מקור הפלטה הכהה. הערכים חיים **כאן בלבד**, ושני גושי הכהה בפרק 2
     רק ממפים אליהם. לפני האיחוד כל צבע כהה הופיע פעמיים, ו"לשנות
     בשניהם או בכלל לא" היה הסכם שבעל פה שאין מי שיאכוף. עכשיו שינוי
     צבע הוא עריכה של שורה אחת, ואי אפשר לשנות עותק אחד ולפספס את השני.
     The dark palette is defined once, here. The two dark blocks in §2
     only map to it, so no hex appears twice.
     ====================================================================== */
  --dark-bg: #1a1a1a;
  --dark-panel: #252525;
  --dark-panel-2: #2d2d2d;
  --dark-chip: #353535;
  --dark-ink: #f2e8da;
  --dark-muted: #bcac95;
  --dark-line: #3b3b3b;
  --dark-line-strong: #7e7e7e;

  --dark-accent: #f0a077;
  --dark-accent-ink: #1a1410;
  /* ‏נייטרלי, ולא גוון רך של האקסנט. כל תשעת השימושים ב-‎--accent-soft‎ הם
     ‎background‎ — אף אחד מהם אינו טקסט ואינו מסגרת — כלומר זהו טוקן של
     משטח בלבד, ומשטח חום מול צ'רקול נייטרלי נקרא כשריד ולא כבחירה.
     האקסנט עצמו נשאר: הכרטיס הנבחר מסומן במסגרת ‎--accent‎, והמילוי רק
     מרים אותו מהמשטח שמתחתיו.

     ‏#3e3e3e ולא האפור בעל אותה בהירות כמו ‎#3b2517‎, שהוא ‎#2a2a2a‎: שם
     הכרומה הייתה זו שנשאה את ההבדל, וניטרול בלבד היה משאיר את הכרטיס
     הנבחר ב-‎dE 1.4‎ מ-‎--panel-2‎ שעליו יושבים הלא-נבחרים — כלומר בלי
     סימן מילוי כלל. עלייה במדרג שומרת על ההבדל: ‎dE 7.7‎ מ-‎--panel-2‎
     ו-‎dE 4.0‎ מ-‎--chip‎, ששורת מרצה מדורגת יושבת לצדו. */
  --dark-accent-soft: #3e3e3e;
  --dark-focus: #f0a077;

  --dark-info-bg: #1b2431;  --dark-info-line: #4a6f9e;  --dark-info-ink: #bcd3ef;
  --dark-ok-bg:   #1a2c17;  --dark-ok-line:   #4f8a45;  --dark-ok-ink:   #b6e0a2;
  --dark-warn-bg: #3a2c0e;  --dark-warn-line: #c99a3f;  --dark-warn-ink: #f2cf8a;
  --dark-err-bg:  #3a1620;  --dark-err-line:  #d9697f;  --dark-err-ink:  #f5aab8;

  --dark-pin-bg: #1a2c17;
  --dark-pin-line: #66b356;
  /* ‏הועלה מ-‎#b099e8‎ יחד עם ניטרול ‎--accent-soft‎. התג "קורס צמוד" הוא
     היחיד עם ‎background: transparent‎, כלומר הוא יושב על רקע הכרטיס —
     וכשהכרטיס הנבחר עלה מ-‎#3b2517‎ ל-‎#3e3e3e‎ הוא ירד ל-4.36:1. עכשיו
     ‏5.02 שם, ‏6.46 על ‎--panel-2‎ ו-7.19 על ‎--panel‎. */
  --dark-tie-line: #bba7ec;
  --dark-dead-line: #e88fa8;

  --dark-shadow: 0 1px 0 rgba(0, 0, 0, .40), 0 2px 8px rgba(0, 0, 0, .38);
  --dark-shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);

  --dark-course-0: #672d1b;  --dark-course-0-bd: #bb5232;  --dark-course-0-fg: #f6e0d9;
  --dark-course-1: #36230c;  --dark-course-1-bd: #b67322;  --dark-course-1-fg: #e2bc8c;
  --dark-course-2: #52410d;  --dark-course-2-bd: #816a16;  --dark-course-2-fg: #f4ecd2;
  --dark-course-3: #293f17;  --dark-course-3-bd: #568432;  --dark-course-3-fg: #bee8a3;
  --dark-course-4: #163524;  --dark-course-4-bd: #369468;  --dark-course-4-fg: #81dfb7;
  --dark-course-5: #18474c;  --dark-course-5-bd: #2a7981;  --dark-course-5-fg: #ceeef3;
  --dark-course-6: #1f365b;  --dark-course-6-bd: #5681c6;  --dark-course-6-fg: #c9d8f1;
  --dark-course-7: #4e2973;  --dark-course-7-bd: #8b58bf;  --dark-course-7-fg: #e7dbf6;
  --dark-course-8: #481b37;  --dark-course-8-bd: #c0579d;  --dark-course-8-fg: #edb8dd;
  --dark-course-9: #5c1c29;  --dark-course-9-bd: #c13c58;  --dark-course-9-fg: #f1c8d1;

  /* ======================================================================
     ‏מקור הפלטה של הנייר. הדף המודפס אינו "בהיר" ואינו "כהה" — הוא לבן,
     תמיד. הערכים כאן, והמיפוי בפרק 15.
     ====================================================================== */
  --print-bg: #ffffff;
  --print-panel: #ffffff;
  --print-panel-2: #ffffff;
  --print-chip: #f1f3f6;
  --print-ink: #000000;
  --print-muted: #444444;
  --print-line: #c9ced6;
  --print-line-strong: #8b939e;
  --print-accent: #14406f;
  --print-accent-ink: #ffffff;
  --print-accent-soft: #eef3fa;
}

/* ==========================================================================
   2. מצב כהה — מיפוי בלבד. הערכים עצמם יושבים בפרק 1.
   ========================================================================== */
/* ‏שני הגושים האלה חייבים להישאר זהים — ‎CSS‎ אינו יודע לצרף תנאי מדיה
   ותנאי סלקטור לכלל אחד, ולכן הכפילות מכוונת. מה שהשתנה: הם כבר אינם
   מחזיקים צבעים, רק הפניות אל ‎--dark-*‎. שכפול של רשימת הפניות אינו
   יכול להיסדק בשקט — ‎tests/test_theme_tokens.py‎ מוודא שהשניים זהים.

   ‏שניהם עטופים ב-‎screen‎ בכוונה. "כהה" הוא מצב של מסך, לא של נייר, ובלי
   העטיפה הזאת ‎:root[data-theme="dark"]‎ בדרגה (0,2,0) גבר על ‎:root‎ של
   גוש ההדפסה בדרגה (0,1,0) — והדף יצא עם ‎--ink: #e6eaf1‎ על נייר לבן,
   יחס ניגודיות 1.16:1. מי שהדפיס במצב כהה הדפיס דף ריק למראה. */

/* ‏א. "לפי המערכת": חל רק כשאין בחירה מפורשת בבהיר.
   בלי ‎:not([data-theme="light"])‎ הגוש הזה היה גובר על בחירת "בהיר"
   של מי שמערכת ההפעלה שלו כהה — שתי הדרגות זהות (0,2,0), והמאוחר מנצח. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: var(--dark-bg);
    --panel: var(--dark-panel);
    --panel-2: var(--dark-panel-2);
    --chip: var(--dark-chip);
    --ink: var(--dark-ink);
    --muted: var(--dark-muted);
    --line: var(--dark-line);
    --line-strong: var(--dark-line-strong);

    --accent: var(--dark-accent);
    --accent-ink: var(--dark-accent-ink);
    --accent-soft: var(--dark-accent-soft);
    --focus: var(--dark-focus);

    --info-bg: var(--dark-info-bg);  --info-line: var(--dark-info-line);  --info-ink: var(--dark-info-ink);
    --ok-bg: var(--dark-ok-bg);  --ok-line: var(--dark-ok-line);  --ok-ink: var(--dark-ok-ink);
    --warn-bg: var(--dark-warn-bg);  --warn-line: var(--dark-warn-line);  --warn-ink: var(--dark-warn-ink);
    --err-bg: var(--dark-err-bg);  --err-line: var(--dark-err-line);  --err-ink: var(--dark-err-ink);

    --pin-bg: var(--dark-pin-bg);
    --pin-line: var(--dark-pin-line);
    --tie-line: var(--dark-tie-line);
    --dead-line: var(--dark-dead-line);

    --shadow: var(--dark-shadow);
    --shadow-sm: var(--dark-shadow-sm);

    --course-0: var(--dark-course-0);  --course-0-bd: var(--dark-course-0-bd);  --course-0-fg: var(--dark-course-0-fg);
    --course-1: var(--dark-course-1);  --course-1-bd: var(--dark-course-1-bd);  --course-1-fg: var(--dark-course-1-fg);
    --course-2: var(--dark-course-2);  --course-2-bd: var(--dark-course-2-bd);  --course-2-fg: var(--dark-course-2-fg);
    --course-3: var(--dark-course-3);  --course-3-bd: var(--dark-course-3-bd);  --course-3-fg: var(--dark-course-3-fg);
    --course-4: var(--dark-course-4);  --course-4-bd: var(--dark-course-4-bd);  --course-4-fg: var(--dark-course-4-fg);
    --course-5: var(--dark-course-5);  --course-5-bd: var(--dark-course-5-bd);  --course-5-fg: var(--dark-course-5-fg);
    --course-6: var(--dark-course-6);  --course-6-bd: var(--dark-course-6-bd);  --course-6-fg: var(--dark-course-6-fg);
    --course-7: var(--dark-course-7);  --course-7-bd: var(--dark-course-7-bd);  --course-7-fg: var(--dark-course-7-fg);
    --course-8: var(--dark-course-8);  --course-8-bd: var(--dark-course-8-bd);  --course-8-fg: var(--dark-course-8-fg);
    --course-9: var(--dark-course-9);  --course-9-bd: var(--dark-course-9-bd);  --course-9-fg: var(--dark-course-9-fg);
  }
}

/* ‏ב. בחירה מפורשת בכהה. רשימה זהה לגוש שמעליו — ראו ההערה בראש הפרק. */
@media screen {
  :root[data-theme="dark"] {
    --bg: var(--dark-bg);
    --panel: var(--dark-panel);
    --panel-2: var(--dark-panel-2);
    --chip: var(--dark-chip);
    --ink: var(--dark-ink);
    --muted: var(--dark-muted);
    --line: var(--dark-line);
    --line-strong: var(--dark-line-strong);

    --accent: var(--dark-accent);
    --accent-ink: var(--dark-accent-ink);
    --accent-soft: var(--dark-accent-soft);
    --focus: var(--dark-focus);

    --info-bg: var(--dark-info-bg);  --info-line: var(--dark-info-line);  --info-ink: var(--dark-info-ink);
    --ok-bg: var(--dark-ok-bg);  --ok-line: var(--dark-ok-line);  --ok-ink: var(--dark-ok-ink);
    --warn-bg: var(--dark-warn-bg);  --warn-line: var(--dark-warn-line);  --warn-ink: var(--dark-warn-ink);
    --err-bg: var(--dark-err-bg);  --err-line: var(--dark-err-line);  --err-ink: var(--dark-err-ink);

    --pin-bg: var(--dark-pin-bg);
    --pin-line: var(--dark-pin-line);
    --tie-line: var(--dark-tie-line);
    --dead-line: var(--dark-dead-line);

    --shadow: var(--dark-shadow);
    --shadow-sm: var(--dark-shadow-sm);

    --course-0: var(--dark-course-0);  --course-0-bd: var(--dark-course-0-bd);  --course-0-fg: var(--dark-course-0-fg);
    --course-1: var(--dark-course-1);  --course-1-bd: var(--dark-course-1-bd);  --course-1-fg: var(--dark-course-1-fg);
    --course-2: var(--dark-course-2);  --course-2-bd: var(--dark-course-2-bd);  --course-2-fg: var(--dark-course-2-fg);
    --course-3: var(--dark-course-3);  --course-3-bd: var(--dark-course-3-bd);  --course-3-fg: var(--dark-course-3-fg);
    --course-4: var(--dark-course-4);  --course-4-bd: var(--dark-course-4-bd);  --course-4-fg: var(--dark-course-4-fg);
    --course-5: var(--dark-course-5);  --course-5-bd: var(--dark-course-5-bd);  --course-5-fg: var(--dark-course-5-fg);
    --course-6: var(--dark-course-6);  --course-6-bd: var(--dark-course-6-bd);  --course-6-fg: var(--dark-course-6-fg);
    --course-7: var(--dark-course-7);  --course-7-bd: var(--dark-course-7-bd);  --course-7-fg: var(--dark-course-7-fg);
    --course-8: var(--dark-course-8);  --course-8-bd: var(--dark-course-8-bd);  --course-8-fg: var(--dark-course-8-fg);
    --course-9: var(--dark-course-9);  --course-9-bd: var(--dark-course-9-bd);  --course-9-fg: var(--dark-course-9-fg);
  }
}

/* ‏color-scheme קובע את הגוון של פקדי המערכת עצמם — תיבות בחירה, שדה
   השעה, פסי הגלילה. בלי זה בחירה מפורשת הייתה צובעת את העמוד ומשאירה
   את הפקדים בגוון ההפוך. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

/* ==========================================================================
   3. בסיס
   ========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Segoe UI", "Arial Hebrew", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

h1, h2, h3 { margin: 0; font-weight: 700; line-height: 1.25; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

[hidden] { display: none !important; }

/* מספרים, שעות וקודי קורס — תמיד משמאל לימין, מבודדים מהטקסט העברי.
   ‏**רק על האסימון עצמו, לא על התא שמכיל אותו.** ‏.cell-group ישב כאן
   ‏עד 2026-09-10 והוא ``<td>``: ‏direction: ltr עליו הפך את
   ‏text-align: start של הטבלה משמאל לימין, ולכן עמודת "קבוצה" יושרה
   ‏שמאלה בזמן שכל השאר — והכותרת שלה עצמה — יושרו ימינה. הוא גם הפך
   ‏לטיני את הערת הקבוצה ואת תג "הקורס מלא", שהם עברית. קוד הקבוצה
   ‏מבודד ב-.gid שבתוך התא, בדיוק כפי שטווח השעות מבודד ב-.cell-time
   ‏בתוך תא היום — אותה תבנית, ועכשיו בשני המקומות. */
.ltr,
.fresh-meta,
.course-code,
.cell-time,
.log-lines {
  direction: ltr;
  unicode-bidi: isolate;
}

/* ==========================================================================
   4. כותרת עליונה
   ========================================================================== */
.busy-bar {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  z-index: 60;
  background: var(--line);
  overflow: hidden;
}

.busy-bar > span {
  display: block;
  block-size: 100%;
  inline-size: 40%;
  background: var(--accent);
  animation: busy-slide 1.1s linear infinite;
}

@keyframes busy-slide {
  from { transform: translateX(-120%); }
  to   { transform: translateX(320%); }
}

.app-header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  align-items: flex-start;
  justify-content: space-between;
  padding: 16px clamp(12px, 3vw, 28px);
  background: var(--panel);
  border-block-end: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}

/* ‏הסימן בצד שמאל. ‎order‎ ולא היפוך ה-DOM: שם המוצר נשאר האלמנט הראשון
   בקריאת מסך ובסדר ה-Tab, ורק המיקום הוויזואלי זז. ‎justify-content:
   space-between‎ שכבר קיים דוחף אותו אל הקצה. */
.brand { order: 1; text-align: left; }

/* ‏הסימן והמילה הם יחידה לטינית אחת, ולכן ‎ltr‎ בתוכה — בלעדיו האייקון
   היה נוחת מימין ל-"SlotWise" ולא משמאלו. הכיתוב מתחת נשאר עברי
   ונקרא ימין-לשמאל כרגיל; רק היישור שלו הוא לשמאל, כמו הסימן שמעליו. */
.brand-mark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  direction: ltr;
}

.brand-icon {
  inline-size: 22px;
  block-size: 22px;
  flex: none;
  color: var(--accent);
}

.brand-title { font-size: 20px; letter-spacing: -.01em; }

.header-side {
  display: flex;
  flex-wrap: wrap;
  gap: 10px var(--gap);
  align-items: center;
}

.freshness {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel-2);
}

.fresh-lines { display: flex; flex-direction: column; line-height: 1.3; }
.fresh-text { font-size: 13px; font-weight: 600; }
.fresh-meta { font-size: 13px; color: var(--muted); }

/* ‏אותה שורה בדיוק, בצבע אזהרה — לא משפט אחר ולא אייקון נוסף. מה שהשתנה
   הוא הגיל, לא מה שהאפליקציה יודעת, ולכן הנוסח נשאר זהה.
   ‏--warn-ink ולא --warn-line: זה טקסט על רקע הכותרת הרגיל, ו--warn-line
   הוא טוקן של מסגרות ונקודות. ‏#freshness-dot כבר נושא את אותו מצב,
   ולכן הצבע אינו הסימון היחיד — כלל 7.1. */
.fresh-text[data-state="stale"] { color: var(--warn-ink); }

.fresh-dot {
  inline-size: 10px;
  block-size: 10px;
  border-radius: 50%;
  flex: none;
  background: var(--line-strong);
  border: 1px solid var(--line-strong);
}

/* ‏--ok-line ולא --pin-line: זהו מצב של הנתונים, ושלושת המצבים כאן הם
   משפחה אחת — ‏ok / warn / err. שימוש בטוקן הנעיצה היה עובד עד היום
   שבו מישהו ישנה את צבע הנעיצה ויגלה שנקודת הטריות זזה איתו. */
.fresh-dot[data-state="fresh"] { background: var(--ok-line); border-color: var(--ok-line); }
.fresh-dot[data-state="stale"] { background: var(--warn-line); border-color: var(--warn-line); }
.fresh-dot[data-state="empty"] { background: var(--dead-line); border-color: var(--dead-line); }

/* ‏חי עכשיו בתוך "פרטים טכניים" ולא בכותרת, ולכן שורת הסיכום שלצדו
   מיושרת אליו במקום להיתלות מתחת לכפתור. */
.header-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  margin-block-end: 12px;
}

/* ---- בורר ערכת הצבעים: שלושה מצבים בפקד אחד ---- */
.theme-toggle {
  display: flex;
  flex: none;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel-2);
}

.theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: inherit;
  padding: 5px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.theme-ico {
  inline-size: 17px;
  block-size: 17px;
  display: block;
}

.theme-btn:hover { color: var(--ink); }

.theme-btn[aria-checked="true"] {
  background: var(--accent);
  color: var(--accent-ink);
}

/* ‏הסימון השני, שאינו צבע. גלולה צבועה לבדה מבדילה בגוון ובבהירות, וכלל
   ‏7.1 דורש סימן שאינו נשען על צבע — כאן הצורה שבתוך האייקון עוברת
   ממתאר למילוי: השמש מקבלת דיסקה, הירח גוף, והמסך זכוכית. ההבדל נשאר
   גלוי גם בגווני אפור ובסימולציית עיוורון צבעים.
   ‏fill-opacity ולא מילוי מלא: מילוי אטום היה בולע את המתאר והופך את
   הירח לכתם. */
.theme-btn .ico-fill { fill: none; }

.theme-btn[aria-checked="true"] .ico-fill {
  fill: currentColor;
  fill-opacity: .3;
}

/* ==========================================================================
   5. כפתורים ושדות
   ========================================================================== */
.btn {
  font: inherit;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn:hover:not(:disabled) { border-color: var(--accent); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.btn-primary:hover:not(:disabled) { filter: brightness(1.08); }
.btn-ghost { background: transparent; }
.btn-ghost:hover:not(:disabled) { background: var(--accent-soft); }
.btn-sm { padding: 5px 11px; font-size: 13px; }

/* ---- שלוש דרגות לכפתורי הכותרת ----
   שלושתם נראו זהים, והם רחוקים מלהיות שקולים: אחד יוצא לרשת ומושך מאות
   עמודים מהידיעון, השני בונה מחדש ממה שכבר במחשב, והשלישי רק פותח יומן.
   המראה עוקב אחרי המחיר. ‏btn-ghost נשאר כפי שהוא — הוא בשימוש בעוד
   כתריסר מקומות בעמוד, ולא הוא הנושא כאן. */

/* ראשי: מילוי מלא. זו הפעולה שבאים בשבילה. */
.btn-primary { font-weight: 700; }

/* משני: מתאר בלבד. אמיתי, אבל לא מה שמושך את העין ראשון. */
.btn-outline {
  background: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
}

.btn-outline:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* שלישוני: בלי מסגרת ובלי רקע — קישור שנראה ככפתור רק כשנוגעים בו.
   הכלל הזה חייב לבוא אחרי ‎.btn:hover‎, שאחרת היה מחזיר לו מסגרת בריחוף. */
.btn-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  font-weight: 500;
}

.btn-quiet:hover:not(:disabled) {
  border-color: transparent;
  background: var(--chip);
  color: var(--ink);
}

.field { display: flex; flex-direction: column; gap: 4px; min-inline-size: 0; }
.field-grow { flex: 1 1 16rem; }

/* ‏בתוך שדה, מחלקת הרוחב היא הקובעת — לא רצפת ה-‎min-inline-size‎ של
   ‎.input‎.
   ‏.input מצהיר על ‎min-inline-size: 9rem‎ כדי ששדה בודד לא ייצא זעיר, אבל
   ‎.field--sm‎ הוא ‎8rem‎. ‏9 > 8, ולכן ה-‎select‎ גלש 16px אל מחוץ למכל שלו,
   וב-RTL הגלישה היא שמאלה — אל תוך השדה השכן. התוצאה: התווית "סמסטר",
   שמיושרת לימין השדה שלה, כיסתה את ‎#select-year‎, וכל תווית נראתה כאילו
   היא שייכת לתיבה הלא נכונה.
   ‏inline-size: 100% ולא רק ביטול הרצפה: כך התיבה **שווה** למחלקה שלה,
   וזה מה ששלב 5 ביקש — "לתת לשדות את רוחב התוכן שלהם וליישר על רשת". */
.field > .input {
  inline-size: 100%;
  min-inline-size: 0;
}

.field-check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  align-self: flex-end;
  padding-block-end: 8px;
}

.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  align-items: flex-start;
}

.label { font-size: 13px; font-weight: 600; color: var(--muted); }

.input {
  font: inherit;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  min-inline-size: 9rem;
}

.input:hover { border-color: var(--accent); }

input[type="checkbox"] { accent-color: var(--accent); inline-size: 1.05rem; block-size: 1.05rem; }
input[type="time"] { direction: ltr; unicode-bidi: isolate; text-align: start; }

/* ==========================================================================
   6. באנרים, הודעות חולפות, יומן
   ========================================================================== */
.banners {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 clamp(12px, 3vw, 28px);
  margin-block-start: 12px;
}

.banners:empty { display: none; }

/* ‏שורה אחת: אייקון, טקסט, "הצג רשימה", פעולה, סגירה.
   ‏align-items: center ולא flex-start — באנר בן שורה אחת, לא פסקה. */
.banner {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  align-items: center;
  padding: 10px 14px;
  border: 1px solid var(--info-line);
  border-inline-start: 4px solid var(--info-line);
  border-radius: var(--radius-sm);
  background: var(--info-bg);
  color: var(--info-ink);
  font-size: 13px;
}

/* ‏min-inline-size: 0 — בלעדיו טקסט ארוך בלי רווחים מרחיב את הבאנר
   מעבר לרוחב העמוד במקום להישבר. */
.banner-icon { order: 0; flex: none; }
.banner-text { order: 1; flex: 1 1 14rem; min-inline-size: 0; }
.banner-more { order: 2; flex: none; }
.banner .btn { order: 3; flex: none; }
.banner-close { order: 4; flex: none; margin-inline-start: auto; }

.banner-icon::before { content: "\2139"; font-weight: 700; }
.banner--ok    { border-color: var(--ok-line);   background: var(--ok-bg);   color: var(--ok-ink); }
.banner--warn  { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn-ink); }
.banner--error { border-color: var(--err-line);  background: var(--err-bg);  color: var(--err-ink); }
.banner--ok .banner-icon::before    { content: "\2713"; }
.banner--warn .banner-icon::before  { content: "\26A0"; }
.banner--error .banner-icon::before { content: "\2716"; }

/* גוון שקט: נכון עובדתית, אבל לא דורש תשומת לב מיידית.
   אין שלישיית טוקנים ניטרלית בקובץ, ולכן זה נבנה מטוקני הבסיס —
   וממילא מקבל מצב כהה בלי שורה נוספת בבלוק הכהה. */
.banner--muted {
  border-color: var(--line-strong);
  background: var(--chip);
  color: var(--muted);
}

/* ---- הרשימה המלאה, מקופלת ---- */
/* פתוח = שורה משלו ברוחב מלא, מתחת להודעה. סגור = פריט קטן בשורה. */
.banner-more[open] {
  order: 9;
  flex: 1 1 100%;
  margin-block-start: 2px;
}

.banner-more-summary {
  cursor: pointer;
  font-weight: 600;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
}

.banner-more-summary:hover { background: rgba(128, 128, 128, .14); }

.banner-more-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 4px 4px;
}

.banner-more-title {
  font-weight: 600;
  font-size: 13px;
}

.banner-more-legend { font-size: 13px; color: var(--muted); }

.code-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  /* מאות קודים לא ידחפו את העמוד: הרשימה נגללת בתוך עצמה. */
  max-block-size: 11rem;
  overflow-y: auto;
}

.code-chip {
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  line-height: 1;
  padding: 4px 6px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel);
  color: var(--ink);
  /* הקוד הוא מספר: מוצג משמאל לימין גם בתוך עמוד ימין-לשמאל. */
  direction: ltr;
  unicode-bidi: isolate;
}

.code-chip.is-failed {
  border-color: var(--err-line);
  color: var(--err-ink);
  background: var(--err-bg);
}

.banner-close {
  font: inherit;
  font-size: 16px;
  line-height: 1;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0 4px;
  opacity: .7;
}

.banner-close:hover { opacity: 1; }

.toasts {
  position: fixed;
  inset-block-end: 16px;
  inset-inline-start: 16px;
  z-index: 70;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-inline-size: min(24rem, 90vw);
}

.toast {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--info-line);
  background: var(--info-bg);
  color: var(--info-ink);
  box-shadow: var(--shadow);
  font-size: 13px;
  animation: toast-in .18s ease-out;
}

.toast--ok    { border-color: var(--ok-line);   background: var(--ok-bg);   color: var(--ok-ink); }
.toast--warn  { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn-ink); }
.toast--error { border-color: var(--err-line);  background: var(--err-bg);  color: var(--err-ink); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.log-panel {
  margin: 12px clamp(12px, 3vw, 28px) 0;
  padding: 14px 16px;
}

.log-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.log-title { font-size: 15px; }

.log-phase {
  font-size: 13px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--chip);
  color: var(--muted);
  margin-inline-end: auto;
}

.log-note {
  font-size: 13px;
  color: var(--warn-ink);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  margin-block: 10px;
}

.log-lines {
  margin: 0;
  padding: 10px 12px;
  max-block-size: 16rem;
  overflow: auto;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: Consolas, "Courier New", monospace;
  font-size: 13px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
  unicode-bidi: plaintext;
  text-align: start;
}

.log-lines:empty::before {
  content: "אין עדיין שורות ביומן.";
  color: var(--muted);
  unicode-bidi: plaintext;
}

/* ==========================================================================
   6ב. סרגל מצוף ושכבת המערכת
   ========================================================================== */

/* ‏fixed ולא sticky: הסרגל צריך להופיע *בגלילה*, לא במקום שבו הוא יושב
   ב-DOM. ‏visibility (ולא display) כדי שההחלקה פנימה תוכל לרוץ — וגם כדי
   שכשהוא מוסתר הוא יוצא מסדר ה-Tab ומעץ הנגישות. */
.sticky-bar {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 55;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px var(--gap);
  /* ~‏52px: הריפוד ועוד שורת פקדים אחת. */
  padding: 8px clamp(12px, 3vw, 28px);
  background: var(--panel);
  border-block-end: 1px solid var(--line);
  box-shadow: var(--shadow);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform .18s ease, visibility .18s;
}

.sticky-bar.is-visible { transform: none; visibility: visible; }

.sticky-tabs {
  display: flex;
  gap: 4px;
  flex: none;
}

.sticky-tab {
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  inline-size: 1.9rem;
  block-size: 1.9rem;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
}

.sticky-tab:hover { border-color: var(--accent); }

.sticky-tab[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.sticky-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  align-items: baseline;
  /* הסרגל לא גדל: העובדות נחתכות לפני שהכפתור נדחף מהמסך. */
  flex: 1 1 auto;
  min-inline-size: 0;
  overflow: hidden;
}

.sticky-fact { display: inline-flex; gap: .4em; align-items: baseline; white-space: nowrap; }
.sticky-fact-label { font-size: 13px; color: var(--muted); }
.sticky-fact-value { font-size: 13.5px; font-variant-numeric: tabular-nums; }

.sticky-bar .btn { flex: none; }

/* ---- שכבת המערכת ---- */
.overlay-backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(8px, 2vw, 24px);
  background: rgba(0, 0, 0, .55);
}

.overlay-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  inline-size: min(1400px, 100%);
  /* גובה מרבי + min-block-size: 0 בילדים = הרשת גוללת בתוך השכבה
     במקום לגלוש ממנה. כאן, בניגוד לעמוד עצמו, זו גלילה אחת וברורה. */
  max-block-size: 100%;
  padding: 14px clamp(12px, 2vw, 20px) 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.overlay-panel:focus { outline: none; }

.overlay-head {
  display: flex;
  flex-wrap: wrap;
  gap: 8px var(--gap);
  align-items: center;
}

.overlay-title { font-size: 16px; flex: none; }
.overlay-head .btn { margin-inline-start: auto; }

.overlay-panel > .legend { flex: none; }

.overlay-panel > .grid-scroll {
  flex: 1 1 auto;
  min-block-size: 0;
  overflow: auto;
  overscroll-behavior: contain;
}

/* נעילת הגלילה מאחורי השכבה */
html.is-modal-open,
html.is-modal-open body { overflow: hidden; }

/* ==========================================================================
   7. השלבים — מראה אשף ממוספר
   ========================================================================== */
.steps {
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 18px clamp(12px, 3vw, 28px) 40px;
  max-inline-size: 1180px;
  margin-inline: auto;
}

.step {
  counter-increment: step;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px clamp(12px, 2.4vw, 22px) 20px;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.step.is-active {
  border-color: var(--accent);
  box-shadow: var(--shadow), 0 0 0 1px var(--accent);
}

.step.is-locked { opacity: .6; }
.step.is-locked .step-body { pointer-events: none; }

.step-head { margin-block-end: 14px; }

.step-title {
  font-size: 17px;
  display: flex;
  align-items: center;
  gap: .55em;
}

.step-title::before {
  content: counter(step);
  flex: none;
  display: inline-grid;
  place-items: center;
  inline-size: 1.9em;
  block-size: 1.9em;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--chip);
  color: var(--muted);
  font-size: .8em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.step.is-active .step-title::before {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ‏"החלטתי כאן" נצבע באקסנט, ולא בירוק ההצלחה.
   ‏שלושת המקומות שאומרים את המשפט הזה — הסימן על הסעיף, השבב בשורת
   ההתקדמות ומתג האישור — חייבים להיראות אותו דבר; אחרת אותה משמעות
   מצוירת בשני צבעים במרחק סנטימטרים זה מזה. הירוק נשאר שמור למצב
   (‏banner--ok, toast--ok, fact--ok) ולנעיצה, ומרגע שאינו מסמן גם
   "הוכרע" הוא מפסיק לומר שני דברים. */
.step.is-complete .step-title::before {
  content: "\2713";
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

.step-hint {
  color: var(--muted);
  font-size: 13px;
  margin-block-start: 6px;
  max-inline-size: 78ch;
}

.step-state {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  margin-block-start: 6px;
}

.step-state:empty { display: none; }

.step-body { display: flex; flex-direction: column; gap: var(--gap); }

/* ---- קיפול שלב לשורת סיכום אחת ----
   הכפתור יושב בתוך ה-h2 ותופס את כל רוחב הכותרת, כדי שאפשר יהיה ללחוץ
   על כל השורה ולא רק על המילה. עיגול המספר/ה-✓ נשאר על ‎.step-title::before‎
   ולכן כל כללי המצב הקיימים ממשיכים לעבוד בלי שינוי. */
.step-toggle {
  flex: 1;
  display: flex;
  align-items: center;
  gap: .5em;
  min-inline-size: 0;
  font: inherit;
  color: inherit;
  text-align: start;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  /* המרווח השלילי מחזיר את הכפתור לקו הכותרת המקורי אחרי הריפוד. */
  padding: 3px 6px;
  margin: -3px -6px;
  cursor: pointer;
}

.step-toggle:hover { background: var(--panel-2); }

.step-name { flex: none; }

/* שורת הסיכום קיימת תמיד ב-DOM (שם נגיש לכפתור), ונראית רק כשמקופל. */
.step-summary { display: none; }

.step-caret {
  flex: none;
  margin-inline-start: auto;
  color: var(--muted);
  font-size: .8em;
  line-height: 1;
}

.step-caret::before {
  content: "\25BE";
  display: block;
  transition: transform .15s ease;
}

.step.is-collapsed .step-caret::before { transform: rotate(90deg); }

.step.is-collapsed { padding-block-end: 16px; }
.step.is-collapsed .step-head { margin-block-end: 0; }
.step.is-collapsed .step-hint,
.step.is-collapsed .step-state { display: none; }

/* ‏‎> ‎ הכרחי: ל-#catalog-browse ול-#electives יש גם הם class="step-body",
   והם יושבים **בתוך** גוף שלב 2. בלי הצירוף הישיר קיפול שלב 2 היה מסתיר
   אותם גם כשהשלב פרוס. */
.step.is-collapsed > .step-body { display: none; }

.step.is-collapsed .step-summary::before {
  content: "\00B7";
  margin-inline-end: .4em;
  color: var(--muted);
  font-weight: 400;
}

.step.is-collapsed .step-summary {
  display: block;
  flex: 1;
  min-inline-size: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  /* סיכום ארוך נחתך ולא שובר את השורה — שורה אחת פירושה שורה אחת. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* שלב נעול לא ניתן לקיפול: אין בו עדיין מה לסכם. */
.step.is-locked .step-toggle { cursor: default; }
.step.is-locked .step-caret { visibility: hidden; }

.note {
  font-size: 13px;
  color: var(--muted);
  max-inline-size: 78ch;
}

.note:empty { display: none; }

.resolved {
  font-size: 13.5px;
  font-weight: 600;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  border: 1px solid var(--line);
  align-self: flex-start;
}

.resolved:empty { display: none; }

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.facts:empty { display: none; }

.fact {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  min-inline-size: 6.5rem;
}

.fact-label { font-size: 13px; color: var(--muted); }
.fact-value { font-size: 16px; font-variant-numeric: tabular-nums; }

/* כיוון הקריאה של המדד. מספר בלי הכיוון הזה — ובעיקר מספר שלילי —
   אינו אומר לסטודנט/ית אם הוא טוב או רע. */
.fact-hint { font-size: 13px; color: var(--muted); }
.fact[title] { cursor: help; }
.fact--warn { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn-ink); }
.fact--ok   { border-color: var(--ok-line);   background: var(--ok-bg);   color: var(--ok-ink); }

.inline-warn {
  font-size: 13px;
  font-weight: 600;
  padding: 9px 13px;
  border: 1px solid var(--warn-line);
  border-inline-start: 4px solid var(--warn-line);
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.advanced {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  padding: 4px 12px;
}

.advanced-summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  padding: 7px 2px;
}

.advanced-body { padding-block: 6px 12px; display: flex; flex-direction: column; gap: 10px; }

.blocked { display: flex; flex-wrap: wrap; gap: 6px; }
.blocked:empty { display: none; }

/* ==========================================================================
   8. שלב 2 — רשימת הקורסים
   ========================================================================== */
.courses-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  align-items: flex-end;
  justify-content: space-between;
}

/* שורת ההמלצה: ההסבר בצד אחד, "החזרת הרשימה המומלצת" בשני. */
.recommended-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: baseline;
  justify-content: space-between;
}

.recommended-row .note { margin: 0; }

.credits {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 6px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
}

.credits-label { font-size: 13px; color: var(--muted); }
.credits-value { font-size: 20px; font-variant-numeric: tabular-nums; }

.search-results {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel);
  box-shadow: var(--shadow);
  max-block-size: 17rem;
  overflow: auto;
}

.search-results > li {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
  padding: 8px 12px;
  cursor: pointer;
  border-block-end: 1px solid var(--line);
}

.search-results > li:last-child { border-block-end: 0; }
.search-results > li:hover,
.search-results > li[aria-selected="true"] { background: var(--accent-soft); }

.course-list {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.course-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-inline-start: 3px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}

.course-item:hover { border-color: var(--accent); }
.course-item.is-selected { background: var(--accent-soft); border-color: var(--accent); }
.course-item.is-tied { border-inline-start-color: var(--tie-line); }

.course-item.is-unavailable {
  color: var(--muted);
  cursor: not-allowed;
  text-decoration: line-through;
  text-decoration-color: var(--dead-line);
}

.course-main { display: flex; flex-direction: column; gap: 3px; min-inline-size: 0; }
.course-name { font-weight: 600; }
.course-code { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.course-meta { font-size: 13px; color: var(--muted); }

.course-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-block-start: 3px; }

.tag {
  font-size: 13px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--chip);
  color: var(--muted);
  white-space: nowrap;
}

/* ‏קטגוריה, לא מצב. ירוק כאן אמר לעין "הכול בסדר" בזמן שלא דווח דבר.
   ‏"בתוכנית" הוא גם המקרה הרגיל — רוב מה שברשימה נמצא בתוכנית — ולכן
   הוא השקט מבין השניים, ו-‎.tag--out-plan‎ נשאר צבוע כי הוא החריג
   שכדאי לשים לב אליו. אלה בדיוק ערכי ‎.tag‎ הבסיסיים, כתובים במפורש
   כדי שהשקט יהיה החלטה ולא היעדר כלל. */
.tag--in-plan  { border-color: var(--line-strong); background: var(--chip); color: var(--muted); }
.tag--out-plan { border-color: var(--info-line); background: var(--info-bg); color: var(--info-ink); }
.tag--tied     { border-color: var(--tie-line);  color: var(--tie-line); background: transparent; }
.tag--warn     { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn-ink); }
.tag--dead     { border-color: var(--err-line);  background: var(--err-bg);  color: var(--err-ink); }

/* ‏הודעת מצב של הידיעון בשורת קבוצה. תג בתוך תא צר, ולכן שורה משלו
   ‏מתחת למספר הקבוצה ולא לצידו — אחרת הוא דוחף את הטבלה לרוחב. */
.group-status {
  display: block;
  inline-size: fit-content;
  margin-block-start: 4px;
  white-space: normal;
}

/* ==========================================================================
   9. שלב 3 — כפתורי ימי הלימוד
   ========================================================================== */
.days-row { display: flex; flex-wrap: wrap; gap: 8px; }

.day-btn {
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.day-btn:hover { border-color: var(--accent); }

.day-btn[aria-checked="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.day-btn.is-impossible {
  border-style: dashed;
  border-color: var(--warn-line);
  color: var(--warn-ink);
}

/* ==========================================================================
   10. שלב 4 — טבלאות המרצים
   ========================================================================== */
.lect-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px var(--gap);
  align-items: center;
  justify-content: space-between;
}

.legend-inline { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 13px; color: var(--muted); }
.legend-item { display: inline-flex; align-items: center; gap: 6px; }

.legend-swatch {
  inline-size: 14px;
  block-size: 14px;
  border-radius: 4px;
  border: 1px solid var(--line-strong);
  background: var(--chip);
}

.legend-swatch--pin { background: var(--pin-bg); border-color: var(--pin-line); }
.legend-swatch--dead { background: var(--err-bg); border-color: var(--dead-line); opacity: .55; }

.lect-courses { display: flex; flex-direction: column; gap: var(--gap); }

.lect-course {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  overflow: hidden;
}

.lect-course-head {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  align-items: baseline;
  padding: 10px 14px;
  background: var(--chip);
  border-block-end: 1px solid var(--line);
}

.lect-course-title { font-size: 14px; font-weight: 700; }
.lect-course-meta { font-size: 13px; color: var(--muted); }

.lect-table-wrap { overflow-x: auto; }

.lect-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.lect-table th,
.lect-table td {
  padding: 7px 10px;
  text-align: start;
  border-block-end: 1px solid var(--line);
  white-space: nowrap;
}

.lect-table th {
  background: var(--panel-2);
  font-weight: 600;
  color: var(--muted);
  font-size: 13px;
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
}

.lect-table td:first-child,
.lect-table th:first-child { border-inline-start: 3px solid transparent; }

/* פסי זברה */
.lect-table tbody tr:nth-child(odd) > td { background: var(--panel-2); }
.lect-table tbody tr:nth-child(even) > td { background: var(--panel); }

.lect-table tbody tr { cursor: pointer; transition: background-color .12s ease; }
.lect-table tbody tr:hover > td { background: var(--accent-soft); }

/* שורה מדורגת */
.lect-table tbody tr.is-ranked > td { background: var(--accent-soft); }

.rank-badge {
  display: inline-grid;
  place-items: center;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* שורה נעוצה — מצב נבדל ומודגש */
.lect-table tbody tr.is-pinned > td {
  background: var(--pin-bg);
  color: var(--pin-line);
  font-weight: 600;
}

.lect-table tbody tr.is-pinned > td:first-child { border-inline-start-color: var(--pin-line); }

/* שורה שמובילה למבוי סתום — מושבתת באופן גלוי */
.lect-table tbody tr.is-dead,
.lect-table tbody tr[aria-disabled="true"] {
  cursor: not-allowed;
}

.lect-table tbody tr.is-dead > td,
.lect-table tbody tr[aria-disabled="true"] > td {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: var(--dead-line);
  text-decoration-thickness: 1.5px;
}

/* הסיבה עצמה יושבת ב-title של השורה ושל כפתור הנעיצה, ולא בעמודה משלה. */
.lect-table tbody tr.is-dead { cursor: help; }

.lect-table tbody tr.is-dead:hover > td,
.lect-table tbody tr[aria-disabled="true"]:hover > td { background: var(--err-bg); }

.lect-table tbody tr.is-dead > td:first-child,
.lect-table tbody tr[aria-disabled="true"] > td:first-child {
  border-inline-start-color: var(--dead-line);
}

.lect-table tbody tr.is-dead > td:first-child::before,
.lect-table tbody tr[aria-disabled="true"] > td:first-child::before {
  content: "\1F512";          /* מנעול — מסמן בחירה חסומה */
  text-decoration: none;
  display: inline-block;
  margin-inline-end: .4em;
  font-size: 13px;
}

/* ---- קוד הקבוצה: הקידומת חוזרת בכל שורה, הסיומת היא ההבדל ---- */
.gid { direction: ltr; unicode-bidi: isolate; }
.gid-prefix { color: var(--muted); font-weight: 400; }
.gid-suffix { font-weight: 700; }

/* קישור בין קבוצות — סמל אחד במקום משפט שחזר בכל שורה */
.link-badge {
  margin-inline-start: .4em;
  font-size: 13px;
  cursor: help;
  /* הסמל אינו טקסט שצריך למתוח עליו קו כשהשורה חסומה */
  text-decoration: none;
  display: inline-block;
}

/* יום ושעה בתא אחד */
.when-line { display: flex; gap: .45em; align-items: baseline; }
.when-day { font-weight: 600; }

/* ---- נעיצה: סמל, לא תווית ---- */
/* ‏.lect-table td הוא (0,1,1) ו-.cell-pin לבדו (0,1,0), ולכן ה-center
   ‏כאן הפסיד ל-text-align: start של הטבלה ומעולם לא נכנס לתוקף. העמודה
   ‏רחבה כמו התוכן שלה, ולכן איש לא ראה זאת — עד שיוחלף האמוג'י בכפתור
   ‏SVG רחב יותר בשלב 7, ואז ההצהרה הייתה מתבררת כשקרית. */
.lect-table .th-pin,
.lect-table .cell-pin { text-align: center; inline-size: 1px; white-space: nowrap; }

.pin-btn {
  font: inherit;
  font-size: 14px;
  line-height: 1;
  padding: 4px 7px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  /* כבוי = מתאר דהוי; דלוק = מלא וצבעוני. ההבדל אינו נשען על צבע בלבד,
     כי גם המסגרת והרקע משתנים. */
  filter: grayscale(1);
  opacity: .45;
  transition: opacity .12s ease, filter .12s ease;
}

.pin-btn:hover:not(:disabled) { opacity: .9; filter: grayscale(.3); }

.pin-btn[aria-pressed="true"] {
  filter: none;
  opacity: 1;
  background: var(--pin-bg);
  border-color: var(--pin-line);
}

.pin-btn:disabled { cursor: not-allowed; opacity: .2; }

/* ==========================================================================
   11. שלב 5 — לשוניות, מקרא, והרשת השבועית
   ========================================================================== */
.sched-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px var(--gap);
  align-items: center;
  justify-content: space-between;
}

.tabs { display: flex; flex-wrap: wrap; gap: 6px; }

.tab {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
}

.tab:hover { border-color: var(--accent); }

.tab[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.legend { display: flex; flex-wrap: wrap; gap: 6px; }
.legend:empty { display: none; }

.legend-chip {
  font-size: 13px;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px solid;
  background: var(--chip);
  border-color: var(--line-strong);
  color: var(--ink);
  line-height: 1.7;
}

/* ---- מיכל הגלילה: הרשת נגללת בתוך עצמה, העמוד עצמו לעולם לא ---- */
.grid-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--panel);
}

.grid-scroll:empty { display: none; }

/* ---- הרשת עצמה ----
   dir="rtl" גורם לעמודה 1 (השעות) לשבת מימין, ואחריה ימים א..ו נפרשים שמאלה.
   grid-column = day + 1 ;  שורה 1 = כותרות ; כל שורה נוספת = 15 דקות. */
.grid {
  display: grid;
  grid-template-columns: var(--time-col) repeat(6, minmax(var(--day-min), 1fr));
  grid-template-rows: auto;
  grid-auto-rows: var(--slot-h);
}

.grid:empty { min-block-size: 8rem; }

.hd {
  position: sticky;
  inset-block-start: 0;
  z-index: 3;
  padding: 7px 4px;
  text-align: center;
  font-weight: 700;
  font-size: 13px;
  background: var(--chip);
  border-block-end: 1px solid var(--line-strong);
}

/* עמודת השעות נשארת גלויה גם כשגוללים את הימים */
.tl {
  position: sticky;
  inset-inline-start: 0;
  z-index: 2;
  background: var(--panel);
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  border-block-start: 1px dotted var(--line);
  border-inline-end: 1px solid var(--line-strong);
  padding-block-start: 1px;
}

.tl.hour { border-block-start: 1px solid var(--line-strong); color: var(--ink); font-weight: 600; }

.slot {
  border-block-start: 1px dotted var(--line);
  border-inline-start: 1px solid var(--line);
}

.slot.hour { border-block-start: 1px solid var(--line-strong); }

.ev {
  z-index: 1;
  margin: 1.5px;
  padding: 3px 5px;
  border-radius: var(--radius-sm);
  border: 1px solid;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 1px;
  /* ‏13px היא רצפת הגופן בבלוק. בלוק שאין בו מקום מוותר על שורה שלמה,
     לפי הסדר שב-fitBlocks — ולא מקטין את הטקסט מתחת לרצפה הזאת. */
  font-size: 13px;
  line-height: 1.25;
  background: var(--ev-bg, var(--chip));
  border-color: var(--ev-bd, var(--line-strong));
  color: var(--ev-fg, var(--ink));
}

.ev b { font-size: 13px; font-weight: 700; }

/* ‏שורות הבלוק אינן מתכווצות. בלי זה בלוק נמוך דוחס את הילדים שלו במקום
   לגלוש, ‏scrollHeight נשאר שווה ל-clientHeight, ‏fitBlocks אינו רואה
   דבר — והשם והסוג נחתכים לרוחב השורה במקום שהחדר והשעה ירדו לפי הסדר. */
.ev > * { flex-shrink: 0; }
.ev-room { font-weight: 600; }
.ev span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* עשרת גווני הקורסים — אותו מיפוי כמו render.py (c0 .. c9) */
.c0 { --ev-bg: var(--course-0); --ev-bd: var(--course-0-bd); --ev-fg: var(--course-0-fg); }
.c1 { --ev-bg: var(--course-1); --ev-bd: var(--course-1-bd); --ev-fg: var(--course-1-fg); }
.c2 { --ev-bg: var(--course-2); --ev-bd: var(--course-2-bd); --ev-fg: var(--course-2-fg); }
.c3 { --ev-bg: var(--course-3); --ev-bd: var(--course-3-bd); --ev-fg: var(--course-3-fg); }
.c4 { --ev-bg: var(--course-4); --ev-bd: var(--course-4-bd); --ev-fg: var(--course-4-fg); }
.c5 { --ev-bg: var(--course-5); --ev-bd: var(--course-5-bd); --ev-fg: var(--course-5-fg); }
.c6 { --ev-bg: var(--course-6); --ev-bd: var(--course-6-bd); --ev-fg: var(--course-6-fg); }
.c7 { --ev-bg: var(--course-7); --ev-bd: var(--course-7-bd); --ev-fg: var(--course-7-fg); }
.c8 { --ev-bg: var(--course-8); --ev-bd: var(--course-8-bd); --ev-fg: var(--course-8-fg); }
.c9 { --ev-bg: var(--course-9); --ev-bd: var(--course-9-bd); --ev-fg: var(--course-9-fg); }

/* שבב מקרא צבוע באותם טוקנים */
.legend-chip.c0, .legend-chip.c1, .legend-chip.c2, .legend-chip.c3, .legend-chip.c4,
.legend-chip.c5, .legend-chip.c6, .legend-chip.c7, .legend-chip.c8, .legend-chip.c9 {
  background: var(--ev-bg);
  border-color: var(--ev-bd);
  color: var(--ev-fg);
}

/* ---- מצב "אין פתרון" ---- */
.empty {
  padding: 16px 18px;
  border: 1px solid var(--warn-line);
  border-radius: var(--radius);
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.empty-title { font-size: 15px; }
.empty-sub { font-size: 13px; margin-block-start: 4px; }

.reasons,
.suggestions { margin-block-start: 10px; display: flex; flex-direction: column; gap: 5px; }

.reasons > li,
.suggestions > li {
  font-size: 13px;
  padding-inline-start: 1.1em;
  position: relative;
}

.reasons > li::before { content: "\2716"; position: absolute; inset-inline-start: 0; }
.suggestions > li::before { content: "\2192"; position: absolute; inset-inline-start: 0; }

/* ==========================================================================
   12. תחתית
   ========================================================================== */
.app-footer {
  padding: 16px clamp(12px, 3vw, 28px) 28px;
  border-block-start: 1px solid var(--line);
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

/* ==========================================================================
   13. מסכים צרים — הרשת נשארת קריאה ונגללת בתוך המיכל שלה
   ========================================================================== */
@media (max-width: 640px) {
  :root { --slot-h: 20px; --time-col: 3.6rem; --day-min: 7.5rem; }
  .app-header { padding-block: 12px; }
  .header-side { inline-size: 100%; justify-content: space-between; }
  .brand-title { font-size: 18px; }
  .courses-toolbar { align-items: stretch; }
  .credits { align-self: flex-start; }
}

@media (max-width: 380px) {
  :root { --day-min: 7rem; }
  .day-btn { inline-size: 2.6rem; block-size: 2.6rem; font-size: 15px; }
}

/* ==========================================================================
   14. העדפת תנועה מופחתת
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  .busy-bar > span { animation: none; inline-size: 100%; opacity: .6; }
}

/* ==========================================================================
   15. הדפסה — הרשת בלבד
   ========================================================================== */
/* ‏margin: 0 ואחריו ריפוד פנימי, ולא שוליים ב-@page: כשיש שוליים, הדפדפן
   מצייר בתוכם כותרת עליונה ותחתונה משלו — תאריך, כתובת הדף ומספור. אין
   ‏CSS שמכבה אותן, אבל בלי שוליים אין להן מקום להיכתב בו. הריפוד מחזיר
   את המרווח הוויזואלי, ובו־בזמן הוא זה שנבלע בשוליים שהמדפסת לא יכולה
   להדפיס — במקום שהמערכת עצמה תיחתך. */
@page {
  size: A4 landscape;
  margin: 0;
}

@media print {
  /* ‏הצבעים באים מ-‎--print-*‎ בפרק 1, ולא נכתבים כאן שוב. הגושים הכהים
     עטופים ב-‎screen‎, ולכן במצב כהה הדף פשוט נופל חזרה לערכי ‎:root‎
     הבהירים — ואין צורך לדרוס כאן את עשרת צבעי הקורס. */
  :root {
    --bg: var(--print-bg);
    --panel: var(--print-panel);
    --panel-2: var(--print-panel-2);
    --chip: var(--print-chip);
    --ink: var(--print-ink);
    --muted: var(--print-muted);
    --line: var(--print-line);
    --line-strong: var(--print-line-strong);
    --accent: var(--print-accent);
    --accent-ink: var(--print-accent-ink);
    --accent-soft: var(--print-accent-soft);
    --shadow: none;
    --shadow-sm: none;
    --slot-h: 17px;
    --time-col: 4rem;
    --day-min: 0;
  }

  body { background: #ffffff; font-size: 11.5px; padding: 8mm; }

  /* הדפסה בזמן שהשכבה פתוחה: בלי זה נעילת הגלילה הייתה חותכת את הדף
     אחרי העמוד הראשון. */
  html.is-modal-open,
  html.is-modal-open body { overflow: visible !important; }

  /* ‏על הנייר: הרשת, ושורת כותרת אחת מעליה. שום דבר אחר.
     ניקוד, לשוניות, אזהרת חפיפה, אריחי העובדות, פירוק הקנסות, שבבי
     הקורסים והמקרא הם כולם עזרי **החלטה**. אחרי שההחלטה התקבלה,
     מדפיסים את המערכת שנבחרה — לא את הדרך אליה.

     היתר, לא איסור. הגרסה הקודמת מנתה מזהים להסתרה, וכך כל אלמנט חדש
     דלף אל הנייר בשקט: שורת ההתקדמות וכפתור הבנייה היו כל תוכנו של
     העמוד המודפס הראשון, והמערכת עצמה התחילה בעמוד השני. רשימה
     שמתארת מה **כן** מודפס אינה יכולה לשכוח. */
  body > *:not(.steps) { display: none !important; }
  .steps > *:not(#step-schedule) { display: none !important; }
  #step-schedule > .step-head { display: none !important; }
  #step-schedule > .step-body > *:not(#grid-scroll):not(#print-head) {
    display: none !important;
  }

  /* שורת הכותרת: שם המערכת ותאריך, שורה אחת.
     ‏#id ולא .class: כלל ההסתרה למסך יושב בהמשך הקובץ, ובמפורש שווה לו
     ‏(0,1,0) — הוא היה מנצח בסדר. עוצמה גבוהה יותר, לא הסתמכות על מיקום. */
  #print-head {
    display: block;
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 700;
    color: #000;
  }

  .steps { padding: 0; gap: 0; max-inline-size: none; }

  #step-schedule {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    margin: 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  #step-schedule .step-title::before { display: none; }
  /* שלב 5 אינו מתקפל, ובכל זאת: הדף המודפס הוא רק הוא, ודף ריק בגלל
     class שנשאר תקוע אינו כשל שרוצים לגלות מול המדפסת. */
  #step-schedule > .step-body { display: flex !important; }
  .step-caret { display: none !important; }
  .step-head { margin-block-end: 8px; }
  .facts { gap: 6px; }
  .fact { padding: 4px 10px; }

  .grid-scroll {
    overflow: visible;
    border: 1px solid var(--line-strong);
    border-radius: 0;
  }

  .grid { grid-template-columns: var(--time-col) repeat(6, 1fr); }

  .hd,
  .tl { position: static; }

  .ev,
  .hd,
  .tl,
  .legend-chip,
  .fact {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* ==========================================================================
   16. שלב 1 של השכתוב — פעולה ראשית, פרטים טכניים, חובת נוכחות
   ========================================================================== */

/* הפעולה הראשית היחידה של מסך ההגדרות. */
.build-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--gap);
  align-items: baseline;
  padding: 0 clamp(12px, 3vw, 28px);
  max-inline-size: 1180px;
  margin-inline: auto;
}

.btn-build { font-size: 15px; padding: 10px 22px; }

/* ‏"פרטים טכניים" — מקופל, שקט, ובתחתית. */
.tech-details {
  max-inline-size: 1180px;
  margin: 0 auto 24px;
  padding: 0 clamp(12px, 3vw, 28px);
  color: var(--muted);
  font-size: 13px;
}

.tech-summary { cursor: pointer; font-weight: 600; padding: 6px 2px; }
.tech-body { display: flex; flex-direction: column; gap: 10px; padding-block: 8px; }

.tech-facts {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-variant-numeric: tabular-nums;
}

.tech-facts:empty { display: none; }

/* השיעורים שוויתרו בהם על נוכחות — רשימה, לא זנב פסיקים בסוף פסקה. */
.attendance-off {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  padding: 8px 12px;
}

.attendance-off-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin-block-end: 4px;
}

.attendance-off-list { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.attendance-off-list li { padding-inline-start: 0; }

/* שורות יומן בתוך באנר תקלה — מקוצרות, ניתנות לגלילה, וקריאות. */
.banner-more-log {
  margin: 0;
  max-block-size: 12rem;
  overflow: auto;
  font-family: ui-monospace, "Consolas", "Courier New", monospace;
  font-size: 13px;
  line-height: 1.5;
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
}

/* ==========================================================================
   17. שלב 2 של השכתוב — ההתאמה, והפרדת עובדות מקנסות
   ========================================================================== */

/* ההתאמה היא הכותרת של הפאנל, לא עוד שבב בשורה. */
.fit {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
}

.fit-label { font-size: 13px; color: var(--muted); font-weight: 600; }
.fit-value { font-size: 22px; font-variant-numeric: tabular-nums; }

/* ‏המערכת המדורגת ראשונה נושאת משפט במקום מספר, ולכן היא זקוקה לגודל
   משלה: ‎22px‎ נבחר לשני תווים ומחצה, ו"ההתאמה הגבוהה ביותר" באותו גודל
   היה בולע את השורה. ‏700 ולא 600 — ‎Noto Sans Hebrew‎ מגיע ב-400 וב-700
   בלבד, ומשקל ביניים על עברית נצמד ל-700 בעוד לטינית לצדו מקבלת 600
   אמיתי. הצירוף עם ‎.fit--close‎ נחוץ כי הכלל שם הוא (0,2,0) ומנצח. */
.fit-value--best,
.fit--close .fit-value--best {
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: normal;
}
.fit-note { font-size: 13px; color: var(--muted); flex: 1 1 14rem; min-inline-size: 0; }

/* שני חצאי הפאנל, כל אחד עם כותרת משלו. */
.panel-block { display: flex; flex-direction: column; gap: 8px; }

.panel-block-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: .01em;
}

/* עובדות — ניטרליות. אין כאן שיפוט, ולכן אין גם צבע מצב. */
.facts--plain .fact { background: var(--panel); }

/* קנסות — פס באורך יחסי, ולעולם לא מספר שלילי חשוף. */
.penalties { display: flex; flex-direction: column; gap: 7px; }

.penalty {
  display: grid;
  grid-template-columns: minmax(8rem, 14rem) 1fr;
  gap: 4px 12px;
  align-items: center;
  cursor: help;
}

.penalty-label { font-size: 13px; }

.penalty-track {
  block-size: 8px;
  border-radius: 999px;
  background: var(--chip);
  overflow: hidden;
}

.penalty-fill {
  display: block;
  block-size: 100%;
  border-radius: 999px;
  background: var(--warn-line);
}

/* ‏הפס הראשון הוא המשפיע ביותר — גם בצבע, וגם במילים שבתווית. */
.penalty:first-child .penalty-fill { background: var(--dead-line); }
.penalty:first-child .penalty-label { font-weight: 600; }

@media (max-width: 640px) {
  .penalty { grid-template-columns: 1fr; }
}

/* שורת המרצים נושאת משפט שלם, ולכן היא רחבה ובלי תווית נפרדת. */
.fact--wide {
  flex: 1 1 100%;
  font-size: 13px;
  padding: 7px 14px;
  cursor: help;
}

/* ‏#schedule-summary נושא class="facts" מהמקור, כלומר שורת שבבים גמישה.
   מרגע שיש בו שני גושים — עובדות וקנסות — הוא חייב לערום אותם, אחרת
   שניהם נדחסים לחצי רוחב והפסים נעלמים לגמרי. */
#schedule-summary {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
}

#schedule-summary .facts--plain {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

/* ==========================================================================
   18. נוסח חסר — נראה כתקלה, לא כעיצוב
   ========================================================================== */

/* ‏T() מחזיר ⟦path⟧ למפתח חסר, ו-markMissingStrings() ב-app.js מסמן את
   האלמנט שמכיל אותו. הכלל הזה עושה את התקלה בלתי אפשרית לפספוס: עד כה
   נוסח חסר נראה כתווית ריקה או כמילה "compactness", ושתיהן נקראות כמו
   עיצוב — כך אפשר היה לשלוח עמוד שלם בלי שאיש ישים לב. */
.missing-string {
  outline: 2px dashed var(--dead-line);
  background: var(--err-bg);
  color: var(--err-ink);
  font-family: ui-monospace, "Consolas", monospace;
  font-size: 13px;
  direction: ltr;
  unicode-bidi: isolate;
}

/* ==========================================================================
   19. שלב 3 — מה מבדיל בין המערכות
   ========================================================================== */

/* התווית המבדילה, כשהמערכות קרובות מדי בציון כדי שהציון יעזור. */
.fit--close .fit-value { font-size: 15px; color: var(--muted); font-weight: 600; }
.fit--close .fit-label { order: 2; }
.fit--close .fit-value { order: 3; }
.fit--close .fit-note  { order: 4; }

.fit-headline {
  order: 1;
  flex: 1 1 100%;
  font-size: 16px;
  color: var(--ink);
}

/* בסרגל המצוף ובשכבה — מה מייחד, במקום סטטיסטיקה שחוזרת מתחת. */
.sticky-label { font-size: 13px; font-weight: 600; }

/* ---- טבלת ההשוואה ---- */
.compare {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  padding: 4px 12px;
}

.compare-summary { cursor: pointer; font-size: 13px; font-weight: 600; padding: 7px 2px; }
.compare-body { padding-block: 8px 12px; }
.compare-scroll { overflow-x: auto; }

.compare-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.compare-table th,
.compare-table td {
  padding: 6px 10px;
  text-align: start;
  border-block-end: 1px solid var(--line);
  white-space: nowrap;
}

.compare-table thead th {
  font-size: 13px;
  color: var(--muted);
  background: var(--chip);
}

.compare-table tbody th {
  font-weight: 600;
  color: var(--muted);
  font-size: 13px;
}

/* ‏שורה שנבדלת בין המערכות היא המקום היחיד שבו ההחלטה נמצאת — ולכן
   היא מודגשת, ושורה שזהה בכולן נסוגה. לכל תא יש ערך בשני המקרים:
   צביעה לבדה אומרת "כאן שונה" בלי לומר במה. */
.compare-table tr.same td,
.compare-table tr.same th { color: var(--muted); }

.compare-table td.is-diff {
  font-weight: 700;
  color: var(--ink);
  background: var(--accent-soft);
}

/* המערכת שמוצגת כרגע — עמודה מסומנת, כדי לדעת על מה מסתכלים. */
.compare-table .is-active { outline: 1px solid var(--accent); outline-offset: -1px; }
.compare-table thead th.is-active { color: var(--accent); font-weight: 700; }

/* ‏"מערכת:" לפני העיגולים — בלעדיה חמישה מספרים בשורה אינם אומרים דבר. */
.sticky-selector-label {
  flex: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

/* ==========================================================================
   20. שלב 4 — הרשת: פחות טקסט בבלוק, יום ריק צר, ופאנל פרטים
   ========================================================================== */

:root { --day-empty: 3.2rem; }

/* ---- הבלוק ---- */
/* ‏<button> ולא <div>, ולכן צריך לאפס את מראה הכפתור ולהשאיר את הפריסה. */
/* ‏<button> מביא גופן משלו, ולכן צריך לאפס אותו — אבל ‏font: inherit
   הוא קיצור שדורס גם את ה-font-size שנקבע למעלה, ואז גודל הטקסט בבלוק
   נקבע במקרה. רק המשפחה יורשת; המידה נשארת מוצהרת במקום אחד. */
.ev {
  font-family: inherit;
  font-size: 13px;
  line-height: 1.25;
  text-align: start;
  cursor: pointer;
  inline-size: auto;
}

/* ‏"אם זה לא נכנס, זה לא שייך לבלוק": אין חיתוך בשלוש נקודות. שורה
   שאין לה מקום יורדת כולה, לפי הסדר שב-fitBlocks — ולא נחתכת באמצע.
   שעה שנקטעה ל-"10:30–12:2" נראית שלמה, וזה בדיוק מה שהופך אותה למסוכנת:
   חדר "F 506" הוא חדר קיים אחר. לכן ארבע השורות נשברות ולא נחתכות. */
.ev span { overflow: hidden; text-overflow: clip; white-space: nowrap; }
.ev b,
.ev .ev-kind,
.ev .cell-time,
.ev .ev-lect,
.ev .ev-room { white-space: normal; overflow-wrap: anywhere; }

.ev:hover { filter: brightness(1.06); }
.ev:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* תג החפיפה. הוא יושב על כל אחד משני הבלוקים בחצי הרוחב — לא על
   בלוק ממוזג, שכבר אינו קיים. */
.ev-badge {
  align-self: flex-start;
  font-size: 13px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn-line);
}

/* שורת הכותרת של הדף המודפס — קיימת רק על הנייר. על המסך אותו מידע
   כבר נמצא בלשוניות ובכותרת הסעיף. */
.print-head { display: none; }

/* ---- יום ריק ---- */
.hd.is-empty { color: var(--muted); }
.hd.is-empty { font-size: 13px; }
.hd-empty { display: block; font-size: 13px; font-weight: 400; color: var(--muted); }
.slot.is-empty { background: var(--panel-2); }

/* ---- כלי הרשת: מקרא ומתג השעות ---- */
.grid-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px var(--gap);
  align-items: center;
  justify-content: space-between;
}

.grid-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  flex: none;
}

.legend-chip--overlap {
  border-style: dashed;
  border-color: var(--warn-line);
  color: var(--warn-ink);
  background: var(--warn-bg);
}

/* ---- פאנל הפרטים ---- */
.detail {
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.detail:focus { outline: none; }
.detail-head { display: flex; align-items: center; gap: var(--gap); }
.detail-title { font-size: 14px; flex: 1; }
.detail-body { display: flex; flex-direction: column; gap: 10px; }

.detail-item {
  border-inline-start: 4px solid var(--ev-bd, var(--line-strong));
  padding-inline-start: 10px;
}

.detail-list {
  display: grid;
  grid-template-columns: minmax(4.5rem, auto) 1fr;
  gap: 2px 12px;
  margin: 0;
  font-size: 13px;
}

.detail-list dt { color: var(--muted); font-size: 13px; }
.detail-list dd { margin: 0; }
.detail-code { margin-inline-start: .5em; color: var(--muted); font-size: 13px; }

.detail-overlap {
  font-size: 13px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn-line);
}

/* במסך צר הפאנל הופך לגיליון תחתון. */
@media (max-width: 700px) {
  .detail {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 75;
    border-radius: var(--radius) var(--radius) 0 0;
    max-block-size: 70vh;
    overflow: auto;
  }
}

/* ‏מזהה לטיני בתוך שורה עברית — חדר, קבוצה, קוד קורס.
   ‏dir="ltr" יושב על האלמנט עצמו (ראו ltrCode ב-app.js); כאן רק הבידוד,
   כדי שהרצף לא יתערבב עם הטקסט שסביבו. */
.code {
  unicode-bidi: isolate;
  direction: ltr;
}

/* גם בהדפסה — הדף המודפס הוא המקום שבו קוד חדר הפוך עולה הכי ביוקר. */
@media print {
  .code,
  .cell-time,
  .gid { direction: ltr; unicode-bidi: isolate; }
}

/* ==========================================================================
   21. שלב 5 — מצב הסעיפים, שורת המצב, ורוחב שדות
   ========================================================================== */

/* ---- הסימון על הסעיף: שלושה מצבים, לא אחד ---- */
/* ‏✓ ירוק שמופיע על כל סעיף מהרגע הראשון אינו נושא מידע. מתאר ריק =
   ברירת מחדל, ‏✓ = נבחר, ‏! = יש בעיה שדורשת החלטה. */
.step.is-default .step-title::before {
  content: counter(step);
  background: transparent;
  border-color: var(--line-strong);
  color: var(--muted);
}

.step.is-conflict .step-title::before {
  content: "!";
  background: var(--warn-bg);
  border-color: var(--warn-line);
  color: var(--warn-ink);
}

.step.is-conflict { border-color: var(--warn-line); }

/* ---- שורת המצב שמעל הסעיפים ---- */
.progress {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: center;
  padding: 0 clamp(12px, 3vw, 28px);
  max-inline-size: 1180px;
  margin: 0 auto 4px;
}

.progress-chip {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--muted);
  cursor: pointer;
}

.progress-chip::before { margin-inline-end: .4em; }
.progress-chip.is-default::before { content: "○"; }
.progress-chip.is-chosen::before  { content: "✓"; }
.progress-chip.is-conflict::before { content: "!"; font-weight: 800; }

.progress-chip.is-chosen {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

.progress-chip.is-conflict {
  border-color: var(--warn-line);
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.progress-chip:hover { border-color: var(--accent); }
.progress-hint { font-size: 13px; color: var(--muted); }

/* ---- שדות לפי תוכן, לא ברוחב מלא ---- */
.field--sm { flex: 0 1 8rem; }
.field--md { flex: 0 1 13rem; }
.field--lg { flex: 0 1 22rem; }

/* ==========================================================================
   22. תיקוני שלב 4 — סוג השיעור בבלוק, וחפיפה כשני חצאים
   ========================================================================== */

/* סוג השיעור: שורה קצרה משלו. הוא מהדברים הראשונים שמחפשים על הרשת,
   והוא גם מה שמבדיל הרצאה מתרגול כשהצבע מציין את הקורס בלבד.

   ‏.ev .ev-kind ולא .ev-kind: הכלל ‎.ev span‎ הוא (0,1,1) ומנצח מחלקה
   בודדת בכל סדר. הצירוף נשאר גם אחרי ש-‎opacity‎ ירדה משתי השורות, כי
   הוא עדיין מה שמאפשר לכלל הזה לגבור על ‎.ev span‎. */
.ev .ev-kind {
  font-size: 13px;
  font-weight: 600;
}

/* שם המרצה, מלא. ‏13px כמו החדר והשעה ולא קטן מהם: מבין שלוש השורות
   שיכולות לרדת הוא האחרון שיורד, ולכן אין סיבה שיהיה הקשה ביותר לקריאה.
   שם ארוך נשבר לשתי שורות — עדיף מקוצר. */
.ev .ev-lect { font-size: 13px; }

/* ‏fitBlocks מסתיר שורות שאינן נכנסות, לפי הסדר: חדר, שעה, מרצה.
   ‏[hidden] כבר display:none גלובלית — הכלל כאן רק מתעד את הסדר. */
.ev .ev-drop-1[hidden],
.ev .ev-drop-2[hidden],
.ev .ev-drop-3[hidden] { display: none !important; }

/* חפיפה מכוונת: שני בלוקים זה לצד זה, כל אחד בחצי רוחב, ולכל אחד
   המסגרת המקווקוות שלו. מיזוג לבלוק אחד הסתיר אילו קורסים מתנגשים. */
.ev.is-soft {
  outline: 2px dashed var(--warn-line);
  outline-offset: -3px;
}

/* בהדפסה סוג השיעור נשאר — הוא לא קישוט מסך.

   ‏עד 2026-09-08 עמד כאן גם ‎opacity: 1 !important‎ על שלוש שורות הבלוק,
   כדי לבטל החוורה שנעשתה למסך. ההחוורה עצמה נמחקה — היא הורידה את שורת
   המרצה אל 5.4:1 מול רף 7:1 שהפרויקט מצהיר עליו — ולכן גם הביטול שלה
   מיותר. כלל שכל תפקידו לבטל כלל אחר נמחק יחד איתו. */
@media print {
  .ev .ev-kind { display: block !important; }
}


/* ==========================================================================
   23. ויתורים נמדדים — מצב "אין פתרון"
   ========================================================================== */

.relax { margin-block-start: 14px; }
.relax-title { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.relax-intro { margin: 0 0 10px; font-size: 13px; color: var(--muted); }

.relax-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  margin-block-end: 6px;
}

.relax-what { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.relax-what b { font-size: 13px; }

/* ‏זוג: שתי שורות וסוגר. הסוגר הוא גבול בצד ההתחלה — בעברית זהו הצד
   הימני — ולא תו סוגריים, כדי שהוא יימתח לגובה שתי השורות בכל גופן. */
.relax-pair {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-inline-start: 10px;
  border-inline-start: 3px solid var(--accent);
  border-start-start-radius: 3px;
  border-end-start-radius: 3px;
}
.relax-pair-line { font-size: 13px; font-weight: 700; }
.relax-pair-both {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  margin-block-start: 2px;
}

.relax-opens { font-size: 13px; font-weight: 600; }
.relax-opens.is-quiet { font-weight: 400; color: var(--muted); }
.relax-cost { font-size: 13px; color: var(--muted); }
.relax-checked { margin: 8px 0 0; font-size: 13px; color: var(--muted); }

/* הסיבות שמתקפלות: הראשונה גלויה, השאר בגילוי. */
.reasons-more-wrap { list-style: none; margin-inline-start: -1em; }
.reasons-more summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--accent);
}
.reasons-more[open] summary { margin-block-end: 4px; }

/* הודעת הביטול — לא במצב הריק, שנעלם ברגע שיש תוצאות. */
.relax-undo {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 10px;
  padding: 7px 10px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--chip);
  font-size: 13px;
}
.relax-undo-text { color: var(--ink); }

@media print {
  .relax, .relax-undo { display: none !important; }
}


/* ---- שלב 3: מה יאפשר את יעד הימים ---- */
.days-relax { margin-block-start: 10px; }
.days-relax-title { margin: 0 0 3px; font-size: 13px; font-weight: 700; }
.days-relax-intro { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.days-relax-list { margin: 0; padding: 0; list-style: none; }
.days-relax-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  margin-block-end: 4px;
  font-size: 13px;
}
.days-relax-count { font-weight: 600; white-space: nowrap; }
.days-relax-count.is-quiet { font-weight: 400; color: var(--muted); }
.days-relax-checked { margin: 6px 0 0; font-size: 13px; color: var(--muted); }

@media print { .days-relax { display: none !important; } }

.days-relax-note {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--muted);
  font-style: italic;
}

/* הסתייגות בתוך באנר — שורה שנייה, מושתקת. */
.banner-note {
  flex-basis: 100%;
  font-size: 13px;
  color: var(--muted);
  margin-block-start: 2px;
}

/* שורת המצב של החישוב: טקסט, ולידו דרך לצאת. */
#schedule-note {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
#schedule-note:empty { display: none; }
