/* ============================================================================
   שפת התנועה של דף הבית — "נשימה" · #347, 16.9.2026
   ============================================================================

   🔑 **הכרעת איתי (16.9.2026):** "נשימה" כבסיס, ובתוכה **שלושה רגעים
   מושאלים משפת "מדידה"** — ולא יותר משלושה:
     1. קו סריקה אחד שעובר על ההירו בכניסה לדף (פעם אחת בלבד).
     2. סרגלי מפלס שמתמלאים בארבעת כרטיסי המדדים כשהם נחשפים.
     3. המחירים שסופרים למעלה, ברוחב **נעול מראש** כדי שאף ₪ לא יזוז.

   ⚠ **תכונות, לא מחלקות.** כל הסימון בדף נעשה ב-‎data-r‎ ו-‎data-sec‎ ולא
     במחלקות חדשות — בדיקות קיימות סופרות מופעי מחלקות ב-‎index.html‎,
     ומחלקה חדשה הייתה מפילה אותן בלי קשר לתנועה.

   🔴 **הדפוס: גלוי כברירת מחדל, מוסתר רק אחרי שה-JS חימש.**
     ההסתרה תלויה כולה ב-‎html[data-motion="armed"]‎, שנקבע ב-
     ‎shared/motion.js‎ **רק** כשיש ‎IntersectionObserver‎ ואין בקשת
     הפחתת תנועה. דף בלי JS, עם JS חסום, או עם סקריפט ששבר — מציג
     את כל התוכן מיד. אין מצב שבו תוכן נתקע בלתי-נראה.

   ⚠ **‎translate‎ ו-‎scale‎ כתכונות עצמאיות, לא ‎transform‎.** כרטיסי
     המדדים נושאים ‎transform: rotate(...)‎ מ-‎style.css‎ (‎.value-card.card-1‎
     וחבריו). לו הכניסה הייתה כתובה ב-‎transform‎ היא הייתה **מוחקת את
     ההטיה** ברגע החשיפה. התכונות העצמאיות מתחברות אל ה-‎transform‎ הקיים
     במקום להחליף אותו. דפדפן ישן שאינו מכיר אותן מתעלם מהן — והתוכן
     פשוט דוהה פנימה בלי הזזה, שזו נחיתה תקינה.

   ⚠ **אפס הזזת פריסה.** רק ‎opacity‎ · ‎translate‎ · ‎scale‎. כל שכבה
     שמתווספת כאן (‎[data-scan]‎) היא ‎position:absolute‎, וסרגל המפלס
     ‎[data-lvl]‎ **קיים בפריסה גם כשאינו מחומש** — אחרת עצם החימוש היה
     מוסיף גובה לכרטיס. נמדד: גובה הדף זהה מחומש ולא-מחומש, ב-393, ב-360
     וב-WebKit 390.

   ⚠ **הפחתת תנועה** — אין כאן כלל ‎@media (prefers-reduced-motion)‎ בכוונה.
     הכלל הגלובלי ב-‎style.css‎ נשאר המקור היחיד, ו-‎motion.js‎ פשוט **אינו
     מחמש** במצב הזה: התוכן מופיע מיד, בסדר שלו, בלי אף ‎translate‎.
   ========================================================================= */

