/* ═══════════════════════════════════════════════════════════════════════
   طبقة المكالمة (.call-*) · js/ui/call-ui.js
   ───────────────────────────────────────────────────────────────────────
   المرجع: docs/DESIGN.md. ثلاثة أسطح في شجرة واحدة داخل #call-layer:
     • المسرح .call-stage — ملء الشاشة: واردة · صادرة · جارية.
     • الشريط .call-pill — مكالمة مصغّرة: «اضغط للعودة إلى المكالمة • 02:31».
   المسرح داكن دائماً (كواتساب) أياً كانت سمة التطبيق، فألوانه رموز محلية
   (--call-*) لا رموز السمة؛ والضوء الخافت خلفه من hue اسم الزميل (--h)،
   كالصورة الرمزية نفسها. الأخضر والأحمر من --success و--danger.
   استثناء مقصود من «لا ألوان حرفية» في DESIGN.md: سطح لا يتبع السمة لا يجد
   في رموزها ما يصلح له، فالألوان الحرفية مجموعة في كتلة رموز واحدة على
   #call-layer (القسم ١) ولا تتكرّر في القواعد.

   الطبقات: الشريط 10000 والمسرح 10001 — فوق كل شيء، وفوق قفل التطبيق عمداً
   (9999): قفلٌ يظهر أثناء المكالمة كان يدفن زرّ الإنهاء الوحيد خلف لوحة الرقم
   السري، ومكالمة تصل والقفل ظاهر كانت لا تُجاب. القفل يبقى خلف المسرح، ويرى
   المقفول اسم المتصل وزرّي الردّ والإنهاء فقط — كما تفعل أنظمة الهواتف كلها.
   (js/ui/lock-screen.js يعلّق القفل أثناء المكالمة أيضاً؛ الاثنان مقصودان.)

   الحركة: transform وopacity وحدهما. الحلقات النابضة ونفَس الضوء وقفزة زرّ
   الردّ حلقات لا نهائية، فتُلغى كلياً مع تقليل الحركة (مدة 1ms لا تكفي: حلقة
   لا نهائية بمدة 1ms تعيد الرسم إلى الأبد).
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══ ١. المضيف ═══════════════════════════════════════════════════════
   الابنان position:fixed فالمضيف بلا ارتفاع، ولا يلتقط اللمس. بلا مكالمة
   كلاهما [hidden] — لا رسم ولا اختبار لمس. شقيق #screen-container لا ابنه:
   الموجّه يفرغ الحاوية مع كل تنقّل، ومكالمة داخلها كانت ستُهدم. */
#call-layer {
  height: 0; pointer-events: none;
  /* الحافة الآمنة الحقيقية: body.has-call-pill يزيد --safe-t للتطبيق تحته
     بارتفاع الشريط، فالمكالمة تقرأ env() مباشرة. */
  --call-safe-t: env(safe-area-inset-top, 0px);
  --call-safe-b: env(safe-area-inset-bottom, 0px);
  --call-pill-h: 32px;

  /* رموز السطح الداكن الدائم — الألوان الحرفية الوحيدة في هذا الملف */
  --call-bg: #080C13;
  --call-fg: #FFFFFF;
  --call-fg-2: rgba(255, 255, 255, .74);
  --call-fg-3: rgba(255, 255, 255, .52);
  --call-key: rgba(255, 255, 255, .13);
  --call-key-press: rgba(255, 255, 255, .24);
  --call-dock: rgba(255, 255, 255, .06);
  --call-shade: rgba(0, 0, 0, .45);
}
#call-layer > * { pointer-events: auto; }
#call-layer[hidden] { display: none !important; }

/* ═══ ٢. الشريط المصغّر ═══════════════════════════════════════════════
   شريط كامل العرض فوق منطقة الحالة، أخضر كواتساب. التطبيق كله ينزل تحته
   (القسم ٣) بدل أن يطفو الشريط فوق الرأس. */
