/* call.css — экран звонка, кнопка в шапке и служебная строка в ленте (задумка #161).

   Отдельным листом, а не правкой components.css: тот 46 КБ, и патч везёт файл целиком — платить
   его весом за каждую подгонку звонка не за что. Подключается списком надстроек в index.php,
   последним в каскаде, поэтому перебивает базу без !important и снимается одной строкой оттуда же.

   Цвета — только токенами (css/tokens.css). Отдельная оговорка про --bubble-out: это
   linear-gradient, и в свойстве ЦВЕТА (color/border-color/outline) он недопустим целиком —
   браузер выбрасывает такое объявление молча. Где нужен цвет фирменного пузыря, берём --accent. */

/* ---------- Экран звонка ----------
   Поверх всего, но не модальным диалогом: у звонка нет «отмены по Esc», выйти из него можно
   только трубкой. position:fixed с инсетами, а не 100vw/100vh: на телефоне vh врёт на величину
   адресной строки, и низ карточки уезжал бы под неё вместе с кнопкой «завершить». */
#call-overlay{
  position:fixed; inset:0; z-index:120;
  display:none; align-items:center; justify-content:center;
  background:rgba(12,14,18,.55);
  backdrop-filter:blur(var(--blur,12px)) saturate(1.4);
  -webkit-backdrop-filter:blur(var(--blur,12px)) saturate(1.4);
  /* Экран звонка поднимается сам, без нажатия человека, — на телефоне это значит «под пальцем,
     который куда-то целился». Поэтому первые полсекунды он не принимает касаний вовсе. */
  animation:callIn .28s ease both;
}
#call-overlay.on{ display:flex; }
@keyframes callIn{ from{ opacity:0 } to{ opacity:1 } }

.call-card{
  position:relative;                             /* якорь для бегущей рамки, см. ниже */
  display:flex; flex-direction:column; align-items:center; gap:14px;
  padding:34px 30px 26px; min-width:270px; max-width:min(92vw,360px);
  border-radius:28px; border:1px solid var(--border);
  background:var(--panel2); color:var(--text);
  box-shadow:0 0 44px rgba(0,0,0,.28);
  animation:callCard .3s cubic-bezier(.2,.9,.3,1.2) both;
}
@keyframes callCard{ from{ opacity:0; transform:scale(.92) translateY(10px) } to{ opacity:1; transform:none } }

.call-avatar{ width:96px; height:96px; border-radius:50%; overflow:hidden; flex-shrink:0 }
.call-avatar .avatar{ width:96px!important; height:96px!important; font-size:36px!important }

.call-name{ font-family:inherit; font-size:20px; font-weight:600; text-align:center; line-height:1.25; word-break:break-word }

/* Статус — единственная строка, которая меняется каждую секунду (таймер разговора). Ширина
   табличных цифр обязательна: без неё «1:09 → 1:10» дёргает карточку по горизонтали. */
.call-status{
  font-family:inherit; font-size:15px; color:var(--text2); min-height:20px;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum";
}

/* Входящий звонок пульсирует, исходящий нет: пульс здесь значит «от тебя ждут действия».
   prefers-reduced-motion гасит его целиком — мигающий экран это то, что просят выключить в
   первую очередь. */
#call-overlay[data-st="incoming"] .call-status{ color:var(--accent); animation:callPulse 1.6s ease-in-out infinite }
@keyframes callPulse{ 0%,100%{ opacity:1 } 50%{ opacity:.45 } }

.call-actions{ display:flex; gap:18px; align-items:center; justify-content:center; margin-top:6px }

.call-btn{
  position:relative;                             /* якорь для бегущей рамки на «Ответить» */
  width:58px; height:58px; border-radius:19px; border:0; padding:0;
  corner-shape:superellipse(2.6);                /* тот же силуэт, что у кнопок мессенджера */
  display:flex; align-items:center; justify-content:center;
  /* line-height:0 убирает единственную причину, по которой значок мог стоять выше середины:
     кнопка — это ещё и текстовый контейнер, и её строчный просвет добавляет невидимую строку под
     значком, а она сдвигает содержимое вверх. Внутри flex это обычно не проявляется, но «обычно»
     — плохое слово там, где перекос уже видно глазами. Заодно place-items вместо пары
     align/justify: одно свойство труднее рассогласовать, чем два. */
  line-height:0; place-items:center;
  font-family:inherit; cursor:pointer; color:#fff;
  transition:transform .12s ease, filter .12s ease;
}
/* display:block — чтобы значок не считался буквой в строке; margin:auto — вторая опора центровки,
   работающая даже если у кнопки почему-то отняли display:flex. */