/* ══ הקצב של החשיפה · סבב 3, 16.9.2026 ══════════════════════════════════════
   🔑 **הכרעת איתי:** *"הכניסה הרכה של הטקסט בזמן הגלילה מהירה מדי, וגם בחלק
   ממצבי הגלילה הטקסט נכנס מוקדם מדי עוד לפני שהספקתי לגלול אליו"*.

   🔴 **למה זה קרה — נמדד, ולא נוחש.** שתי סיבות נפרדות:
     1. ‎--mo-dur‎ היה 820ms ו**אינו מוכפל ב-‎Crawl.PACE‎**. כשכל האתר הואט
        ל-1.5 (‎shared/crawl.js‎) הקובץ הזה נשאר מאחור — כלומר הכניסה לא
        "הרגישה" מהירה, היא **הייתה** מהירה ביחס לכל השאר.
     2. הירי היה מוקדם. נמדד ב-Chromium 393/360 וב-WebKit 390, עם בקרה
        שלילית 8px לפני הסף ובקרה חיובית 8px אחריו — 11 מתוך 11 אישרו:
        האלמנט נחשף כשראשו רק **46–118px מעל קו הקיפול**, כלומר בזמן
        שהוא יושב בשישית התחתונה של המסך.

   ⚠ **שלוש ערכות מכוילות — שורה אחת משנה את התחושה.** הערכים כאן הם
     ‎balanced‎, שנבחרה.
       calm     : --mo-dur 1300ms · --mo-stag 90ms · REVEAL_MARGIN 0.32
       balanced : --mo-dur 1100ms · --mo-stag 70ms · REVEAL_MARGIN 0.25   ← פעיל
       snappy   : --mo-dur  900ms · --mo-stag 55ms · REVEAL_MARGIN 0.18
     ⚠ ‎REVEAL_MARGIN‎ יושב ב-‎shared/motion.js‎ ולא כאן — הוא פרמטר של
       המשקיף ולא של הסגנון. **שינוי ערכה נוגע בשני הקבצים.**
   ⚠ **המדרגה ירדה מ-95 ל-70 והתקרה מ-7 ל-5 צעדים** (‎MAX_STEP‎ ב-motion.js):
     עם משך של 1100ms, שרשרת של שבעה צעדים ×95 הייתה מסיימת אחרי 1765ms.
     כעת 1100 + 5×70 = 1450ms — ארוך יותר מקודם, אבל הסוף אינו נגרר. */
:root {
  --mo-dur: 1100ms;
  --mo-stag: 70ms;
  --mo-ease: cubic-bezier(.22, .61, .36, 1);
  /* צביעת מילת ההדגשה — אחרי שהשורה כבר הגיעה למקומה, ולא יחד איתה */
  --mo-acc-dur: 520ms;
  --mo-acc-lag: 420ms;
  /* סרגלי המפלס — ערך **אחד** לארבעת הכרטיסים. ראה ההסבר אצל [data-lvl]. */
  --mo-v: .62;

  /* ── דופק · שלושה קצבים, מקור אחד · 17.9.2026 ─────────────────────────
     🔑 הכרעת איתי: הלב פועם תמיד, המילים פועמות תמיד, והמלבנים חיים
        בקצב איטי בהרבה שכמעט אינו מורגש. שלושת הקצבים יושבים כאן ולא
        בשלושה קבצים, כי שלושה קצבים שנכתבים בנפרד סוטים זה מזה תוך שבוע
        ואז האתר פועם בשלוש מהירויות שאיש לא בחר.
     ⚠ --beat הוא קצב הלב-והמילים שאיתי אישר ב-#338 (1500ms, לאב-דאב).
        אין לשנותו בלי הכרעה מחודשת שלו.
     ⚠ --breath-card הוא ה"כמעט לא מורגש": מחזור ארוך פי ארבעה ומשרעת
        זעירה. המשרעת היא מה שהופך אותו לרקע ולא לתנועה — 0.4% בקושי
        נקרא בעין, ומעל 1% הכרטיס מתחיל לקפוץ. */
  --beat: 1500ms;
  --beat-ease: cubic-bezier(.3, 0, .2, 1);
  --breath-card: 6000ms;
  --breath-card-amp: 1.004;
}

/* ── הבסיס: נשימה ────────────────────────────────────────────────────────
   עלייה רכה של 14px ודהייה, בפער 95ms לפי סדר הקריאה. ‎--mo-d‎ נקבע
   ב-motion.js לפי מקום האלמנט בקבוצה שלו, בתקרה של שבעה צעדים. */
html[data-motion="armed"] [data-r] {
  opacity: 0;
  translate: 0 14px;
  transition:
    opacity var(--mo-dur) var(--mo-ease) var(--mo-d, 0ms),
    translate var(--mo-dur) var(--mo-ease) var(--mo-d, 0ms),
    scale var(--mo-dur) var(--mo-ease) var(--mo-d, 0ms);
}
/* כרטיסים ותמונות נכנסים מעט יותר "מרחוק" — 16px ו-98.5% */
html[data-motion="armed"] [data-r="item"],
html[data-motion="armed"] [data-r="img"] {
  translate: 0 16px;
  scale: .985;
}
html[data-motion="armed"] [data-r][data-in] {
  opacity: 1;
  translate: none;
  scale: none;
}

