/* ── Рамка аватара (PRO-косметика) ───────────────────────────────────────────
   Оверлей поверх аватара. Разметку даёт avatar_frame_markup() (include/
   avatar_frames.php), файлы — assets/images/frames/pro/<slug>.webp.

   Как это работает:
     .ava-frame-wrap — система координат (position:relative). Оборачиваем ЛЮБОЙ
       аватар: <img>, div с инициалами, ссылку.
     .ava-frame      — сам оверлей. Тянется за края аватара на --af-inset,
       который у каждой рамки свой (посадка подобрана под геометрию аватара
       116px: фото 106px + бордюр 5px) и приходит инлайном.

   Тонкости, которые ломались:
     • pointer-events:none — иначе рамка перехватывает клик по аватару;
     • image-rendering:pixelated нельзя ставить всем: у пиксель-арта без него
       мыло, у градиентных рамок с ним — рваные края. Даём классом --pixel;
     • background-size:100% 100% (не cover): рамка уже квадратная, cover при
       нецелом масштабе сдвигает её на полпикселя относительно аватара. */

.ava-frame-wrap {
    position: relative;
    display: inline-flex;
    line-height: 0;
    flex: none;
}

.ava-frame {
    position: absolute;
    inset: calc(-1 * var(--af-inset, 0px));
    background: var(--af-url) center / 100% 100% no-repeat;
    pointer-events: none;
    z-index: 2;
}

.ava-frame--pixel { image-rendering: pixelated; }

/* Анимацию рамок глушим вместе со всей моторикой интерфейса: у части рамок
   пламя/искры мигают, и для prefers-reduced-motion это раздражитель. Статичный
   постер вместо анимации — та же картинка, только один кадр. */
@media (prefers-reduced-motion: reduce) {
    .ava-frame { background-image: var(--af-url-still, var(--af-url)); }
}

/* ── Галерея выбора рамок (модалка PRO) ─────────────────────────────────────
   Раскладка: чипы-категории + плотная сетка круглых превью БЕЗ карточек-боксов.
   Прошлый вариант (37 карточек с рамкой и подписью) давал длинный скролл и
   визуальный шум — здесь превью крупнее, а рамка читается сразу, потому что
   вокруг неё нет конкурирующих границ. Теги берём из реестра (они там были,
   но не использовались). */

.af-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 12px 0 4px;
}

.af-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 11px;
    border: 1px solid var(--c-slate-200);
    border-radius: var(--radius-pill, 999px);
    background: var(--surface-base);
    font: inherit;
    font-size: var(--fs-xs, 12px);
    font-weight: 600;
    color: var(--c-slate-600);
    cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}

.af-tag span {
    font-size: var(--fs-2xs, 11px);
    font-weight: 700;
    color: var(--c-slate-400);
}

.af-tag:hover { border-color: var(--c-slate-300); color: var(--c-slate-800); }

.af-tag.is-on {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--text-inverse);
}
.af-tag.is-on span { color: color-mix(in srgb, var(--text-inverse) 70%, transparent); }

.af-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    gap: 18px 10px;
    margin-top: 14px;
}

.af-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.af-cell[hidden] { display: none; }
.af-cell:active .af-cell__preview { transform: scale(.94); }

/* Превью: круг аватара + рамка поверх. Выделение выбранной — кольцом вокруг
   превью, а не рамкой ячейки: рамки сами по себе цветные, и вторая рамка
   вокруг них сливалась. */
.af-cell__preview {
    position: relative;
    width: 84px;
    height: 84px;
    flex: none;
    border-radius: var(--radius-full, 50%);
    transition: transform .12s, box-shadow .15s;
}

.af-cell:hover .af-cell__preview {
    box-shadow: 0 0 0 2px var(--c-slate-200);
}

.af-cell.is-active .af-cell__preview {
    box-shadow: 0 0 0 2px var(--color-primary);
}

.af-cell__ava {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border-radius: var(--radius-full, 50%);
    object-fit: cover;
}

.af-cell__frame {
    position: absolute;
    inset: calc(-1 * var(--af-inset-rel, 0px));
    background: var(--af-url) center / 100% 100% no-repeat;
    pointer-events: none;
}

.af-cell__label {
    font-size: var(--fs-xs, 12px);
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    color: var(--c-slate-500);
    overflow-wrap: anywhere;
}

.af-cell.is-active .af-cell__label { color: var(--color-primary); }

/* «Без рамки» — та же ячейка, но с перечёркнутым кругом вместо превью. */
.af-cell--none .af-cell__preview {
    display: grid;
    place-items: center;
    background: var(--c-slate-100);
}
.af-cell--none i { font-size: 22px; color: var(--c-slate-400); }

@media (max-width: 480px) {
    .af-grid { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 14px 8px; }
    .af-cell__preview { width: 72px; height: 72px; }
}

