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>
This commit is contained in:
q
2026-09-26 10:05:26 +03:00
co-authored by Claude Opus 5.5
parent 6e5b57fd7c
commit f8900e531a
94 changed files with 3337 additions and 2432 deletions
@@ -3,7 +3,7 @@ import { authService, setAuthError, setAuthInfo, state } from '../state.js';
import { deriveEspPairingPasswordHash } from '../services/device-pairing-service.js';
import { toUserMessage } from '../services/ui-error-texts.js';
export const pageMeta = { id: 'trusted-device-login-settings-view', title: 'Настройки входа через устройство' };
export const pageMeta = { id: 'trusted-device-login-settings-view', title: 'Вход с другого устройства' };
function setStatus(statusEl, message, kind = 'info') {
statusEl.classList.toggle('is-unavailable', kind === 'error');
@@ -38,15 +38,14 @@ export function render({navigate, chrome}) {
status.style.display = 'none';
const actions = document.createElement('div');
actions.className = 'row';
actions.style.flexWrap = 'wrap';
actions.className = 'stack trusted-login-actions';
const enableToggleBtn = document.createElement('button');
enableToggleBtn.className = 'primary-btn';
enableToggleBtn.type = 'button';
const noPasswordBtn = document.createElement('button');
noPasswordBtn.className = 'ghost-btn';
noPasswordBtn.className = 'secondary-btn';
noPasswordBtn.type = 'button';
noPasswordBtn.textContent = 'Сделать вход без пароля';
@@ -77,6 +76,7 @@ export function render({navigate, chrome}) {
busy = flag;
enableToggleBtn.disabled = flag;
noPasswordBtn.disabled = flag || !settings.enabled || !settings.hasPassword;
noPasswordBtn.hidden = !settings.enabled || !settings.hasPassword;
savePasswordBtn.disabled = flag;
passwordInput.disabled = flag;
passwordConfirmInput.disabled = flag;
@@ -87,6 +87,7 @@ export function render({navigate, chrome}) {
enableToggleBtn.textContent = settings.enabled
? 'Запретить вход через другое устройство'
: 'Разрешить вход через другое устройство';
enableToggleBtn.className = settings.enabled ? 'destructive-btn' : 'primary-btn';
actions.innerHTML = '';
actions.append(enableToggleBtn);
@@ -183,7 +184,7 @@ export function render({navigate, chrome}) {
});
chrome?.setTopbar(createTopBar({
title: 'Настройки входа через устройство',
title: 'Вход с другого устройства',
back: { label: '←', onClick: () => navigate('device-pairing-view') },
}));
screen.append(