/* ── מילת ההדגשה נצבעת — **במקטעים הבהירים בלבד** ──────────────────────────
   🔑 **הכרעת איתי (16.9.2026):** הרעיון חוזר, ורק שם. בסבב הקודם הוא הושמט
   כולו כי במקטע הכהה (‎#report‎ · ‎.science-section‎, רקע ‎#1a1a1a‎) המילה
   הייתה צריכה להתחיל בצבע כלשהו ולהגיע לוורוד — וכל צבע התחלה שם נוגע
   בשער הניגודיות של #340.
   🔴 **הפתרון אינו "לצבוע בזהירות" אלא לא לגעת:** ‎.science-title-accent‎
   **אינו ברשימה**, ולכן הוא ‎#ff5fa2‎ מהפריים הראשון ועד האחרון, בין אם
   התנועה חומשה ובין אם לא. השער של #340 אינו רואה כאן אף כלל חדש.
   ⚠ הרשימה מפורשת ולא ‎[class$="-accent"]‎ — סלקטור כללי היה **סוחף
     לתוכו** כל מילת הדגשה שתיווצר בעתיד, כולל במקטע כהה חדש. בקרה
     שלילית לזה ב-‎motion.test.js‎.
   ⚠ צבע בלבד. אין ‎opacity‎ ואין תזוזה — המילה כבר נעה עם השורה שלה. */
html[data-motion="armed"] [data-r] :is(
  .hero-title-accent, .values-title-accent, .about-title-accent,
  .how-title-accent, .offer-title-accent, .faq-title-accent, .booking-title-accent) {
  color: #1a1a1a;
  transition: color var(--mo-acc-dur) var(--mo-ease) calc(var(--mo-d, 0ms) + var(--mo-acc-lag));
}
html[data-motion="armed"] [data-r][data-in] :is(
  .hero-title-accent, .values-title-accent, .about-title-accent,
  .how-title-accent, .offer-title-accent, .faq-title-accent, .booking-title-accent) {
  color: #ff2d87;
}

/* ── האווירה: דבר אחד בלבד נושם על המסך ─────────────────────────────────
   כפתור ההירו, 1.8%, מחזור 7 שניות — ארוך מכדי שהעין תקרא אותו כתנועה.
   ⚠ שלושה תנאים מצטברים לכיבוי, וכולם נקבעים ב-motion.js:
     • ‎[data-secin]‎ — ההירו יצא מהמסך.
     • ‎html[data-tabhidden]‎ — הלשונית מוסתרת.
     • ‎html[data-fc-live]‎ — **הכפתור הצף על המסך.** ההילה שלו כבר פועמת
       כל 5 שניות (‎.fc.is-idle .fc-halo‎ ב-style.css). שתי פעימות בו-זמנית
       הן בדיוק ה"רעש" שהשפה הזו אמורה למנוע. */
html[data-motion="armed"] .hero-section[data-secin] .hero-cta {
  animation: sfgBreath 7s ease-in-out infinite;
}
html[data-tabhidden] .hero-cta,
html[data-fc-live] .hero-cta {
  animation: none !important;
}
@keyframes sfgBreath {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.018); }
}

/* ══ רגע מושאל 1 · קו הסריקה על ההירו ═══════════════════════════════════
   פעם אחת, בכניסה לדף, 1100ms. ‎--mo-scan-h‎ = גובה ההירו, נמדד פעם אחת
   ב-motion.js ומעודכן רק בשינוי רוחב — לא בגלילה ולא בכל פריים. */
[data-scan] {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}
html[data-motion="armed"] [data-scan] { display: block; }
[data-scan]::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, rgba(255, 45, 135, 0), #ff2d87, rgba(255, 45, 135, 0));
  opacity: 0;
  transform: translateY(0);
}
[data-scan][data-run]::before {
  animation: sfgScan 1100ms cubic-bezier(.4, 0, .2, 1) both;
}
@keyframes sfgScan {
  0%   { transform: translateY(0); opacity: 0; }
  14%  { opacity: .5; }
  86%  { opacity: .5; }
  100% { transform: translateY(var(--mo-scan-h, 320px)); opacity: 0; }
}