.call-btn svg{ width:25px; height:25px; display:block; margin:auto; flex:none }
.call-btn:active{ transform:scale(.92) }
.call-btn:hover{ filter:brightness(1.08) }

.call-accept{ background:#28a745 }
.call-hang{ background:#e5484d }
/* Трубка «завершить» — та же иконка, что «ответить», повёрнутая: так её узнают без подписи,
   и так же она нарисована в любом телефоне последние тридцать лет. */
.call-hang svg{ transform:rotate(135deg) }

/* Вторичные кнопки — на стекле мессенджера, а не на своей заливке: тот же --panel2, тот же блюр,
   та же рамка, что у пилюль шапки и полосы ввода. Экран звонка — часть приложения, а не отдельное
   приложение внутри него. */
.call-mute,.call-cam,.call-flip,.call-spk{
  background:var(--panel2); color:var(--text); border:1px solid var(--border);
  backdrop-filter:blur(var(--blur)) saturate(1.4); -webkit-backdrop-filter:blur(var(--blur)) saturate(1.4);
}
.call-mute.off,.call-cam.off{ background:#e5484d; color:#fff; border-color:transparent }

/* ---------- Кнопка звонка в шапке ----------
   Живёт ВНУТРИ стеклянной пилюли имени, слева от лупы поиска — сама себе стеклом не будет.
   Размеры один в один с #head-search-btn (css/comp-waves.css): две кнопки в одном ряду обязаны
   быть одного роста, иначе пилюля выглядит собранной наспех. */
#head-call-btn{
  border:none; background:transparent; color:var(--text2); cursor:pointer;
  width:38px; height:38px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; flex-shrink:0; padding:0;
}
#head-call-btn svg{ width:18px; height:18px }
#head-call-btn:hover{ color:var(--accent); background:var(--hover) }
/* Поиск открыт — шапка отдаёт всё место полю ввода, и лишние кнопки уходят вместе с именем.
   Строка повторяет правило #head-search-btn из comp-waves.css: там перечислены поимённо все,
   кто прячется, и новый сосед обязан встать в тот же список. */
#chathead.searching #head-call-btn{ display:none }
@media(max-width:760px){ #head-call-btn{ width:40px; height:40px } }

/* Идёт звонок — кнопка не должна звать во второй: сервер откажет «занято», но честнее не
   предлагать вовсе. */
body.in-call #head-call-btn{ opacity:.35; pointer-events:none }

/* ---------- Служебная строка звонка в ленте ----------
   Не пузырь, а плашка посередине: это не чьи-то слова, а событие. Тем же языком, что чипы дней
   (В2), — они отвечают на родственный вопрос «что случилось между сообщениями». */
.mrow.call-row{
  display:flex; justify-content:center; align-items:center;
  padding:6px 0; width:100%;
}
/* Форма — фирменный суперэллипс, как у всего своего в приложении. Селектор нарочно тяжелее
   правила: внутри ленты corner-shape гасит `#messages *{corner-shape:round}` из layout.css, и это
   правило проекта, а не небрежность — суперэллипс считается дороже круга, а мелочи в ленте
   десятками на экран. Поэтому его возвращают поимённо избранным силуэтам: пузырю, аватарке, чипу
   даты. Строка звонка — из того же ряда: её на экране одна-две, цена формы ничтожна, а выпадать
   из общего силуэта ей не за что. `#messages .call-chip` — id + класс против id + звезды, поэтому
   выигрывает независимо от порядка файлов.
   Радиус не трогаем: 16px при высоте чипа около 28px — углы уже смыкаются, и суперэллипс
   превращает пилюлю ровно в ту форму, что у пузырей и кнопок. Один в один довод чипа даты (#194). */
#messages .call-chip{ corner-shape:superellipse(2.6) }

.call-chip{
  display:inline-flex; align-items:center; gap:7px;
  max-width:82%; padding:6px 13px; border-radius:16px;
  background:var(--panel); border:1px solid var(--border);
  color:var(--text2); font-size:13px; line-height:1.3;
  backdrop-filter:blur(10px) saturate(1.4); -webkit-backdrop-filter:blur(10px) saturate(1.4);
}
.call-chip svg{ width:14px; height:14px; flex-shrink:0; opacity:.75 }
.call-chip-t{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.call-chip-tm{ opacity:.6; font-size:11px; flex-shrink:0; font-variant-numeric:tabular-nums }

/* Пропущенный, отклонённый и несостоявшийся — красным. Это единственные строки, на которые
   человек может захотеть ответить действием, и найти их в ленте глазами нужно за секунду.
   Цвет непрозрачный: лента лежит на обоях, а не на ровном фоне, и полупрозрачный красный на
   фотографии обоев дал бы сдвиг в единицы яркости вместо заметной пометки. */
.call-chip.bad{ color:#c0353a; border-color:rgba(192,53,58,.28) }
.call-chip.bad svg{ opacity:1 }
body.dark .call-chip.bad{ color:#ff8085; border-color:rgba(255,128,133,.3) }

@media(prefers-reduced-motion:reduce){
  #call-overlay,.call-card{ animation:none }
  #call-overlay[data-st="incoming"] .call-status{ animation:none }
}

/* Проба без реле (CALLS_NO_RELAY): предупреждение под статусом. Отдельной строкой, а не в самом
   статусе, — статус меняется каждую секунду таймером, и предупреждение мигало бы вместе с ним. */
.call-warn{ font-size:12px; color:var(--text2); opacity:.8; text-align:center; max-width:240px; line-height:1.35 }

/* ---------- Видеозвонок (#161, фаза 4) ----------
   Слои экрана снизу вверх: картинка собеседника во весь экран → своё окошко в углу → карточка со
   знаком, именем и кнопками. У аудиозвонка два первых слоя просто пустые и невидимые, поэтому
   отдельного экрана для видео заводить не пришлось — это тот же экран с включёнными слоями. */

.call-remote,.call-local{ display:none }

/* has-video ставится только когда картинка ПОШЛА, а не когда звонок объявлен видео: до ответа
   показывать нечего, и всё это время экран обязан оставаться карточкой со знаком и именем —
   иначе человек полминуты смотрит в чёрный прямоугольник и думает, что сломалось. */
#call-overlay.has-video .call-remote{
  display:block; position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; background:#0b0d10; z-index:0;
}
#call-overlay.has-video .call-local{
  display:block; position:absolute; z-index:2;
  right:14px; bottom:calc(112px + env(safe-area-inset-bottom));
  width:104px; height:150px; object-fit:cover;
  border-radius:14px; border:1.5px solid rgba(255,255,255,.35);
  box-shadow:0 8px 24px rgba(0,0,0,.4);
  /* Себя показываем зеркально — так человек привык видеть себя, а не наоборот. Собеседника,
     разумеется, нет: его надпись на футболке должна читаться. */
  transform:scaleX(-1);
}

/* Пошла картинка — карточка уходит с дороги: перестаёт быть стеклянной коробкой посреди экрана и
   превращается в подпись сверху и кнопки снизу. Иначе лицо собеседника закрыто нашим оформлением. */
#call-overlay.has-video{ background:#000 }
#call-overlay.has-video .call-card{
  position:absolute; inset:0; z-index:3;
  background:none; border:0; box-shadow:none; backdrop-filter:none; -webkit-backdrop-filter:none;
  max-width:none; width:100%; padding:0;
  justify-content:space-between; align-items:center; animation:none;
  /* Кнопки внизу ловят нажатия, всё остальное поле — нет: тап по лицу собеседника не должен
     ничего задевать. */
  pointer-events:none;
}
#call-overlay.has-video .call-avatar{ display:none }
#call-overlay.has-video .call-name{
  margin-top:calc(26px + env(safe-area-inset-top)); color:#fff;
  text-shadow:0 2px 12px rgba(0,0,0,.6);
}
#call-overlay.has-video .call-status{ color:rgba(255,255,255,.82); text-shadow:0 2px 10px rgba(0,0,0,.6) }
#call-overlay.has-video .call-warn{ color:rgba(255,255,255,.72) }
#call-overlay.has-video .call-actions{
  pointer-events:auto;
  margin:0 0 calc(26px + env(safe-area-inset-bottom));
  padding:12px 16px; border-radius:34px;
  background:rgba(20,22,26,.42);
  backdrop-filter:blur(14px) saturate(1.3); -webkit-backdrop-filter:blur(14px) saturate(1.3);
}

/* Камера и переворот — те же круглые кнопки, что микрофон. */
/* Поверх видео стекло не годится — под ним живая картинка, и панель на ней должна быть темнее,
   иначе значки теряются на светлых кадрах. */
#call-overlay.has-video .call-cam,
#call-overlay.has-video .call-flip,
#call-overlay.has-video .call-spk,
#call-overlay.has-video .call-mute{ background:rgba(255,255,255,.18); color:#fff; border-color:transparent }
#call-overlay.has-video .call-cam.off,
#call-overlay.has-video .call-mute.off{ background:#e5484d }

/* Вторая кнопка в шапке — видеозвонок. Ростом и повадками ровно как соседи. */
#head-vcall-btn{
  border:none; background:transparent; color:var(--text2); cursor:pointer;
  width:38px; height:38px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; flex-shrink:0; padding:0;
}
#head-vcall-btn svg{ width:19px; height:19px }
#head-vcall-btn:hover{ color:var(--accent); background:var(--hover) }
#chathead.searching #head-vcall-btn{ display:none }
body.in-call #head-vcall-btn{ opacity:.35; pointer-events:none }
@media(max-width:760px){ #head-vcall-btn{ width:40px; height:40px } }

/* Служебная строка видеозвонка: к стрелке направления добавляется камера. Два значка отвечают на
   два разных вопроса — «кто кому» и «чем», — и слить их в один значит потерять один ответ. */
.call-chip.vid svg:last-of-type{ opacity:.7 }

@media(max-width:520px){
  #call-overlay.has-video .call-local{ width:88px; height:126px; right:10px }
  #call-overlay.has-video .call-actions{ gap:12px; padding:10px 12px }
  #call-overlay.has-video .call-btn{ width:54px; height:54px }
}


/* ---------- Бегущая рамка на звонящем экране ----------
   Пока звонок идёт — по краю карточки бежит светящийся отрезок. Это не украшение: экран звонка
   поднимается сам, без нажатия, и человеку нужно за долю секунды понять, что происходит прямо
   сейчас и от него ждут ответа. Неподвижная рамка так не читается, а мигание целиком раздражает —
   бежит только отрезок.

   КАК СДЕЛАНО. Конический градиент с одним ярким участком, крутящийся вокруг центра, и маска,
   оставляющая от него только полоску по краю. Маска обязательна: карточка стеклянная
   (полупрозрачный фон плюс размытие подложки), и градиент, положенный просто под неё, просвечивал
   бы сквозь всю карточку мутным пятном.
   Угол крутится через @property — переменную с объявленным типом угла. Без объявления браузер
   считает её просто текстом и анимировать не умеет вовсе: рамка стояла бы на месте. Тот же приём,
   что у --seam-p в components.css.
   Форма рамки — суперэллипс, как у самой карточки, иначе на углах она разъезжалась бы с ней.
   Радиус берётся с прибавкой в толщину: рамка снаружи, её кривая длиннее. */
@property --snake{ syntax:'<angle>'; inherits:false; initial-value:0deg }

#call-overlay{ --snake-w:3px }

@supports ((mask-composite:exclude) or (-webkit-mask-composite:xor)){
  #call-overlay[data-st="incoming"] .call-card::before,
  #call-overlay[data-st="outgoing"] .call-card::before,
  #call-overlay[data-st="incoming"] .call-accept::after{
    content:''; position:absolute; pointer-events:none;
    inset:calc(var(--snake-w) * -1); padding:var(--snake-w);
    background:conic-gradient(from var(--snake),
      transparent 0deg 186deg,
      color-mix(in srgb, var(--accent) 55%, transparent) 250deg,
      var(--accent) 290deg, #fff 306deg, var(--accent) 322deg,
      color-mix(in srgb, var(--accent) 55%, transparent) 344deg,
      transparent 360deg);
    /* Две маски и исключение: видимой остаётся ровно разница между внешним краем и внутренним,
       то есть полоска толщиной в padding. Всё, что внутри, вырезается — карточка остаётся
       карточкой. */
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;
    mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite:exclude;
    animation:snakeRun 2.4s linear infinite;
  }
  #call-overlay[data-st="incoming"] .call-card::before,
  #call-overlay[data-st="outgoing"] .call-card::before{
    border-radius:calc(28px + var(--snake-w));
    corner-shape:superellipse(2.6);
  }
  /* Кнопка НЕ круглая, хотя у неё border-radius:50%: глобальное правило tokens.css даёт всем
     элементам суперэллипс, и вместе с радиусом 50% выходит скруглённый квадрат. Рамке форму надо
     задать ОТДЕЛЬНО и такую же — звёздочка в `*{corner-shape:…}` подбирает элементы, но НЕ
     псевдоэлементы, поэтому ::after доставалась начальная форма round, и вокруг квадратной кнопки
     бегало круглое кольцо. Ровно это и было видно. */
  #call-overlay[data-st="incoming"] .call-accept::after{
    border-radius:50%;
    corner-shape:superellipse(2.6);
    /* Быстрее карточки: у кнопки периметр короче, и на общей скорости отрезок казался бы
       ползущим. Совпадение по ощущению важнее совпадения по числу. */
    animation-duration:1.5s;
  }
}
@keyframes snakeRun{ to{ --snake:360deg } }

