/* ── ПЛЕЕР И МЕДИА В ЛЕНТЕ ПЕРЕПИСКИ (этап В) ─────────────────────────────────────────────────
   Пара к media-player.js: разметку строит он, правила — здесь. Компонент ОБЩИЙ, поэтому под
   #tab-clients НЕ заскоуплен: его возьмут ленты заявок и поручений, у которых своих id нет.

   ⚠️ БЕЗ ЗАСКОУПЛЕННОСТИ ПОРЯДОК ПОДКЛЮЧЕНИЯ СТАНОВИТСЯ ЗНАЧИМЫМ. У правил раздела впереди id
      (#tab-clients .tg-files), у наших — только классы; при споре выигрывает раздел, как бы ни
      стоял файл. Поэтому спорных правил здесь нет вовсе: всё, что обязано победить оформление
      пузыря (медиа без подложки), живёт в crm-panel.css рядом с самим пузырём.

   ⚠️ МОДИФИКАТОРЫ — НИЖЕ БАЗОВЫХ ПРАВИЛ. При равной специфичности побеждает нижнее; правило
      проекта, заработанное дважды за один заход (.zay-tab--err, .zay-ac--up). */

/* ── ПЛЕЕР: кнопка, дорожка, время, скорость. Один вид на голосовое и на присланный mp3 ── */
.tg-pl { display: flex; align-items: center; gap: 9px; min-width: 232px; max-width: 100%; margin-top: 6px; }
.tg-pl audio { display: none; }
.tg-pl__btn { flex: none; width: 34px; height: 34px; border-radius: 50%; border: 0; padding: 0;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
    background: var(--primary); color: #fff; }
.tg-pl__btn svg { width: 14px; height: 14px; }
.tg-pl__mid { display: block; flex: 1 1 auto; min-width: 0; }
/* Имя присланного файла: обрезаем многоточием — в пузыре шириной 240px оно не помещается никогда. */
.tg-pl__name { display: block; font-size: 12px; color: var(--muted); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; margin-bottom: 2px; }
/* ⚠️ ДОРОЖКА — КНОПКА ПО СМЫСЛУ: по ней перематывают касанием, и она обязана быть <button>, а не
   раскрашенным div. Полоса высотой 4px, а область нажатия 14px: пальцем в четыре пикселя не
   попасть, и «перемотка не работает» означало бы ровно это. */
.tg-pl__bar { display: block; position: relative; height: 14px; cursor: pointer;
    border: 0; padding: 0; background: none; width: 100%; }
.tg-pl__bar::before { content: ''; position: absolute; left: 0; right: 0; top: 5px;
    height: 4px; border-radius: 2px; background: rgba(79, 70, 229, .22); }
.tg-pl__fill { position: absolute; left: 0; top: 5px; height: 4px; width: 0;
    border-radius: 2px; background: var(--primary); }
.tg-pl__t { display: flex; justify-content: space-between; gap: 8px; font-size: 11px;
    color: var(--muted); }
/* ⚠️ РАДИУС — ТОКЕН, А НЕ «ПОЛОВИНА ВЫСОТЫ». Соблазн написать 11px (капсула на высоте 22px) велик,
   и разницы на глаз почти нет — но это кнопка с текстом, а у таких радиус в проекте один на всех
   (--btn-radius), и своё число здесь означало бы ещё одно исключение в radius-check без нужды. */
.tg-pl__rate { flex: none; min-width: 34px; height: 22px; border-radius: var(--btn-radius, 10px);
    border: 1px solid var(--border); background: transparent; color: var(--muted); font-size: 11px;
    cursor: pointer; }

/* ── ВИДЕО: превью, длительность в углу, кнопка поверх ── */
/* ⚠️ text-decoration И color СНИМАЕМ ЯВНО, И ЭТО ПОЙМАНО НА ЖИВОЙ ЛЕНТЕ. Плитка — это <a href> (без
   href она не открывалась бы в новой вкладке по Ctrl-клику и не читалась бы как ссылка), а у <a>
   браузерный ПО УМОЛЧАНИЮ рисует синее подчёркивание. Подчёркивание ставит ПРЕДОК, поэтому у самой
   подписи text-decoration-line вычисляется как none — и на глаз она всё равно подчёркнута: замерено,
   getComputedStyle подписи говорит «none», а на экране линия есть. Имя файла под превью читалось
   отдельной ссылкой. У .tg-file это снято с первого дня (crm-panel.css), у новых плиток — здесь. */
.tg-vid, .tg-doc-img { text-decoration: none; color: inherit; }
/* ⚠️ ПОТОЛОК ВЫСОТЫ — ЭТО ПРО ЛЕНТУ, А НЕ ПРО КРАСОТУ. Вертикальное видео (замерено на живом экране:
   406×720 → плитка 240×426) ВЫШЕ видимой ленты карточки (340px): одно сообщение занимает экран
   целиком, и соседних не видно вовсе. Потолок 300px оставляет над и под ним по краю соседнего
   пузыря — то есть лента продолжает читаться лентой.
   ⚠️ ОБРЕЗАЕМ ПО ЦЕНТРУ (object-fit: cover), А НЕ СЖИМАЕМ. contain вписал бы кадр целиком, добавив
   чёрные поля сверху и снизу, — плитка стала бы шире кадра и читалась как ошибка вёрстки. Обрезка
   честнее: превью и не обещает показать весь кадр, для этого есть модалка.
   ⚠️ В МОДАЛКЕ ПОТОЛКА НЕТ. Там у видео свой класс (.attm__video, 88vh) — человек открыл кадр
   именно затем, чтобы увидеть его целиком. */
/* ⚠️ min-height — ПРОТИВ СХЛОПЫВАНИЯ, И ТОЛЬКО. Высота картинки не задана (height: auto), до её
   загрузки коробка нулевая: плитка исчезает, кнопка «играть» висит в пустоте, а лента дёргается,
   когда кадр наконец приезжает. Размеров видео в базе НЕТ (width/height пусты у всех 27 строк —
   их пишут только фотографиям), поэтому задать точные width/height тегу нечем; минимальная высота
   решает то же и ничего не обещает о пропорциях.
   ⚠️ ЛЕНИВУЮ ЗАГРУЗКУ ЭТО НЕ ЧИНИТ, И Я ПРОВЕРЯЛ ИМЕННО ЭТО. Первая догадка была, что превью не
   грузится из-за нулевой коробки; замер её опроверг — с высотой 96 и картинкой В КАДРЕ запроса
   по-прежнему не было. Лечится снятием loading="lazy" (довод и замер — в media-player.js,
   videoHtml), а высота остаётся здесь по своей причине.
   ⚠️ ФОН — ЗДЕСЬ, А НЕ ТОЛЬКО У --noshot. Он нужен обеим: плитке без превью навсегда и плитке с
   превью на время загрузки. Два одинаковых объявления в двух правилах разошлись бы на первой правке. */
.tg-vid { display: block; position: relative; margin-top: 6px; border-radius: 10px;
    overflow: hidden; max-width: 240px; max-height: 300px; min-height: 96px;
    background: rgba(17, 24, 39, .14); cursor: pointer; }
/* ⚠️ ВЫСОТА И У САМОЙ КАРТИНКИ: до загрузки <img> сам по себе нулевой, и потолок/обрезка ему
   нечего обрезать. Довод тот же, что у коробки выше, — про схлопывание, не про загрузку. */
.tg-vid img { display: block; width: 100%; height: auto; min-height: 96px; max-height: 300px;
    object-fit: cover; }
.tg-vid__play { display: flex; position: absolute; inset: 0; align-items: center;
    justify-content: center; }
.tg-vid__play span { width: 44px; height: 44px; border-radius: 50%;
    background: rgba(17, 24, 39, .55); display: flex; align-items: center; justify-content: center;
    color: #fff; }
.tg-vid__len { display: block; position: absolute; right: 6px; bottom: 6px;
    padding: 1px 6px; border-radius: 999px; background: rgba(17, 24, 39, .6); color: #fff;
    font-size: 11px; }
/* ⚠️ ПРЕВЬЮ МОЖЕТ НЕ БЫТЬ, И ТОГДА ПЛИТКА ОБЯЗАНА ОСТАТЬСЯ ПЛИТКОЙ. Тег <img> строится только
   когда миниатюра есть на диске (гейт на отсутствующую теперь честно отказывает), а без него у
   блока нет ни одного ребёнка с размером — он схлопнулся бы в ноль, и кнопка «играть» повисла бы
   в пустоте. Подложка задаёт минимальный кадр. */
.tg-vid--noshot { width: 160px; height: 96px; }
/* Кружок — тот же блок круглой формы: видеосообщение читается формой, а не подписью. */
.tg-vid--note { width: 160px; height: 160px; border-radius: 50%; max-width: 160px; }
.tg-vid--note img { height: 100%; object-fit: cover; }
.tg-vid--note .tg-vid__len { right: 50%; transform: translateX(50%); }

/* ── КАРТИНКА, ПРИСЛАННАЯ ДОКУМЕНТОМ: миниатюра вместо строки с именем ──
   ⚠️ ПРОПОРЦИИ СНИМКА, А НЕ КВАДРАТ. Это фотография, которую прислали файлом, и обрезать её до
      квадрата значит показать не то, что отправили; ограничиваем ширину, высота идёт сама. */
.tg-doc-img { display: block; max-width: 200px; margin-top: 6px; cursor: pointer; }
/* ⚠️ ТА ЖЕ МИНИМАЛЬНАЯ ВЫСОТА, И ПО ТОЙ ЖЕ ПРИЧИНЕ. Круг «нулевая коробка → lazy не грузит →
   коробка остаётся нулевой» не про видео, а про любую картинку с height: auto внутри прокрутки;
   у картинок-документов он просто не выстрелил на том экране, где я смотрел. Чинить одну из двух
   значило бы ждать, пока вторая выстрелит у человека. */
.tg-doc-img img { display: block; width: 100%; height: auto; min-height: 60px;
    background: rgba(17, 24, 39, .08); border-radius: 10px; }
/* Подпись — имя файла, обрезанное многоточием ПО ШИРИНЕ ПРЕВЬЮ (оно и задаёт ширину блока). */
.tg-doc-img__cap { display: block; font-size: 11px; color: var(--muted); margin-top: 3px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── СВОЙ ПУЗЫРЬ: на акцентном фоне серое не читается ──
   Ниже базовых правил намеренно: при равной специфичности побеждает нижнее. */
.tc-bubble--own .tg-pl__btn { background: rgba(255, 255, 255, .92); color: var(--primary-ink, var(--primary)); }
.tc-bubble--own .tg-pl__bar::before { background: rgba(255, 255, 255, .3); }
.tc-bubble--own .tg-pl__fill { background: var(--card, #fff); }
.tc-bubble--own .tg-pl__t,
.tc-bubble--own .tg-pl__name,
.tc-bubble--own .tg-doc-img__cap { color: rgba(255, 255, 255, .85); }
.tc-bubble--own .tg-pl__rate { border-color: rgba(255, 255, 255, .45);
    color: rgba(255, 255, 255, .92); }

/* ── «НЕ ИГРАЕТ В ЭТОМ БРАУЗЕРЕ» — ОДНА СТРОКА ──
   ⚠️ ЗАРАБОТАНО МАКЕТОМ: прежняя редакция писала причину, имя файла и слово «скачать» сплошным
      текстом, и в пузыре шириной 240px это разваливалось на ТРИ строки с висящим «голосовое».
      Причина не переносится (nowrap снят только с неё — на 375px ей разрешено уехать на вторую
      строку целиком), кнопка не сжимается. */
.tg-file--dead { align-items: center; gap: 6px; flex-wrap: wrap; }
.tg-file--dead .tg-file__why { flex: 1 1 auto; min-width: 0; }
.tg-file--dead .tg-file__get { flex: none; text-decoration: none; }