/* ══ רגע מושאל 2 · סרגלי המפלס בכרטיסי המדדים ═══════════════════════════
   ⚠ הסרגל **תמיד בפריסה** — גלוי ומלא כשאין חימוש, כדי שגובה הכרטיס
     יהיה זהה בשני המצבים. רק המילוי מתאפס, ורק אחרי חימוש.
   ⚠ ‎transform-origin: right‎ — RTL: המדידה מתחילה מימין.

   🔴 **ארבעתם באותו אורך — הכרעת איתי, 16.9.2026, וזה גבול מקצועי ולא טעם.**
   עד כאן נשאו הכרטיסים ארבעה ערכים שונים בקוד (‎.42 · .74 · .58 · .63‎),
   והם יושבים מתחת לכותרות "מסת שומן", "מסת שריר", "לפי איברים" ו"נתוני
   מים". סרגל באורך שונה לצד כל אחת מהן **נקרא כמדידה של מי שמסתכלת** —
   וזו בדיוק ההטעיה ש-‎superfitgirls-context‎ אוסר. אורך אחד הוא קישוט;
   ארבעה אורכים הם טענה.
   ⚠ **הערך יושב ב-‎:root‎ בלבד** (‎--mo-v: .62‎) ולא בתכונת ‎style‎ על כל
     כרטיס. כך אי אפשר שאחד מהם יסטה בשקט בעריכה עתידית, ולכן זה גם מה
     שהבדיקה אוכפת: אפס ‎--mo-v‎ מוטבעים ב-‎index.html‎.
   ⚠ ‎aria-hidden‎ נשאר על כל אחד מהם — קורא מסך אינו שומע כאן דבר. */
[data-lvl] {
  display: block;
  height: 4px;
  margin: 8px 4px 0;
  border-radius: 2px;
  background: #ffe3ef;
  overflow: hidden;
}
[data-lvl] > i {
  display: block;
  height: 100%;
  background: #ff2d87;
  transform: scaleX(var(--mo-v, .5));
  transform-origin: right;
}
html[data-motion="armed"] [data-lvl] > i {
  transform: scaleX(0);
  transition: transform 900ms cubic-bezier(.16, 1, .3, 1) var(--mo-d, 0ms);
}
html[data-motion="armed"] [data-r][data-in] [data-lvl] > i {
  transform: scaleX(var(--mo-v, .5));
}

/* ══ רגע מושאל 3 · המחירים סופרים למעלה — **בוטל 17.9.2026** ═══════════
   🔑 הכרעת איתי: *"תסיר את האנימציה של הספירה של המספר 500."*
   ⚠ הכלל ‎[data-num]‎ שישב כאן (‎inline-block‎ · ‎tabular-nums‎ · ‎min-width‎
     מ-JS) התקיים **אך ורק** כדי שהספירה לא תזיז את ה-₪. בלי ספירה אין מה
     לייצב, והמחיר חזר להיות טקסט רגיל בתוך ‎.offer-price‎. המדידה שהראתה
     שלמנגנון לא היה שימוש אחר — ב-‎shared/motion.js‎, סעיף 3. */