/* Мини-превью выбранной рамки в свёрнутой строке модалки PRO. Показывает
   статичный постер: в строке-аккордеоне анимация только отвлекает. */
.afs-mini {
    position: relative;
    width: 30px;
    height: 30px;
    flex: none;
    margin-left: auto;
    margin-right: 8px;
}

.afs-mini__ava {
    position: absolute;
    inset: 2px;
    width: calc(100% - 4px);
    height: calc(100% - 4px);
    border-radius: var(--radius-full, 50%);
    object-fit: cover;
}

/* --af-inset-rel считает PHP через avatar_frame_inset(inset, 30, 2) — это уже
   выступ за ВЕСЬ контейнер 30px с учётом каймы 2px, поэтому смещать ещё и на
   эти 2px нельзя: рамка выходила на 13% у́же и врезалась в аватар. */
.afs-mini__frame {
    position: absolute;
    inset: calc(-1 * var(--af-inset-rel, 0px));
    background: var(--af-url) center / 100% 100% no-repeat;
    pointer-events: none;
}
.afs-mini__frame[hidden] { display: none; }

/* Discovery, карточка автора: .disc-acard__ava наезжает на обложку отрицательным
   margin и режет содержимое (overflow:hidden), поэтому рамку кладём в обёртку
   снаружи, а отрицательный отступ переносим на неё — иначе аватар съезжает. */
.disc-acard__ava-holder {
    position: relative;
    display: inline-flex;
    z-index: 1;
    margin-top: -38px;
    margin-bottom: 8px;
}
.disc-acard__ava-holder .disc-acard__ava {
    margin-top: 0;
    margin-bottom: 0;
}

/* Комментарии: раньше .user-avatar был квадратом со скруглением 6px, и круглую
   рамку приходилось «дожимать» здесь — только для .ava-frame-wrap. С редизайна
   2026-08-02 аватар комментария круглый по умолчанию (comments.css), поэтому
   оверрайд снят: посадка рамки и снятие overflow/кольца живут теперь в самом
   компоненте (.user-avatar.ava-frame-wrap там же). */

/* Мелкие аватары в лентах Discovery (20px): рамка нужна и там, но у неё свой
   holder — .disc-feed__ava/.disc-pcard__ava имеют overflow:hidden и срезали бы
   оверлей внутри себя. */
.disc-ava-holder {
    position: relative;
    display: inline-flex;
    flex: none;
}

/* Рекомендации авторов («Авторы для вас» / «Похожие авторы»): .cr-rec-avatar
   устроен как карточка автора в Discovery — overflow:hidden + отрицательный
   margin-top, наезжающий на обложку. Рамку кладём в обёртку снаружи и переносим
   на неё отступ, иначе аватар съедет вниз.

   ⚠️ Наезд считается ИЗ --cr-ava-size (объявлена на .cr-rec-card в
   recommendations.css), а не числом. С захардкоженными -38px мобильный
   брейкпоинт компонента (аватар 64px) сюда не доезжал: холдер продолжал тянуть
   половину десктопных 76px, и аватар вставал на 6px выше края обложки. */
.cr-rec-holder {
    position: relative;
    display: inline-flex;
    z-index: 1;
    margin-top: calc(-1 * var(--cr-ava-size, 76px) / 2);
    margin-bottom: 10px;
}
.cr-rec-holder .cr-rec-avatar {
    margin-top: 0;
    margin-bottom: 0;
}

/* /creators, hero «автор недели»: .ex-hero__ava — 90px с БЕЛОЙ каймой 4px,
   наезжает на обложку (margin-top:-45px) и режет содержимое (overflow:hidden).
   Тот же приём, что у .disc-acard__ava-holder: рамка снаружи, наезд переносим
   на обёртку. ⚠️ Кайма 4px обязана уйти третьим аргументом в
   user_avatar_frame_markup($uid, 90, 4) — inset считается от ФОТО (90−2×4=82),
   иначе кольцо врежется в аватар (см. avatar_frame_inset). */
.ex-hero__ava-holder {
    position: relative;
    display: inline-flex;
    align-self: flex-start;   /* .ex-hero__body — column-flex: без этого обёртка растянется на всю ширину */
    margin-top: -45px;
}
.ex-hero__ava-holder .ex-hero__ava { margin-top: 0; }

/* /creators, строка рейтинга: .ex-rank__ava — скруглённый КВАДРАТ 42px, и круглая
   рамка на нём читается инородно. Скругляем в круг ТОЛЬКО когда рамка есть
   (.ava-frame-wrap сервер ставит лишь PRO с выбранной рамкой) — у остальных вид
   рейтинга не меняется. Тот же приём, что раньше применялся к .user-avatar
   в комментариях (там аватар стал круглым по умолчанию, см. выше). */
