:root {
    --bg: #121212; --surface: #1E1E1E; --border: #2A2A2A;
    --pixiv-blue: #0096FA; --text: #FFFFFF; --subtext: #A0A0A0;
    --red: #FF453A; --green: #66BB6A; --purple: #d324ff;
    --sat: 0px;
}

/* --- СВЕТЛАЯ И СУПЕР-ТЕМНАЯ ТЕМЫ (Привязываем и к html, и к body) --- */
html.theme-oled, body.theme-oled {
    --bg: #000000; 
    --surface: #0A0A0A; 
    --border: #1A1A1A;
}

html.theme-light, body.theme-light {
    --bg: #F5F5F5; 
    --surface: #FFFFFF; 
    --border: #E0E0E0;
    --text: #121212; 
    --subtext: #757575;
}

/* Фиксы полупрозрачных элементов для светлой темы */
body.theme-light .search-bar-container { background: rgba(255, 255, 255, 0.85); }
body.theme-light .search-suggestions { box-shadow: 0 12px 30px rgba(0,0,0,0.15); border: 1px solid var(--border); }
body.theme-light .suggestion-item { border-bottom: 1px solid rgba(0,0,0,0.05); }
body.theme-light .show-all-overlay { background: linear-gradient(transparent, rgba(255,255,255,0.9)); }

* { box-sizing: border-box; margin: 0; padding: 0; font-family: sans-serif; -webkit-tap-highlight-color: transparent; }

/* #3 Полностью убираем скроллбары во всём приложении (мобильный клиент — скролл жестом).
   Работает и в WebKit (Android WebView), и через scrollbar-width (Firefox/движки погрубее). */
* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; }

/* #3 Video без «браузерного плейсхолдера»: прозрачный фон вместо чёрного бокса до загрузки,
   ровное вписывание кадра и никакого случайного выделения/подсветки тапа. */
video { background: transparent; -webkit-tap-highlight-color: transparent; }
video::-webkit-media-controls-overlay-play-button { display: none; }
video::-webkit-media-controls-start-playback-button { display: none; }

/* Жестко фиксируем фоны и растягиваем на весь экран */
/* Жестко фиксируем фоны и растягиваем на весь экран */
html {
    background: var(--bg);
    min-height: 100vh;
}

body { 
    background: var(--bg); 
    color: var(--text); 
    overflow-x: hidden; /* Прячем горизонтальный скролл ТОЛЬКО у body! */
    overscroll-behavior-y: none; 
    min-height: 100vh; 
    width: 100%;
}

/* --- Дальше идет твой код: ЭКРАН ЗАГРУЗКИ --- */

/* --- ЭКРАН ЗАГРУЗКИ --- */
#loader-wrapper {
    position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
    background: var(--bg); z-index: 9999;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    transition: opacity 0.5s ease, visibility 0.5s;
}
.loader-logo {
    color: var(--pixiv-blue); font-size: 32px; font-weight: 900; letter-spacing: -1px;
    animation: pulse 1.5s infinite;
}
.loader-logo span {
    font-size: 14px; color: var(--text); font-weight: normal; padding: 2px 6px; border-radius: 4px;
}
.loader-spinner {
    width: 30px; height: 30px; border: 3px solid rgba(0, 150, 250, 0.2);
    border-top-color: var(--pixiv-blue); border-radius: 50%;
    margin-top: 16px; animation: spin 1s linear infinite;
}
/* Подсказка на экране загрузки: случайная фишка приложения. Появляется мягким fade-in,
   чтобы не «прыгать» вместе с лого; на русском видна сразу, перевод — через t() в app.js. */
#loader-tip {
    margin-top: 22px; max-width: 86%; padding: 0 6px;
    font-size: 13px; line-height: 1.45; text-align: center;
    color: var(--subtext);
    opacity: 0; animation: loaderTipIn 0.6s ease 0.25s forwards;
}
@keyframes loaderTipIn { to { opacity: 1; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* --- ЭКРАН ВХОДА (когда нет ни одной сессии) --- */
#authGate {
    position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
    background: var(--bg); z-index: 9998;
    display: none; align-items: center; justify-content: center;
    padding: calc(24px + var(--sat)) 28px 40px;
    opacity: 0; transition: opacity 0.4s ease;
}
#authGate.visible { display: flex; opacity: 1; }
.auth-gate-inner { width: 100%; max-width: 320px; text-align: center; }
.auth-gate-logo {
    color: var(--pixiv-blue); font-size: 36px; font-weight: 900; letter-spacing: -1.5px; margin-bottom: 28px;
}
.auth-gate-logo span {
    font-size: 14px; color: var(--text); font-weight: 700; letter-spacing: 0;
    background: rgba(128,128,128,0.18); padding: 3px 8px; border-radius: 4px; margin-left: 4px;
}
.auth-gate-title { font-size: 18px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.auth-gate-text { font-size: 14px; line-height: 1.5; color: var(--subtext); margin-bottom: 28px; }
.auth-gate-btn {
    width: 100%; background: var(--pixiv-blue); color: #FFF; border: none;
    padding: 14px; border-radius: 4px; font-size: 15px; font-weight: 700; cursor: pointer;
}
.auth-gate-btn:active { opacity: 0.85; }

/* Сохранённые сессии из резервной копии (показываются, если копия найдена) */
.auth-gate-acc {
    display: flex; align-items: center; gap: 12px; text-align: left;
    padding: 10px 12px; margin-bottom: 8px; cursor: pointer;
    background: var(--surface); border: 1px solid var(--border); border-radius: 4px;
}
.auth-gate-acc:active { background: var(--bg); }
.auth-gate-acc img { width: 36px; height: 36px; border-radius: 4px; object-fit: cover; flex-shrink: 0; border: 1px solid var(--border); }
.auth-gate-acc-text { overflow: hidden; }
.auth-gate-acc-name { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.auth-gate-acc-id { font-size: 11px; font-family: monospace; color: var(--subtext); margin-top: 2px; }
.auth-gate-sep { font-size: 12px; color: var(--subtext); margin: 14px 0; }

/* Крестик очистки строки поиска — плавное сужение/расширение */
.search-clear-btn {
    display: flex; align-items: center; justify-content: center;
    color: var(--subtext); cursor: pointer; overflow: hidden;
    max-width: 0; padding: 8px 0; opacity: 0; transform: scale(0.6);
    transition: max-width 0.22s ease, padding 0.22s ease, opacity 0.18s ease, transform 0.18s ease;
}
.search-clear-btn.show { max-width: 38px; padding: 8px; opacity: 1; transform: scale(1); }
.search-clear-btn:active { opacity: 0.6; }

/* === КОЛЛЕКЦИИ: компактный поповер у иконки === */
.cpop-overlay {
    position: fixed; inset: 0; z-index: 10050;
    display: none; background: transparent;
}
.cpop-overlay.open { display: block; }
.cpop {
    position: fixed; z-index: 10051; width: 230px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.35); padding: 0; overflow: hidden;
    opacity: 0; transform: scale(0.92); transform-origin: top left; pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s cubic-bezier(0.2, 0.9, 0.25, 1);
}
.cpop.open { opacity: 1; transform: scale(1); pointer-events: auto; }
#collectionPopoverList { max-height: 260px; overflow-y: auto; }
.cpop-item {
    display: flex; align-items: center; gap: 10px; padding: 13px 16px;
    cursor: pointer; font-size: 14px; color: var(--text);
}
#collectionPopoverList .cpop-item + .cpop-item { border-top: 1px solid var(--border); }
.cpop-item:active { background: var(--bg); }
.cpop-item.checked { background: rgba(0, 150, 250, 0.18); }
.cpop-item.checked .cpop-name { color: var(--pixiv-blue); }
.cpop-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cpop-empty { text-align: center; color: var(--subtext); font-size: 13px; padding: 14px 8px; }
.cpop-create { color: var(--pixiv-blue); font-weight: 700; border-top: 1px solid var(--border); }
.cpop-plus { width: 18px; height: 18px; fill: currentColor; flex-shrink: 0; }
.cpop-create-row { display: flex; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--border); }
.cpop-input {
    flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border); color: var(--text);
    border-radius: 8px; padding: 9px 10px; font-size: 14px;
}
.cpop-go { color: var(--pixiv-blue); font-weight: 700; font-size: 14px; padding: 9px 10px; cursor: pointer; }
.cpop-go:active { opacity: 0.6; }

/* Активная иконка коллекции в детали (работа уже в какой-то коллекции) */
#detCollectionBtn.in-collection #detCollectionIcon { color: var(--pixiv-blue); }

/* Карточная сетка на странице «Коллекции» */
.col-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; padding: 12px; }
.col-card2 { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; cursor: pointer; transition: transform 0.15s, border-color 0.2s; }
.col-card2:active { transform: scale(0.97); border-color: var(--pixiv-blue); }
.col-card2-cover { width: 100%; aspect-ratio: 1 / 1; background: var(--bg); display: flex; align-items: center; justify-content: center; color: var(--subtext); overflow: hidden; }
.col-card2-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.col-card2-cover .col-cover-ph { width: 40px; height: 40px; opacity: 0.5; }
.col-card2-body { padding: 10px 12px 12px; }
.col-card2-name { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.col-card2-sub { font-size: 12px; color: var(--subtext); margin-top: 3px; }
.col-card2-del { position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; border-radius: 50%; background: rgba(0,0,0,0.5); color: #fff; display: flex; align-items: center; justify-content: center; }
.col-card2-del:active { background: var(--red); }

/* --- ИКОНКИ --- */
.icon, .icon-sm, .icon-xs { fill: currentColor; display: inline-block; vertical-align: middle; }
.icon { width: 24px; height: 24px; } .icon-sm { width: 18px; height: 18px; } .icon-xs { width: 14px; height: 14px; }

/* --- УТИЛИТЫ --- */
.section-title { font-size: 14px; font-weight: bold; color: var(--subtext); margin-bottom: 12px; margin-top: 16px; padding: 0 16px; }
.flat-card { background: var(--surface); padding: 16px; margin-bottom: 8px; }
.text-green { color: var(--green); font-size: 13px; font-weight: bold; }
.text-red { color: var(--red); font-size: 13px; font-weight: bold; }
.text-sub { color: var(--subtext); font-size: 13px; margin-top: 4px; line-height: 1.4; }
.font-bold { font-weight: bold; }
.disabled-section { opacity: 0.4; pointer-events: none; filter: grayscale(100%); }
.page { display: none; }
.page.active { display: block; }

/* --- КНОПКИ --- */
.btn-progress { position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center; }
.btn-progress-fill { position: absolute; top: 0; left: 0; bottom: 0; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 1; }
.btn-text { position: relative; z-index: 2; pointer-events: none; display: flex; align-items: center; justify-content: center; gap: 8px; }
.btn-main { width: 100%; background: var(--pixiv-blue); color: #FFF; border: none; padding: 14px; border-radius: 24px; font-size: 15px; font-weight: bold; cursor: pointer; margin-top: 12px; }
.btn-main:active { opacity: 0.8; }
.btn-main .btn-progress-fill { background: rgba(0, 0, 0, 0.25); }
.btn-secondary { width: 100%; background: transparent; color: var(--text); border: 1px solid var(--border); padding: 14px; border-radius: 4px; font-size: 15px; font-weight: bold; cursor: pointer; margin-top: 12px; position: relative; transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); }
.btn-secondary:active { background: var(--border); }
.btn-secondary .btn-progress-fill { background: rgba(255, 255, 255, 0.1); }
.action-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-top: 16px; }
.btn-outline { background: var(--bg); border: 0px solid var(--border); color: var(--text); padding: 10px 4px; border-radius: 6px; font-size: 9px; font-weight: bold; text-align: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 6px; }

/* --- ПОИСК И ФИЛЬТРЫ --- */
.search-input-row { display: flex; gap: 8px; align-items: center; width: 100%; }
.input-box { flex: 1; background: var(--bg); border: 1px solid var(--border); color: var(--text); padding: 12px 16px; border-radius: 24px; font-size: 15px; outline: none; }
.filter-container { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 4px; align-items: center; }
.filter-container::-webkit-scrollbar { display: none; }

/* Закреплённая (sticky) панель фильтров в разделе "Может понравиться".
   Прилипает под фиксированным заголовком при скролле ленты.
   Смещение top подбирается под высоту/положение заголовка в каждом режиме меню. */
#page-discovery #discoveryFilterBar {
    position: sticky;
    top: calc(56px + var(--sat, 0px));
    z-index: 90;
    background: var(--bg);
    box-shadow: 0 6px 8px -6px rgba(0, 0, 0, 0.35);
}
/* В floating-режимах заголовок-«островок» опущен на 16px, его нижний край ниже */
body.nav-floating #page-discovery #discoveryFilterBar {
    top: calc(72px + var(--sat, 0px));
}

.chip { padding: 6px 14px; border-radius: 20px; background: var(--bg); border: 1px solid var(--border); color: var(--subtext); font-size: 13px; font-weight: bold; cursor: pointer; white-space: nowrap; display: flex; align-items: center; gap: 6px; transition: 0.2s; }
.chip.active { background: rgba(0, 150, 250, 0.15); border-color: var(--pixiv-blue); color: var(--pixiv-blue); }
.chip.r18.active { background: rgba(255, 69, 58, 0.15); border-color: var(--red); color: var(--red); }
.chip.r18g.active { background: rgba(156, 39, 176, 0.15); border-color: #9C27B0; color: #9C27B0; }
.chip-divider { width: 1px; height: 16px; background: var(--border); margin: 0 4px; }
.expandable-panel { max-height: 0; overflow: hidden; opacity: 0; transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease, margin-top 0.3s ease; }
.expandable-panel.open { max-height: 900px; opacity: 1; margin-top: 8px; }
.expandable-panel-inner { padding-top: 12px; border-top: 1px solid var(--border); }

/* ===== Блок «Исключить теги» в панели фильтров (главная и поиск) ===== */
.exclude-block { margin-top: 4px; padding-top: 14px; border-top: 1px dashed var(--border); }
.exclude-head {
    display: flex; align-items: center; gap: 6px; margin-bottom: 10px;
    font-size: 13px; font-weight: 700; color: var(--text);
}
.exclude-head .icon-xs { width: 14px; height: 14px; color: var(--red); flex-shrink: 0; }
.exclude-head .exclude-hint { color: var(--subtext); font-weight: 500; font-size: 11px; }

.exclude-input-row {
    display: flex; align-items: center; gap: 6px; background: var(--bg);
    border: 1px solid var(--border); border-radius: 12px; padding: 4px 4px 4px 14px;
    transition: border-color 0.2s;
}
.exclude-input-row:focus-within { border-color: var(--pixiv-blue); }
.exclude-input {
    flex: 1; min-width: 0; background: transparent; border: none; outline: none;
    color: var(--text); font-size: 14px; padding: 9px 0;
}
.exclude-input::placeholder { color: var(--subtext); }
.exclude-add-btn {
    flex-shrink: 0; width: 34px; height: 34px; border-radius: 9px; border: none;
    background: var(--pixiv-blue); color: #fff; display: flex; align-items: center;
    justify-content: center; cursor: pointer; transition: transform 0.15s, opacity 0.2s; padding: 0;
}
.exclude-add-btn:active { transform: scale(0.9); opacity: 0.85; }

.exclude-autocomplete {
    display: none; background: var(--surface); border: 1px solid var(--border);
    border-radius: 12px; margin-top: 8px; max-height: 180px; overflow-y: auto;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}

.exclude-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.exclude-chips:empty { display: none; }
.exclude-chip {
    display: inline-flex; align-items: center; gap: 6px; padding: 5px 6px 5px 12px;
    max-width: 100%; background: var(--bg); border: 1px solid var(--border);
    border-radius: 20px; font-size: 12px; font-weight: 600; color: var(--text);
}
.exclude-chip .exclude-chip-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.exclude-chip .exclude-chip-x {
    flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--border); color: var(--subtext); cursor: pointer;
    transition: background 0.2s, color 0.2s;
}
.exclude-chip .exclude-chip-x:active { background: var(--red); color: #fff; }
.exclude-chip .exclude-chip-x svg { width: 9px; height: 9px; }

.exclude-apply-row { display: flex; justify-content: flex-end; margin-top: 16px; }
.exclude-apply-btn {
    border: none; background: var(--pixiv-blue); color: #fff; font-weight: 700;
    font-size: 14px; padding: 10px 28px; border-radius: 10px; cursor: pointer;
    transition: transform 0.15s, opacity 0.2s;
}
.exclude-apply-btn:active { transform: scale(0.97); opacity: 0.9; }

/* --- СЕТКА АРТОВ --- */
.search-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.search-item { 
    position: relative; cursor: pointer; 
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: shimmer-load 1.5s infinite linear;
    aspect-ratio: 1; overflow: hidden; 
}
.search-item:active { opacity: 0.8; }
.search-img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 0.4s ease; }
.search-img.loaded { opacity: 1; }
/* ВАЖНО: shimmer-load — бесконечная анимация фона-скелетона на КАЖДОЙ ячейке. Раньше она не
   останавливалась после загрузки картинки → десятки ячеек постоянно перерисовывали фон, и лента
   дрожала/лагала при скролле (+ мерцающие слои давали чёрные рамки). Как только картинка
   загрузилась — глушим анимацию и убираем фон-градиент (он всё равно скрыт под картинкой). */
.search-item:has(.search-img.loaded) { animation: none !important; background: var(--surface); }
@keyframes shimmer-load { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }

.grid-progress-bg { position: absolute; bottom: 0; left: 0; right: 0; height: 4px; background: rgba(0,0,0,0.5); z-index: 10; display: none; }
.grid-progress-fill { height: 100%; width: 0%; background: var(--pixiv-blue); transition: 0.3s; }
.badges-top { position: absolute; top: 6px; left: 6px; display: flex; flex-direction: column; gap: 4px; align-items: flex-start; z-index: 5; }
.badge { padding: 4px 6px; border-radius: 4px; font-size: 10px; font-weight: bold; color: #FFF; text-shadow: 1px 1px 2px rgba(0,0,0,0.8); }
.badge-r18 { background: rgba(255, 69, 58, 0.9); }
.badge-r18g { background: rgba(156, 39, 176, 0.9); } 
.badge-ai { background: rgba(200, 200, 200, 0.2); border: 1px solid rgba(255,255,255,0.4); }
.badge-pages { background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; gap: 2px; }

.quick-dl-btn { position: absolute; bottom: 6px; right: 6px; background: rgba(0,0,0,0.5); width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #FFF; z-index: 10; border: 1px solid rgba(255,255,255,0.1); }
.quick-dl-btn:active { background: var(--pixiv-blue); transform: scale(0.9); }
.quick-dl-btnPost { position: absolute; bottom: 6px; right: 6px; background: rgba(0,0,0,0.5); width: 28px; height: 28px; border-radius: 10%; display: flex; align-items: center; justify-content: center; color: #FFF; z-index: 10; border: 1px solid rgba(255,255,255,0.1); }
.quick-dl-btnPost:active { background: var(--pixiv-blue); transform: scale(0.9); }

.like-btn-grid { position: absolute; top: 6px; right: 6px; background: rgba(0,0,0,0.5); width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #FFF; z-index: 10; border: 1px solid rgba(255,255,255,0.1); transition: 0.2s; cursor: pointer; }
.like-btn-grid.liked { color: var(--red); }
.like-btn-grid:active { transform: scale(1.2); }

/* --- МИНИ-СЕТКА --- */
.mini-grid-container { display: flex; overflow-x: auto; gap: 2px; padding: 0 16px 16px 16px; scrollbar-width: none; }
.mini-grid-container::-webkit-scrollbar { display: none; }
.mini-item { width: 140px; flex-shrink: 0; aspect-ratio: 1; position: relative; overflow: hidden; border-radius: 0px; background: var(--border); cursor: pointer; }

/* --- ДЕТАЛИ ПОСТА --- */
.det-image-container { position: relative; margin-top: 0px; display: flex; flex-direction: column; background: #000; width: 100%; max-height: 70vh; overflow: hidden; justify-content: center; }
.det-image-container.expanded { max-height: none; display: block; }
.det-first-img { width: 100%; height: 100%; object-fit: contain; display: block; }
.det-img-list { display: none; flex-direction: column; gap: 4px; }
.det-img-list img { width: 100%; display: block; }
.det-image-container.expanded .det-first-img { display: none !important; }
.det-image-container.expanded .det-img-list { display: flex; }
.show-all-overlay { position: absolute; bottom: 0; left: 0; right: 0; height: 120px; background: linear-gradient(transparent, rgba(0,0,0,0.8)); display: flex; align-items: flex-end; justify-content: center; padding-bottom: 24px; cursor: pointer; }
.show-all-btn { background: #FFF; color: #000; padding: 10px 24px; border-radius: 24px; font-weight: bold; font-size: 14px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); pointer-events: none; }
.det-image-container.expanded .show-all-overlay { display: none; }
.det-action-bar { position: relative; display: flex; justify-content: space-between; padding: 12px 16px; align-items: center; border-bottom: 1px solid var(--border); }
.det-action-left { display: flex; align-items: center; gap: 16px; color: var(--subtext); }
/* touch-action:none + user-select:none — иначе долгое удержание кнопки скачивания
   запускает выделение соседнего текста и рвёт long-press (pointercancel). */
.det-like-btn { cursor: pointer; display: flex; align-items: center; transition: 0.2s;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.det-like-btn.liked { color: var(--red); }
.det-like-btn:active { transform: scale(1.2); }
.inline-progress-bg { position: absolute; bottom: 0px; left: 0; right: 0; height: 3px; background: transparent; z-index: 10; display: none; }
.inline-progress-fill { height: 100%; width: 0%; background: var(--pixiv-blue); transition: 0.3s; }
.det-stats { display: flex; gap: 16px; padding: 12px 16px 12px 16px; color: var(--subtext); font-size: 12px; border-bottom: 1px solid var(--border); }
.det-stats span { display: flex; align-items: center; gap: 4px; }
.tags-container { display: flex; flex-wrap: wrap; gap: 8px; padding: 16px; }
.tag-chip { color: var(--pixiv-blue); font-size: 14px; font-weight: bold; cursor: pointer; word-break: break-word; }

/* --- АВТОР И ПОДПИСКИ --- */
.author-card { display: flex; align-items: center; padding: 16px; gap: 12px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); margin-top: 16px; }
.author-card-avatar { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; background: var(--border); cursor: pointer; }
.author-card-info { flex: 1; overflow: hidden; cursor: pointer; }
.author-card-name { font-weight: bold; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
.author-card-btn { background: transparent; color: var(--pixiv-blue); border: 1px solid var(--pixiv-blue); padding: 6px 16px; border-radius: 16px; font-size: 13px; font-weight: bold; cursor: pointer; }

.follow-block { background: var(--surface); margin-bottom: 8px; padding-top: 16px; border-bottom: 1px solid var(--border); }
.follow-header { display: flex; align-items: center; justify-content: space-between; padding: 0 16px 12px 16px; }
.follow-author { display: flex; align-items: center; gap: 12px; cursor: pointer; flex: 1; overflow: hidden; }
.follow-avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; border: 1px solid var(--border); }
.follow-name { font-weight: bold; font-size: 15px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.follow-btn { background: rgba(0, 150, 250, 0.1); color: var(--pixiv-blue); border: 1px solid var(--pixiv-blue); padding: 6px 16px; border-radius: 16px; font-size: 13px; font-weight: bold; cursor: pointer; transition: 0.2s; }
.follow-btn.active { background: var(--bg); color: var(--subtext); border-color: var(--border); }
.follow-btn:active { transform: scale(0.95); }

/* === ПРОФИЛЬ АВТОРА (редизайн) === */
/* --- Карточка профиля: центрированный вертикальный лейаут.
   Всё складывается в колонку, поэтому помещается на любом, даже узком экране.
   Кнопки действий вынесены в отдельный ряд во всю ширину (раньше теснились
   рядом с именем и не влезали на маленьких экранах). --- */
.author-profile-header { background: var(--surface); display: flex; flex-direction: column; }
/* Вход/выход в профиль пользователя: раскрытие/схлопывание шапки ведёт JS (clip-path+opacity на
   #page-author). Вход: инфо (аватар/имя) слегка «подаётся» сверху; работы просто проступают —
   без вертикального сдвига, иначе фон грида «улетал» бы. */
/* Плавное появление всей страницы (замена снятому pop-in, без margin — чтобы не было отступа). */
#page-author.author-enter { animation: authorPageFade 0.3s ease both; }
@keyframes authorPageFade { from { opacity: 0; } to { opacity: 1; } }
#page-author.author-enter .author-info-container { animation: authorInfoEnter 0.44s cubic-bezier(0.34, 1.4, 0.5, 1) 0.1s both; }
#page-author.author-enter .author-section-head,
#page-author.author-enter #authorGrid { animation: authorContentEnter 0.42s ease 0.12s both; }
@keyframes authorInfoEnter {
  from { opacity: 0; transform: translateY(-16px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes authorContentEnter {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Выход — зеркало: инфо слегка уходит вверх, работы гаснут без сдвига. */
#page-author.author-exit .author-info-container { animation: authorInfoExit 0.28s cubic-bezier(0.4, 0, 0.2, 1) both; }
#page-author.author-exit .author-section-head,
#page-author.author-exit #authorGrid { animation: authorContentExit 0.28s ease both; }
@keyframes authorInfoExit {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(-16px) scale(0.96); }
}
@keyframes authorContentExit {
  from { opacity: 1; }
  to   { opacity: 0; }
}
.author-banner { width: 100%; height: calc(116px + var(--sat)); position: relative; overflow: hidden; background: var(--bg); }
.author-banner-img { width: 100%; height: 100%; position: absolute; inset: 0; object-fit: cover; filter: blur(6px) brightness(0.5) saturate(1.15); transform: scale(1.1); z-index: 1; }
.author-banner-gradient { position: absolute; inset: 0; z-index: 2;
    background: linear-gradient(to bottom, rgba(0,0,0,0.30) 0%, rgba(0,0,0,0) 45%, var(--surface) 100%); }

/* === Окрашивание страницы автора в основной цвет аватарки ===
   JS ставит --author-tint (rgb) на :root; здесь — оттенок шапки, баннера и акцентов. Без цвета
   переменная не задана → var(...) берёт нейтральный fallback, вид как раньше. Плавно через transition. */
.author-profile-header {
    background: linear-gradient(to bottom,
        color-mix(in srgb, var(--author-tint, var(--surface)) 38%, var(--surface)) 0%,
        var(--surface) 82%);
    transition: background 0.45s ease;
}
/* Баннер затемняется ИМЕННО основным цветом аватарки: поверх размытого аватара кладём тёмную
   версию цвета (микс с полупрозрачным чёрным), плотнее сверху, к низу — в цвет поверхности. */
.author-banner-gradient {
    background: linear-gradient(to bottom,
        color-mix(in srgb, var(--author-tint, black) 68%, rgba(0,0,0,0.62)) 0%,
        color-mix(in srgb, var(--author-tint, black) 48%, rgba(0,0,0,0.30)) 48%,
        var(--surface) 100%);
    transition: background 0.45s ease;
}
/* Кольцо вокруг аватара и акцент-полоса раздела — в цвет аватарки. */
.author-avatar-wrapper {
    border-color: color-mix(in srgb, var(--author-tint, var(--surface)) 70%, var(--surface));
    transition: border-color 0.45s ease;
}
.author-section-head .author-accent {
    background: var(--author-tint, var(--pixiv-blue));
    transition: background 0.45s ease;
}

.author-info-container { padding: 0 16px 18px; position: relative; z-index: 3;
    display: flex; flex-direction: column; align-items: center; text-align: center; }
.author-avatar-wrapper { width: 92px; height: 92px; border-radius: 50%; border: 3px solid var(--surface); background: var(--surface); margin-top: -48px; overflow: hidden; box-shadow: 0 8px 22px rgba(0,0,0,0.45); flex-shrink: 0; }
.author-avatar-wrapper img { width: 100%; height: 100%; object-fit: cover; }

.author-info-main { width: 100%; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 9px; margin-top: 11px; }
.author-name { font-size: 20px; font-weight: 800; color: var(--text); line-height: 1.25; letter-spacing: -0.3px; word-break: break-word; max-width: 100%; }
.author-name > div:first-child { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.author-id-chip { max-width: 100%; padding: 5px 12px; display: inline-flex; align-items: center; gap: 5px; background: rgba(128,128,128,0.15); border-radius: 16px; font-size: 12px; color: var(--subtext); cursor: pointer; transition: background 0.15s ease; }
.author-id-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.author-id-chip:active { background: rgba(128,128,128,0.28); }
.author-username-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; max-width: 100%; }
.author-username-chip { max-width: 100%; padding: 4px 12px; display: inline-flex;
  align-items: center; background: rgba(0,150,250,0.14); border-radius: 16px; font-size: 13px;
  font-weight: 600; color: var(--pixiv-blue); cursor: pointer; transition: background 0.15s ease; }
.author-username-chip:active { background: rgba(0,150,250,0.26); }
.author-username-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Кнопка «также» — раскрывашка доп. юзернеймов автора. */
.author-uname-more { flex-shrink: 0; display: inline-flex; align-items: center; gap: 3px;
  padding: 4px 9px; background: rgba(128,128,128,0.14); border: none; border-radius: 16px;
  font-size: 12px; font-weight: 600; color: var(--subtext); cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease; }
.author-uname-more:active { background: rgba(128,128,128,0.26); }
.author-uname-more.open { color: var(--pixiv-blue); background: rgba(0,150,250,0.14); }
.author-uname-chev { width: 12px; height: 12px; transition: transform 0.28s cubic-bezier(0.22,1,0.36,1); }
.author-uname-more.open .author-uname-chev { transform: rotate(180deg); }

/* Контейнер доп. алиасов — плавное раскрытие по высоте. */
.author-uname-extra { max-height: 0; overflow: hidden; display: flex; flex-wrap: wrap; gap: 6px;
  transition: max-height 0.3s cubic-bezier(0.22,1,0.36,1), opacity 0.25s ease, margin-top 0.3s ease;
  opacity: 0; margin-top: 0; }
.author-uname-extra.open { opacity: 1; margin-top: 2px; margin-bottom: 6px; }
.author-uname-alias { padding: 4px 11px; background: rgba(0,150,250,0.10); border: none; border-radius: 14px;
  font-size: 12.5px; font-weight: 600; color: var(--pixiv-blue); cursor: pointer;
  transition: background 0.15s ease, transform 0.12s ease; }
.author-uname-alias:active { background: rgba(0,150,250,0.24); transform: scale(0.96); }

/* Ряд кнопок действий — во всю ширину карточки, кнопки делят место поровну. */
.author-actions { display: flex; gap: 10px; width: 100%; margin-top: 15px; }
.author-actions:empty { display: none; }
.author-follow-btn { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 11px 16px; border-radius: 22px; font-size: 14px; font-weight: bold; cursor: pointer; border: none; background: var(--pixiv-blue); color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: transform 0.15s ease, opacity 0.15s ease, background 0.15s ease; }
.author-follow-btn .icon-xs { width: 15px; height: 15px; flex-shrink: 0; }
.author-follow-btn:active { transform: scale(0.97); opacity: 0.9; }
.author-follow-btn.active { background: transparent; color: var(--subtext); border: 1px solid var(--border); box-shadow: none; }
/* Кнопка «Написать» — вторичный стиль (нейтральная заливка). */
.author-msg-btn { background: rgba(128,128,128,0.16); color: var(--text); }
.author-msg-btn:active { background: rgba(128,128,128,0.28); }

.author-section-head { display: flex; align-items: center; gap: 10px; padding: 18px 20px 14px 20px; }
.author-section-head .author-accent { width: 4px; height: 16px; background: var(--pixiv-blue); border-radius: 2px; flex-shrink: 0; }
.author-tab-name { font-size: 15px; font-weight: bold; color: var(--text); }

/* --- МЕНЕДЖЕР ЗАГРУЗОК --- */
.manager-item { padding: 12px 16px; background: var(--surface); margin-bottom: 3px; border-radius: 5px; display: flex; gap: 12px; align-items: center; }
.manager-thumb { width: 48px; height: 48px; border-radius: 5px; object-fit: cover; background: var(--border); flex-shrink: 0; cursor: pointer; }
.manager-progress-track { background: var(--bg); height: 4px; border-radius: 2px; overflow: hidden; margin-top: 8px; }
.manager-progress-fill { background: var(--pixiv-blue); width: 0%; height: 100%; transition: 0.3s; }
.action-icon { padding: 8px; color: var(--subtext); cursor: pointer; border-radius: 4px; display: flex; transition: 0.2s; }
.action-icon:active { background: rgba(255,255,255,0.1); }
.action-icon.danger { color: var(--red); }
.action-icon.primary { color: var(--pixiv-blue); }

/* --- МОДАЛЬНЫЕ ОКНА И МЕНЮ --- */
.modal-overlay { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.6); z-index: 300; opacity: 0; pointer-events: none; transition: 0.3s; backdrop-filter: blur(1px); }
.modal-overlay.open { opacity: 1; pointer-events: auto; }
.custom-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); opacity: 0; pointer-events: none; z-index: 301; width: 85%; max-width: 320px; background: var(--surface); border-radius: 6px; padding: 20px; transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; gap: 8px; box-shadow: 0 10px 40px rgba(0,0,0,0.6); border: 0px solid var(--border); }
.custom-modal.open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
.modal-title { font-size: 18px; font-weight: bold; color: var(--text); }
.modal-text { font-size: 14px; color: var(--subtext); line-height: 1.4; margin-bottom: 8px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.btn-modal { padding: 10px 16px; border-radius: 5px; font-size: 14px; font-weight: bold; cursor: pointer; border: none; transition: 0.2s; outline: none; }
.btn-modal.cancel { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn-modal.cancel:active { background: var(--border); }
.btn-modal.danger { background: var(--red); color: #FFF; }
.btn-modal.danger:active { opacity: 0.8; }

/* === Универсальные модалки (appConfirm / appPrompt) — замена системным диалогам === */
.app-modal-overlay { position: fixed; inset: 0; z-index: 10500; display: flex; align-items: center;
  justify-content: center; padding: 24px; background: rgba(0,0,0,0.55); backdrop-filter: blur(2px);
  opacity: 0; transition: opacity 0.18s ease; }
.app-modal-overlay.open { opacity: 1; }
.app-modal { width: 100%; max-width: 320px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 16px; padding: 20px; box-shadow: 0 16px 48px rgba(0,0,0,0.5);
  display: flex; flex-direction: column; gap: 10px;
  transform: scale(0.92) translateY(8px); transition: transform 0.2s cubic-bezier(0.2, 1.1, 0.3, 1); }
.app-modal-overlay.open .app-modal { transform: scale(1) translateY(0); }
.app-modal-title { font-size: 17px; font-weight: 700; color: var(--text); }
.app-modal-text { font-size: 14px; color: var(--subtext); line-height: 1.45; }
.app-modal-input { width: 100%; box-sizing: border-box; margin-top: 2px; padding: 11px 14px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px; color: var(--text);
  font-size: 15px; outline: none; transition: border-color 0.15s ease; }
.app-modal-input:focus { border-color: var(--pixiv-blue); }
.app-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.app-modal-btn { padding: 10px 18px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer;
  border: none; outline: none; transition: transform 0.12s ease, opacity 0.12s ease; }
.app-modal-btn:active { transform: scale(0.96); }
.app-modal-btn.cancel { background: transparent; color: var(--text); border: 1px solid var(--border); }
.app-modal-btn.primary { background: var(--pixiv-blue); color: #fff; }
.app-modal-btn.danger { background: var(--red); color: #fff; }

/* === Редактор профиля (полноэкранный, карточный) === */
.profile-editor { position: fixed; inset: 0; z-index: 10000; background: var(--bg);
  display: flex; flex-direction: column;
  opacity: 0; transform: translateY(12px); transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.2,1,0.3,1); }
.profile-editor.open { opacity: 1; transform: translateY(0); }
.pe-header { display: flex; align-items: center; gap: 12px; flex-shrink: 0;
  padding: calc(12px + var(--sat, 0px)) 12px 12px; background: var(--surface);
  border-bottom: 1px solid var(--border); }
.pe-close { background: none; border: none; color: var(--text); padding: 6px; cursor: pointer; display: flex; }
.pe-close svg { width: 24px; height: 24px; }
.pe-title { flex: 1; font-size: 17px; font-weight: 700; color: var(--text); }
.pe-save { background: var(--pixiv-blue); border: none; color: #fff; padding: 9px 20px;
  border-radius: 20px; font-size: 14px; font-weight: 700; cursor: pointer; transition: transform 0.12s ease, opacity 0.12s ease; }
.pe-save:active { transform: scale(0.96); }
.pe-save:disabled { opacity: 0.6; }
.pe-scroll { flex: 1; min-height: 0; overflow-y: auto;
  padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px)); }

/* Герой: баннер + крупный аватар внахлёст */
.pe-hero { position: relative; display: flex; flex-direction: column; align-items: center;
  padding-bottom: 14px; margin-bottom: 8px; }
.pe-hero-banner { width: 100%; height: 120px; overflow: hidden; background: linear-gradient(135deg, var(--pixiv-blue), var(--purple, #7b3ff2)); }
.pe-hero-banner img { width: 100%; height: 100%; object-fit: cover; }
.pe-avatar { position: relative; width: 104px; height: 104px; margin-top: -52px; padding: 0;
  border-radius: 50%; overflow: hidden; border: 4px solid var(--bg); background: var(--surface);
  cursor: pointer; flex-shrink: 0; box-shadow: 0 6px 20px rgba(0,0,0,0.25); }
.pe-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pe-avatar-cam { position: absolute; inset: 0; display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 8px; background: linear-gradient(to top, rgba(0,0,0,0.5), rgba(0,0,0,0) 55%); }
.pe-avatar-cam svg { width: 22px; height: 22px; color: #fff; }
.pe-hero-hint { font-size: 12px; color: var(--subtext); margin-top: 10px; }

/* Карточки-секции */
.pe-card-title { font-size: 12px; font-weight: 600; color: var(--subtext); text-transform: uppercase;
  letter-spacing: 0.04em; padding: 8px 20px 6px; }
.pe-card { background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  margin: 0 12px 6px; overflow: hidden; }
.pe-field { padding: 12px 14px; }
.pe-divider { height: 1px; background: var(--border); margin: 0 14px; }
.pe-label { display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; font-weight: 600; color: var(--subtext); margin-bottom: 8px;
  text-transform: uppercase; letter-spacing: 0.02em; }
.pe-count { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--subtext); opacity: 0.7; }
.pe-input { width: 100%; box-sizing: border-box; background: var(--bg); border: 1px solid var(--border);
  border-radius: 10px; color: var(--text); padding: 11px 14px; font-size: 15px; outline: none;
  font-family: inherit; transition: border-color 0.15s ease; }
.pe-input:focus { border-color: var(--pixiv-blue); }
.pe-input::placeholder { color: var(--subtext); opacity: 0.6; }
.pe-textarea { resize: none; line-height: 1.4; min-height: 92px; }

/* Поле юзернейма с префиксом @ и галочкой валидности */
.pe-uname-bar { display: flex; align-items: center; gap: 2px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; padding: 0 12px; transition: border-color 0.15s ease; }
.pe-uname-bar:focus-within { border-color: var(--pixiv-blue); }
.pe-uname-bar.valid { border-color: var(--green, #66bb6a); }
.pe-uname-bar.invalid { border-color: var(--red); }
.pe-uname-at { color: var(--subtext); font-size: 16px; font-weight: 600; }
.pe-uname-input { flex: 1; background: none; border: none; padding: 11px 4px; }
.pe-uname-input:focus { border: none; }
.pe-uname-ok { width: 20px; height: 20px; color: var(--green, #66bb6a); flex-shrink: 0; }
.pe-uname-spin { width: 15px; height: 15px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--pixiv-blue); animation: at-spin 0.7s linear infinite; }
.pe-hint { font-size: 11px; color: var(--subtext); margin-top: 8px; line-height: 1.4; }
.pe-hint.error { color: var(--red); }

/* Список имён-алиасов + квота + кнопка добавления */
.pe-quota { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--subtext); opacity: 0.7; margin-left: 6px; }
.pe-uname-list { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 14px; }
.pe-uname-loading, .pe-uname-empty { font-size: 13px; color: var(--subtext); opacity: 0.8; }
.pe-uname-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 999px; padding: 6px 6px 6px 12px; font-size: 14px; color: var(--text); }
.pe-uname-chip span { font-weight: 600; }
.pe-uname-del { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border: none; border-radius: 50%; background: rgba(128,128,128,0.18); color: var(--subtext); cursor: pointer; padding: 0; }
.pe-uname-del:active { background: rgba(229,57,53,0.2); color: var(--red); }
.pe-uname-del svg { width: 13px; height: 13px; }
.pe-uname-add { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex-shrink: 0;
  border: none; border-radius: 8px; background: var(--pixiv-blue); color: #fff; cursor: pointer; padding: 0;
  transition: opacity 0.15s ease, transform 0.12s ease; }
.pe-uname-add:disabled { opacity: 0.4; cursor: default; }
.pe-uname-add:not(:disabled):active { transform: scale(0.9); }
.pe-uname-add svg { width: 18px; height: 18px; }

.search-suggestions { background: var(--bg); border-radius: 16px; margin-top: 12px; padding: 16px; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 12px 30px rgba(0,0,0,0.7); z-index: 90; }
.suggestions-header { display: flex; justify-content: space-between; font-size: 13px; color: var(--subtext); font-weight: bold; margin-bottom: 12px; }
.clear-history { color: var(--red); cursor: pointer; }
.suggestion-item { display: flex; align-items: center; justify-content: space-between; padding: 12px 8px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.05); }
.suggestion-item:last-child { border-bottom: none; }
.suggestion-text { color: var(--text); font-size: 15px; display: flex; align-items: center; gap: 12px; flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.suggestion-remove { color: var(--subtext); padding: 8px; margin: -8px; cursor: pointer; }
.suggestion-remove:active { color: var(--red); }

/* --- Выбор акцентного цвета (HSV-палитра: квадрат SV + полоса тона) --- */
.accent-picker { display: flex; flex-direction: column; gap: 10px; }
.accent-sv { position: relative; width: 100%; height: 130px; border-radius: 10px; overflow: hidden;
  background: linear-gradient(to right, #fff, var(--accent-hue, #f00));
  touch-action: none; cursor: crosshair; border: 1px solid var(--border); }
.accent-sv-white { position: absolute; inset: 0; background: linear-gradient(to right, #fff, transparent); }
.accent-sv-black { position: absolute; inset: 0; background: linear-gradient(to top, #000, transparent); }
.accent-sv-knob, .accent-hue-knob { position: absolute; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 1px 4px rgba(0,0,0,0.5);
  transform: translate(-50%, -50%); pointer-events: none; background: transparent; }
.accent-hue { position: relative; width: 100%; height: 18px; border-radius: 9px; touch-action: none; cursor: pointer;
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); }
.accent-hue-knob { top: 50%; width: 18px; height: 18px; }
.accent-foot { display: flex; align-items: center; gap: 10px; }
.accent-preview { width: 26px; height: 26px; border-radius: 7px; background: var(--pixiv-blue);
  border: 1px solid var(--border); flex-shrink: 0; }
.accent-hex { font-size: 13px; font-weight: 700; color: var(--text); font-family: monospace; text-transform: uppercase; }
.accent-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.accent-swatch { width: 26px; height: 26px; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; box-shadow: 0 0 0 1px var(--border); transition: transform 0.12s ease; }
.accent-swatch:active { transform: scale(0.9); }
.accent-swatch.active { border-color: var(--text); }

.theme-segmented { display: flex; background: var(--bg); border-radius: 8px; padding: 4px; margin-top: 12px; border: 1px solid var(--border); }
.theme-segment { flex: 1; text-align: center; padding: 10px 0; font-size: 13px; font-weight: bold; color: var(--subtext); border-radius: 6px; cursor: pointer; transition: color 0.25s ease; }
.theme-segment.active { color: var(--pixiv-blue); background: transparent; box-shadow: none; }
/* Скользящая подложка под активный сегмент */
.search-mode-slider {
    position: absolute; top: 2px; left: 2px; height: calc(100% - 4px); width: 0;
    background: var(--surface);
    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
    z-index: 0; pointer-events: none; border-radius: 18px;
    transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Переключатель Похожие/Комментарии — стиль вкладок-разделов, компактный слева */
.det-tabs {
    position: relative; display: flex; gap: 4px;
    padding: 4px 16px 0 16px; margin-top: 8px;
    border-bottom: 1px solid var(--border);
}
.det-tab {
    padding: 10px 14px; font-size: 14px; font-weight: bold;
    color: var(--subtext); cursor: pointer; white-space: nowrap;
    transition: color 0.25s ease;
}
.det-tab.active { color: var(--text); }
.det-tab-slider {
    position: absolute; bottom: 0; left: 16px; width: 0; height: 3px;
    background: var(--pixiv-blue); border-radius: 3px 3px 0 0;
    z-index: 1; pointer-events: none;
    transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Комментарии */
.det-comment-item { padding: 12px 0; border-bottom: 1px solid var(--border); }
.det-comment-item:last-child { border-bottom: none; }
.det-comment-head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.det-comment-name { font-size: 13px; font-weight: bold; color: var(--text); }
.det-comment-date { font-size: 11px; color: var(--subtext); margin-left: auto; }
.det-comment-text { font-size: 14px; color: var(--text); line-height: 1.5; word-break: break-word; }
.det-comment-stamp { max-height: 60px; margin-top: 4px; border-radius: 6px; }
.det-comment-replies { font-size: 12px; color: var(--pixiv-blue); margin-top: 6px; }

/* Поле отправки комментария — капсула с круглой кнопкой */
.comment-compose {
    display: flex; align-items: flex-end; gap: 8px;
    margin: 12px 16px 16px 16px; padding: 6px 6px 6px 14px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 24px; transition: border-color 0.2s ease;
}
.comment-compose:focus-within { border-color: var(--pixiv-blue); }
.comment-compose-input {
    flex: 1; border: none; background: transparent; color: var(--text);
    font-size: 14px; font-family: inherit; line-height: 1.4;
    resize: none; outline: none; padding: 8px 0; max-height: 120px;
}
.comment-compose-input::placeholder { color: var(--subtext); }
.comment-send-btn {
    flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%;
    border: none; background: var(--pixiv-blue); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: transform 0.15s ease, opacity 0.15s ease;
}
.comment-send-btn:active { transform: scale(0.9); }
.comment-send-btn svg { margin-left: -1px; }

.scroll-filler { position: absolute; top: 0; left: 0; bottom: 0; width: 0%; background: rgba(0, 150, 250, 0.3); border-radius: inherit; pointer-events: none; z-index: 0; }

/* --- АНИМАЦИИ --- */
@keyframes floatUpAndFade {
    0% { transform: translateY(110vh) translateX(var(--start-x)) rotate(var(--start-rot)) scale(var(--scale)); opacity: 0; }
    15% { opacity: var(--max-opacity); }
    85% { opacity: var(--max-opacity); }
    100% { transform: translateY(-30vh) translateX(var(--end-x)) rotate(var(--end-rot)) scale(var(--scale)); opacity: 0; }
}

.flying-art { position: absolute; bottom: 0; border-radius: 12px; object-fit: cover; box-shadow: 0 10px 40px rgba(0,0,0,0.8); animation: floatUpAndFade var(--duration) linear forwards; pointer-events: none; }

/* Компактный контейнер для облака тегов */
.compact-tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 8px; /* Расстояние между тегами */
    margin-top: 10px;
    margin-bottom: 20px;
}

/* Внешний вид самого тега (чипа) */
.compact-tag-chip {
    display: inline-block;
    background: var(--surface); /* Темный фон карточки */
    border: 1px solid var(--border);
    padding: 6px 12px;
    border-radius: 16px; /* Овальные края */
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s;
}

/* Специфичный стиль для трендов (синие) */
.compact-tag-chip.trending {
    color: var(--pixiv-blue);
    background: rgba(0, 150, 250, 0.08); /* Очень легкий синий оттенок фона */
    border-color: rgba(0, 150, 250, 0.2);
}

/* Специфичный стиль для истории (серые) */
.compact-tag-chip.history {
    color: var(--subtext);
}

.compact-tag-chip:active {
    opacity: 0.7;
}

/* Компактные элементы автозаполнения в выпадающем списке */
.autocomplete-compact-item {
    padding: 10px 12px;
    font-size: 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    cursor: pointer;
}
.autocomplete-compact-item:last-child {
    border-bottom: none;
}

/* --- Компактные чипы для тегов --- */
.compact-tags-container { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 20px; }
.compact-tag-chip {
    display: inline-block; padding: 6px 12px; border-radius: 16px;
    font-size: 13px; cursor: pointer; white-space: nowrap;
    background: var(--surface); border: 1px solid var(--border);
    transition: background 0.2s, color 0.2s;
}
.compact-tag-chip.trending { color: var(--pixiv-blue); background: rgba(0,150,250,0.08); border-color: rgba(0,150,250,0.2); }
.compact-tag-chip.history { color: var(--subtext); }
.compact-tag-chip:active { opacity: 0.7; }

/* --- Автозаполнение --- */
.autocomplete-compact-item { padding: 10px 12px; font-size: 14px; color: var(--text); border-bottom: 1px solid var(--border); cursor: pointer; }
.autocomplete-compact-item:last-child { border-bottom: none; }

/* =========================================================
   FULLSCREEN VIEWER
   ========================================================= */
.image-viewer {
    position: fixed;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: #000;
    z-index: 50000; /* Выше всего */
    display: none;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.2s ease;
}
.image-viewer.open {
    display: flex;
    opacity: 1;
}
.viewer-content {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
#viewerImg {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    will-change: transform;
    /* Добавь это: */
    user-select: none;
    -webkit-user-drag: none;
    touch-action: none; 
}
.viewer-header {
    position: absolute;
    top: calc(10px + var(--sat));
    right: 16px;
    z-index: 50001;
}
.viewer-close {
    width: 40px; height: 40px;
    background: rgba(0,0,0,0.5);
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff;
}

.badge-beta {
    display: inline-block;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.5px;
    color: #fff;
    background: var(--pixiv-blue);
    border-radius: 4px;
    padding: 1px 5px 2px;
    vertical-align: middle;
    line-height: 1;
    margin-left: 6px;
    user-select: none;
    pointer-events: none;
}

/* =========================================================
   МЕНЕДЖЕР ЗАГРУЗОК — PIXIV STYLE
   ========================================================= */
.dlm-hero {
    margin: 14px 16px 4px;
    padding: 16px;
    border-radius: 16px;
    background: var(--surface);
    border: 1px solid var(--border);
}
.dlm-hero-top { display: flex; align-items: center; gap: 12px; }
.dlm-hero-icon {
    width: 44px; height: 44px; border-radius: 12px; flex-shrink: 0;
    background: rgba(0,150,250,0.12); color: var(--pixiv-blue);
    display: flex; align-items: center; justify-content: center;
}
.dlm-hero-texts { flex: 1; min-width: 0; }
.dlm-hero-label { font-size: 11px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; color: var(--subtext); }
.dlm-hero-value { font-size: 26px; font-weight: 800; letter-spacing: -0.5px; color: var(--text); margin-top: 2px; }
.dlm-refresh {
    width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
    background: var(--bg); color: var(--pixiv-blue);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    transition: transform 0.35s cubic-bezier(0.25,0.8,0.25,1), background 0.2s;
}
.dlm-refresh:active { transform: rotate(180deg); background: rgba(0,150,250,0.15); }

.dlm-bar { height: 8px; border-radius: 4px; background: var(--bg); overflow: hidden; margin: 16px 0 12px; display: flex; }
.dlm-bar-seg { height: 100%; transition: width 0.6s cubic-bezier(0.2,0.8,0.2,1); }
.dlm-bar-seg.used { background: var(--pixiv-blue); }
.dlm-bar-seg.saved { background: var(--green); }

.dlm-hero-legend { display: flex; gap: 22px; flex-wrap: wrap; }
.dlm-leg { display: flex; align-items: center; gap: 7px; }
.dlm-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.dlm-dot.used { background: var(--pixiv-blue); }
.dlm-dot.saved { background: var(--green); }
.dlm-leg-cap { font-size: 12px; color: var(--subtext); }
.dlm-leg-val { font-size: 13px; font-weight: 700; color: var(--text); }
.dlm-hero-foot { margin-top: 10px; font-size: 11px; color: var(--subtext); }

.dlm-section-head { display: flex; align-items: center; gap: 8px; padding: 22px 16px 10px; }
.dlm-accent { width: 4px; height: 16px; background: var(--pixiv-blue); border-radius: 2px; flex-shrink: 0; }
.dlm-sec-title { font-size: 16px; font-weight: 800; letter-spacing: -0.3px; color: var(--text); }
.dlm-count { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--subtext); background: var(--surface); border: 1px solid var(--border); padding: 1px 10px; border-radius: 20px; min-width: 22px; text-align: center; }

.dlm-empty { color: var(--subtext); font-size: 13px; display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 28px 16px; grid-column: 1 / -1; }
.dlm-empty-icon { width: 34px; height: 34px; fill: currentColor; opacity: 0.4; }

#page-history .detail-header-title { margin-left: 12px; }
.dh-action { margin-left: auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 50%; cursor: pointer; color: var(--text); }
.dh-action:active { background: rgba(128,128,128,0.2); }

/* Активные загрузки */
.dlm-active-wrap { padding: 0 16px; display: flex; flex-direction: column; gap: 8px; }
.dlm-active { display: flex; align-items: center; gap: 12px; padding: 10px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
.dlm-active-thumb { width: 50px; height: 50px; border-radius: 8px; object-fit: cover; background: var(--border); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.dlm-active-body { flex: 1; min-width: 0; }
.dlm-active-title { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dlm-active-row { display: flex; justify-content: space-between; align-items: center; margin-top: 3px; }
.dlm-active-text { font-size: 11px; color: var(--subtext); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dlm-active-pct { font-size: 11px; font-weight: 800; color: var(--pixiv-blue); flex-shrink: 0; margin-left: 8px; }
.dlm-active-track { height: 4px; border-radius: 2px; background: var(--bg); overflow: hidden; margin-top: 8px; }
.dlm-active-fill { height: 100%; width: 0%; border-radius: 2px; background: var(--pixiv-blue); transition: width 0.3s; }
.dlm-act-btns { display: flex; gap: 6px; flex-shrink: 0; }
.dlm-act-btn { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; background: var(--bg); color: var(--subtext); transition: transform 0.15s, background 0.2s; }
.dlm-act-btn:active { transform: scale(0.9); }
.dlm-act-btn.primary { color: var(--pixiv-blue); background: rgba(0,150,250,0.12); }
.dlm-act-btn.danger { color: var(--red); background: rgba(255,69,58,0.1); }

/* Сохранённое — сетка обложек в стиле ленты Pixiv (подписи под превью) */
.dlm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 8px; padding: 4px 16px 28px; }
.dlm-tile { cursor: pointer; }
.dlm-tile-frame { position: relative; aspect-ratio: 1; border-radius: 8px; overflow: hidden; background: var(--surface); transition: transform 0.15s; }
.dlm-tile:active .dlm-tile-frame { transform: scale(0.96); }
.dlm-tile-frame.incomplete { outline: 2px solid var(--red); outline-offset: -2px; }
.dlm-tile-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dlm-tile-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--subtext); }
.dlm-tile-fallback .icon { width: 30px; height: 30px; }
.dlm-tile-cap { padding: 6px 2px 0; }
.dlm-tile-title { font-size: 12px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dlm-tile-size { font-size: 11px; color: var(--subtext); margin-top: 1px; }
.dlm-tile-del { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%; background: rgba(0,0,0,0.55); color: #fff; display: flex; align-items: center; justify-content: center; transition: background 0.2s; }
.dlm-tile-del:active { background: var(--red); }
/* Фирменный бейдж количества страниц Pixiv */
.dlm-tile-pages { position: absolute; top: 6px; left: 6px; display: flex; align-items: center; gap: 3px; padding: 2px 7px 2px 5px; border-radius: 10px; background: rgba(0,0,0,0.6); font-size: 11px; font-weight: 700; color: #fff; }
.dlm-pages-ico { width: 12px; height: 12px; fill: none; stroke: #fff; }
.dlm-tile-badge { position: absolute; top: 6px; left: 6px; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 800; color: #fff; }
.dlm-tile-badge.warn { background: var(--red); }
.dlm-tile-sync { position: absolute; bottom: 6px; right: 6px; width: 30px; height: 30px; border-radius: 50%; background: var(--pixiv-blue); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,0.4); }
.dlm-tile-offline { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, var(--pixiv-blue), #0066cc); }
.dlm-tile-offline .icon { width: 36px; height: 36px; }

/* Подпись-капшн (генерится в buildItemHtml) глобально скрыта —
   используется только при необходимости акцентных карточек. */
.grid-caption { display: none; }

/* Маленький фирменный акцент у заголовка секции рекомендаций */
#recomStatus {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text);
    font-size: 15px;
    font-weight: 800;
    letter-spacing: -0.3px;
    text-transform: none;
}
#recomStatus::before {
    content: "";
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background: var(--pixiv-blue);
    flex-shrink: 0;
}

/* =====================================================================
   ГЛАВНАЯ (вариант 6): hero + горизонтальные ленты разделов.
   Все правила скоупим внутри #page-home, чтобы не задеть другие экраны.
   ===================================================================== */

/* Hero — топовая работа */
.home-hero { position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: var(--border); cursor: pointer; }
.home-hero .search-img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 0.4s ease; }
.home-hero .search-img.loaded { opacity: 1; }
.home-hero-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 44px 16px 14px; background: linear-gradient(transparent, rgba(0,0,0,0.8)); }
.home-hero-cap .badge-feat {
    display: inline-block; font-size: 10px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;
    color: #fff; background: var(--pixiv-blue); padding: 3px 8px; border-radius: 10px; margin-bottom: 8px;
}
.home-hero-cap .title {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    color: #fff; font-size: 18px; font-weight: 800; letter-spacing: -0.3px; line-height: 1.2;
    text-shadow: 0 1px 4px rgba(0,0,0,0.7);
}

/* Заголовок секции (кликабельный -> полный раздел) */
.home-sec-head { display: flex; align-items: center; gap: 8px; padding: 16px 16px 8px; }
.home-sec-head.clickable { cursor: pointer; }
.home-sec-head.clickable:active { opacity: 0.6; }
.home-sec-head .bar { width: 4px; height: 16px; border-radius: 2px; background: var(--pixiv-blue); flex-shrink: 0; }
.home-sec-head .txt { font-size: 15px; font-weight: 800; letter-spacing: -0.3px; color: var(--text); flex: 1; }
.home-sec-head .all { font-size: 12px; font-weight: 700; color: var(--pixiv-blue); white-space: nowrap; }

/* Горизонтальная лента: без закруглений, отступ между картинками как у сетки */
.home-strip { display: flex; gap: 4px; overflow-x: auto; padding: 0 16px 4px; scrollbar-width: none; }
.home-strip::-webkit-scrollbar { display: none; }
.home-strip .strip-item {
    position: relative; width: 195px; flex-shrink: 0; aspect-ratio: 3 / 4; overflow: hidden;
    background: var(--border); cursor: pointer;
}
.home-strip .strip-item .search-img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 0.4s ease; }
.home-strip .strip-item .search-img.loaded { opacity: 1; }
.home-strip .strip-item:active { opacity: 0.85; }

/* Лента коллекций: карточки 4:3 с подписью */
.home-strip.strip-col .strip-item { width: 260px; aspect-ratio: 4 / 3; }
.home-strip .col-item .col-meta {
    position: absolute; left: 0; right: 0; bottom: 0; padding: 24px 10px 8px;
    background: linear-gradient(transparent, rgba(0,0,0,0.82)); display: flex; flex-direction: column; gap: 1px;
}
.home-strip .col-item .col-name { color: #fff; font-size: 13px; font-weight: 700; letter-spacing: -0.2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-strip .col-item .col-cnt { color: #cfcfcf; font-size: 11px; }
.home-strip .col-cover-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--subtext); background: var(--surface); }
.home-strip .col-cover-empty .icon { width: 36px; height: 36px; }

/* Небольшой отступ перед нижним блоком рекомендаций */
#recomCard { margin-top: 10px; }

/* ===== Скелетоны главной (резервируют место, чтобы интерфейс не прыгал при загрузке) ===== */
@keyframes skel-shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
.skel {
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
}
/* Скелетон hero: показываем сам блок с мерцанием, картинку и подпись прячем */
.home-hero.home-hero-skeleton {
    display: block !important;
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
}
.home-hero.home-hero-skeleton .search-img,
.home-hero.home-hero-skeleton .home-hero-cap { display: none; }
/* Скелетон-карточки строятся из существующих классов strip-item/search-item.
   Спецификое правило ниже перебивает сплошной фон .home-strip .strip-item,
   чтобы было видно мерцание. */
.home-strip .strip-item.skel {
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
}

/* ===== Скелетоны детальной страницы (мерцающие плейсхолдеры во время загрузки) ===== */
.det-skel-line {
    border-radius: 6px;
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
    display: inline-block;
}
/* Картинка-плейсхолдер: резервирует высоту, чтобы интерфейс не прыгал */
.det-image-container.det-skel-img {
    width: 100%;
    min-height: 420px;
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
}
/* Аватар автора как круглый шиммер */
.author-card-avatar.det-skel-avatar {
    background: linear-gradient(90deg, var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.5s infinite linear;
}

/* ===== Поиск по картинке (AnimeTrace) ===== */
.search-image-btn {
    color: var(--pixiv-blue);
    cursor: pointer;
    padding: 8px;
    display: flex;
    align-items: center;
}
.animetrace-panel {
    margin: 10px 16px 16px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.animetrace-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 10px;
}
.animetrace-head .animetrace-close {
    margin-left: auto;
    cursor: pointer;
    color: var(--subtext);
    font-size: 14px;
    padding: 0 4px;
}
.animetrace-spin {
    animation: at-spin 0.9s linear infinite;
    color: var(--pixiv-blue);
}
@keyframes at-spin { to { transform: rotate(360deg); } }

/* Оверлей загрузки при прыжке к дальнему закреплённому сообщению (до-рендер истории). */
.chat-jump-loader { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center; pointer-events: none;
  background: rgba(0,0,0,0.06); animation: chatJumpFade 0.15s ease; }
.chat-jump-spinner { width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(128,128,128,0.25); border-top-color: var(--pixiv-blue);
  animation: at-spin 0.7s linear infinite;
  background: var(--surface); box-shadow: 0 2px 10px rgba(0,0,0,0.18); box-sizing: border-box; }
@keyframes chatJumpFade { from { opacity: 0; } to { opacity: 1; } }
.animetrace-group-label {
    font-size: 12px;
    font-weight: 700;
    color: var(--subtext);
    margin: 4px 0 6px;
}
.animetrace-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.animetrace-chips + .animetrace-group-label {
    margin-top: 12px;
}
.animetrace-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 8px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.animetrace-chip:active {
    border-color: var(--pixiv-blue);
    background: var(--surface);
}
.animetrace-chip-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}
.animetrace-chip-work {
    font-size: 12px;
    color: var(--subtext);
}
.animetrace-err {
    font-size: 13px;
    color: #ff6b6b;
}
.animetrace-hint {
    font-size: 12px;
    color: var(--subtext);
}

/* === CHAT UI === */
.chat-contacts-screen { display: flex; flex-direction: column; height: 100%; }
.chat-header { padding: 16px; border-bottom: 1px solid var(--border); }
.chat-header h2 { margin: 0; font-size: 20px; font-weight: 800; color: var(--text); }
.chat-contacts-list { flex: 1; overflow-y: auto; padding: 8px 0; touch-action: pan-y; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.chat-contacts-empty { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--subtext); }
.chat-contact-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.15s; }
.chat-contact-item:active { background: var(--surface); }
.chat-contact-avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--surface); }
.chat-contact-details { flex: 1; min-width: 0; }
.chat-contact-name { font-size: 14px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-contact-last { font-size: 12px; color: var(--subtext); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 4px; }
.chat-conversation-screen { display: flex; flex-direction: column; height: 100%; position: relative; overflow: hidden; }
/* Анимация захода в чат: экран диалога выезжает справа, лёгкая параллакс-подача.
   Класс вешается на #chatConversation в момент открытия и снимается по завершении. */
.chat-conversation-screen.chat-conv-enter { animation: chatConvEnter 0.3s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes chatConvEnter {
  from { transform: translateX(28px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
/* Выход из чата: диалог уезжает вправо и гаснет. Абсолютно позиционируем поверх списка —
   иначе оба экрана делят высоту flex-колонки #page-chat 50/50 и анимация ломается. */
.chat-conversation-screen.chat-conv-exit {
  animation: chatConvExit 0.26s cubic-bezier(0.4, 0, 1, 1) both;
  position: absolute; inset: 0; z-index: 5; background: var(--bg);
}
@keyframes chatConvExit {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(32px); opacity: 0; }
}
.chat-conversation-header { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface); touch-action: none; overscroll-behavior: none; flex-shrink: 0; position: relative; z-index: 6; /* поверх FLIP-сдвига ленты при закрытии клавиатуры */ }

/* === Режим выделения сообщений: панель действий поверх шапки + подсветка выбранных === */
.chat-sel-bar { position: absolute; inset: 0; z-index: 3; display: flex; align-items: center; gap: 6px;
  padding: 0 12px; background: var(--surface); }
.chat-sel-count { flex: 1; font-size: 17px; font-weight: 700; color: var(--text); margin-left: 4px; }
.chat-sel-bar .chat-back-btn { padding: 8px; border-radius: 50%; }
.chat-sel-bar .chat-back-btn:active { background: rgba(128,128,128,0.16); }
.chat-sel-del { color: #e0564b !important; }
/* Подсветка выбранной строки — направленная заливка задаётся у .chat-msg-row ниже. */
/* Скролл в режиме выделения НЕ блокируем глобально — обычная прокрутка должна работать после
   отпускания пальца. Скролл гасится только на время самой выделения-протяжки (preventDefault в
   chatSetupDragSelect, non-passive touchmove), а выделение по тапу обрабатывает ряд. */
/* touch-action не наследуется: без этого тач по детям шапки (аватар/имя/кнопки) панил/скроллил
   страницу при открытой клавиатуре. Тапы/клики при touch-action:none продолжают работать. */
.chat-conversation-header * { touch-action: none; }
.chat-back-btn { background: none; border: none; cursor: pointer; padding: 4px; color: var(--text); }
.chat-header-info { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.chat-header-avatar { width: 40px; height: 40px; border-radius: 13px; overflow: hidden; flex-shrink: 0; display: block; background: var(--surface); }
.chat-header-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.chat-header-text { flex: 1; min-width: 0; }
.chat-header-name { font-size: 14px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-header-id { font-size: 11px; color: var(--subtext); }
.chat-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 8px; overscroll-behavior: none;
  /* Гасим нативное выделение текста/callout на всей ленте — иначе долгое нажатие и протяжка
     массового выделения перехватываются системным выделением текста. */
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* Ряд-обёртка на всю ширину: жесты (тап, двойной тап, свайп) работают не
   только на пузыре, но и в пустом пространстве рядом с ним. */
/* position:relative — под абсолютную стрелку свайп-ответа; touch-action:pan-y — вертикаль
   остаётся скроллом ленты, а горизонталь забирает свайп-ответ (не конфликтует со скроллом). */
.chat-msg-row { display: flex; width: 100%; position: relative; touch-action: pan-y;
  /* Заливка выделения — фоновый градиент, растущий по ширине из стороны отправителя.
     Фон рисуется ПОД содержимым пузыря, поэтому z-index-игры не нужны. */
  background-image: linear-gradient(color-mix(in srgb, var(--pixiv-blue) 16%, transparent),
                                    color-mix(in srgb, var(--pixiv-blue) 16%, transparent));
  background-repeat: no-repeat;
  background-size: 0% 100%;
  transition: background-size 0.28s cubic-bezier(0.22, 1, 0.36, 1); }
/* Чужие сообщения слева → заливка выходит слева; свои справа → заливка выходит справа. */
.chat-msg-row.mine { justify-content: flex-end; background-position: right center; }
.chat-msg-row.theirs { justify-content: flex-start; background-position: left center; }
.chat-msg-row.selected { background-size: 100% 100%; }
/* Стрелка «ответить», проявляющаяся при свайпе влево (у правого края ряда). */
.chat-swipe-reply { position: absolute; right: 10px; top: 50%; transform: translateY(-50%) scale(0.5);
  width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--pixiv-blue); color: #fff; opacity: 0; pointer-events: none; z-index: 1; }
.chat-swipe-reply .icon-sm { width: 16px; height: 16px; }
.chat-bubble { max-width: 80%; padding: 10px 14px; border-radius: 14px; word-wrap: break-word; font-size: 14px; line-height: 1.4; }
/* solo / last — «хвост» на стороне отправителя */
.chat-bubble.mine  { background: var(--pixiv-blue); color: #fff; border-radius: 14px 4px 14px 14px; }
.chat-bubble.theirs { background: var(--surface); color: var(--text); border-radius: 4px 14px 14px 14px; }
/* first / mid в группе — сторона отправителя выровнена (нет хвоста снизу) */
.chat-bubble.mine.group-first,
.chat-bubble.mine.group-mid  { border-radius: 14px 4px 4px 14px; }
.chat-bubble.theirs.group-first,
.chat-bubble.theirs.group-mid { border-radius: 4px 14px 14px 4px; }
/* last в группе — хвост снизу, верх выровнен */
.chat-bubble.mine.group-last  { border-radius: 14px 14px 4px 14px; }
.chat-bubble.theirs.group-last { border-radius: 14px 14px 14px 4px; }
/* Уменьшаем отступ между сообщениями одного отправителя */
.chat-msg-row.group-mid,
.chat-msg-row.group-last { margin-top: -5px; }
/* Аватар участника группы слева от пузыря (на нижнем сообщении серии). */
.chat-bubble-avatar {
  width: 40px; height: 40px; border-radius: 13px; object-fit: cover;
  align-self: flex-end; margin-right: 8px; flex-shrink: 0;
  background: var(--surface); display: block;
}
/* Плейсхолдер той же ширины на верхних/средних пузырях серии — для выравнивания. */
.chat-bubble-avatar-hidden { visibility: hidden; }
/* Поле ввода — редизайн: менее скруглённый, более «прямоугольный» современный вид. */
.chat-input-bar { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--border); background: var(--surface); touch-action: none; overscroll-behavior: none; flex-shrink: 0; }
.chat-input { flex: 1; padding: 10px 14px; background: var(--bg); border: 1px solid var(--border); border-radius: 12px; color: var(--text); font-size: 14px; outline: none; overscroll-behavior: contain; }
.chat-input:focus { border-color: var(--pixiv-blue); }
.chat-input::placeholder { color: var(--subtext); }
.chat-send-btn { background: var(--pixiv-blue); color: #fff; border: none; border-radius: 12px; width: 40px; height: 40px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.15s; }
.chat-send-btn:active { transform: scale(0.95); }
/* Кнопка-иконка слева (эмодзи/GIF) — в одном стиле с отправкой, но нейтральная. */
.chat-input-iconbtn { background: none; border: none; color: var(--subtext); width: 40px; height: 40px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; cursor: pointer; border-radius: 12px; transition: color 0.15s, background 0.15s; }
.chat-input-iconbtn:active { background: rgba(128,128,128,0.15); }
.chat-input-iconbtn.active { color: var(--pixiv-blue); }

/* === Чат: полноэкранный режим ===
   .page по умолчанию display:block без высоты, поэтому height:100% у внутренних
   экранов схлопывался — раскладка ломалась. Делаем #page-chat фиксированным
   оверлеем поверх навигации со своим flex-каркасом. */
#page-chat.active {
  position: fixed;
  inset: 0;
  z-index: 9000;            /* выше top-bar(100)/tabs(99), ниже сайдбара(10001) */
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow: hidden;          /* шапка и бар ввода не должны уезжать за пределы экрана */
  /* Плавное появление/уход клавиатуры: padding-bottom (высота IME) анимируется, поэтому поле
     ввода и лента едут вверх/вниз мягко, а не рывком. Класс .chat-kb-anim включается в JS только
     на момент смены высоты клавиатуры, чтобы переход не мешал прочим изменениям paddinga. */
}
#page-chat.active.chat-kb-anim {
  /* Монотонная кривая замедления (Material «decelerate»): плавно, без перелёта. Анимируем
     padding-bottom (высота IME) — панель ввода и лента мягко едут вверх/вниз с клавиатурой.
     Шапка в flex-колонке остаётся вверху (flex-shrink:0), панель внизу — без transform/top. */
  transition: padding-bottom 0.32s cubic-bezier(0, 0, 0.2, 1);
}
#page-chat .chat-contacts-screen,
#page-chat .chat-conversation-screen { flex: 1; min-height: 0; height: auto; }
#page-chat .chat-messages,
#page-chat .chat-contacts-list { min-height: 0; }   /* чтобы внутренний скролл работал */
/* Отступ под статус-бар сверху */
#page-chat .chat-header,
#page-chat .chat-conversation-header { padding-top: calc(12px + var(--sat, 0px)); }
/* Отступ под навигационную панель/жесты снизу */
#page-chat .chat-input-bar { padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
#page-chat .chat-contacts-list { padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
/* Кнопка закрытия списка контактов */
.chat-header-row { display: flex; align-items: center; gap: 8px; }
.chat-newchat-bar { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--border); }
.chat-close-btn { background: none; border: none; cursor: pointer; padding: 4px; color: var(--text); display: flex; align-items: center; }

/* === Шит уведомлений чата (iOS-стиль: вырастает из колокольчика, пункты со стаггером) === */
.chat-notif-sheet { position: absolute; top: calc(var(--sat,0px) + 52px); right: 8px; z-index: 9100;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.34); min-width: 210px; overflow: hidden;
  transform-origin: top right; will-change: transform, opacity;
  animation: chatNotifSheetIn 0.34s cubic-bezier(0.2, 1.15, 0.3, 1) both; }
.chat-notif-sheet.closing { pointer-events: none;
  animation: chatNotifSheetOut 0.18s cubic-bezier(0.4, 0, 1, 1) both; }
@keyframes chatNotifSheetIn {
  0%   { opacity: 0; transform: scale(0.82) translateY(-8px); }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes chatNotifSheetOut {
  0%   { opacity: 1; transform: scale(1) translateY(0); }
  100% { opacity: 0; transform: scale(0.86) translateY(-6px); }
}
.chat-notif-row { display: flex; align-items: center; gap: 10px; padding: 12px 16px; cursor: pointer;
  font-size: 14px; color: var(--text);
  opacity: 0; animation: chatNotifRowIn 0.3s cubic-bezier(0.2, 1, 0.3, 1) both; }
.chat-notif-sheet .chat-notif-row:nth-child(1) { animation-delay: 0.06s; }
.chat-notif-sheet .chat-notif-row:nth-child(2) { animation-delay: 0.11s; }
.chat-notif-sheet .chat-notif-row:nth-child(3) { animation-delay: 0.16s; }
.chat-notif-sheet.closing .chat-notif-row { animation: none; opacity: 1; }
@keyframes chatNotifRowIn {
  from { opacity: 0; transform: translateX(10px); }
  to   { opacity: 1; transform: translateX(0); }
}
.chat-notif-row:active { background: var(--bg); }
.chat-notif-row.active { color: var(--pixiv-blue); font-weight: 600; }
.chat-notif-row .icon-sm { flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) {
  .chat-notif-sheet, .chat-notif-sheet.closing, .chat-notif-row { animation: none; opacity: 1; }
}

/* === Чат: список диалогов (превью, время, непрочитанные) === */
.chat-contact-item { display: flex; align-items: center; gap: 12px; padding: 10px 16px; position: relative; }
.chat-contact-item:active { background: var(--surface); }
.chat-contact-details { flex: 1; min-width: 0; }
.chat-contact-name { font-size: 15px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-contact-last { font-size: 13px; color: var(--subtext); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.chat-group-avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--pixiv-blue); color: #fff; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.chat-group-avatar .icon-sm { width: 24px; height: 24px; }
.chat-unread-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--pixiv-blue); color: #fff; font-size: 12px; font-weight: 600; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* === Кнопка «новая группа» в шапке списка === */
.chat-newgroup-btn { display: flex; align-items: center; gap: 4px; background: none; border: 1px solid var(--border); border-radius: 16px; padding: 5px 10px; color: var(--pixiv-blue); font-size: 13px; cursor: pointer; }
.chat-newgroup-btn:active { transform: scale(0.97); }
.chat-newgroup-btn .icon-sm { width: 16px; height: 16px; }

/* === Форма создания группы === */
.chat-group-form { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface); }
.chat-group-form-actions { display: flex; justify-content: flex-end; gap: 8px; }
.chat-btn-primary { background: var(--pixiv-blue); color: #fff; border: none; border-radius: 16px; padding: 8px 18px; font-size: 14px; cursor: pointer; }
.chat-btn-secondary { background: none; color: var(--subtext); border: 1px solid var(--border); border-radius: 16px; padding: 8px 18px; font-size: 14px; cursor: pointer; }
.chat-btn-primary:active, .chat-btn-secondary:active { transform: scale(0.97); }

/* === Кнопка добавления участника в шапке группы === */
/* Цвет иконки — как у колокольчика уведомлений (.chat-back-btn → var(--text)). */
.chat-groupadd-btn { margin-left: auto; position: relative; background: none; border: none; cursor: pointer; padding: 6px; display: flex; align-items: center; color: var(--text); }
.chat-groupadd-plus { position: absolute; right: 0; bottom: 2px; font-size: 13px; font-weight: 700; line-height: 1; background: var(--bg); border-radius: 50%; }

/* === Имя отправителя над чужим сообщением в группе === */
.chat-bubble-sender { font-size: 11px; font-weight: 600; color: var(--pixiv-blue); margin-bottom: 2px; }
.chat-bubble.theirs .chat-bubble-sender { color: var(--pixiv-blue); }
.chat-bubble-text { white-space: pre-wrap; word-break: break-word; }
/* Сообщение из одних эмодзи — без фона, крупно как в Discord / Telegram. */
.chat-bubble.chat-emoji-only { background: none !important; box-shadow: none; padding: 2px 0; }
.chat-bubble.mine.chat-emoji-only { color: var(--text); }
.chat-emoji-only .chat-bubble-text { line-height: 1.15; }
/* Чем меньше эмодзи в сообщении-эмодзи, тем крупнее (1 — самое большое, 5 — меньше; >5 — обычный пузырь). */
.chat-emoji-only-1 .chat-bubble-text { font-size: 4em; }
.chat-emoji-only-2 .chat-bubble-text { font-size: 3.4em; }
.chat-emoji-only-3 .chat-bubble-text { font-size: 2.9em; }
.chat-emoji-only-4 .chat-bubble-text { font-size: 2.4em; }
.chat-emoji-only-5 .chat-bubble-text { font-size: 2em; }
/* Сообщение в очереди отправки (ещё не подтверждено сервером) */
.chat-bubble.pending { opacity: 0.6; }

/* === Эмодзи в стиле Discord (Twemoji как цветной COLR-шрифт) ===
   unicode-range ограничивает шрифт только эмодзи-диапазонами, поэтому обычный
   текст, цифры и латиница/кириллица остаются системным sans-serif и не
   перехватываются. Если WebView не поддержит цветной шрифт — мягкий фолбэк на
   системные эмодзи (sans-serif в стеке). */
@font-face {
  font-family: 'TwemojiMozilla';
  src: url('TwemojiMozilla.ttf') format('truetype');
  font-display: swap;
  unicode-range: U+00A9, U+00AE, U+203C, U+2049, U+2122, U+2139, U+2194-2199,
    U+21A9-21AA, U+231A-231B, U+2328, U+23CF, U+23E9-23F3, U+23F8-23FA, U+24C2,
    U+25AA-25AB, U+25B6, U+25C0, U+25FB-25FE, U+2600-27BF, U+2934-2935,
    U+2B00-2BFF, U+3030, U+303D, U+3297, U+3299, U+1F000-1FAFF, U+FE00-FE0F,
    U+200D, U+20E3;
}
/* Применяем шрифт ко всему чату и поп-апу реакций. Селекторы с id/классом
   перебивают правило `* { font-family: sans-serif }`, которое иначе сбрасывало
   бы шрифт на каждом элементе. Текст не меняется (база — тот же sans-serif). */
#page-chat, #page-chat *, .chat-react-popup, .chat-react-popup * {
  font-family: 'TwemojiMozilla', sans-serif;
}

/* === Реакции на сообщения === */
.chat-reactions { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.chat-reaction-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 12px;
  background: rgba(128,128,128,0.18); border: 1px solid transparent; cursor: pointer; font-size: 13px; line-height: 1.4; }
.chat-bubble.mine .chat-reaction-chip { background: rgba(255,255,255,0.2); }
.chat-reaction-chip.mine { border-color: var(--pixiv-blue); background: rgba(0,150,250,0.18); }
.chat-reaction-emoji { font-size: 14px; }
/* Цифра счётчика: на чужих сообщениях — белая, на своих — тёмно-серая. */
.chat-reaction-count { font-size: 12px; font-weight: 700; }
.chat-bubble.theirs .chat-reaction-count { color: #ffffff; }
.chat-bubble.mine .chat-reaction-count { color: #2b2b2b; }
/* Аватарки реагировавших (режим Telegram при 1-3 реакциях на сообщении). */
.chat-reaction-avas { display: inline-flex; align-items: center; }
.chat-reaction-ava { width: 16px; height: 16px; border-radius: 50%; object-fit: cover;
  margin-left: -5px; border: 1.5px solid var(--surface); background: rgba(128,128,128,0.45); }
.chat-reaction-ava:first-child { margin-left: 1px; }
.chat-bubble.mine .chat-reaction-ava { border-color: rgba(255,255,255,0.6); }

/* === Плавная анимация появления/снятия реакции (iOS-стиль) === */
/* .chat-reaction-pop — только НОВЫЙ эмодзи (см. chatBuildReactionsRow), поэтому пружина
   не повторяется на ре-рендерах. Появление: пружина чипа + желе-эмодзи + мягкая рябь. */
.chat-reaction-chip { position: relative; }
.chat-reaction-chip.chat-reaction-pop {
  animation: chatReactionPop 0.46s cubic-bezier(0.22, 1.15, 0.32, 1) both;
  transform-origin: center bottom; will-change: transform, opacity;
}
.chat-reaction-chip.chat-reaction-pop .chat-reaction-emoji {
  display: inline-block;
  animation: chatReactionEmoji 0.56s cubic-bezier(0.3, 1.6, 0.5, 1) both;
}
/* Мягкая рябь вокруг чипа — «tapback»-щелчок iMessage. */
.chat-reaction-chip.chat-reaction-pop::before {
  content: ""; position: absolute; inset: -3px; border-radius: 16px;
  border: 2px solid var(--pixiv-blue); pointer-events: none;
  transform: scale(0.6); opacity: 0;
  animation: chatReactionRing 0.55s cubic-bezier(0.2, 0.7, 0.25, 1) both;
}
@keyframes chatReactionPop {
  0%   { transform: scale(0.3) translateY(4px); opacity: 0; }
  55%  { transform: scale(1.16) translateY(0);  opacity: 1; }
  76%  { transform: scale(0.95); }
  100% { transform: scale(1); }
}
@keyframes chatReactionEmoji {
  0%   { transform: scale(0.5) rotate(-12deg); }
  50%  { transform: scale(1.32) rotate(7deg); }
  72%  { transform: scale(0.92) rotate(-2deg); }
  100% { transform: scale(1) rotate(0); }
}
@keyframes chatReactionRing {
  0%   { transform: scale(0.6); opacity: 0.6; }
  100% { transform: scale(1.7); opacity: 0; }
}

/* Изменение состава существующей реакции (± свою/чужую): пилюля ПЛАВНО тянется по ширине
   (max-width из старой в новую через JS-FLIP — см. chatMeasureAndResizeReactions). Аватар
   выезжает из-под края, ничего не масштабируется и не «прыгает». */

/* Снятие реакции: чип-«призрак» плавно схлопывается (scale + fade + сжатие ширины),
   соседние чипы мягко сдвигаются на его место. Реальную ширину проставляет JS перед
   стартом перехода, дальше max-width гоним к 0. */
.chat-reaction-chip.chat-reaction-ghost {
  pointer-events: none; overflow: hidden; white-space: nowrap;
  transform-origin: center; will-change: max-width, transform, opacity;
}
.chat-reaction-chip.chat-reaction-leaving {
  max-width: 0 !important; opacity: 0; transform: scale(0.3);
  margin-left: -4px; padding-left: 0; padding-right: 0;
  transition: max-width 0.34s cubic-bezier(0.55, 0, 0.35, 1),
              transform 0.34s cubic-bezier(0.5, 0, 0.5, 0.35),
              opacity 0.26s ease, margin 0.34s ease, padding 0.34s ease;
}
/* Снятие ПОСЛЕДНЕЙ реакции: ряд схлопывается по высоте → пузырь сжимается плавно. */
.chat-reactions.chat-reactions-collapsing {
  max-height: 0 !important; margin-top: 0 !important; opacity: 0; overflow: hidden;
  transition: max-height 0.34s cubic-bezier(0.55, 0, 0.35, 1),
              margin-top 0.34s ease, opacity 0.28s ease;
}

/* Пружинистый «boing» при выборе эмодзи в мини-плашке реакций. */
.chat-react-emoji.chat-react-emoji-bounce {
  animation: chatReactTapPop 0.34s cubic-bezier(0.34, 1.6, 0.5, 1);
}
@keyframes chatReactTapPop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.2); }
  60%  { transform: scale(0.86); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .chat-reaction-chip.chat-reaction-pop,
  .chat-reaction-chip.chat-reaction-pop .chat-reaction-emoji,
  .chat-reaction-chip.chat-reaction-pop::before,
  .chat-react-emoji.chat-react-emoji-bounce { animation: none; }
  .chat-reaction-chip.chat-reaction-leaving,
  .chat-reactions.chat-reactions-collapsing { transition: none; }
}

/* === Анимация появления нового сообщения (отправка / прилёт) === */
/* Класс вешается только на новые пузыри (не на всю историю при открытии чата).
   Свои выезжают чуть справа, чужие — слева; лёгкий подъём + масштаб, как в Telegram. */
/* Появление сообщения: мягкий fade + лёгкий подъём (не конфликтует со скроллом — большой выезд
   снизу дёргал ленту). Длительность синхронна с CHAT_MSG_ANIM_MS (300ms); при ре-рендере анимация
   продолжается через отрицательный animation-delay, поэтому не перезапускается. */
.chat-msg-row.chat-msg-enter { animation: chatMsgEnter 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
  will-change: transform, opacity; }
@keyframes chatMsgEnter {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .chat-msg-row.chat-msg-enter { animation: none; }
}

/* === Системные строки группы (присоединение/выход/закреп и т.п.) === */
.chat-system-msg { align-self: center; max-width: 84%; margin: 8px auto; padding: 4px 12px;
  background: rgba(128,128,128,0.15); border-radius: 12px; font-size: 12px; color: var(--subtext);
  text-align: center; line-height: 1.35; word-break: break-word; }

/* === Плашка закреплённого сообщения над лентой === */
.chat-pin-bar { display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  border-left: 3px solid var(--pixiv-blue); cursor: pointer; flex-shrink: 0; }
.chat-pin-bar-icon { width: 16px; height: 16px; color: var(--pixiv-blue); flex-shrink: 0; }
.chat-pin-bar-text { flex: 1 1 auto; min-width: 0; }
.chat-pin-bar-title { font-size: 12px; font-weight: 700; color: var(--pixiv-blue); line-height: 1.2; }
.chat-pin-bar-preview { font-size: 13px; color: var(--text); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-pin-bar-close, .chat-pin-bar-btn { flex-shrink: 0; background: none; border: none; cursor: pointer;
  color: var(--subtext); padding: 4px; display: flex; align-items: center; }
.chat-pin-bar-close:active, .chat-pin-bar-btn:active { color: var(--text); }
/* Строки во всплывающем списке закреплённых. */
.chat-pinlist-text { font-size: 14px; color: var(--text); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-pinlist-unpin { flex-shrink: 0; background: none; border: none; cursor: pointer;
  color: var(--subtext); padding: 6px; display: flex; align-items: center; }
.chat-pinlist-unpin:active { color: var(--text); }
.chat-pinlist-unpinall { width: calc(100% - 24px); margin: 8px 12px 12px; padding: 10px;
  border: none; border-radius: 12px; background: rgba(128,128,128,0.15); color: #e0564b;
  font-size: 14px; font-weight: 600; cursor: pointer; }
.chat-pinlist-unpinall:active { background: rgba(128,128,128,0.28); }

/* === Мета сообщения (время + галочки ✓/✓✓) — вне пузыря, у нижнего края ряда === */
/* Ряд выровнен flex-end (свои справа). Мета — отдельная колонка: у своих идёт ПЕРЕД
   пузырём (оказывается слева от него), у чужих — ПОСЛЕ (справа). Время и галочки
   выровнены по нижнему краю пузыря. */
.chat-msg-meta { display: inline-flex; align-items: flex-end; align-self: flex-end;
  gap: 3px; line-height: 1; flex-shrink: 0; white-space: nowrap;
  font-size: 11px; color: var(--subtext); }
.chat-msg-meta.mine { margin: 0 4px 4px 0; }
.chat-msg-meta.theirs { margin: 0 0 4px 4px; }
.chat-msg-time { font-size: 11px; color: var(--subtext); }
.chat-msg-ticks { display: inline-flex; align-items: flex-end; line-height: 1; flex-shrink: 0; }
.chat-tick-ic { width: 14px; height: 14px; fill: currentColor; }
.chat-msg-ticks .chat-tick-ic { color: var(--subtext); }
.chat-msg-ticks.pending .chat-tick-ic { opacity: 0.5; }
.chat-msg-ticks .chat-tick-ic + .chat-tick-ic { margin-left: -7px; }   /* вторая галочка наезжает (как в TG) */

/* === Аватарки прочитавших в разделе «Просмотры» контекстного меню === */
.chat-react-views { justify-content: flex-start; }
.chat-react-views > span:nth-of-type(1) { flex: 1; }
.chat-views-avas { display: inline-flex; align-items: center; margin-left: auto; }
.chat-views-ava { width: 20px; height: 20px; border-radius: 50%; object-fit: cover;
  margin-left: -6px; border: 1.5px solid var(--surface); background: rgba(128,128,128,0.45); }
.chat-views-ava:first-child { margin-left: 0; }

/* === Всплывающий список «кто прочитал» === */
.chat-readers-overlay { position: fixed; inset: 0; z-index: 9600; background: rgba(0,0,0,0.5);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  animation: chatReactPopIn 0.16s ease-out both; }
.chat-readers-sheet { background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.4); width: 100%; max-width: 360px; max-height: 70vh;
  display: flex; flex-direction: column; overflow: hidden; }
.chat-readers-head { display: flex; align-items: center; gap: 8px; padding: 14px 16px;
  border-bottom: 1px solid var(--border); font-size: 15px; font-weight: 600; color: var(--text); }
.chat-readers-head .icon-sm { width: 18px; height: 18px; color: var(--subtext); }
.chat-readers-close { margin-left: auto; background: none; border: none; cursor: pointer;
  color: var(--subtext); padding: 4px; display: flex; }
.chat-readers-list { overflow-y: auto; padding: 4px 0; }

/* === Поп-ап выбора реакции (long-press) === */
/* z-index выше #page-chat (9000), иначе поп-ап рисуется позади экрана чата и невиден. */
.chat-react-popup { position: fixed; z-index: 9500; background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 8px 28px rgba(0,0,0,0.28); padding: 6px; display: flex; flex-direction: column; gap: 4px;
  max-width: 92vw; overflow: hidden;
  /* Плавное появление меню БЕЗ bounce; bounce оставлен только для раскрытия списка. */
  animation: chatReactPopIn 0.16s ease-out both;
  transition: width 0.36s cubic-bezier(0.34, 1.45, 0.5, 1), height 0.36s cubic-bezier(0.34, 1.45, 0.5, 1),
    top 0.36s cubic-bezier(0.34, 1.45, 0.5, 1), left 0.36s cubic-bezier(0.34, 1.45, 0.5, 1), border-radius 0.28s ease; }
@keyframes chatReactPopIn {
  0%   { transform: scale(0.94); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes chatReactPopOut {
  0%   { transform: scale(1); opacity: 1; }
  100% { transform: scale(0.88); opacity: 0; }
}
.chat-react-popup.closing { animation: chatReactPopOut 0.13s ease-in both; pointer-events: none; }
.chat-react-quickwrap { display: flex; align-items: center; gap: 2px; }
/* Горизонтальный ряд: прокручиваемый, скроллбар скрыт. */
.chat-react-emojis { display: flex; align-items: center; gap: 2px; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
.chat-react-emojis::-webkit-scrollbar { display: none; }
.chat-react-emoji { background: none; border: none; cursor: pointer; font-size: 24px; line-height: 1; padding: 6px;
  border-radius: 10px; transition: transform 0.1s ease, background 0.1s ease; flex-shrink: 0; }
.chat-react-emoji:active { transform: scale(1.2); }
.chat-react-emoji.active { background: rgba(0,150,250,0.18); }
/* Грип «потяни влево, чтобы открыть все реакции». */
.chat-react-grip { flex-shrink: 0; background: rgba(128,128,128,0.12); border: none; cursor: pointer;
  color: var(--subtext); font-size: 20px; font-weight: 700; line-height: 1; width: 22px; align-self: stretch;
  border-radius: 8px; margin-left: 2px; display: flex; align-items: center; justify-content: center; }
.chat-react-action { display: flex; align-items: center; gap: 8px; background: none; border: none; cursor: pointer;
  padding: 8px 10px; border-radius: 10px; color: var(--text); font-size: 14px; text-align: left; }
.chat-react-action:active { background: rgba(128,128,128,0.15); }
.chat-react-action .icon-sm { width: 18px; height: 18px; color: var(--subtext); }
.chat-react-action.chat-react-danger { color: #e0564b; }
.chat-react-action.chat-react-danger .icon-sm { color: #e0564b; }

/* === Раскрытая панель: поиск + сетка всех реакций === */
.chat-react-full { display: none; flex-direction: column; gap: 6px; min-height: 0; flex: 1; }
.chat-react-popup.expanded { border-radius: 14px; }
.chat-react-popup.expanded .chat-react-action { display: none; }
.chat-react-popup.expanded .chat-react-quickwrap { flex-shrink: 0; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
.chat-react-popup.expanded .chat-react-full { display: flex; }
.chat-react-search { width: 100%; box-sizing: border-box; padding: 8px 10px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 14px; outline: none; }
.chat-react-grid { flex: 1; min-height: 0; overflow-y: auto; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 2px; align-content: start; }
.chat-react-gemoji { background: none; border: none; cursor: pointer; font-size: 24px; line-height: 1;
  padding: 6px 0; border-radius: 8px; }
.chat-react-gemoji:active { transform: scale(1.2); }
.chat-react-gemoji.active { background: rgba(0,150,250,0.18); }
.chat-react-empty { grid-column: 1 / -1; padding: 16px; text-align: center; color: var(--subtext); font-size: 14px; }

/* Подсветка сообщения при переходе по цитате. Белая обводка (--chat-hl)
   контрастирует и на синих «своих» пузырях, и на «чужих» — прежний синий
   сливался со своими сообщениями. Один мягкий импульс: свечение вокруг
   пузыря + лёгкий подъём, затем плавное затухание. */
:root { --chat-hl: 255, 255, 255; }
.chat-bubble-highlight { animation: chatBubbleHl 1.2s cubic-bezier(.34, 1.2, .42, 1) both; }
@keyframes chatBubbleHl {
  0%   { box-shadow: 0 0 0 0 rgba(var(--chat-hl), 0); transform: scale(1); }
  22%  { box-shadow: 0 0 0 3px rgba(var(--chat-hl), 0.95), 0 6px 20px 2px rgba(var(--chat-hl), 0.5); transform: scale(1.04); }
  48%  { box-shadow: 0 0 0 3px rgba(var(--chat-hl), 0.8), 0 6px 20px 2px rgba(var(--chat-hl), 0.32); transform: scale(1); }
  100% { box-shadow: 0 0 0 0 rgba(var(--chat-hl), 0); transform: scale(1); }
}

/* === Многострочный ввод (textarea с авто-ростом до 4 строк) ===
   Высота задаётся инлайн из chatInputAutogrow; line-height фиксируем,
   чтобы расчёт «4 строки» был стабилен. Кнопка отправки прижата книзу. */
.chat-input-bar { align-items: flex-end; }
textarea.chat-input { resize: none; line-height: 20px; max-height: calc(20px * 4 + 20px); overflow-y: hidden; font-family: inherit; touch-action: pan-y; overscroll-behavior: contain; }

/* === Плавающая кнопка «вниз» === */
.chat-scrolldown { position: absolute; right: 14px; bottom: 76px; z-index: 50;
  width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--border);
  background: var(--surface); color: var(--text); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0,0,0,0.35); animation: chatScrollDownIn 0.18s ease-out both; }
.chat-scrolldown:active { transform: scale(0.92); }
@keyframes chatScrollDownIn { from { opacity: 0; transform: translateY(8px) scale(0.8); } to { opacity: 1; transform: none; } }

/* === Панель эмодзи / GIF === */
.chat-emoji-panel { display: flex; flex-direction: column; height: 280px; border-top: 1px solid var(--border); background: var(--surface); }
/* Хэндл изменения высоты панели (drag сверху). Высота хранится в localStorage chat_emoji_panel_h_<uid>. */
.chat-emoji-resize { flex: 0 0 auto; height: 18px; display: flex; align-items: center; justify-content: center;
  cursor: row-resize; touch-action: none; user-select: none; -webkit-user-select: none; position: relative; }
.chat-emoji-resize::before { content: ""; width: 38px; height: 4px; border-radius: 2px; background: var(--border); transition: background 0.12s; }
.chat-emoji-resize:active::before { background: var(--pixiv-blue); }
.chat-emoji-panel.resizing { user-select: none; -webkit-user-select: none; }
.chat-emoji-tabs { display: flex; flex-shrink: 0; border-bottom: 1px solid var(--border); }
.chat-emoji-tab { flex: 1; padding: 10px; background: none; border: none; cursor: pointer; color: var(--subtext); font-size: 14px; font-weight: 600; border-bottom: 2px solid transparent; }
.chat-emoji-tab.active { color: var(--pixiv-blue); border-bottom-color: var(--pixiv-blue); }
.chat-emoji-pane { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.chat-emoji-grid { flex: 1; overflow-y: auto; padding: 8px; display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
.chat-emoji-grid button { background: none; border: none; cursor: pointer; font-size: 24px; line-height: 1; padding: 4px; border-radius: 8px; }
.chat-emoji-grid button:active { background: rgba(128,128,128,0.2); }
.chat-sticker-empty { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--subtext); font-size: 14px; font-weight: 600; opacity: 0.7; cursor: pointer; }
/* Раздел «Стикеры»: ряд иконок паков + прокручиваемая сетка секций (лэйаут как в Telegram). */
.chat-sticker-tabs { display: flex; gap: 4px; overflow-x: auto; padding: 6px 8px; border-bottom: 1px solid var(--border); flex: 0 0 auto; align-items: center; scrollbar-width: none; touch-action: pan-x; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
.chat-sticker-tabs::-webkit-scrollbar { display: none; }
.chat-sticker-tab { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: none; border: none; padding: 4px; cursor: pointer; color: var(--subtext);
  /* Гасим выделение/контекстное меню по долгому тапу: иначе WebView стартует жест выделения
     и рвёт long-press (pointercancel) — не давал удерживать таб пака для удаления. pan-x на
     контейнере НЕ трогаем (нужен горизонтальный скролл табов). */
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.chat-sticker-tab img { width: 100%; height: 100%; object-fit: contain; }
.chat-sticker-tab:active { background: rgba(128,128,128,0.18); }
.chat-sticker-add { font-size: 22px; font-weight: 400; line-height: 1; }
.chat-sticker-grid { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; touch-action: pan-y; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.chat-sticker-section-title { font-size: 12px; color: var(--subtext); font-weight: 600; margin: 8px 2px 4px; }
.chat-sticker-section-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.chat-sticker-item { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; cursor: pointer; border-radius: 8px; padding: 4px; }
.chat-sticker-item img { max-width: 100%; max-height: 100%; object-fit: contain; }
.chat-sticker-item:active { background: rgba(128,128,128,0.15); }
/* Long-press удаления пака/стикера: картинки внутри не должны быть целью касания и таскаться —
   иначе долгое нажатие запускает нативный drag картинки (pointercancel) и удержание не срабатывает. */
.chat-sticker-tab *, .chat-sticker-item * { pointer-events: none; -webkit-user-drag: none; }
.chat-sticker-item { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* Иконка пака во время импорта: кольцо-прогресс + % в центре. */
.chat-sticker-tab-importing { position: relative; }
.chat-sticker-prog { position: relative; width: 30px; height: 30px; border-radius: 50%;
  background: conic-gradient(var(--pixiv-blue) var(--pct, 0%), rgba(128,128,128,0.25) 0);
  display: flex; align-items: center; justify-content: center; }
.chat-sticker-prog::after { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: var(--surface); }
.chat-sticker-prog-label { position: relative; z-index: 1; font-size: 10px; font-weight: 700; color: var(--text); }
/* Плейсхолдер секции пака, который ещё качается. */
.chat-sticker-importing-box { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 28px 8px; color: var(--subtext); }
.chat-sticker-importing-spin { width: 26px; height: 26px; border: 3px solid rgba(128,128,128,0.25);
  border-top-color: var(--pixiv-blue); border-radius: 50%; animation: chatMediaSpin 0.8s linear infinite; }
.chat-sticker-importing-text { font-size: 13px; font-weight: 600; }
/* Стикер в ленте — без пузыря, ~128px. */
.chat-bubble-sticker { background: transparent !important; padding: 0 !important; box-shadow: none !important; }
.chat-sticker { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 128px; height: 128px; cursor: pointer; }
.chat-sticker img, .chat-sticker video { width: 100%; height: 100%; object-fit: contain; }
.chat-sticker.chat-sticker-missing { font-size: 56px; }
/* #2 Анимированное превью (video/tgs) поверх статичного thumb; при активной анимации thumb прячем. */
.chat-sticker-item { position: relative; }
.csa-media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; background: transparent; }
.chat-sticker-item .csa-media { padding: 4px; }
/* #1 Пока анимация не пошла — видео/lottie невидимы (opacity 0), виден статичный thumb;
   так чёрный poster-кадр WebView не мелькает. Класс .csa-playing вешаем по первому кадру. */
.csa-media { opacity: 0; transition: opacity 0.12s linear; }
.csa-playing > .csa-media { opacity: 1; }
.csa-playing > img { visibility: hidden; }
.csa-playing > .csa-media svg { width: 100%; height: 100%; }
/* Оверлей ввода ссылки на пак. */
.chat-sticker-import-ov { position: fixed; inset: 0; z-index: 10060; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; padding: 20px; }
.chat-sticker-import-box { background: var(--surface); border-radius: 14px; padding: 16px; width: 100%; max-width: 360px; box-shadow: 0 8px 30px rgba(0,0,0,0.35); }
.chat-sticker-import-title { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 12px; }
.chat-sticker-import-input { width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 14px; }
.chat-sticker-import-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.chat-sticker-import-actions button { padding: 8px 16px; border-radius: 10px; border: none; cursor: pointer; font-weight: 600; font-size: 14px; }
.chat-sticker-import-actions .csi-cancel { background: var(--bg); color: var(--subtext); }
.chat-sticker-import-actions .csi-ok { background: var(--pixiv-blue); color: #fff; }
.chat-sticker-import-actions .csi-ok.csi-del { background: #ff5a5a; }
.chat-sticker-import-box .csi-msg { font-size: 14px; color: var(--subtext); margin-top: -4px; word-break: break-word; }
/* #3 Превью удаляемого стикера в диалоге подтверждения. */
.chat-sticker-import-box .csi-sticker-preview { display: flex; align-items: center; justify-content: center; margin: 4px 0; }
.chat-sticker-import-box .csi-sticker-preview img { width: 96px; height: 96px; object-fit: contain; }
/* Нижний лист вариантов скачивания (долгое нажатие на кнопку загрузки в деталях). */
.dl-opts-sheet { position: fixed; inset: 0; z-index: 10060; background: rgba(0,0,0,0); display: flex; align-items: flex-end;
  transition: background 0.22s ease; }
.dl-opts-sheet.open { background: rgba(0,0,0,0.5); }
.dl-opts-box { background: var(--surface); width: 100%; border-radius: 16px 16px 0 0; padding: 14px 14px calc(18px + var(--sab, 0px));
  box-sizing: border-box; transform: translateY(100%); transition: transform 0.28s cubic-bezier(0.22,0.61,0.36,1); }
.dl-opts-sheet.open .dl-opts-box { transform: translateY(0); }
.dl-opts-title { font-size: 15px; font-weight: 700; color: var(--text); padding: 4px 6px 12px; }
.dl-opts-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 12px; border: none; border-radius: 12px;
  background: var(--bg); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer; margin-bottom: 8px; text-align: left; }
.dl-opts-item .icon { width: 22px; height: 22px; flex: 0 0 auto; color: var(--subtext); }
.dl-opts-item.dl-opts-primary { background: var(--pixiv-blue); color: #fff; }
.dl-opts-item.dl-opts-primary .icon { color: #fff; }
.dl-opts-item.dl-opts-primary b { font-weight: 800; }
.dl-opts-hint { font-size: 12px; color: var(--subtext); padding: 2px 8px; line-height: 1.4; }
/* Попап всего пака при клике по стикеру в чате (нижний лист). #5 плавное появление/закрытие. */
.chat-sticker-pack-popup { position: fixed; inset: 0; z-index: 10060; background: rgba(0,0,0,0); display: flex; align-items: flex-end;
  transition: background 0.22s ease; }
.chat-sticker-pack-popup.open { background: rgba(0,0,0,0.5); }
.chat-sticker-pack-popup.closing { background: rgba(0,0,0,0); }
.cspp-box { background: var(--surface); width: 100%; max-height: 72%; border-radius: 16px 16px 0 0; display: flex; flex-direction: column; padding: 12px; box-sizing: border-box;
  transform: translateY(100%); transition: transform 0.28s cubic-bezier(0.22,0.61,0.36,1); }
.chat-sticker-pack-popup.open .cspp-box { transform: translateY(0); }
.chat-sticker-pack-popup.closing .cspp-box { transform: translateY(100%); }
.cspp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cspp-title { font-size: 15px; font-weight: 700; color: var(--text); }
.cspp-close { background: none; border: none; color: var(--subtext); font-size: 18px; cursor: pointer; padding: 4px 8px; }
.cspp-grid { flex: 1; min-height: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.cspp-grid .chat-sticker-item { aspect-ratio: 1; }
.cspp-add { margin-top: 10px; padding: 12px; border-radius: 12px; border: none; background: var(--pixiv-blue); color: #fff; font-weight: 700; font-size: 15px; cursor: pointer; }
.cspp-add.cspp-del { background: rgba(255,90,90,0.15); color: #ff5a5a; }
.chat-gif-search { flex-shrink: 0; margin: 8px; padding: 9px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; color: var(--text); font-size: 14px; outline: none; }
.chat-gif-grid { flex: 1; overflow-y: auto; padding: 0 8px 8px; overscroll-behavior: contain; }
.chat-gif-cols { columns: 2; column-gap: 6px; }
.chat-gif-item { position: relative; break-inside: avoid; margin-bottom: 6px; }
.chat-gif-item img { width: 100%; border-radius: 8px; cursor: pointer; display: block; background: rgba(128,128,128,0.15); }
/* Сердечко «в избранное» поверх превью (как в Discord). */
.chat-gif-fav { position: absolute; top: 5px; right: 5px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(0,0,0,0.5); border: none; color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.chat-gif-fav.active { color: #ff5a7a; }
.chat-gif-fav .icon-sm { width: 15px; height: 15px; }
.chat-gif-section { font-size: 12px; font-weight: 700; color: var(--subtext); padding: 8px 4px 6px; }
.chat-gif-empty { color: var(--subtext); text-align: center; padding: 24px; font-size: 13px; }

/* GIF-сообщение в пузыре */
.chat-gif { max-width: 220px; width: 100%; border-radius: 14px; display: block; background: rgba(128,128,128,0.15); }

/* === Медиа-вложения чата (фото/видео) === */
.chat-media { position: relative; max-width: 240px; width: 100%; border-radius: 14px; overflow: hidden;
  background: rgba(128,128,128,0.15); cursor: pointer; display: block; }
.chat-media-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Значок play по центру видео. */
.chat-media-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.chat-media-play svg { width: 54px; height: 54px; color: #fff; filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5));
  background: rgba(0,0,0,0.4); border-radius: 50%; padding: 10px; }
/* Длительность видео в углу. */
.chat-media-dur { position: absolute; right: 8px; bottom: 8px; font-size: 11px; font-weight: 600; color: #fff;
  background: rgba(0,0,0,0.6); border-radius: 6px; padding: 2px 6px; pointer-events: none; }
/* #6 Оверлей прогресса загрузки/скачивания — круговой прогресс-бар с процентами. */
.chat-media-progress { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px;
  align-items: center; justify-content: center; background: rgba(0,0,0,0.45); pointer-events: none; }
.chat-media-ring { position: relative; width: 54px; height: 54px; border-radius: 50%;
  background: conic-gradient(var(--pixiv-blue) var(--pct, 0%), rgba(255,255,255,0.25) 0);
  display: flex; align-items: center; justify-content: center; transition: background 0.15s linear; }
.chat-media-ring::after { content: ""; position: absolute; inset: 5px; border-radius: 50%; background: rgba(0,0,0,0.6); }
.chat-media-ring.indet { background: none; border: 4px solid rgba(255,255,255,0.3); border-top-color: #fff;
  animation: chatMediaSpin 0.8s linear infinite; }
.chat-media-ring.indet::after { display: none; }
.chat-media-pct { position: relative; z-index: 1; font-size: 12px; font-weight: 700; color: #fff; }
.chat-media-spinner { width: 34px; height: 34px; border: 3px solid rgba(255,255,255,0.35);
  border-top-color: #fff; border-radius: 50%; animation: chatMediaSpin 0.8s linear infinite; }
@keyframes chatMediaSpin { to { transform: rotate(360deg); } }
/* Ошибка отправки медиа: значок по центру, тап по пузырю — повтор. */
.chat-media-failed { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.45); }
.chat-media-failed svg { width: 40px; height: 40px; color: #ff5a5a; filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5)); }
/* #7 Полноэкранный просмотр фото. */
.chat-media-overlay { position: fixed; inset: 0; z-index: 10050; background: rgba(0,0,0,0.92);
  display: flex; align-items: center; justify-content: center; padding: 12px;
  opacity: 0; transition: opacity 0.2s ease; }
.chat-media-overlay.open { opacity: 1; }
.chat-media-overlay img, .chat-media-overlay video { max-width: 100%; max-height: 100%; display: block; border-radius: 8px; }
/* Кнопка закрытия ✕ (общая для фото-оверлея и плеера). */
.chat-media-close, .cvp-close, .cvp-fit { position: absolute; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(0,0,0,0.5); border: none; color: #fff; font-size: 20px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; z-index: 3; }
.chat-media-close { top: 14px; right: 14px; }

/* === #4 Кастомный видеоплеер === */
.chat-video-player { position: fixed; inset: 0; z-index: 10055; background: #000;
  display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.22s ease; }
.chat-video-player.open { opacity: 1; }
.cvp-stage { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.cvp-video { max-width: 100%; max-height: 100%; width: 100%; height: 100%; object-fit: contain; background: transparent;
  opacity: 0; transition: opacity 0.15s linear; }
/* #1 Кадр проявляем только после декодирования первого кадра (cvp-ready) — до этого чистый
   чёрный фон плеера + спиннер, без дефолтного poster-плейсхолдера. */
.chat-video-player.cvp-ready .cvp-video { opacity: 1; }
.chat-video-player.cvp-fill .cvp-video { object-fit: cover; }
/* Буфер-спиннер. */
.cvp-buffer { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; pointer-events: none; }
.cvp-buffer.on { display: flex; }
/* Большая кнопка play по центру (видна на паузе). */
.cvp-bigplay { position: absolute; width: 74px; height: 74px; border-radius: 50%; border: none;
  background: rgba(0,0,0,0.45); color: #fff; display: none; align-items: center; justify-content: center; cursor: pointer; }
.cvp-bigplay svg { width: 40px; height: 40px; }
.chat-video-player:not(.cvp-playing):not(.cvp-buffering) .cvp-bigplay { display: flex; }
/* Верхняя панель (закрыть / вписать). */
.cvp-top { position: absolute; top: 0; left: 0; right: 0; height: 66px; z-index: 3;
  background: linear-gradient(rgba(0,0,0,0.55), transparent);
  opacity: 0; transition: opacity 0.2s ease; pointer-events: none; }
.cvp-top .cvp-close { top: 14px; left: 14px; }
.cvp-top .cvp-fit { top: 14px; right: 14px; background: rgba(0,0,0,0.5); }
.cvp-fit svg { width: 20px; height: 20px; }
/* Нижняя панель управления. */
.cvp-bottom { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: center; gap: 10px; padding: 14px 16px 20px;
  background: linear-gradient(transparent, rgba(0,0,0,0.6));
  opacity: 0; transform: translateY(8px); transition: opacity 0.2s ease, transform 0.2s ease; pointer-events: none; }
.chat-video-player.cvp-controls .cvp-top,
.chat-video-player.cvp-controls .cvp-bottom { opacity: 1; transform: none; pointer-events: auto; }
.cvp-play { width: 36px; height: 36px; flex: 0 0 auto; border: none; background: none; color: #fff; cursor: pointer; padding: 0; }
.cvp-play svg { width: 30px; height: 30px; }
.cvp-cur, .cvp-dur { flex: 0 0 auto; font-size: 12px; font-weight: 600; color: #fff; min-width: 34px; text-align: center; }
/* Дорожка перемотки: буфер + заполнение + невидимый range сверху. */
.cvp-seek { position: relative; flex: 1; height: 22px; display: flex; align-items: center; }
.cvp-seek::before { content: ""; position: absolute; left: 0; right: 0; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.25); }
.cvp-seek-buf { position: absolute; left: 0; height: 4px; width: 0; border-radius: 2px; background: rgba(255,255,255,0.45); }
.cvp-seek-fill { position: absolute; left: 0; height: 4px; width: 0; border-radius: 2px; background: var(--pixiv-blue); }
.cvp-seek-input { position: absolute; left: -8px; right: -8px; width: calc(100% + 16px); height: 22px; margin: 0;
  background: none; -webkit-appearance: none; appearance: none; }
.cvp-seek-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px;
  border-radius: 50%; background: var(--pixiv-blue); box-shadow: 0 0 0 3px rgba(255,255,255,0.25); cursor: pointer; }
.cvp-seek-input::-webkit-slider-runnable-track { background: transparent; }

/* === Медиа-сообщения без пузыря (иллюстрации Pixiv и GIF) === */
/* Снимаем фон/паддинг/радиус пузыря — остаётся «чистое» медиа со своим скруглением. */
.chat-bubble.chat-bubble-media { background: transparent !important; padding: 0; border-radius: 0; }
.chat-bubble-media .chat-art-card { width: 240px; max-width: 100%; box-shadow: 0 2px 10px rgba(0,0,0,0.3); }
.chat-bubble.mine.chat-bubble-media .chat-art-card { background: rgba(128,128,128,0.16); }
/* Подпись под медиа — маленьким текстом, без фона. */
.chat-bubble-media .chat-art-card-caption { margin-top: 6px; color: var(--text); }
/* Цитата над медиа (ответ гифкой/иллюстрацией): у media-пузыря нет фона/паддинга, поэтому
   даём цитате свою подложку и ширину по медиа, чтобы она читалась как прикреплённая к нему. */
.chat-bubble-media .chat-quote {
  background: rgba(128,128,128,0.14); border-radius: 12px;
  padding: 5px 9px; margin-bottom: 5px; max-width: 220px; box-sizing: border-box;
}
.chat-bubble.mine.chat-bubble-media .chat-quote { background: rgba(128,128,128,0.20); }

/* === Аватар группы (картинка работы Pixiv с CSS-обрезкой) === */
.chat-group-ava-img { overflow: hidden; border-radius: 50%; flex-shrink: 0; }
.chat-group-ava-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Аватар в профиле группы: картинка заполняет круг, бейдж-камера у владельца. */
.chat-gp-avatar { position: relative; overflow: hidden; }
.chat-gp-avatar.has-img > svg { display: none; }
.chat-gp-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.chat-gp-avatar-edit { position: absolute; right: 0; bottom: 0; width: 26px; height: 26px;
  border-radius: 50%; background: var(--pixiv-blue); color: #fff; display: flex;
  align-items: center; justify-content: center; border: 2px solid var(--surface); }
.chat-gp-avatar-edit svg { width: 14px; height: 14px; }

/* === Кроп аватара группы === */
.chat-crop-overlay { position: fixed; inset: 0; z-index: 9700; background: rgba(0,0,0,0.7);
  display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px; }
.chat-crop-frame { width: 280px; height: 280px; max-width: 80vw; max-height: 80vw; border-radius: 50%;
  overflow: hidden; position: relative; background: #111; box-shadow: 0 0 0 9999px rgba(0,0,0,0.4); touch-action: none; }
.chat-crop-frame img { width: 100%; height: 100%; object-fit: cover; user-select: none; -webkit-user-drag: none; pointer-events: none; }
.chat-crop-hint { color: #fff; opacity: 0.8; font-size: 13px; margin-top: 16px; text-align: center; }
.chat-crop-actions { display: flex; gap: 12px; margin-top: 18px; }
.chat-crop-actions button { padding: 10px 22px; border-radius: 12px; border: none; cursor: pointer; font-size: 14px; font-weight: 600; }
.chat-crop-cancel { background: rgba(255,255,255,0.15); color: #fff; }
.chat-crop-save { background: var(--pixiv-blue); color: #fff; }

/* === Ответы: панель-цитата над полем ввода === */
.chat-reply-bar { display: flex; align-items: flex-start; gap: 10px; padding: 8px 16px; border-top: 1px solid var(--border); background: var(--surface); flex-shrink: 0; }
/* pointer-events: none — текст цитаты не перехватывает касания и скролл (кнопка
   закрытия лежит вне этого блока и остаётся кликабельной). */
.chat-reply-bar-info { flex: 1; min-width: 0; border-left: 3px solid var(--pixiv-blue); padding-left: 8px; pointer-events: none; }
.chat-reply-bar-name { font-size: 12px; font-weight: 600; color: var(--pixiv-blue); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Превью цитаты над полем ввода — не более 5 строк, дальше обрезается. */
.chat-reply-bar-text { font-size: 13px; color: var(--subtext); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; line-clamp: 5; overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat-reply-bar-close { background: none; border: none; cursor: pointer; padding: 4px; color: var(--subtext); display: flex; align-items: center; flex-shrink: 0; }

/* === Ответы: цитата внутри пузыря === */
.chat-quote { border-left: 3px solid currentColor; padding: 2px 0 2px 8px; margin-bottom: 4px; opacity: 0.85; max-width: 100%; }
.chat-bubble.mine .chat-quote { border-left-color: rgba(255,255,255,0.7); }
.chat-quote-name { font-size: 11px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Цитата внутри пузыря — не более 5 строк, дальше обрезается. */
.chat-quote-text { font-size: 12px; opacity: 0.85; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; line-clamp: 5; overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere; }

/* === Пузырь: позиционирование для кнопки ответа + блокировка выделения при long-press === */
.chat-bubble { position: relative; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.chat-reply-btn { position: absolute; top: 50%; transform: translateY(-50%); background: var(--bg); border: 1px solid var(--border); border-radius: 50%; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer; color: var(--subtext); opacity: 0; transition: opacity 0.15s; }
.chat-bubble:hover .chat-reply-btn { opacity: 0.9; }
.chat-bubble.mine .chat-reply-btn { left: -32px; }
.chat-bubble.theirs .chat-reply-btn { right: -32px; }
.chat-reply-btn .icon-sm { width: 14px; height: 14px; }

/* === Присутствие: статус в шапке диалога === */
.chat-header-status { font-size: 12px; line-height: 1.3; display: flex; align-items: center; gap: 5px; }
.chat-status-online { color: #4caf50; }
.chat-status-dim { color: var(--subtext); }
.chat-online-dot { width: 8px; height: 8px; border-radius: 50%; background: #4caf50; flex-shrink: 0; }

/* === Чип состояния связи в шапке списка чатов === */
.chat-conn-chip { display: inline-flex; align-items: center; font-size: 12px; color: var(--subtext); padding: 2px 10px; border-radius: 12px; background: var(--surface); border: 1px solid var(--border); margin-left: 8px; }

/* === Статус «печатает…» в шапке диалога === */
.chat-status-typing { color: var(--pixiv-blue); font-style: italic; }

/* === Профиль/настройки группы (карточный дизайн, как в iOS/Telegram) === */
.chat-groupprofile-screen { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* Вход в профиль группы как «растягивание шапки»: сначала виден только верхний бар (ровно там,
   где была шапка чата), затем экран раскрывается вниз до полного — шапка будто растягивается на
   весь экран, открывая профиль. Само раскрытие (clip-path) ведёт JS через transition в пикселях
   (надёжнее keyframe с var/calc в WebView). Здесь — только «подача» содержимого. */
.chat-groupprofile-screen.chat-gp-enter { will-change: clip-path; }
/* Содержимое стартует чуть позже раскрытия шторы и «падает» сверху. */
.chat-groupprofile-screen.chat-gp-enter .chat-groupprofile-body { animation: chatGpBodyEnter 0.42s cubic-bezier(0.22, 1, 0.36, 1) 0.18s both; }
@keyframes chatGpBodyEnter {
  from { opacity: 0; transform: translateY(-22px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Аватар/имя героя выезжают ещё заметнее — акцент раскрытия. */
.chat-groupprofile-screen.chat-gp-enter .chat-gp-hero { animation: chatGpHeroEnter 0.44s cubic-bezier(0.34, 1.4, 0.5, 1) 0.14s both; }
@keyframes chatGpHeroEnter {
  from { opacity: 0; transform: translateY(-30px) scale(0.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Выход — зеркало: содержимое уходит вверх и гаснет, пока профиль схлопывается в шапку. */
.chat-groupprofile-screen.chat-gp-exit .chat-groupprofile-body { animation: chatGpBodyExit 0.32s cubic-bezier(0.4, 0, 0.2, 1) both; }
@keyframes chatGpBodyExit {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-22px); }
}
.chat-groupprofile-screen.chat-gp-exit .chat-gp-hero { animation: chatGpHeroExit 0.3s cubic-bezier(0.4, 0, 0.2, 1) both; }
@keyframes chatGpHeroExit {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(-30px) scale(0.92); }
}
.chat-groupprofile-body { flex: 1; min-height: 0; overflow-y: auto;
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }

/* Герой: крупный аватар по центру, имя и мета */
.chat-gp-hero { display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 24px 16px 20px; gap: 4px; }
.chat-gp-hero .chat-gp-avatar { width: 92px; height: 92px; flex-shrink: 0; margin-bottom: 12px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.18); }
.chat-gp-hero .chat-gp-avatar .icon-sm { width: 44px; height: 44px; }
.chat-gp-heroname { display: flex; align-items: center; justify-content: center; gap: 6px; max-width: 100%; width: 100%; }
.chat-gp-name { font-size: 22px; font-weight: 700; color: var(--text); word-break: break-word; line-height: 1.2; }
/* Редактируемое имя группы (выглядит как заголовок, у владельца — с подсказкой правки). */
.chat-gp-nameinput { font-size: 22px; font-weight: 700; color: var(--text); text-align: center;
  background: none; border: none; outline: none; width: 100%; max-width: 320px; line-height: 1.2;
  padding: 4px 8px; border-radius: 8px; }
.chat-gp-nameinput.editable { box-shadow: inset 0 -1px 0 var(--border); transition: box-shadow 0.18s ease; }
.chat-gp-nameinput.editable:focus { box-shadow: inset 0 -2px 0 var(--pixiv-blue); }
.chat-gp-nameinput[readonly] { cursor: default; }
.chat-gp-meta { font-size: 13px; color: var(--subtext); }
.chat-gp-meta-uname { color: var(--pixiv-blue); font-weight: 600; }

/* Галочка «Сохранить» в правом углу шапки профиля — чистая иконка, без фона-«шарика» */
.chat-gp-headersave { flex-shrink: 0; margin-left: auto; background: none; color: var(--pixiv-blue);
  border: none; padding: 6px; display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: transform 0.12s ease, opacity 0.12s ease;
  animation: chatGpSaveIn 0.22s cubic-bezier(0.2, 1.1, 0.3, 1) both; }
.chat-gp-headersave:active { transform: scale(0.86); }
.chat-gp-headersave .icon-sm { width: 24px; height: 24px; }
@keyframes chatGpSaveIn { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: translateX(0); } }

/* Сворачиваемый список участников (> 3): плавная высота + градиент снизу + кнопка */
.chat-gp-members-collapse { position: relative; overflow: hidden; transition: max-height 0.3s cubic-bezier(0.4,0,0.2,1); }
.chat-gp-members-fade { position: absolute; left: 0; right: 0; bottom: 0; height: 48px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(0,0,0,0), var(--surface)); }
.chat-gp-members-toggle { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%;
  background: none; border: none; border-top: 1px solid var(--border); cursor: pointer;
  color: var(--pixiv-blue); font-size: 14px; font-weight: 500; padding: 12px; }
.chat-gp-members-chevron { width: 16px; height: 16px; transition: transform 0.25s ease; }
.chat-gp-members-toggle.expanded .chat-gp-members-chevron { transform: rotate(180deg); }

/* Секция и её заголовок-подпись */
.chat-gp-section { padding: 8px 0; }
.chat-gp-card-title { font-size: 12px; font-weight: 600; color: var(--subtext);
  padding: 6px 20px; text-transform: uppercase; letter-spacing: 0.04em; }

/* Карточка со скруглением — обёртка для строк/полей */
.chat-gp-card { background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; margin: 0 12px; overflow: hidden; }
.chat-gp-card.chat-contacts-list { padding: 4px 0; }
.chat-gp-divider { height: 1px; background: var(--border); margin: 0 14px; }

/* Строка-настройка (лейбл + описание слева, контрол справа) */
.chat-gp-listrow { display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin: 0; cursor: pointer; }
.chat-gp-listrow-main { flex: 1; min-width: 0; }
.chat-gp-listrow-label { font-size: 15px; color: var(--text); font-weight: 500; }
.chat-gp-listrow-sub { font-size: 12px; color: var(--subtext); margin-top: 2px; line-height: 1.3; }

/* iOS-подобный переключатель */
.chat-switch { position: relative; flex-shrink: 0; width: 46px; height: 28px; display: inline-block; }
.chat-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.chat-switch-track { position: absolute; inset: 0; border-radius: 999px; background: rgba(128,128,128,0.35);
  transition: background 0.25s ease; }
.chat-switch-thumb { position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.35); transition: transform 0.25s cubic-bezier(0.4,0,0.2,1); }
.chat-switch input:checked + .chat-switch-track { background: var(--pixiv-blue); }
.chat-switch input:checked + .chat-switch-track .chat-switch-thumb { transform: translateX(18px); }

/* Поле внутри карточки */
.chat-gp-field { padding: 12px 14px; }
.chat-gp-field-label { font-size: 12px; font-weight: 600; color: var(--subtext); margin-bottom: 8px;
  text-transform: uppercase; letter-spacing: 0.03em; }
.chat-gp-uname-bar { display: flex; align-items: center; gap: 2px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; padding: 0 12px; transition: border-color 0.15s ease; }
.chat-gp-uname-bar:focus-within { border-color: var(--pixiv-blue); }
.chat-gp-uname-bar.valid { border-color: var(--green, #66bb6a); }
.chat-gp-uname-bar.invalid { border-color: var(--red); }
.chat-gp-uname-at { color: var(--subtext); font-size: 16px; font-weight: 600; }
.chat-gp-uname-bar .chat-input { flex: 1; background: none; border: none; padding: 11px 4px;
  color: var(--text); font-size: 15px; outline: none; }
.chat-gp-uname-ok { width: 20px; height: 20px; color: var(--green, #66bb6a); flex-shrink: 0; }
.chat-gp-uname-spin { width: 15px; height: 15px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--pixiv-blue); animation: at-spin 0.7s linear infinite; }
.chat-gp-uname-hint { font-size: 11px; color: var(--subtext); margin-top: 8px; line-height: 1.4; }
.chat-gp-uname-hint.error { color: var(--red); }
/* Список имён-алиасов группы + квота + кнопка добавления */
.chat-gp-uname-quota { font-weight: 500; color: var(--subtext); opacity: 0.7; margin-left: 6px; }
.chat-gp-uname-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.chat-gp-uname-list:empty { display: none; }
.chat-gp-uname-empty { font-size: 12px; color: var(--subtext); opacity: 0.8; line-height: 1.4; }
.chat-gp-uname-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 5px 5px 12px; font-size: 14px; color: var(--text); }
.chat-gp-uname-chip span { font-weight: 600; }
.chat-gp-uname-del { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border: none; border-radius: 50%; background: rgba(128,128,128,0.18); color: var(--subtext); cursor: pointer; padding: 0; }
.chat-gp-uname-del:active { background: rgba(229,57,53,0.2); color: var(--red); }
.chat-gp-uname-del svg { width: 12px; height: 12px; }
.chat-gp-uname-add { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex-shrink: 0;
  border: none; border-radius: 8px; background: var(--pixiv-blue); color: #fff; cursor: pointer; padding: 0;
  transition: opacity 0.15s ease, transform 0.12s ease; }
.chat-gp-uname-add:disabled { opacity: 0.4; cursor: default; }
.chat-gp-uname-add:not(:disabled):active { transform: scale(0.9); }
.chat-gp-uname-add svg { width: 18px; height: 18px; }

/* Сегментированный контрол выбора режима вступления */
.chat-gp-seg { display: flex; gap: 4px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 10px; padding: 4px; }
.chat-gp-seg-opt { flex: 1; margin: 0; cursor: pointer; }
.chat-gp-seg-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.chat-gp-seg-btn { display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 6px; border-radius: 7px; font-size: 14px; font-weight: 500; color: var(--subtext);
  transition: background 0.18s ease, color 0.18s ease; }
.chat-gp-seg-btn .icon-sm { width: 16px; height: 16px; }
.chat-gp-seg-opt input:checked + .chat-gp-seg-btn { background: var(--pixiv-blue); color: #fff; }

/* Примечание с иконкой (E2E-предупреждение) */
.chat-gp-note { display: flex; gap: 8px; padding: 4px 14px 14px; color: var(--subtext);
  font-size: 12px; line-height: 1.4; }
.chat-gp-note .icon-sm { width: 15px; height: 15px; flex-shrink: 0; margin-top: 1px; opacity: 0.8; }

/* Строка добавления по ID */
.chat-gp-addbar { display: flex; gap: 8px; padding: 4px 12px 8px; }
.chat-gp-addbar .chat-input { flex: 1; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 11px 14px; color: var(--text); font-size: 15px; outline: none; }
.chat-gp-addbtn { flex-shrink: 0; width: 44px; border: none; border-radius: 10px;
  background: var(--pixiv-blue); color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.chat-gp-addbtn .icon-sm { width: 20px; height: 20px; }

/* Участники / заявки внутри карточки */
.chat-gp-card .chat-contact-item { padding: 8px 14px; }
.chat-gp-owner-badge { font-size: 10px; font-weight: 700; color: var(--pixiv-blue);
  background: rgba(0,150,250,0.12); border-radius: 6px; padding: 1px 6px; margin-left: 8px;
  vertical-align: middle; text-transform: uppercase; letter-spacing: 0.02em; }
.chat-gp-iconbtn, .chat-gp-del { background: none; border: none; cursor: pointer; color: var(--pixiv-blue);
  padding: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.chat-gp-del { color: #e53935; margin-left: auto; }
.chat-gp-noreq { padding: 14px; color: var(--subtext); font-size: 13px; text-align: center; }
.chat-gp-req-approve, .chat-gp-req-reject { flex-shrink: 0; background: none; border: none; cursor: pointer;
  padding: 8px; display: flex; align-items: center; border-radius: 8px; transition: background 0.15s ease; }
.chat-gp-req-approve { color: var(--pixiv-blue); }
.chat-gp-req-reject { color: #e53935; }
.chat-gp-req-approve:active { background: rgba(0,150,250,0.12); }
.chat-gp-req-reject:active { background: rgba(229,57,53,0.12); }
.chat-gp-req-approve .icon-sm, .chat-gp-req-reject .icon-sm { width: 20px; height: 20px; }

/* Действия внизу: единый стиль кнопок-строк */
.chat-gp-actions { display: flex; flex-direction: column; gap: 8px; padding: 16px 12px; }
.chat-gp-actionbtn { display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 12px;
  padding: 13px; font-size: 15px; font-weight: 500; cursor: pointer; transition: transform 0.12s ease; }
.chat-gp-actionbtn:active { transform: scale(0.985); }
.chat-gp-actionbtn .icon-sm { width: 18px; height: 18px; }
.chat-gp-actionbtn-danger { color: #e53935; }
.chat-gp-actionbtn-danger .icon-sm { color: #e53935; }

/* === Карточка-превью работы в чате (шаринг со страницы работы) === */
/* Карточка пересланной работы: крупное изображение сверху, текст под ним —
   чтобы иллюстрацию можно было рассмотреть, не открывая её. */
.chat-art-card { display: flex; flex-direction: column; background: rgba(128,128,128,0.12); border-radius: 12px; overflow: hidden; cursor: pointer; width: 240px; max-width: 100%; }
.chat-bubble.mine .chat-art-card { background: rgba(255,255,255,0.15); }
.chat-art-card-thumb { width: 100%; height: 220px; object-fit: cover; background: rgba(128,128,128,0.2); display: block; }
.chat-art-card-noimg { height: 220px; display: flex; align-items: center; justify-content: center; color: var(--subtext); }
.chat-art-card-noimg .icon-sm { width: 40px; height: 40px; }
.chat-art-card-info { min-width: 0; padding: 8px 10px 10px; display: flex; flex-direction: column; }
.chat-art-card-tag { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; opacity: 0.6; }
.chat-art-card-title { font-size: 14px; font-weight: 600; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.chat-art-card-author { font-size: 12px; opacity: 0.7; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-art-card-caption { margin-top: 6px; }

/* === Многокартиночная арт-карточка: пейджер страниц прямо в чате === */
.chat-artpg { position: relative; width: 100%; height: 220px; overflow: hidden;
  background: rgba(128,128,128,0.2); touch-action: pan-y; }
.chat-artpg-track { display: flex; height: 100%; width: 100%;
  transition: transform 0.28s cubic-bezier(0.22,1,0.36,1); will-change: transform; }
.chat-artpg-img { width: 100%; height: 100%; flex: 0 0 100%; object-fit: cover; display: block;
  -webkit-user-drag: none; user-select: none; pointer-events: none; }
/* Счётчик N/M в правом верхнем углу */
.chat-artpg-counter { position: absolute; top: 7px; right: 7px; padding: 2px 8px;
  background: rgba(0,0,0,0.55); color: #fff; font-size: 11px; font-weight: 600;
  border-radius: 11px; line-height: 1.5; pointer-events: none; }
/* Точки-индикаторы снизу по центру */
.chat-artpg-dots { position: absolute; bottom: 8px; left: 0; right: 0; display: flex;
  justify-content: center; gap: 5px; pointer-events: none; }
.chat-artpg-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,0.45);
  transition: background 0.2s ease, transform 0.2s ease; }
.chat-artpg-dot.active { background: #fff; transform: scale(1.25); }

/* === Контекст-меню чата (long-press по строке списка) — в стиле меню сообщений === */
/* Плавающая карточка .chat-react-popup; ряды пунктов чуть шире для удобного тапа. */
.chat-ctxmenu-pop { min-width: 190px; }
.chat-ctxmenu-pop .chat-react-action { padding: 11px 12px; font-size: 15px; }
/* Затемнение под меню. Лежит ВНУТРИ .chat-contacts-screen (контекст #page-chat), z-index выше
   контента списка (шапка, FAB=20), но ниже поднятой строки. Ловит тап «мимо» → закрытие,
   не давая ему провалиться на строку списка (иначе открывался бы чат). */
.chat-ctx-overlay { position: absolute; inset: 0; z-index: 30; background: rgba(0,0,0,0.5);
  opacity: 0; transition: opacity 0.2s ease; }
.chat-ctx-overlay.show { opacity: 1; }
/* Выбранная строка поверх затемнения — сама строка, точно на месте (не копия). Непрозрачный
   фон, чтобы затемнение не просвечивало; pointer-events:none — тап уходит в оверлей (закрытие). */
.chat-contact-item.chat-ctx-raised { position: relative; z-index: 40; pointer-events: none;
  background: var(--surface); }

/* ===================== Редизайн списка чатов (Telegram-подобно) ===================== */
.chat-contacts-screen { position: relative; }
.chat-header { padding: 12px 12px 0; border-bottom: 1px solid var(--border); }
.chat-header h2 { font-size: 22px; font-weight: 800; }

/* Поиск */
.chat-search-bar { display: flex; align-items: center; gap: 8px; margin: 10px 4px 12px; padding: 9px 12px; background: var(--surface); border-radius: 20px; }
.chat-search-icon { width: 18px; height: 18px; color: var(--subtext); flex-shrink: 0; }
.chat-search-input { flex: 1; min-width: 0; background: none; border: none; outline: none; color: var(--text); font-size: 15px; padding: 0; }
.chat-search-input::placeholder { color: var(--subtext); }
.chat-search-clear { background: none; border: none; color: var(--subtext); display: flex; align-items: center; padding: 2px; cursor: pointer; flex-shrink: 0; }
.chat-search-clear .icon-sm { width: 16px; height: 16px; }

/* Строка чата — карточный редизайн: скруглённые карточки, squircle-аватары,
   выделение непрочитанных (тональный фон + жирнее + акцент), без разделителей. */
.chat-contact-item {
    display: flex; align-items: center; gap: 13px;
    margin: 0 8px 6px; padding: 10px 12px;
    border-radius: 18px; border-bottom: none; cursor: pointer;
    background: transparent;
    transition: background 0.18s ease, transform 0.12s ease;
}
.chat-contact-item:active { background: var(--surface); transform: scale(0.985); }
.chat-contact-item.unread { background: color-mix(in srgb, var(--pixiv-blue) 9%, transparent); }
.chat-contact-avatar {
    width: 56px; height: 56px; border-radius: 19px; object-fit: cover;
    flex-shrink: 0; background: var(--surface);
}
.chat-group-avatar { width: 56px; height: 56px; border-radius: 19px; display: flex; align-items: center; justify-content: center; }
.chat-group-avatar .icon-sm { width: 26px; height: 26px; }
.chat-contact-details { flex: 1; min-width: 0; }
.chat-contact-row1 { display: flex; align-items: baseline; gap: 8px; }
.chat-contact-name { flex: 1; font-size: 16px; font-weight: 700; color: var(--text); letter-spacing: -0.2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; }
.chat-contact-time { font-size: 12px; font-weight: 500; color: var(--subtext); flex-shrink: 0; }
.chat-contact-item.unread .chat-contact-time { color: var(--pixiv-blue); font-weight: 700; }
.chat-contact-row2 { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.chat-contact-last { flex: 1; font-size: 14px; color: var(--subtext); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; }
.chat-contact-item.unread .chat-contact-last { color: var(--text); }
.chat-last-sender { font-weight: 600; color: var(--text); }
.chat-unread-badge {
    min-width: 22px; height: 22px; padding: 0 7px; border-radius: 11px;
    background: var(--pixiv-blue); color: #fff; font-size: 12px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    box-shadow: 0 3px 10px color-mix(in srgb, var(--pixiv-blue) 40%, transparent);
}
.chat-contact-action .chat-group-avatar { background: var(--pixiv-blue); }

/* === In-app уведомление (глобальный баннер сверху, поверх любой страницы) === */
.chat-inapp { position: fixed; top: calc(8px + var(--sat, 0px)); left: 10px; right: 10px; z-index: 10050;
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 6px 22px rgba(0,0,0,0.4); cursor: pointer;
  animation: chatInAppIn 0.22s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes chatInAppIn { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: none; } }
.chat-inapp-ava { width: 38px; height: 38px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.chat-inapp-ava.chat-group-avatar, .chat-inapp-ava.chat-group-ava-img { width: 38px; height: 38px; }
.chat-inapp-text { flex: 1; min-width: 0; }
.chat-inapp-title { font-size: 14px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-inapp-preview { font-size: 13px; color: var(--subtext); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-inapp-close { flex-shrink: 0; background: none; border: none; cursor: pointer; color: var(--subtext); padding: 4px; display: flex; }

/* === @-упоминания === */
.chat-mention { background: rgba(128,128,128,0.18); border-radius: 4px; padding: 1px 5px; cursor: pointer; }
/* @everyone — заметнее обычного упоминания, не кликабельно в профиль. */
.chat-mention.chat-mention-all { background: rgba(0,150,250,0.22); color: var(--pixiv-blue); font-weight: 600; cursor: default; }
.chat-mention-panel { position: fixed; left: 8px; right: 8px; z-index: 9200;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.3); max-height: 220px; overflow-y: auto;
  overscroll-behavior: contain; touch-action: pan-y; -webkit-overflow-scrolling: touch; }
.chat-mention-item { display: flex; align-items: center; gap: 10px; padding: 10px 14px; cursor: pointer; }
.chat-mention-item:active { background: var(--bg); }
.chat-mention-ava { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.chat-mention-everyone { display: flex; align-items: center; justify-content: center; background: var(--pixiv-blue); color: #fff; }
.chat-mention-everyone .icon-sm { width: 18px; height: 18px; }
.chat-mention-name { font-size: 14px; font-weight: 600; color: var(--text); }

/* Плавающая кнопка «+» */
.chat-fab { position: absolute; right: 16px; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); width: 56px; height: 56px; border-radius: 50%; background: var(--pixiv-blue); border: none; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 14px rgba(0,0,0,0.45); cursor: pointer; z-index: 20; transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease; }
.chat-fab:active { transform: scale(0.9); }
.chat-fab.open { transform: rotate(90deg); box-shadow: 0 6px 20px rgba(0,0,0,0.55); }
.chat-fab.open:active { transform: rotate(90deg) scale(0.9); }
.chat-fab-icon { width: 26px; height: 26px; fill: #fff; transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); }
.chat-fab.open .chat-fab-icon { transform: rotate(45deg); }
/* кнопка «схлопывается» в точку — как будто превращается в выросшее из неё поле */
.chat-fab.morphed { opacity: 0; transform: scale(0.2); pointer-events: none; transition: opacity 0.22s ease, transform 0.32s cubic-bezier(0.4, 0, 1, 1); }

/* Меню FAB */
.chat-fab-menu { position: absolute; right: 18px; bottom: calc(88px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; align-items: flex-end; z-index: 20; gap: 12px; }
.chat-fab-item {
  display: flex; align-items: center; gap: 10px; background: none; border: none; cursor: pointer; padding: 0;
  transform-origin: bottom right;
  opacity: 0;
  transform: translateY(16px) scale(0.75);
  /* появление — с лёгким «перелётом» как в iOS; исчезновение — быстрое затухание вниз */
  transition: opacity 0.18s ease, transform 0.2s cubic-bezier(0.32, 0, 0.67, 0);
}
/* каскад закрытия: дальний от кнопки пункт исчезает первым */
.chat-fab-item:nth-child(1) { transition-delay: 0s; }
.chat-fab-item:nth-child(2) { transition-delay: 0.04s; }
.chat-fab-item:nth-child(3) { transition-delay: 0.08s; }
.chat-fab-item:nth-child(4) { transition-delay: 0.12s; }
.chat-fab-menu.open .chat-fab-item {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1), transform 0.42s cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* каскад: ближний к кнопке пункт всплывает первым */
.chat-fab-menu.open .chat-fab-item:nth-last-child(1) { transition-delay: 0.02s; }
.chat-fab-menu.open .chat-fab-item:nth-last-child(2) { transition-delay: 0.07s; }
.chat-fab-menu.open .chat-fab-item:nth-last-child(3) { transition-delay: 0.12s; }
.chat-fab-menu.open .chat-fab-item:nth-last-child(4) { transition-delay: 0.17s; }
.chat-fab-item-label { background: var(--surface); color: var(--text); font-size: 14px; font-weight: 500; padding: 7px 12px; border-radius: 9px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); white-space: nowrap; }
.chat-fab-item-ico { width: 44px; height: 44px; border-radius: 50%; background: var(--surface); display: flex; align-items: center; justify-content: center; color: var(--pixiv-blue); box-shadow: 0 2px 8px rgba(0,0,0,0.3); }
.chat-fab-item-ico .icon-sm { width: 20px; height: 20px; }

/* Затемнение под меню/шторки */
.chat-sheet-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 15; opacity: 0; pointer-events: none; transition: opacity 0.25s ease; }
.chat-sheet-overlay.show { opacity: 1; pointer-events: auto; }

/* Нижние шторки (новое сообщение / новая группа) */
.chat-bottom-sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: 25; display: flex; flex-direction: column; gap: 10px; background: var(--bg); border-top-left-radius: 18px; border-top-right-radius: 18px; padding: 8px 16px calc(20px + env(safe-area-inset-bottom, 0px)); box-shadow: 0 -8px 28px rgba(0,0,0,0.45); border-bottom: none; }
.chat-bottom-sheet-handle { width: 40px; height: 4px; border-radius: 2px; background: var(--border); margin: 4px auto 6px; flex-shrink: 0; }
.chat-bottom-sheet-title { font-size: 17px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
.chat-bottom-sheet .chat-newchat-bar { padding: 0; border-bottom: none; }

/* ===== Морф: шторка «вырастает» из кнопки + (контейнерный трансформ, iOS-стиль) =====
   Точка роста — центр FAB: ~44px от правого края, ~48px от низа (плюс safe-area). */
.chat-bottom-sheet { transform-origin: calc(100% - 44px) calc(100% - 48px - env(safe-area-inset-bottom, 0px)); }
.chat-bottom-sheet.sheet-morph-in  { animation: chatSheetMorphIn  0.44s cubic-bezier(0.22, 1, 0.36, 1) both; }
.chat-bottom-sheet.sheet-morph-out { animation: chatSheetMorphOut 0.26s cubic-bezier(0.4, 0, 1, 1) both; }
@keyframes chatSheetMorphIn {
  0%   { opacity: 0; transform: scale(0.14); border-radius: 28px; }
  45%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1); border-radius: 18px 18px 0 0; }
}
@keyframes chatSheetMorphOut {
  0%   { opacity: 1; transform: scale(1); border-radius: 18px 18px 0 0; }
  100% { opacity: 0; transform: scale(0.14); border-radius: 28px; }
}
/* содержимое проявляется, когда контейнер уже почти развернулся — без «растягивания» текста */
.chat-bottom-sheet.sheet-morph-in > * { animation: chatSheetContentIn 0.26s ease 0.14s both; }
@keyframes chatSheetContentIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Пустое состояние — по центру области списка */
.chat-contacts-empty { position: absolute; left: 0; right: 0; top: 120px; bottom: 0; display: flex; align-items: center; justify-content: center; color: var(--subtext); z-index: 1; pointer-events: none; text-align: center; padding: 0 24px; }