/* Разговор пошёл — рамке больше нечего сообщать, и она уходит вместе со звонком. */
#call-overlay[data-st="active"] .call-card::before{ display:none }

@media(prefers-reduced-motion:reduce){
  #call-overlay .call-card::before,
  #call-overlay .call-accept::after{ animation:none; --snake:270deg }
}


/* ---------- Форма: всё своё в звонке одним силуэтом ----------
   Задаём поимённо и явно, хотя tokens.css уже раздаёт суперэллипс всем элементам звёздочкой.
   Причина в двух местах, где звёздочка не работает:
     • псевдоэлементы (::before/::after) она не подбирает вовсе — им достаётся начальная форма
       round, и бегущая рамка оказывалась круглой вокруг квадратной кнопки;
     • строки звонков лежат в ленте, где действует `#messages *{corner-shape:round}`.
   Явная запись стоит ничего и снимает вопрос «почему вот этот блок другой». */
#call-overlay .call-card,
#call-overlay .call-actions,
#call-overlay .call-local,
#call-overlay .call-btn,
#call-overlay .call-warn{ corner-shape:superellipse(2.6) }

/* Плашка со звонками — только на телефоне.
   На широком экране кнопки живут в пилюле с именем: места достаточно, и звонок логично лежит
   рядом с собеседником. На узком места нет — две кнопки по 40px отбирают у имени треть строки, и
   оно обрезается на втором слове. Плашка отдаёт им отдельный ряд: попасть пальцем проще, имя
   остаётся целым, обе кнопки подписаны словами, а не только значком.

   Живёт она ВНУТРИ #chathead вторым рядом. Причина не в удобстве разметки: на узком экране
   #chathead absolute и плавает над лентой (layout.css), а лента отступает сверху на его высоту.
   Плашка, положенная следующим элементом за шапкой, попадала в обычный поток и оказывалась ПОД
   плавающей шапкой — не видна вовсе. Внутри шапки она наследует и положение, и слой. */
