Пересобрать верхний UI-бар

This commit is contained in:
2026-08-22 12:34:07 +03:00
parent bc8c7f318b
commit f5e401cff8
14 changed files with 700 additions and 98 deletions
+535
View File
@@ -8193,3 +8193,538 @@ html, body { overflow-x: hidden; }
body.chat-topbar-overlay .app-shell.keyboard-open .scroll-to-bottom-btn {
bottom: calc(var(--keyboard-offset, 0px) + var(--composer-height, 0px) + 18px);
}
/* ===== Унифицированный верхний toolbar приложения =====
* Единая геометрия для основных экранов и вложенных страниц:
* слева действие/назад, по центру заголовок, справа действия.
*/
:root {
--app-topbar-base-height: 64px;
--app-topbar-title-size: 18px;
--app-topbar-bg: #05070A;
}
.page-header.app-topbar-shell {
display: grid;
grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr);
align-items: center;
gap: 8px;
}
.page-header.app-topbar-shell .header-center {
min-width: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.page-header.app-topbar-shell .header-left,
.page-header.app-topbar-shell .header-actions {
min-width: 0;
width: 100%;
}
.page-header.app-topbar-shell .header-left {
justify-content: flex-start;
}
.page-header.app-topbar-shell .header-actions {
justify-content: flex-end;
}
.page-header .page-title,
.topbar-slot .dm-head-title,
.topbar-slot .channels-top-title,
.app-topbar-title-action {
margin: 0;
min-width: 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--font-main);
font-size: var(--app-topbar-title-size);
line-height: 1.2;
font-weight: 700;
letter-spacing: 0;
color: rgba(255, 255, 255, 0.95);
text-shadow: none;
text-align: center;
}
.topbar-slot {
padding: 0 12px;
background: var(--app-topbar-bg);
}
.topbar-slot .page-header,
.topbar-slot .dm-head,
.topbar-slot .channels-top-bar {
width: 100%;
min-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
margin: 0;
padding: calc(10px + env(safe-area-inset-top)) 0 10px;
box-sizing: border-box;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
.topbar-slot .channels-top-bar {
display: grid;
grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr);
align-items: center;
gap: 8px;
}
.topbar-slot .channels-top-left,
.topbar-slot .channels-top-right {
width: 100%;
min-width: 0;
}
.topbar-slot .channels-top-left {
justify-content: flex-start;
}
.topbar-slot .channels-top-right {
justify-content: flex-end;
}
.topbar-slot .channels-top-title {
justify-self: center;
}
.app-topbar-shell--profile {
justify-content: stretch;
}
.app-topbar-shell--profile .header-left,
.app-topbar-shell--profile .header-actions,
.app-topbar-shell .header-left,
.app-topbar-shell .header-actions {
min-width: 0;
}
/* Одинаковая стрелка назад на всех экранах. Визуально чуть крупнее текста,
* чтобы сам глиф по воспринимаемому размеру совпадал с 18px заголовком. */
.header-back-btn,
.channels-top-back-btn.header-back-btn {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-main);
font-size: 24px;
line-height: 1;
font-weight: 500;
}
/* В канале и треде название остаётся кликабельным, но визуально является
* тем же центральным заголовком, а не отдельной кнопкой справа. */
.topbar-slot .app-topbar-title-action {
width: auto;
min-height: 40px;
padding: 0 4px;
justify-content: center;
}
.topbar-slot .channels-screen--thread .app-topbar-title-action,
.topbar-slot .channels-screen--channel .app-topbar-title-action {
max-width: 100%;
}
.topbar-slot .page-header.channel-thread-topbar {
display: grid;
grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr);
align-items: center;
gap: 8px;
}
.topbar-slot .page-header.channel-thread-topbar .header-left,
.topbar-slot .page-header.channel-thread-topbar .header-actions {
display: flex;
width: 100%;
min-width: 0;
flex: initial;
gap: 8px;
}
.topbar-slot .page-header.channel-thread-topbar .header-left {
justify-content: flex-start;
}
.topbar-slot .page-header.channel-thread-topbar .header-actions {
justify-content: flex-end;
}
.topbar-slot .page-header.channel-thread-topbar .header-center {
min-width: 0;
}
/* Чат: в центре только компактная идентичность собеседника. */
.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: 28px;
height: 28px;
min-width: 28px;
min-height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.chat-header-avatar.avatar,
.chat-header-avatar.avatar-image {
width: 28px;
height: 28px;
min-width: 28px;
min-height: 28px;
font-size: 11px;
border: 0;
box-shadow: none;
}
.chat-header-login {
min-width: 0;
max-width: 96px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--font-main);
font-size: 13px;
line-height: 1.15;
font-weight: 600;
color: rgba(255, 255, 255, 0.78);
}
/* «Связи» рисует шапку внутри сцены, поэтому повторяем тот же контракт там. */
.network-header-overlay,
.network-header-overlay.page-header {
top: 0;
left: 0;
right: 0;
min-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
margin: 0;
padding: calc(10px + env(safe-area-inset-top)) 12px 10px;
display: grid;
grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr);
align-items: center;
gap: 8px;
border: 0;
border-radius: 0;
background: var(--app-topbar-bg);
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
.network-header-overlay .header-center {
min-width: 0;
display: flex;
justify-content: center;
}
.network-header-overlay .page-title {
font-family: var(--font-main);
font-size: var(--app-topbar-title-size);
line-height: 1.2;
font-weight: 700;
letter-spacing: 0;
color: rgba(255, 255, 255, 0.95);
text-shadow: none;
}
.network-header-overlay .header-left,
.network-header-overlay .header-actions {
width: 100%;
min-width: 0;
}
.network-header-overlay .icon-btn {
min-height: 40px;
padding: 0 8px;
font-size: 14px;
border: 0;
background: transparent;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
.network-header-overlay .header-back-btn {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
padding: 0;
font-size: 24px;
}
/* ===== Верхний toolbar: финальная унификация геометрии и типографики ===== */
:root {
--app-topbar-gold: #F0C56B;
}
/* Фиксированная высота, а не только min-height: при смене основных вкладок
* верхняя граница контента больше не меняется из-за локальной шапки страницы. */
.topbar-slot .page-header,
.topbar-slot .dm-head,
.topbar-slot .channels-top-bar {
height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
min-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
max-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
padding-top: env(safe-area-inset-top);
padding-bottom: 0;
}
/* Один и тот же текстовый ритм на Контактах / Каналах / Связях /
* Уведомлениях / Профиле и вложенных экранах. */
.page-header .page-title,
.topbar-slot .dm-head-title,
.topbar-slot .channels-top-title,
.app-topbar-title-action,
.network-header-overlay .page-title {
font-family: var(--font-main);
font-size: 18px;
font-weight: 700;
font-style: normal;
line-height: 22px;
letter-spacing: 0;
color: var(--app-topbar-gold);
text-shadow: none;
}
/* В списке контактов логин слева также остаётся в общей палитре шапки. */
.topbar-slot .dm-head-name {
font-family: var(--font-main);
color: var(--app-topbar-gold);
}
/* Все интерактивные элементы верхней шапки имеют одинаковую рабочую высоту. */
.topbar-slot .icon-btn,
.topbar-slot .dm-head-menu-btn,
.topbar-slot .channels-top-more-btn {
min-height: 40px;
height: 40px;
color: var(--app-topbar-gold);
}
.topbar-slot .dm-head-menu-btn {
width: 40px;
min-width: 40px;
border-radius: 0;
}
.topbar-slot .channels-top-more-btn {
width: 40px;
min-width: 40px;
font-size: 24px;
line-height: 1;
}
/* Личный чат: аватар остаётся компактным, логин теперь равен общему 18px. */
.chat-header-identity {
max-width: 176px;
gap: 8px;
}
.chat-header-login {
max-width: 136px;
font-size: 18px;
line-height: 22px;
font-weight: 700;
color: var(--app-topbar-gold);
}
/* Связи живут вне topbar-slot, поэтому фиксируем ту же фактическую высоту. */
.network-header-overlay,
.network-header-overlay.page-header {
height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
min-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
max-height: calc(var(--app-topbar-base-height) + env(safe-area-inset-top));
padding-top: env(safe-area-inset-top);
padding-bottom: 0;
}
.network-header-overlay .icon-btn,
.network-header-overlay .header-back-btn {
color: var(--app-topbar-gold);
}
/* ===== Верхний toolbar: белый интерфейс с мягким синим свечением ===== */
:root {
--app-topbar-gold: #F7FBFF;
--app-topbar-blue-glow: rgba(92, 190, 255, 0.72);
--app-topbar-blue-glow-soft: rgba(72, 145, 255, 0.34);
}
.page-header .page-title,
.topbar-slot .dm-head-title,
.topbar-slot .channels-top-title,
.app-topbar-title-action,
.network-header-overlay .page-title,
.topbar-slot .dm-head-name,
.chat-header-login {
color: var(--app-topbar-gold);
text-shadow:
0 0 5px var(--app-topbar-blue-glow),
0 0 14px var(--app-topbar-blue-glow-soft);
}
.topbar-slot .icon-btn,
.topbar-slot .dm-head-menu-btn,
.topbar-slot .channels-top-more-btn,
.network-header-overlay .icon-btn,
.network-header-overlay .header-back-btn {
color: var(--app-topbar-gold);
text-shadow:
0 0 5px var(--app-topbar-blue-glow),
0 0 12px var(--app-topbar-blue-glow-soft);
}
.topbar-slot .icon-btn svg,
.network-header-overlay .icon-btn svg {
filter:
drop-shadow(0 0 3px var(--app-topbar-blue-glow))
drop-shadow(0 0 7px var(--app-topbar-blue-glow-soft));
}
.topbar-slot .dm-head-menu-dots i {
background: var(--app-topbar-gold);
box-shadow:
0 0 5px var(--app-topbar-blue-glow),
0 0 10px var(--app-topbar-blue-glow-soft);
}
/* Уведомления: переключатели лент повторяют стеклянные чипы экрана «Связи». */
.notifications-screen .notification-feed-tabs {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
padding: 8px 12px 4px;
margin: 0;
background: transparent;
border: 0;
box-shadow: none;
}
.notifications-screen .notification-feed-tabs .notification-tab-btn {
min-width: 92px;
text-align: center;
}
/* Личный чат: логин остаётся строго в центральной колонке,
* аватар живёт отдельно в левой колонке рядом со стрелкой назад. */
.page-header.app-topbar-shell .header-center {
overflow: hidden;
}
.chat-header-login {
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;
}
/* ===== Shared primary topbar + upper tabs geometry (2026-08-22) =====
* «Связи» теперь монтируют header в общий topbar-slot, как остальные основные экраны.
* Верхние переключатели используют один ритм и не меняют вертикальную позицию между страницами.
*/
:root {
--app-primary-tabs-top-gap: 14px;
--app-primary-tabs-gap: 8px;
--app-primary-tab-min-height: 28px;
}
/* Граф занимает ровно доступную область между общей шапкой и нижним toolbar. */
.screen-content.network-scroll-lock .network-screen {
width: 100%;
height: 100%;
min-height: 0;
margin: 0;
}
.screen-content.network-scroll-lock .network-stage {
width: 100%;
height: 100%;
min-height: 0;
}
/* Общий контейнер верхних кнопок-вкладок. */
.app-top-tabs {
min-height: var(--app-primary-tab-min-height);
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: var(--app-primary-tabs-gap);
margin: 0;
padding: 0;
border: 0;
background: transparent;
box-shadow: none;
}
/* На обычных экранах отступ создаёт стандартный padding screen-content (14px). */
.notifications-screen .notification-feed-tabs.app-top-tabs {
min-height: var(--app-primary-tab-min-height);
padding: 0;
margin: 0;
}
/* В «Связях» screen-content намеренно без padding, поэтому тот же отступ задаём явно. */
.network-stage > .fg-filter-bar.app-top-tabs {
position: absolute;
top: var(--app-primary-tabs-top-gap);
left: 14px;
right: 14px;
z-index: 11;
min-height: var(--app-primary-tab-min-height);
padding: 0;
}
/* Одинаковая фактическая высота и типографика самих верхних чипов. */
.app-top-tabs .fg-filter-chip {
min-height: var(--app-primary-tab-min-height);
height: var(--app-primary-tab-min-height);
padding: 0 14px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-main);
font-size: 12px;
font-weight: 600;
line-height: 1;
white-space: nowrap;
}
.notifications-screen .notification-feed-tabs .notification-tab-btn {
min-width: 92px;
}