.call-pill {
  position: fixed; top: 0; inset-inline: 0; z-index: 10000;
  height: calc(var(--call-safe-t) + var(--call-pill-h));
  padding: var(--call-safe-t) 16px 0; margin: 0; border: 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  background: color-mix(in srgb, var(--success) 84%, var(--call-bg)); color: var(--call-fg);
  font: inherit; font-size: var(--fz-sm); font-weight: 700; line-height: 1;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  animation: call-pill-in var(--dur-3) var(--ease) backwards;
  transition: background-color var(--dur-1);
}
.call-pill[hidden] { display: none !important; }
.call-pill:active { background: color-mix(in srgb, var(--success) 72%, var(--call-bg)); }
.call-pill:focus-visible { outline: 2px solid var(--call-fg); outline-offset: -4px; }
.call-pill-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--call-fg);
  animation: call-blink 1.6s ease-in-out infinite;
}
.call-pill-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* المؤقّت LTR (وإلا قلبت ثنائية الاتجاه «02:31» إلى «31:02»)، والنقطة
   الفاصلة بعده في صندوقه = على يمينه، أي بينه وبين النص في العربية. */
.call-pill-timer {
  flex: none; direction: ltr; unicode-bidi: isolate;
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.call-pill-timer::after { content: "•"; margin-inline-start: 8px; opacity: .75; }
.call-pill-timer:empty { display: none; }

@keyframes call-pill-in { from { transform: translateY(-100%); } to { transform: none; } }
@keyframes call-blink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ═══ ٣. التطبيق تحت الشريط ═══════════════════════════════════════════
   الحالة ملك هذه الطبقة (call-ui.js يضع has-call-pill على body). لا قاعدة
   هنا تمسّ هندسة الغلاف: الشريط يصير جزءاً من «الحافة الآمنة» نفسها، فكل ما
   يحترم --safe-t ينزل تحته وحده — الرأس العام ورأس المحادثة وبحثها، والحاوية
   (--top-inset يحسبه shell.js على body من --safe-t)، وشريط الإشعار، والورقة
   الكاملة، وشريط عارض الصور. 32px = --call-pill-h (مكرّر لأن ذاك على المضيف
   لا على body). مطلوب نقلها إلى ui.css §٣ — انظر طلبات التقرير؛ وجودها في
   الملفين معاً لا يضرّ لأنها القيمة نفسها. */
/* body.has-call-pill { --safe-t: … } — صارت في css/ui.css (الغلاف يملك الحافة الآمنة). */

/* ═══ ٤. المسرح ═══════════════════════════════════════════════════════ */
.call-stage {
  /* hue الزميل؛ call-ui.js يضعه من الاسم. ألوان السطح من رموز #call-layer. */
  --h: 210;

  position: fixed; inset: 0; z-index: 10001;
  display: flex; flex-direction: column;
  padding-top: var(--call-safe-t); padding-bottom: var(--call-safe-b);
  overflow: hidden; isolation: isolate;
  background: var(--call-bg); color: var(--call-fg);
  color-scheme: dark;
  -webkit-user-select: none; user-select: none;
  animation: call-stage-in var(--dur-3) var(--ease) backwards;
}
.call-stage[hidden] { display: none !important; }
/* انتهت المكالمة: تلاشٍ قصير، ثم [hidden]. call-ui.js يقرأ --dur-2 نفسه
   (_exitMs) فلا يسبق الإخفاءُ الحركةَ ولا يتأخّر عنها. */
.call-stage.is-leaving { animation: call-stage-out var(--dur-2) var(--ease-in) forwards; pointer-events: none; }
/* تصغير إلى الشريط: يصعد قليلاً وينكمش نحوه ويتلاشى (المدة نفسها) */
.call-stage.is-collapsing { animation: call-stage-collapse var(--dur-2) var(--ease-in) forwards; pointer-events: none; }

@keyframes call-stage-in { from { opacity: 0; transform: scale(1.03); } to { opacity: 1; transform: none; } }
@keyframes call-stage-out { to { opacity: 0; transform: scale(.98); } }
@keyframes call-stage-collapse { to { opacity: 0; transform: translateY(-28px) scale(.95); } }

/* الضوء: hue الزميل من أعلى، ولمسة من hue+28 من الأسفل (تدرّج صورته نفسه).
   يُرسم مرة؛ ولا «يتنفّس» إلا والهاتف يرنّ. */
.call-glow {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  transform-origin: 50% 32%;
  background:
    radial-gradient(72% 44% at 50% 30%, hsl(var(--h) 78% 54% / .42) 0%, hsl(var(--h) 72% 46% / .14) 48%, transparent 76%),
    radial-gradient(90% 38% at 50% 108%, hsl(calc(var(--h) + 28) 70% 46% / .22) 0%, transparent 72%),
    linear-gradient(180deg, hsl(var(--h) 42% 14%) 0%, var(--call-bg) 58%);
}
.call-stage[data-mode="incoming"] .call-glow,
.call-stage[data-mode="outgoing"] .call-glow {
  will-change: transform, opacity;
  animation: call-breathe 3.2s ease-in-out infinite alternate;
}
@keyframes call-breathe { from { transform: none; opacity: .86; } to { transform: scale(1.08); opacity: 1; } }

/* ── الشريط العلوي: تصغير (حين يمكن) ونوع المكالمة ── */
.call-top {
  position: relative; flex: none; height: 56px;
  display: flex; align-items: center; justify-content: center; padding-inline: 60px;
}
/* في منتصف الشريط عمودياً أياً كان ارتفاعه (56 / 48 / 40px في القسم ٦):
   inset-block + margin auto لا translateY، كي يبقى transform حرّاً لضغطة الزرّ. */
.call-min {
  position: absolute; inset-block: 0; margin-block: auto; inset-inline-start: 8px;
  width: 44px; height: 44px; border: 0; border-radius: 50%; padding: 0;
  display: grid; place-items: center;
  background: transparent; color: var(--call-fg);
  transition: background-color var(--dur-1), transform var(--dur-1) var(--ease);
}
.call-min[hidden] { display: none !important; }
.call-min:active { background: var(--call-key); transform: scale(.92); }
.call-min:focus-visible { outline: 2px solid var(--call-fg); outline-offset: -2px; }
.call-min > svg { width: 26px; height: 26px; display: block; stroke-width: 2; }
.call-kind {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fz-sm); font-weight: 500; color: var(--call-fg-3);
}
.call-kind .icon-svg { width: 15px; height: 15px; }