#call-mobbar{ display:none }
@media(max-width:760px){
  /* Два числа на весь ряд, и оба общие для пилюли и закрепа. Держать их порознь значило бы
     однажды развести на пару пикселей — и получить перекос, который на глаз видно, а в коде
     непонятно откуда. Высота 50px близка к собственной высоте закрепа (две строки плюс отступы),
     поэтому ничего не сдавливается. */
  body{ --cb-w:104px; --cb-h:50px }

  /* Пилюля — свой абсолютный слой в том же родителе, что шапка и закреп (#chatpane), и с тем же
     top, что у закрепа. Общая система координат — единственный способ выровнять их насовсем:
     внутри шапки координаты считались бы от неё, и любое изменение её высоты снова бы их развело. */
  #call-mobbar{
    display:flex; position:absolute; top:70px; right:9px; z-index:8;
  }
  #call-mobbar .cb-pill{
    display:flex; align-items:stretch;
    width:var(--cb-w); height:var(--cb-h); overflow:hidden;
    border:1px solid var(--border); border-radius:16px;
    corner-shape:superellipse(2.6);
    background:var(--panel);
    backdrop-filter:blur(var(--blur)) saturate(1.4); -webkit-backdrop-filter:blur(var(--blur)) saturate(1.4);
    box-shadow:0 0 16px rgba(0,0,0,.08);
  }
  #call-mobbar button{
    flex:1; display:flex; place-items:center;
    border:0; background:transparent; color:var(--accent);
    padding:0; cursor:pointer; border-radius:0;
    line-height:0;              /* см. довод у .call-btn: строчный просвет поднимал значок */
  }
  /* ВОТ ОНО. Пятый заход на «значки прижаты вверх», и наконец не догадка, а измерение: мерная
     черта по середине кнопки (js/axis.js) легла на 20px от верха пилюли вместо 24 — ровно на 4px
     выше центра, и это же смещение видно глазом у значков.
     Причина: кнопки в пилюле — ТЕ ЖЕ САМЫЕ #head-call-btn / #head-vcall-btn, что живут в пилюле
     имени на широком экране. js их переселяет (ensureButton → mk() берёт элемент по id), а не
     заводит вторую пару, — и вместе с элементом переезжает его размер: #head-call-btn задан
     38×38, а на узком экране правило чуть ниже в этом же файле поднимает его до 40×40, потому что
     в шапке он должен быть ростом с лупу поиска.
     Пилюля высотой 50px (внутри 48) ставит детей через align-items:stretch — но stretch НЕ
     растягивает элемент, у которого высота задана явно: такой ребёнок остаётся 40px и прижимается
     к началу поперечной оси, то есть к верху. Дальше всё честно: значок центрован абсолютно от
     кнопки, кнопка на 8px короче пилюли и стоит вверху — значок и оказывается на 4px выше
     середины пилюли. Все прежние починки правили центровку значка ВНУТРИ кнопки, а перекос был
     не там: кнопка сама сидела не по центру.
     Поэтому здесь снимается размер, а не добавляется сдвиг: ширину и без того задаёт flex:1
     (flex-basis:0 сильнее width), а высоту теперь берёт stretch — она равна пилюле, и центр
     кнопки становится центром пилюли арифметически. Селектор с двумя id (2,0,0) заведомо сильнее
     одиночного #head-call-btn (1,0,0) в правиле для шапки, поэтому порядок строк тут ничего не
     решает — правило для шапки можно не трогать, оно нужно на один кадр после поворота экрана.
     min-height:0 — на случай, если у кнопки однажды появится min-height: он бы пережил и это. */
  #call-mobbar #head-call-btn,
  #call-mobbar #head-vcall-btn{ width:auto; height:auto; min-width:0; min-height:0 }
  /* Граница между значками — тонкая линия внутри одной пилюли, а не зазор: это ОДИН предмет с
     двумя действиями, а не две кнопки рядом. */
  #call-mobbar button + button{ border-left:1px solid var(--border) }
  #call-mobbar button:active{ background:var(--hover) }
  /* display:block — чтобы значок не считался буквой в строке. Внутри flex-кнопки он и так
     становится блоком, но правило стоит явно: стоит кому-нибудь однажды снять с кнопки display:flex,
     и значок молча съедет вниз на величину межстрочного просвета, а искать это будут в отступах.
     flex:none — чтобы его не тянуло и не сжимало вместе с кнопкой. */
  #call-mobbar button svg{ width:22px; height:22px; display:block; margin:auto; flex:none }

  /* В шапке их больше нет — переехали. Правило страхует один кадр после поворота экрана. */
  #chathead .peer-head #head-call-btn,
  #chathead .peer-head #head-vcall-btn{ display:none }

  /* Поиск открыт — шапка отдаёт место полю ввода, пилюле тем более не время. */
  #chathead.searching ~ #call-mobbar{ display:none }

  /* Закреп: тот же ряд, тот же top, ТА ЖЕ высота — иначе они стоят рядом, но не вровень, и это
     видно сразу. Справа он укорачивается на ширину пилюли плюс такой же отступ, какой у него
     слева: зазор между ними получается тот же, что и от края экрана, а не случайное число. */
  body.callbar #pin-bar{ right:calc(var(--cb-w) + 18px); height:var(--cb-h) }

  /* Место под ряд освобождает лента: её отступ сверху задан в layout.css под голую шапку. */
  body.callbar #chathead:not(.searching) ~ #messages{ padding-top:calc(70px + var(--cb-h) + 10px) }

  /* Рамка потоньше: на телефоне те же 3px читаются толще — плотность точек выше, а сама карточка
     занимает почти весь экран, и толстая рамка превращается из подсказки в оправу. */
  #call-overlay{ --snake-w:2px }
}


