Files
SHiNE-server/shine-UI/styles/features/chat.css
T
qandClaude Opus 5.5 f8900e531a UI: новый общий стиль, тёмная/светлая тема, настраиваемая палитра
- styles/main.css: роли цветов (по умолчанию «Индиго»), шкала отступов/скруглений/шрифтов,
  цвета отношений для обеих тем; жёсткие цвета в стилях заменены на роли.
- Палитра: пресеты и личные правки, «Оформление» Авто/День/Ночь, долгое нажатие —
  редактор цветов с экспортом/импортом.
- Каналы: пузыри постов автора, плашки дней, строка «Написать в канал…», «О канале»,
  создание канала с адресом из названия; лента открывается на свежих постах.
- Чаты: плоский список, чипы-фильтры, пузыри, плашки дней; нижняя панель скрыта в переписке.
- Корневые разделы — единая шапка; профиль и чужой профиль — общая карточка;
  настройки, кошелёк, сеансы — меню-списки.
- Нижняя панель: иконки без подписей, бейджи на иконках.
- confirmDialog вместо window.confirm/alert; на телефоне диалоги — шторки снизу.
- docs/UI-Design/ISSUES-for-dev.md — найденные ошибки сервера/UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:05:26 +03:00

1454 lines
30 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Direct chat screen and composer/message styles. */
.chat-header-icon-btn {
min-width: 44px;
width: 44px;
min-height: 44px;
height: 44px;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 20px;
line-height: 1;
}
.chat-header-call-btn {
border-radius: 12px;
}
.chat-header-menu-btn {
border-radius: 12px;
font-size: 24px;
}
.chat-unread-separator {
display: flex;
align-items: center;
gap: 10px;
margin: 8px 0;
color: var(--accent);
font-size: 12px;
}
.chat-unread-separator::before,
.chat-unread-separator::after {
content: "";
flex: 1 1 auto;
height: 1px;
background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 12%, transparent), color-mix(in srgb, var(--accent) 45%, transparent), color-mix(in srgb, var(--accent) 12%, transparent));
}
.chat-unread-separator > span {
white-space: nowrap;
}
.bubble {
max-width: 76%;
padding: 10px 12px;
border-radius: 14px;
font-size: 14px;
line-height: 1.35;
}
.bubble-text {
white-space: pre-wrap;
word-break: break-word;
}
.bubble-reply-preview {
display: block;
width: 100%;
margin: 0 0 8px;
padding: 8px 10px;
border-radius: 10px;
text-align: left;
cursor: pointer;
}
.bubble-reply-preview-author {
font-size: 12px;
font-weight: 700;
color: var(--warning);
}
.bubble-reply-preview-text {
margin-top: 3px;
font-size: 12px;
line-height: 1.3;
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.bubble-meta {
margin-top: 4px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 5px;
font-size: 11px;
line-height: 1.1;
color: var(--text-primary);
}
.bubble-meta-edited {
margin-top: 3px;
justify-content: flex-end;
color: var(--warning);
}
.bubble-time {
letter-spacing: 0.01em;
}
.bubble-status {
min-width: 14px;
text-align: right;
color: var(--text-primary);
}
.bubble-status--delivered,
.bubble-status--read {
color: var(--text-primary);
text-shadow: 0 0 6px color-mix(in srgb, var(--accent) 36%, transparent);
}
.bubble-status--failed {
color: var(--danger);
}
.bubble-delivery-note {
max-width: 280px;
margin-top: 6px;
font-size: 11px;
line-height: 1.3;
color: var(--warning);
}
.bubble-delivery-note--failed {
color: var(--danger);
}
.bubble.in {
justify-self: start;
background: var(--surface);
border-top-left-radius: 6px;
}
.bubble.out {
justify-self: end;
background: var(--surface);
border-top-right-radius: 6px;
}
.bubble.call-tech {
max-width: 90%;
justify-self: center;
border-radius: 16px;
border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
background: var(--surface);
color: var(--text-primary);
font-size: 12px;
padding: 12px 14px;
}
.bubble-call-card {
display: grid;
min-width: min(280px, 72vw);
}
.bubble-call-head {
display: inline-flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.bubble-call-icon {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
color: var(--text-primary);
flex: 0 0 auto;
}
.bubble-call-icon-phone {
font-size: 28px;
line-height: 1;
transform: translateY(-1px);
}
.bubble-call-icon-arrow {
position: absolute;
right: 4px;
bottom: 3px;
font-size: 11px;
line-height: 1;
font-weight: 700;
}
.bubble-call-icon--incoming .bubble-call-icon-arrow {
color: var(--text-primary);
}
.bubble-call-icon--outgoing .bubble-call-icon-arrow {
color: var(--warning);
}
.bubble-call-title {
font-size: 14px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.bubble-call-line {
font-size: 12px;
line-height: 1.2;
margin-left: 2px;
}
.bubble-call-line--success {
color: var(--success);
}
.bubble-call-line--plain {
color: var(--text-primary);
}
.dm-chat-wrap {
gap: 12px;
}
.dm-chat-screen {
display: flex;
flex-direction: column;
min-height: 0;
gap: 12px;
}
.dm-chat-screen > .dm-chat-wrap {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
}
.dm-chat-composer {
position: sticky;
bottom: 0;
z-index: 12;
flex: 0 0 auto;
}
.screen-content:has(> .dm-chat-screen) > .dm-chat-screen {
flex: 1 1 auto;
min-height: 0;
}
.screen-content:has(> .dm-chat-screen) {
display: flex;
flex-direction: column;
overflow: hidden;
padding-top: 0;
padding-bottom: 0;
scrollbar-width: none;
-ms-overflow-style: none;
}
.screen-content:has(> .dm-chat-screen)::-webkit-scrollbar {
width: 0;
height: 0;
display: none;
}
.dm-messages-log {
gap: 10px;
}
.dm-screen .bubble {
max-width: 78%;
padding: 11px 14px;
line-height: 1.42;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
}
.dm-screen .bubble.in {
justify-self: start;
border-radius: 18px 18px 18px 4px;
border: 1px solid var(--border-subtle);
background: var(--surface);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.dm-screen .bubble.out {
justify-self: end;
border-radius: 18px 18px 4px 18px;
border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
background: color-mix(in srgb, var(--accent) 16%, transparent);
color: var(--text-primary);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.dm-edit-banner {
grid-column: 1 / -1;
display: grid;
grid-template-columns: 1fr auto;
align-items: start;
gap: 10px;
padding: 10px 12px;
border-radius: 14px;
border: 1px solid transparent;
background: color-mix(in srgb, var(--warning) 12%, transparent);
color: var(--text-primary);
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.22);
}
.dm-edit-banner[hidden] {
display: none;
}
.dm-edit-banner__text {
min-width: 0;
font-size: 12px;
line-height: 1.35;
white-space: pre-line;
overflow: hidden;
}
.dm-edit-banner__close {
min-width: 30px;
width: 30px;
height: 30px;
padding: 0;
border-radius: 10px;
}
.dm-chat-input--multiline .dm-actions-col {
grid-template-columns: 46px;
grid-template-rows: repeat(2, 46px);
grid-template-areas:
"emoji"
"send";
}
.dm-emoji-btn {
grid-area: emoji;
min-width: 46px;
width: 46px;
padding: 0;
line-height: 1;
}
.dm-emoji-btn__glyph {
display: inline-grid;
place-items: center;
width: 100%;
height: 100%;
font-size: 27px;
line-height: 1;
}
.bubble.bubble--emoji-only,
.dm-screen .bubble.bubble--emoji-only {
padding: 0;
border: 0;
background: transparent;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
color: inherit;
}
.bubble.bubble--emoji-only.in,
.dm-screen .bubble.bubble--emoji-only.in,
.bubble.bubble--emoji-only.out,
.dm-screen .bubble.bubble--emoji-only.out {
border: 0;
background: transparent;
}
.bubble.bubble--emoji-only .bubble-meta {
margin-top: 2px;
padding: 0 4px;
color: var(--text-secondary);
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.bubble-text--twemoji-only {
font-size: 56px;
line-height: 1;
}
.bubble-text--twemoji-only .chat-twemoji {
width: 1em;
height: 1em;
}
.dm-chat-input .dm-input {
min-height: 42px;
max-height: 180px;
width: 100%;
min-width: 0;
resize: none;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
line-height: 1.35;
padding: 10px 12px;
}
.dm-chat-input--multiline .dm-input {
padding-right: 14px;
}
.dm-chat-input .dm-input::-webkit-scrollbar {
width: 0;
height: 0;
}
.dm-input {
background: color-mix(in srgb, var(--text-primary) 4%, transparent);
border: 1px solid transparent;
border-radius: 14px;
color: var(--text-primary);
}
.dm-input::placeholder {
color: var(--text-secondary);
}
.dm-send-btn {
background: color-mix(in srgb, var(--warning) 20%, transparent);
border: 1px solid transparent;
color: var(--warning);
border-radius: 14px;
font-weight: 700;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
.dm-send-icon-btn {
grid-area: send;
min-width: 46px;
width: 46px;
padding: 0;
font-size: 15px;
line-height: 1;
}
.dm-message-actions-popover {
position: fixed;
left: 12px;
top: 12px;
margin: 0;
pointer-events: auto;
opacity: 0;
transform: translateY(8px) scale(0.98);
transition: opacity 120ms ease, transform 120ms ease;
box-shadow: 0 18px 34px rgba(0, 0, 0, 0.42);
}
.dm-message-actions-popover.is-visible {
opacity: 1;
transform: translateY(0) scale(1);
}
.dm-message-action-btn {
width: 100%;
min-height: 42px;
justify-content: flex-start;
padding: 0 14px;
border-radius: 12px;
}
.dm-message-action-btn--danger {
color: var(--text-primary);
border-color: color-mix(in srgb, var(--danger) 30%, transparent);
background: color-mix(in srgb, var(--surface) 22%, transparent);
}
/* Чат: в центре только компактная идентичность собеседника. */
.chat-header-identity {
min-width: 0;
max-width: 132px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 7px;
}
.chat-header-avatar-slot {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.chat-header-avatar.avatar,
.chat-header-avatar.avatar-image {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
font-size: 14px;
border: 0;
box-shadow: none;
}
/* Фиксированная высота, а не только min-height: при смене основных вкладок
* верхняя граница контента больше не меняется из-за локальной шапки страницы. */
/* Один и тот же текстовый ритм на Контактах / Каналах / Связях /
* Уведомлениях / Профиле и вложенных экранах. */
/* В списке контактов логин слева также остаётся в общей палитре шапки. */
/* Все интерактивные элементы верхней шапки имеют одинаковую рабочую высоту. */
/* Личный чат: аватар остаётся компактным, логин теперь равен общему 18px. */
.chat-header-identity {
max-width: 176px;
gap: 8px;
}
/* Личный чат: логин остаётся строго в центральной колонке,
* аватар живёт отдельно в левой колонке рядом со стрелкой назад. */
.chat-header-login {
min-width: 0;
font-family: var(--font-main);
font-size: 18px;
line-height: 22px;
font-weight: 700;
color: var(--app-topbar-gold);
text-shadow: 0 0 5px var(--app-topbar-blue-glow),
0 0 14px var(--app-topbar-blue-glow-soft);
display: block;
max-width: min(42vw, 180px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
}
.chat-header-avatar-slot--left {
flex: 0 0 28px;
margin-left: 0;
}
.chat-header-connections-btn,
.chat-header-avatar-btn {
padding: 0;
min-width: 0;
min-height: 0;
border: 0;
background: transparent;
box-shadow: none;
transform: none;
}
.chat-header-connections-btn:hover,
.chat-header-connections-btn:active,
.chat-header-connections-btn:focus,
.chat-header-connections-btn:focus-visible,
.chat-header-avatar-btn:hover,
.chat-header-avatar-btn:active,
.chat-header-avatar-btn:focus,
.chat-header-avatar-btn:focus-visible {
border: 0;
background: transparent;
box-shadow: none;
transform: none;
}
.chat-header-connections-btn {
width: 38px;
height: 38px;
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--surface);
border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 8%, transparent), 0 0 12px color-mix(in srgb, var(--accent) 18%, transparent);
}
.chat-header-connections-btn:hover,
.chat-header-connections-btn:focus-visible {
border-color: color-mix(in srgb, var(--accent) 38%, transparent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 16%, transparent), 0 0 16px color-mix(in srgb, var(--accent) 28%, transparent);
}
.chat-header-connections-logo {
width: 24px;
height: 24px;
object-fit: contain;
display: block;
}
.chat-header-avatar-btn {
display: inline-flex;
align-items: center;
justify-content: center;
}
.chat-header-avatar-btn .chat-header-avatar-slot {
display: inline-flex;
}
/* Пузырям сообщений не нужна отдельная обводка: направление читается по фону и геометрии. */
.dm-chat-screen .bubble,
.dm-chat-screen .bubble.in,
.dm-chat-screen .bubble.out,
.dm-chat-screen .bubble.call-tech {
border: 0;
}
.dm-chat-screen .bubble-reply-preview {
border: 0;
}
/* Нижняя панель чата повторяет бело-голубую цветовую роль верхнего toolbar вместо золота. */
.dm-chat-input .dm-input {
border-color: var(--border-subtle);
color: var(--app-topbar-gold);
text-shadow:
0 0 4px color-mix(in srgb, var(--accent) 34%, transparent),
0 0 10px color-mix(in srgb, var(--accent) 16%, transparent);
caret-color: var(--app-topbar-gold);
}
.dm-chat-input .dm-input:focus {
border-color: color-mix(in srgb, var(--accent) 28%, transparent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 8%, transparent);
}
.dm-chat-input .dm-input::placeholder {
color: var(--text-secondary);
text-shadow: none;
}
.dm-chat-input .dm-emoji-btn,
.dm-chat-input .dm-send-btn,
.dm-chat-input .dm-edit-banner__close {
color: var(--app-topbar-gold);
text-shadow:
0 0 5px var(--app-topbar-blue-glow),
0 0 12px var(--app-topbar-blue-glow-soft);
filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 42%, transparent));
}
.dm-chat-input .dm-send-btn {
border-color: var(--border-subtle);
background: color-mix(in srgb, var(--accent) 8%, transparent);
box-shadow: none;
}
.dm-chat-input .dm-edit-banner {
border-color: color-mix(in srgb, var(--accent) 18%, transparent);
background: color-mix(in srgb, var(--accent) 8%, transparent);
color: var(--app-topbar-gold);
}
.dm-chat-input .emoji-picker-tab.is-active {
background: color-mix(in srgb, var(--accent) 12%, transparent);
}
/* Composer должен быть продолжением основного фона: без верхнего разделителя
* и без отдельной затемнённой/стеклянной подложки. */
/* ===== Feature geometry around the centralized App Shell ===== */
/* DM: shell рисует global fade, а внутренний scroll-container только резервирует
* место под TopBar/Composer, не реализуя собственное глобальное затухание. */
.app-shell--scroll-nested .dm-chat-screen > .dm-chat-wrap {
box-sizing: border-box;
padding-top: calc(var(--topbar-height, 64px) + 12px);
padding-bottom: calc(var(--composer-height, 0px) + 52px);
}
/* Один визуальный язык для меню профиля, чатов и каналов. */
.dm-message-action-btn {
width: 100%;
min-height: 42px;
padding: 0 11px;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 10px;
border: 0;
border-radius: 10px;
background: transparent;
color: var(--text-primary);
font: inherit;
font-size: 14px;
font-weight: 600;
line-height: 1.2;
text-align: left;
white-space: nowrap;
}
.dm-message-action-btn:hover,
.dm-message-action-btn:focus-visible {
outline: none;
background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.dm-message-action-btn--danger {
color: var(--text-primary);
background: transparent;
}
.dm-message-actions-menu {
min-width: 196px;
padding: 6px;
gap: 2px;
border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
border-radius: 16px;
background: linear-gradient(155deg, var(--surface), var(--surface));
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.48),
0 0 24px color-mix(in srgb, var(--accent) 10%, transparent),
inset 0 1px 0 color-mix(in srgb, var(--text-primary) 6%, transparent);
backdrop-filter: blur(20px) saturate(125%);
-webkit-backdrop-filter: blur(20px) saturate(125%);
width: min(78vw, 240px);
}
.chat-header-login-btn {
padding: 4px 7px;
min-height: 34px;
border: 0;
border-radius: 10px;
background: transparent;
cursor: pointer;
}
/* Поле сообщения занимает почти всю ширину; действия прижаты к правому краю. */
.composer-slot:has(> .dm-chat-input) {
padding-left: 0;
padding-right: 4px;
}
.dm-chat-input {
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
position: relative;
z-index: 10;
margin-inline: 0;
padding: 10px 0;
border-top: 0;
background: transparent;
backdrop-filter: none;
-webkit-backdrop-filter: none;
gap: 4px;
padding-left: 0;
padding-right: 0;
}
.dm-chat-input--multiline .dm-actions-col {
grid-template-columns: 43px;
}
.dm-emoji-btn,
.dm-send-icon-btn {
min-width: 43px;
width: 43px;
}
/* DM peer identity: one large invisible button fills the area between Back and Call. */
.chat-header-peer-btn {
width: 100%;
min-width: 0;
min-height: 46px;
padding: 2px 0;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 7px;
text-align: left;
cursor: pointer;
}
.chat-header-peer-btn .chat-header-avatar-slot {
flex: 0 0 40px;
}
.chat-header-peer-text {
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 2px;
}
.chat-header-peer-name,
.chat-header-peer-meta {
display: block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.chat-header-peer-name {
font-size: 14px;
line-height: 1.15;
font-weight: 650;
color: var(--text-primary);
}
.chat-header-peer-meta {
font-size: 11px;
line-height: 1.15;
font-weight: 500;
color: var(--text-secondary);
}
/* ===== DM header regression fix (2026-09-02) =====
* The peer identity button intentionally spans the whole free header area.
* Its avatar uses a 119% glass overlay, so neither the center cell nor the
* button may clip overflow. Text keeps its own ellipsis boundary instead.
*/
.chat-header-peer-btn {
overflow: visible;
padding-inline: 2px;
}
.chat-header-peer-btn .chat-header-avatar-slot {
width: 44px;
height: 44px;
min-width: 44px;
min-height: 44px;
flex: 0 0 44px;
overflow: visible;
}
.chat-header-peer-btn .chat-header-avatar-slot .chat-header-avatar {
overflow: visible;
}
.chat-header-peer-text {
flex: 1 1 auto;
overflow: hidden;
}
/* Shell state + Chat-owned composer adjustment (moved out of app-shell.css). */
.app-shell--scroll-nested.keyboard-open .composer-slot .dm-chat-input {
padding-bottom: 0;
}
/* Composer icon actions own their white/blue interaction surface. */
.dm-chat-input :is(.dm-emoji-btn, .dm-send-btn, .dm-edit-banner__close),
.dm-chat-input :is(.dm-emoji-btn, .dm-send-btn, .dm-edit-banner__close):hover,
.dm-chat-input :is(.dm-emoji-btn, .dm-send-btn, .dm-edit-banner__close):focus {
color: var(--text-primary);
text-shadow: 0 0 5px color-mix(in srgb, var(--accent) 72%, transparent), 0 0 12px color-mix(in srgb, var(--accent) 34%, transparent);
filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 46%, transparent));
}
/* ===== Зашифрованные вложения в личных сообщениях ===== */
.dm-file-btn {
position: absolute;
right: 45px;
bottom: 52px;
z-index: 6;
min-width: 43px;
width: 43px;
height: 43px;
padding: 0;
border-radius: 14px;
font-size: 21px;
line-height: 1;
background: var(--surface);
border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 8%, transparent);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
}
.dm-file-btn[hidden] {
display: none;
}
.dm-file-btn:disabled {
opacity: 0.7;
cursor: progress;
}
.dm-file-card {
min-width: min(285px, 72vw);
max-width: min(330px, 76vw);
display: grid;
grid-template-columns: 36px minmax(0, 1fr) auto;
align-items: center;
gap: 9px;
}
.dm-file-card__icon {
width: 36px;
height: 36px;
display: grid;
place-items: center;
border-radius: 12px;
background: color-mix(in srgb, var(--text-primary) 8%, transparent);
font-size: 19px;
}
.dm-file-card__copy {
min-width: 0;
display: grid;
gap: 3px;
}
.dm-file-card__name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
font-weight: 680;
}
.dm-file-card__meta {
font-size: 11px;
color: var(--text-secondary);
}
.dm-file-card__download {
min-height: 34px;
padding: 0 10px;
border-radius: 11px;
font-size: 12px;
font-weight: 650;
white-space: nowrap;
}
.dm-file-card__download:disabled {
opacity: 0.65;
cursor: progress;
}
@media (max-width: 390px) {
.dm-screen .dm-file-card {
min-width: min(264px, 76vw);
grid-template-columns: 32px minmax(0, 1fr);
}
.dm-screen .dm-file-card__download {
grid-column: 2;
justify-self: start;
}
}
.dm-chat-input--multiline .dm-file-btn {
right: 0;
bottom: 104px;
}
/* ===== DM file transfer v2 + voice notes ===== */
.dm-attachment-stack {
display: grid;
gap: 8px;
min-width: 0;
}
.dm-send-icon-btn svg {
width: 22px;
height: 22px;
display: block;
margin: auto;
}
.dm-send-icon-btn.is-recording {
transform: scale(1.04);
box-shadow: 0 0 0 5px color-mix(in srgb, var(--danger) 8%, transparent), 0 0 24px color-mix(in srgb, var(--danger) 18%, transparent);
}
.dm-send-icon-btn.is-recording:not(.is-locked) {
color: var(--text-primary);
}
.dm-send-icon-btn.is-locked {
color: var(--text-primary);
background: color-mix(in srgb, var(--danger) 28%, transparent);
border-color: color-mix(in srgb, var(--danger) 32%, transparent);
}
.dm-send-busy-dot {
display: inline-grid;
place-items: center;
width: 100%;
height: 100%;
font-size: 20px;
line-height: 1;
}
.dm-voice-recording-status {
grid-column: 1;
min-height: 42px;
display: grid;
grid-template-columns: auto auto minmax(0, 1fr);
align-items: center;
gap: 8px;
padding: 0 12px;
border: 1px solid var(--border-subtle);
border-radius: 14px;
background: color-mix(in srgb, var(--text-primary) 4%, transparent);
overflow: hidden;
}
.dm-voice-recording-status[hidden] {
display: none;
}
.dm-voice-recording-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: color-mix(in srgb, var(--danger) 96%, transparent);
box-shadow: 0 0 12px color-mix(in srgb, var(--danger) 55%, transparent);
animation: dmVoicePulse 1s ease-in-out infinite;
}
@keyframes dmVoicePulse {
0%, 100% { opacity: 0.55; transform: scale(0.82); }
50% { opacity: 1; transform: scale(1); }
}
.dm-voice-recording-time {
font-variant-numeric: tabular-nums;
font-size: 13px;
font-weight: 720;
color: var(--text-primary);
}
.dm-voice-recording-hint {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: right;
font-size: 11px;
color: var(--text-secondary);
}
.dm-chat-input--recording .dm-actions-col {
align-self: center;
}
.dm-voice-card {
min-width: min(280px, 72vw);
max-width: min(330px, 76vw);
display: grid;
grid-template-columns: 42px minmax(0, 1fr);
align-items: center;
gap: 10px;
}
.dm-voice-card__play {
width: 42px;
height: 42px;
min-width: 42px;
padding: 0;
border-radius: 50%;
display: grid;
place-items: center;
font-size: 15px;
line-height: 1;
background: color-mix(in srgb, var(--accent) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.dm-voice-card__play:disabled {
opacity: 0.65;
cursor: progress;
}
.dm-voice-card__body {
min-width: 0;
display: grid;
gap: 6px;
}
.dm-voice-card__track {
position: relative;
width: 100%;
height: 18px;
min-height: 18px;
padding: 0;
border: 0;
background: transparent;
overflow: hidden;
}
.dm-voice-card__track::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 8px;
height: 2px;
border-radius: 999px;
background: color-mix(in srgb, var(--text-primary) 20%, transparent);
}
.dm-voice-card__fill {
position: absolute;
left: 0;
top: 7px;
width: 0;
height: 4px;
border-radius: 999px;
background: currentColor;
box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 35%, transparent);
pointer-events: none;
}
.dm-voice-card__meta {
display: flex;
justify-content: space-between;
gap: 10px;
font-size: 11px;
color: var(--text-secondary);
font-variant-numeric: tabular-nums;
}
@media (max-width: 390px) {
.dm-voice-card {
min-width: min(252px, 76vw);
}
.dm-voice-recording-hint {
max-width: 150px;
}
}
/* Пересылка DM: выбор чата и подтверждение остаются внутри одного feature-owned modal. */
.dm-forward-modal {
align-items: center;
padding: 18px;
}
.dm-forward-card {
width: min(92vw, 430px);
max-height: min(78vh, 680px);
overflow: hidden;
gap: 12px;
border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
border-radius: 24px;
background: linear-gradient(155deg, var(--surface), var(--surface));
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.52), 0 0 34px color-mix(in srgb, var(--accent) 12%, transparent);
backdrop-filter: blur(24px) saturate(130%);
-webkit-backdrop-filter: blur(24px) saturate(130%);
}
.dm-forward-head,
.dm-forward-confirm-peer {
display: flex;
align-items: center;
gap: 12px;
}
.dm-forward-head {
justify-content: space-between;
}
.dm-forward-close {
width: 36px;
height: 36px;
border-radius: 50%;
font-size: 25px;
line-height: 1;
color: var(--text-primary);
background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.dm-forward-preview {
padding: 11px 13px;
border: 1px solid var(--border-subtle);
border-radius: 14px;
color: var(--text-primary);
background: color-mix(in srgb, var(--text-primary) 4%, transparent);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dm-forward-preview--confirm {
white-space: normal;
max-height: 128px;
overflow: auto;
}
.dm-forward-list {
display: flex;
flex-direction: column;
gap: 4px;
min-height: 120px;
max-height: min(54vh, 460px);
overflow-y: auto;
padding-right: 2px;
}
.dm-forward-chat-row {
width: 100%;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 11px;
min-height: 62px;
padding: 8px 10px;
border: 0;
border-radius: 15px;
text-align: left;
color: var(--text);
background: transparent;
}
.dm-forward-chat-row:hover,
.dm-forward-chat-row:focus-visible {
outline: none;
background: color-mix(in srgb, var(--accent) 11%, transparent);
}
.dm-forward-chat-copy {
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.dm-forward-chat-copy strong,
.dm-forward-chat-copy span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dm-forward-chat-arrow {
font-size: 28px;
color: var(--accent);
}
.dm-forward-loading {
padding: 20px 8px;
text-align: center;
}
.dm-forward-confirm-peer {
padding: 12px;
border-radius: 16px;
background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.dm-forward-confirm-actions {
margin-top: 2px;
}
.chat-header-peer-btn { border: 0; background: transparent; color: inherit; font: inherit; }
.chat-header-peer-btn:hover { background: var(--surface); }
.chat-header-peer-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.chat-header-peer-name { font-size: var(--text-md); font-weight: var(--weight-bold); }
.chat-header-peer-meta { font-size: var(--text-xs); }
.dm-chat-screen .bubble {
max-width: min(80%, 34rem);
padding: 8px 12px 6px;
border-radius: var(--radius-lg);
color: var(--text-primary);
font-size: var(--text-md);
line-height: var(--leading-md);
box-shadow: none;
}
.dm-chat-screen .bubble.in {
background: var(--surface);
border: 1px solid var(--border-subtle);
border-bottom-left-radius: var(--radius-xs);
border-top-left-radius: var(--radius-lg);
}
.dm-chat-screen .bubble.out {
background: color-mix(in srgb, var(--accent) 24%, var(--surface));
border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border-subtle));
border-bottom-right-radius: var(--radius-xs);
border-top-right-radius: var(--radius-lg);
}
.dm-chat-screen .bubble-meta { font-size: .6875rem; line-height: 1rem; color: var(--text-secondary); }
.dm-chat-screen .bubble-status--read { color: var(--accent); }
.dm-day-separator { display: flex; justify-content: center; margin: 8px 0; }
.dm-day-separator span { padding: 3px 10px; border-radius: var(--radius-pill); color: var(--text-secondary); background: var(--surface); border: 1px solid var(--border-subtle); font-size: var(--text-xs); line-height: var(--leading-xs); }
.dm-chat-input .dm-input {
min-height: var(--control-height);
border: 1px solid var(--border-control);
border-radius: 22px;
color: var(--text-primary);
background: var(--surface);
text-shadow: none;
caret-color: var(--accent);
font-size: 1rem;
}
.dm-chat-input .dm-input:focus { border-color: var(--accent); box-shadow: none; }
.dm-chat-input .dm-input::placeholder { color: color-mix(in srgb, var(--text-secondary) 62%, var(--surface)); }
.dm-chat-input .dm-emoji-btn,
.dm-chat-input .dm-edit-banner__close { color: var(--text-secondary); text-shadow: none; filter: none; }
.dm-chat-input .dm-send-btn {
color: var(--on-accent);
background: var(--accent);
border: 0;
text-shadow: none;
filter: none;
}
.dm-chat-input .dm-edit-banner { color: var(--text-primary); }
.composer-slot:has(> .dm-chat-input) { padding-inline: var(--page-gutter); }
.dm-chat-input .dm-send-btn { width: 44px; min-width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%; }