/* ── الهوية: الصورة، الاسم، سطر الحالة ── */
.call-id {
  position: relative; flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: clamp(12px, 9vh, 88px) 20px 12px;
}
/* لا ينكمش شيء داخل الكتلة: عنصر بـoverflow:hidden (الاسم المقصوص) يصير
   min-height:auto عنده صفراً، فكان الاسم يختفي على الشاشات القصيرة. */
.call-id > * { flex-shrink: 0; }
.call-av { position: relative; width: 124px; height: 124px; flex: none; display: grid; place-items: center; margin-bottom: 24px; }
.call-avatar { position: relative; z-index: 1; display: grid; }
.call-avatar .av {
  --sz: 124px;
  box-shadow: 0 18px 48px var(--call-shade), 0 0 0 4px var(--call-dock);
}

/* حلقات نابضة حول الصورة ما دام الهاتف يرنّ (وارد أو صادر) */
.call-halo { position: absolute; inset: 0; pointer-events: none; }
.call-halo > span {
  position: absolute; inset: 0; border-radius: 50%; opacity: 0;
  border: 1.5px solid hsl(var(--h) 90% 80% / .5);
  background: hsl(var(--h) 85% 70% / .07);
}
.call-stage[data-mode="incoming"] .call-halo > span,
.call-stage[data-mode="outgoing"] .call-halo > span { animation: call-ring 2.4s cubic-bezier(.2, .6, .35, 1) infinite; }
.call-stage .call-halo > span:nth-child(2) { animation-delay: .8s; }
.call-stage .call-halo > span:nth-child(3) { animation-delay: 1.6s; }
@keyframes call-ring { 0% { transform: scale(1); opacity: .75; } 100% { transform: scale(1.7); opacity: 0; } }

/* الاسم سطر واحد كواتساب وتيليجرام. الاسم الطويل يصغر أولاً (call-ui.js:
   .is-long فوق 22 حرفاً → 24px، و.is-xlong فوق 29 → 20px)، ثم «…» في آخره. لا
   -webkit-line-clamp: يقصّ السطر الأخير بعد توسيطه فيزيحه عن المركز، وتبرز
   ألفات السطر المخفي ولاماته تحته. ارتفاع السطر ثابت بالبكسل (1.4 × 30px)
   أياً كان مقاس الخط: يتّسع لحروف العربية الصاعدة والنازلة داخل صندوق القصّ،
   ولا يتحرّك ما تحت الاسم بين اسم قصير وطويل. */