/* ---------- Преемственность: экран звонка одет как мессенджер ----------
   Он поднимается сам, поверх всего, и оттого легко становится «другим приложением внутри
   приложения». Собираем его из того же, из чего собран чат: те же токены цвета, тот же блюр, тот
   же силуэт углов, тот же шрифт. Ничего своего у него нет и быть не должно. */
#call-overlay,#call-overlay *{ font-family:inherit }
#call-overlay .call-card,
#call-overlay .call-actions,
#call-overlay .call-local,
#call-overlay .call-btn,
#call-overlay .call-warn{ corner-shape:superellipse(2.6) }

/* Тень у пилюли и карточки мягче и без смещения вниз: смещённая тень зрительно удлиняет коробку
   книзу, и содержимое начинает казаться сдвинутым вверх — при том, что оно ровно посередине.
   Ровно на это и жаловались. */
/* ---------- Тень без смещения вниз ----------
   Последняя оставшаяся причина «значок выше середины», и единственная, которую нельзя было
   вычислить: она не в раскладке, а в глазу. Все прочие сняты — значок стоит абсолютно, со
   сдвигом на половину собственного размера, и геометрически он ровно посередине; сбить это нечем.
   А тень со смещением ВНИЗ пририсовывает коробке мягкий довесок снизу, глаз считает границей его,
   и содержимое, стоящее по центру настоящей коробки, читается как поднятое. Ровно на величину
   смещения.
   Смещение убрано в ноль у всех, у кого содержимое надо читать по центру: тень осталась мягким
   ореолом вокруг, а не подложкой снизу. Заодно она перестала спорить с соседями по ряду: у
   закрепа она такая же, и раньше два элемента рядом «стояли» на разной высоте. */