/* ══ נשימת המלבנים · "כל מלבן מרגיש חי" · הכרעת איתי, 17.9.2026 ══════════
   🔑 *"אני רוצה שכל מלבן שמופיע יקבל תחושה של פעימה… כל כך איטית וכל כך
   קטנה שכמעט ולא מרגישים בה, רק מספיק כדי שהמלבן ירגיש חי."*

   ⚠ **וזה גובר על כלל קודם שלו.** עד כאן נשם **דבר אחד בלבד** על המסך
     (כפתור ההירו, למעלה). הכלל ההוא נשאר במקומו לגבי **כפתורים**; המלבנים
     יוצאים ממנו בהוראה מפורשת. ‎motion.test.js‎ עודכן: הוא ספר "לא יותר
     מלולאה אחת", ועכשיו הוא סופר תקציב מדוד.

   🔴 **הנשימה יושבת על ‎::before‎ ולא על המלבן — שלוש סיבות שנמדדו:**
     1. **הטקסט אינו מושפע.** דרישה מפורשת של איתי. הפסבדו אינו הורה של
        שום טקסט, ולכן אין מה לנטרל ואין "קנה מידה נגדי" על הילדים —
        שהיה מכפיל את מספר ההנפשות מ-19 ל-~70.
     2. **אפס הזזת פריסה.** ‎position:absolute‎ אינו משתתף בפריסה בכלל.
     3. 🔴 **וזו הסיבה שהכריעה:** ‎scale‎ על המלבן עצמו **דורס את כניסת
        הגלילה.** ‎[data-r="item"]‎ נכנס ב-‎scale:.985‎ (למעלה בקובץ), והנפשה
        גוברת תמיד על הצהרה — כלומר כל תשעה-עשר הכרטיסים היו מאבדים את
        ההתקרבות בכניסה, בשקט.

   ⚠ **סדר הציור — למה ‎z-index:-1‎ הוא בדיוק הנכון.** לפי סדר הציור של CSS,
     צאצא ממוקם בדרגה שלילית מצויר **אחרי הרקע של האלמנט** ו**לפני התוכן
     שלו**. לכן הפסבדו יושב מעל הרקע הסטטי ומתחת לאותיות: כשהוא גדל ב-0.4%
     הוא מכסה את הרקע ומרחיב אותו, וכשהוא חוזר ל-1 הוא מתיישר איתו בדיוק.
     ⚠ ולכן גם ‎z-index:0‎ על המלבן — בלי הקשר ערימה משלו, הדרגה השלילית
       בורחת אל מאחורי רקע המקטע והנשימה נעלמת (אותה מלכודת מתועדת
       ב-‎shared/tissue-button.css‎).
     ⚠ ‎background-color: inherit‎ — הפסבדו לוקח את צבע המלבן עצמו, ולכן
       שינוי צבע עתידי אינו מפצל את השניים. ‎border-radius: inherit‎ כנ"ל.

   🔑 **"הפעימה הראשונה בלבד — ואיתה גם הטקסט."** בפעימה הראשונה **המלבן
     כולו** (הפסבדו והטקסט יחד) פועם, ואחריה הפסבדו לבדו:
       · המלבן  — מחזור **אחד**, בהשהיה של משך הכניסה (‎--mo-dur + --mo-d‎),
                  כך שהוא מתחיל בדיוק כשהכניסה נחתה ולא קופץ עליה.
       · הפסבדו — אינסופי, באותה השהיה **ועוד מחזור אחד**, כלומר נכנס
                  בדיוק כשהמלבן סיים. אין רגע בלי פעימה ואין רגע כפול.
     ⚠ שתי ההנפשות נוצרות ברגע ש-‎[data-in]‎ מופיע, ולכן השעון שלהן משותף.
       לו הפסבדו היה מוכרז בלי ‎[data-in]‎, השעון שלו היה מתחיל בטעינת הדף
       והפאזה בין השתיים הייתה תלויה במתי המשתמשת גללה לכאן.

   ⚠ **הרשימה מפורשת ונמדדת, ולא "כל מה שיש לו מסגרת".** מה נכלל ומה לא —
     ‎motion-gaps.test.js‎, שער "מה נחשב מלבן". התקציר: ארבע משפחות של
     **פריטים חוזרים בתוך מקטע** — כרטיסי המדדים, שורות "איך זה עובד",
     כרטיסי המחיר ושאלות ה-FAQ (19 בסך הכול). מה שהוחרג: כפתורים וגלולות
     (כפתור ההירו כבר נושם בקצב אחר), ומיכל היומן ‎.booking-widget‎ — משטח
     עבודה שהתנועה בתוכו בבעלות ‎shared/crawl.js‎, ושתי תנועות על אותו
     מלבן נלחמות זו בזו. 🔑 קנה מידה הוא תנועה של **פריט**, לא של **מסך** —
     אותו כלל בדיוק שכבר כתוב ב-‎crawl.js‎.  */
[data-tile] { position: relative; z-index: 0; }
[data-tile]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-color: inherit;
  pointer-events: none;
}
html[data-motion="armed"] [data-tile][data-in] {
  animation: sfgTileBreath var(--breath-card) var(--beat-ease) 1;
  animation-delay: calc(var(--mo-dur) + var(--mo-d, 0ms));
}
html[data-motion="armed"] [data-tile][data-in]::before {
  animation: sfgTileBreath var(--breath-card) var(--beat-ease) infinite;
  animation-delay: calc(var(--mo-dur) + var(--mo-d, 0ms) + var(--breath-card));
}
/* ⚠ ‎scale‎ ולא ‎transform‎ — ‎.value-card.card-1‎ וחבריו נושאים
   ‎transform: rotate(...)‎ ב-‎style.css‎, ותמונת מפתח ב-‎transform‎ הייתה
   **מוחקת את ההטיה**. אותו נימוק בדיוק שכתוב בראש הקובץ על הכניסה. */
@keyframes sfgTileBreath {
  0%, 100% { scale: 1; }
  50%      { scale: var(--breath-card-amp); }
}