.call-peer {
  max-width: 100%; margin: 0;
  font-size: var(--fz-3xl); font-weight: 800; line-height: 42px; letter-spacing: -.01em;
  color: var(--call-fg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.call-peer.is-long { font-size: var(--fz-2xl); }
.call-peer.is-xlong { font-size: var(--fz-xl); }

/* الحالة والمؤقّت في خانة واحدة يتبادلان بالتلاشي: لا قفزة حين يبدأ العدّ */
.call-line { display: grid; justify-items: center; align-items: center; min-height: 26px; margin-top: 8px; }
.call-line > * { grid-area: 1 / 1; margin: 0; transition: opacity var(--dur-2) var(--ease); }
.call-status { font-size: var(--fz-base); font-weight: 500; line-height: 1.5; color: var(--call-fg-2); }
.call-status.is-swap { animation: call-swap var(--dur-2) var(--ease); }
.call-timer {
  opacity: 0;
  font-size: var(--fz-lg); font-weight: 500; line-height: 1.5; color: var(--call-fg);
  font-variant-numeric: tabular-nums; letter-spacing: .03em;
  direction: ltr; unicode-bidi: isolate;
}
.call-stage[data-timing] .call-status { opacity: 0; animation: none; }
.call-stage[data-timing] .call-timer { opacity: 1; }
@keyframes call-swap { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.call-sub {
  min-height: 20px; margin: 2px 0 0;
  font-size: var(--fz-sm); line-height: 1.5; color: var(--call-fg-3);
  font-variant-numeric: tabular-nums;
}
/* سطر ICE في نسخ التصحيح وحدها (DEBUG_BUILD) */
.call-dbg {
  display: block; margin-top: 6px; opacity: .55; letter-spacing: .02em;
  font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* جملة العطل من الخادم أو الجلسة: سطر واحد على أرضية حمراء خافتة */
.call-error {
  margin: 16px 0 0; max-width: 32ch; padding: 8px 14px; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--danger) 22%, transparent);
  color: color-mix(in srgb, var(--danger) 40%, var(--call-fg));
  font-size: var(--fz-md); font-weight: 700; line-height: 1.5;
  animation: call-swap var(--dur-2) var(--ease);
}
.call-error[hidden] { display: none !important; }

/* ═══ ٥. الأزرار ══════════════════════════════════════════════════════
   صفّ لكل وضع، وCSS يختار الظاهر من data-deck لا data-mode: «جارٍ الإنهاء»
   ليست مجموعة أزرار، والصف يبقى على آخر ما كان (رفض مكالمة واردة لا يُظهر
   أزرار مكالمة جارية لم تحدث). */
.call-deck {
  position: relative; flex: none;
  display: flex; justify-content: center;
  padding: 8px 20px 28px;
}
.call-row { display: none; width: 100%; max-width: 380px; align-items: flex-start; }
.call-stage[data-deck="incoming"]   .call-row-answer,
.call-stage[data-deck="outgoing"]   .call-row-cancel,
.call-stage[data-deck="connecting"] .call-row-live,
.call-stage[data-deck="active"]     .call-row-live {
  display: flex;
  animation: call-row-in var(--dur-3) var(--ease-spring) backwards;
}
@keyframes call-row-in { from { opacity: 0; transform: translateY(18px) scale(.96); } to { opacity: 1; transform: none; } }

/* واردة: ردّ وأخضر في البداية (يمين العربية)، رفض في النهاية، وبينهما مسافة
   واسعة — إبهام مرتبك لا يصيب الزرّ الخطأ. */
.call-row-answer { justify-content: space-around; padding-bottom: 6px; }
/* صادرة: زرّ أحمر واحد في المنتصف */
.call-row-cancel { justify-content: center; }
/* جارية: لوح واحد — مكبّر الصوت، كتم، إنهاء */
.call-row-live {
  max-width: 360px; justify-content: space-evenly; gap: 8px;
  padding: 16px 10px 12px; border-radius: 32px; background: var(--call-dock);
}

.call-act { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 76px; }
.call-act-label {
  font-size: var(--fz-xs); font-weight: 500; line-height: 1.3; color: var(--call-fg-2);
  white-space: nowrap;
}

.call-btn, .call-tog {
  position: relative; width: 64px; height: 64px; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; color: var(--call-fg);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-1) var(--ease), background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease), opacity var(--dur-2);
}
/* أيقونات المجموعة مرسومة بسُمك 1.75 لأزرار 24px؛ تثقل هنا لا بنسخة ثانية */
.call-btn > svg, .call-tog > svg { width: 28px; height: 28px; display: block; stroke-width: 2; }
.call-btn:active:not(:disabled), .call-tog:active:not(:disabled) { transform: scale(.92); }
.call-btn:disabled, .call-tog:disabled { opacity: .45; cursor: default; }
.call-btn:focus-visible, .call-tog:focus-visible { outline: 2px solid var(--call-fg); outline-offset: 3px; }