#call-overlay .call-card{ box-shadow:0 0 44px rgba(0,0,0,.24) }
@media(max-width:760px){
  #call-mobbar .cb-pill{ box-shadow:0 0 16px rgba(0,0,0,.08) }
  body.callbar #pin-bar{ box-shadow:0 0 16px rgba(0,0,0,.08) }
}

/* ---------- Значок близости ----------
   Живёт здесь, а не в components.css, по той же причине, что и всё остальное в этом файле: тот
   46 КБ и едет целиком за каждую правку. Лист звонков грузится последним, поэтому перебивает
   базу без !important.

   Было: широкая плашка «2/7» посреди круглых соседей. Знаменатель не нёс ничего — семь величина
   постоянная, её узнают один раз, — а место занимал. Стало: один знак в оболочке ровно такого же
   размера и формы, как кнопка «назад» слева.

   ЦВЕТ НЕСЁТ ТОТ ЖЕ СМЫСЛ, ЧТО ЦИФРА, и читается быстрее её: от холодного к тёплому, 1 синий —
   7 красный, через спектр. Цифра остаётся для точности, цвет — для взгляда мельком. Оба нужны:
   по одному цвету не назвать уровень, по одной цифре не увидеть его боковым зрением. */
#closeness-badge{
  width:54px; height:54px; padding:0; gap:0;
  display:flex; align-items:center; justify-content:center;
  border-radius:50%; corner-shape:superellipse(2.6);
  background:var(--panel); border:1px solid var(--border);
  backdrop-filter:blur(var(--blur)) saturate(1.4); -webkit-backdrop-filter:blur(var(--blur)) saturate(1.4);
  font-size:0;                       /* текст переезжает внутрь цветного кружка, см. ::before */
  overflow:hidden;
}
/* Точку-маркер, которая стояла перед числом, убираем: её роль забрал цвет самого кружка. */
#closeness-badge::before{ content:none }

