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
+24 -51
View File
@@ -531,10 +531,10 @@ export function render({navigate, chrome}) {
function styleSupportInputField(field) {
if (!field) return;
field.style.color = '#111111';
field.style.webkitTextFillColor = '#111111';
field.style.caretColor = '#111111';
field.style.backgroundColor = '#ffffff';
field.style.color = 'var(--text-primary)';
field.style.webkitTextFillColor = 'var(--text-primary)';
field.style.caretColor = 'var(--accent)';
field.style.backgroundColor = 'var(--surface)';
}
function renderSupportHub() {
@@ -1283,55 +1283,28 @@ export function render({navigate, chrome}) {
content.innerHTML = '';
const card = document.createElement('div');
card.className = 'card stack';
card.innerHTML = `
<h2 style="margin:0 0 6px;">Кошелёк</h2>
<p class="meta-muted">Выберите режим кошелька.</p>
`;
const solanaBtn = document.createElement('button');
solanaBtn.className = 'primary-btn';
solanaBtn.style.width = '100%';
solanaBtn.textContent = 'Solana кошелёк';
solanaBtn.addEventListener('click', () => {
void renderSolanaWallet();
card.className = 'nav-list';
const items = [
['Solana кошелёк', 'Баланс SOL', () => renderSolanaWallet()],
['Arweave кошелёк', 'Баланс AR', () => renderArweaveWallet()],
['Предоплаченное место Сияния', 'Лимит, израсходовано и остаток', () => renderShineBlockchainWallet()],
['Закрепление в Solana', 'Что закреплено в Solana и на сервере', () => renderSolanaPublishWallet()],
['Поддержать проект Сияние', 'Билеты и справка', () => renderSupportHub()],
];
const buttons = items.map(([label, hint, open]) => {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'nav-row';
btn.innerHTML = `<span class="nav-row__label"></span><span class="nav-row__hint"></span>`;
btn.querySelector('.nav-row__label').textContent = label;
btn.querySelector('.nav-row__hint').textContent = hint;
btn.addEventListener('click', () => { void open(); });
return btn;
});
const arweaveBtn = document.createElement('button');
arweaveBtn.className = 'primary-btn';
arweaveBtn.style.width = '100%';
arweaveBtn.textContent = 'Arweave кошелёк';
arweaveBtn.addEventListener('click', () => {
void renderArweaveWallet();
});
const shineBchBtn = document.createElement('button');
shineBchBtn.className = 'primary-btn';
shineBchBtn.style.width = '100%';
shineBchBtn.textContent = 'Предоплаченное место Сияния';
shineBchBtn.addEventListener('click', () => {
void renderShineBlockchainWallet();
});
const solanaPublishBtn = document.createElement('button');
solanaPublishBtn.className = 'primary-btn';
solanaPublishBtn.style.width = '100%';
solanaPublishBtn.textContent = 'Закрепление в Solana';
solanaPublishBtn.addEventListener('click', () => {
void renderSolanaPublishWallet();
});
const supportBtn = document.createElement('button');
supportBtn.className = 'primary-btn';
supportBtn.style.width = '100%';
supportBtn.textContent = 'Поддержать проект Сияние';
supportBtn.addEventListener('click', () => {
void renderSupportHub();
});
const [solanaBtn, arweaveBtn, shineBchBtn, solanaPublishBtn, supportBtn] = buttons;
card.append(solanaBtn, arweaveBtn, shineBchBtn, solanaPublishBtn, supportBtn);
content.append(card);
setStatus('Выберите тип кошелька.');
setStatus('');
}
async function renderShineBlockchainWallet() {
@@ -2051,7 +2024,7 @@ export function render({navigate, chrome}) {
helpCard.innerHTML = `
<summary style="cursor:pointer; font-weight:600;">Как получен этот адрес?</summary>
<p class="meta-muted" style="margin-top:8px;">
SHiNE берёт ваш локальный client.key и по стандарту SAWD-v1 получает из него нативный Arweave-кошелёк.
Сияние берёт ваш локальный client.key и по стандарту SAWD-v1 получает из него нативный Arweave-кошелёк.
Приватный ключ не отправляется на сервер. После первого расчёта он хранится только в зашифрованном контейнере этого устройства.
</p>
`;