/* مفتاح (مكبّر، كتم): قرص شفيف؛ مفعّل = قرص أبيض بأيقونة داكنة */
.call-tog { background: var(--call-key); }
.call-tog:active:not(:disabled) { background: var(--call-key-press); }
.call-tog[aria-pressed="true"] { background: var(--call-fg); color: var(--call-bg); }

/* الإنهاء والرفض والإلغاء: السمّاعة نفسها مقلوبة 135° */
.call-btn-end, .call-btn-decline, .call-btn-cancel { background: var(--danger); }
.call-btn-end:active:not(:disabled), .call-btn-decline:active:not(:disabled), .call-btn-cancel:active:not(:disabled) {
  background: color-mix(in srgb, var(--danger) 84%, var(--call-bg));
}
.call-btn-end > svg, .call-btn-decline > svg, .call-btn-cancel > svg { transform: rotate(135deg); }

/* واردة: زرّان أكبر قليلاً، والردّ يقفز بلطف كي تلتقطه العين */
.call-btn-accept, .call-btn-decline { width: 72px; height: 72px; }
.call-btn-accept > svg, .call-btn-decline > svg { width: 31px; height: 31px; }
.call-btn-accept {
  background: var(--success);
  box-shadow: 0 10px 28px color-mix(in srgb, var(--success) 38%, transparent);
  animation: call-bounce 2s cubic-bezier(.3, .6, .4, 1) .5s infinite;
}
.call-btn-accept:active:not(:disabled) { animation: none; background: color-mix(in srgb, var(--success) 84%, var(--call-bg)); }
@keyframes call-bounce {
  0%, 40%, 100% { transform: none; }
  12% { transform: translateY(-9px); }
  24% { transform: none; }
  32% { transform: translateY(-3px); }
}

/* ═══ ٦. شاشات قصيرة (أفقي، هواتف صغيرة) ═════════════════════════════ */
@media (max-height: 640px) {
  .call-top { height: 48px; }
  .call-id { padding-top: 4px; }
  .call-av { width: 92px; height: 92px; margin-bottom: 14px; }
  .call-avatar .av { --sz: 92px; }
  .call-peer, .call-peer.is-long { font-size: var(--fz-2xl); line-height: 34px; }
  .call-peer.is-xlong { font-size: var(--fz-xl); }
  .call-deck { padding-bottom: 16px; }
  .call-row-live { padding-block: 12px 10px; }
}
/* أفقي على هاتف: صورة صغيرة وشريط علوي أقصر كي يتّسع الاسم والأزرار */
@media (max-height: 460px) {
  .call-top { height: 40px; }
  .call-av { width: 64px; height: 64px; margin-bottom: 10px; }
  .call-avatar .av { --sz: 64px; }
  .call-halo { display: none; }
  .call-sub { min-height: 0; }
  .call-deck { padding-top: 0; }
}

/* ═══ ٧. تقليل الحركة وتباين أعلى ════════════════════════════════════ */
body.reduce-motion .call-halo > span,
body.reduce-motion .call-glow,
body.reduce-motion .call-btn-accept,
body.reduce-motion .call-pill-dot { animation: none !important; }
body.reduce-motion .call-halo { display: none; }
@media (prefers-reduced-motion: reduce) {
  .call-halo > span, .call-glow, .call-btn-accept, .call-pill-dot { animation: none !important; }
  .call-halo { display: none; }
}

body.high-contrast .call-stage { --call-fg-2: rgba(255, 255, 255, .92); --call-fg-3: rgba(255, 255, 255, .82); --call-key: rgba(255, 255, 255, .22); }
body.high-contrast .call-tog { box-shadow: inset 0 0 0 1.5px var(--call-fg-3); }