/* Цветной кружок с цифрой. Делаем его ::after с содержимым из data-lvl, а не вторым элементом в
   разметке: chat.html — 60 КБ, и возить его ради вложенного кружка дороже, чем взять цифру из
   атрибута. */
#closeness-badge::after{
  content:attr(data-lvl);
  width:38px; height:38px; border-radius:50%; corner-shape:superellipse(2.6);
  display:flex; align-items:center; justify-content:center;
  font-size:16px; font-weight:800; line-height:1; color:#fff;
  background:var(--lvl-c, #4a72d0);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
}

/* Спектр близости. Тона подобраны так, чтобы белая цифра оставалась читаемой на каждом: у жёлтой
   середины взят более глубокий охряный, а не солнечный — на солнечном белое пропадает. */
#closeness-badge[data-lvl="1"]{ --lvl-c:#3f6fd8 }   /* холодный синий */
#closeness-badge[data-lvl="2"]{ --lvl-c:#2f8fbf }
#closeness-badge[data-lvl="3"]{ --lvl-c:#2f9e83 }
#closeness-badge[data-lvl="4"]{ --lvl-c:#6f9d33 }   /* середина: тепло пошло */
#closeness-badge[data-lvl="5"]{ --lvl-c:#c08a1e }
#closeness-badge[data-lvl="6"]{ --lvl-c:#d8642c }
#closeness-badge[data-lvl="7"]{ --lvl-c:#d23b3b }   /* тёплый красный */