.ex-rank__ava-holder {
    position: relative;
    display: inline-flex;
    flex: none;
}
.ex-rank__ava-holder.ava-frame-wrap .ex-rank__ava,
.ex-rank__ava-holder.ava-frame-wrap .ex-rank__ava img {
    border-radius: var(--radius-full, 50%);
}

/* /subscriptions: .subs-avatar — это сам <img> 44px (без спана-обёртки), поэтому
   холдер оборачивает картинку. flex:none — строка .subs-link флексовая. */
.subs-ava-holder {
    position: relative;
    display: inline-flex;
    flex: none;
    line-height: 0;
}

/* Шапка: .header-avatar сам по себе кнопка 36px с position:relative, поэтому
   класс обёртки вешается прямо на неё. Обёртка нужна ВСЕГДА (даже без рамки):
   по ней live-обновление из модалки PRO находит контейнер, иначе выбранная
   рамка появлялась в шапке только после перезагрузки. */
.header-avatar.ava-frame-wrap {
    display: inline-flex;
    line-height: 0;
}

/* Профиль: белая кайма-«вырубка» (.prx-ava border 5px) нужна, чтобы аватар не
   слипался с обложкой, на которую наезжает. Но когда рамка выбрана, кайму всё
   равно не видно — рамка перекрывает кольцо, — а место она занимает: фото
   сжимается со 116 до 106px, и рамка выходит мельче.

   Поэтому кайму гасим ТОЛЬКО при наличии рамки (:has). У всех остальных
   профилей дизайн не меняется. Побочный эффект ровно тот, что нужен: фото
   становится 116px, и рамка пропорционально крупнее. */
.prx-ava-holder:has(> .ava-frame) .prx-ava {
    border-width: 0;
}

/* ── Чат ────────────────────────────────────────────────────────────
   Три точки: список диалогов (.q3f9-avawrap — обёртка уже была, под
   статус-точку), шапка треда (.q3f9-threadavawrap — добавлена) и список
   подписок (обёртка добавляется сервером только когда рамка есть).

   Во всех случаях рамка лежит РЯДОМ с .q3f9-avatar, а не внутри: у аватара
   overflow:hidden для кадрирования фото, и рамка, которая по геометрии шире
   круга, обрезалась бы по нему. */
.q3f9-threadavawrap {
    position: relative;
    width: 40px;
    height: 40px;
    flex: none;
}

/* ⚠️ .q3f9-threadhead--small > div задаёт overflow:hidden всем прямым потомкам
   шапки (обрезка длинных имён). Раньше под него попадал сам .q3f9-avatar,
   которому обрезка и нужна; теперь прямой потомок — обёртка, и она срезала
   рамку в квадрат. Селектор с ДВУМЯ классами (0,2,0) обязателен: одиночный
   .q3f9-threadavawrap (0,1,0) проигрывает `--small > div` (0,1,1).
   Клиппера здесь было ДВА: сама .q3f9-threadhead--small тоже несла
   overflow:hidden и резала рамку уже снаружи обёртки — снято в style.css,
   см. комментарий у правила. */
.q3f9-threadhead--small > .q3f9-threadavawrap {
    overflow: visible;
}

/* Точка «онлайн» рисуется в правом нижнем углу — там же, куда выступает рамка.
   У .ava-frame z-index:2, у точки его не было вовсе, поэтому рамка её
   перекрывала. Поднимаем точку над рамкой: статус важнее косметики. */
.q3f9-avawrap .q3f9-statusdot {
    z-index: 3;
}

/* Обёртка становится прямым flex-элементом строки ВМЕСТО аватара, а вся защита
   от сжатия висела на самом аватаре (`.q3f9-avatar {flex: 0 0 40px}`). У обёртки
   её нет, и в строке подписок — где сосед .q3f9-newchat-info взял `flex:1` без
   `min-width:0` — длинный НЕРАЗРЫВНЫЙ ник сжимал обёртку до нуля: аватар с
   рамкой пропадал целиком. В списке диалогов не воспроизводилось только потому,
   что там у соседа .q3f9-chatmeta `min-width:0` есть.
   Два класса обязательны: avatar_frame.css грузится РАНЬШЕ style.css, и при
   равной специфичности одиночный .q3f9-avawrap проиграл бы. */
.q3f9-chatitem > .q3f9-avawrap,
.q3f9-newchat-item > .q3f9-avawrap {
    flex: none;
}

/* ── Подсказки поиска (шапка и каталог) ─────────────────────────────
   Обёртка встаёт прямым flex-элементом строки .suggestion-product-item
   ВМЕСТО <img>. У самой картинки flex-shrink не задан (по умолчанию 1), но
   её держали width/height как замещаемого элемента; у пустой обёртки такой
   опоры нет — без flex:none длинное имя автора сожмёт её вместе с рамкой.
   Тот же класс ошибки, что ловили в списке подписок чата. */
.suggestion-ava-holder {
    position: relative;
    display: inline-flex;
    flex: none;
    width: 40px;
    height: 40px;
}