@media(max-width:760px){
  #closeness-badge{ width:54px; height:54px }
  #closeness-badge::after{ width:38px; height:38px; font-size:16px }
}

/* ---------- Значки в кнопках: центровка, которую нечем сбить ----------
   Третий заход, и на этот раз не подпоркой, а снятием самой возможности перекоса. Все прежние
   способы — align-items, place-items, margin:auto, line-height — считают положение значка ОТ
   потока внутри кнопки, а значит зависят от него: от строчного просвета, от того, блок значок или
   буква, от того, не сняли ли с кнопки display:flex. Каждый раз это чинилось и каждый раз
   находилась ещё одна причина.
   Абсолютное положение с переносом на половину собственного размера от потока не зависит вовсе:
   значок ставится по середине кнопки арифметически, и сбить это нечем. */
#call-mobbar button,
.call-btn,
#head-call-btn,
#head-vcall-btn{ position:relative }
#call-mobbar button > svg,
.call-btn > svg,
#head-call-btn > svg,
#head-vcall-btn > svg{
  position:absolute; top:50%; left:50%;
  transform:translate(-50%,-50%);
  margin:0;
}

/* Дужка «моя близость выше взаимной». Заливка кружка — то, что в силе; дужка по краю оболочки —
   то, что поставил я. Две величины на одном знаке, но разными средствами: цифра и заливка
   отвечают на «сколько сейчас», дужка — на «а от меня сколько». Без неё пришлось бы открывать
   профиль, чтобы понять, кто из двоих ещё не подвинул ползунок. */
#closeness-badge[data-my="1"]{ --my-c:#3f6fd8 }
#closeness-badge[data-my="2"]{ --my-c:#2f8fbf }
#closeness-badge[data-my="3"]{ --my-c:#2f9e83 }
#closeness-badge[data-my="4"]{ --my-c:#6f9d33 }
#closeness-badge[data-my="5"]{ --my-c:#c08a1e }
#closeness-badge[data-my="6"]{ --my-c:#d8642c }
#closeness-badge[data-my="7"]{ --my-c:#d23b3b }
#closeness-badge.capped{ box-shadow:inset 0 0 0 2px var(--my-c, var(--accent)) }
