From db6c4f32652344644808e0c356779d3b200b3999 Mon Sep 17 00:00:00 2001 From: wasrusgen Date: Sat, 16 May 2026 12:17:54 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20theme=20switching=20system=20=E2=80=94?= =?UTF-8?q?=204=20palettes=20(ZOV=20=C2=B7=20Foundry=20=C2=B7=20Boardroom?= =?UTF-8?q?=20=C2=B7=20Atelier)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - styles.css v5: replaced old 3-variant system with 4 design-token themes extracted from reference dashboards: · brand (ЗОВ): #003E7E blue / #76BD22 green, Inter · b Foundry: #EFE9D8 cream / #B68A1A mustard, Archivo, sharp corners · c Boardroom: #F2E9D6 linen / #D08A55 copper, Geist, petrol tones · d Atelier: #E9EBEF dove / #2E5266 steel-blue, Manrope Each theme: --paper, --ink, --accent-*, --status-*, --r-*, --font-ui, --warm - app.js: applyVariant() + savedVariant() helpers with localStorage persistence; renderPaletteSwitcher() component (color swatches + name label); injected in renderManagerHome + renderStaff; setupTelegram() restores saved variant - index.html: added Archivo + Manrope to Google Fonts; cache-bust v20260517a - podbor.css: .role-card .role-icon uses color: var(--accent-1) (was hardcoded walnut); SVG strokes switched to currentColor for theme-awareness Co-Authored-By: Claude Sonnet 4.6 --- miniapp/assets/app.js | 70 +++++++++- miniapp/assets/podbor.css | 188 +++++++++++++-------------- miniapp/assets/styles.css | 264 +++++++++++++++++++++++++++----------- miniapp/index.html | 8 +- 4 files changed, 354 insertions(+), 176 deletions(-) diff --git a/miniapp/assets/app.js b/miniapp/assets/app.js index 0002c1e..7db679d 100644 --- a/miniapp/assets/app.js +++ b/miniapp/assets/app.js @@ -9,12 +9,35 @@ const BACKEND_URL = "https://api.wasrusgen1.pro"; const app = document.getElementById("app"); +/* ----------------- Theme / variant helpers ----------------- */ +const THEME_KEY = "zov_variant"; +const THEMES = [ + { id: "", name: "ЗОВ", dotA: "#003E7E", dotB: "#76BD22", outline: false }, + { id: "b", name: "Foundry", dotA: "#15140F", dotB: "#B68A1A", outline: false }, + { id: "c", name: "Boardroom",dotA: "#0E2A2E", dotB: "#D08A55", outline: false }, + { id: "d", name: "Atelier", dotA: "#2E5266", dotB: "#E9EBEF", outline: true }, +]; + +function applyVariant(id) { + const html = document.documentElement; + if (id) { + html.setAttribute("data-variant", id); + } else { + html.removeAttribute("data-variant"); + } + try { localStorage.setItem(THEME_KEY, id); } catch(e) {} +} + +function savedVariant() { + try { return localStorage.getItem(THEME_KEY) ?? ""; } catch(e) { return ""; } +} + /* ----------------- Telegram WebApp setup ----------------- */ function setupTelegram() { const scheme = tg?.colorScheme || (window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light"); document.documentElement.setAttribute("data-theme", scheme); - // Зафиксирован вариант A — Editorial Calm - document.documentElement.setAttribute("data-variant", "a"); + // Восстанавливаем тему из localStorage (по умолч. — brand) + applyVariant(savedVariant()); if (!tg) return; try { @@ -36,6 +59,38 @@ function haptic(type = "selection") { } catch (e) {} } +/* ----------------- Palette switcher UI ----------------- */ +function renderPaletteSwitcher() { + const current = savedVariant(); + const wrap = el(`
`); + // Маленький ярлык слева + const lbl = el(`Тема`); + wrap.appendChild(lbl); + + THEMES.forEach(t => { + const btn = el(` + + `); + btn.addEventListener("click", () => { + haptic(); + applyVariant(t.id); + // Перерисовываем все кнопки + wrap.querySelectorAll(".ps-btn").forEach((b, i) => { + b.classList.toggle("active", THEMES[i].id === t.id); + }); + }); + wrap.appendChild(btn); + }); + + return wrap; +} + /* ----------------- Data ----------------- */ async function fetchMe() { if (!BACKEND_URL) { @@ -122,6 +177,9 @@ async function renderManagerHome(me) { app.innerHTML = ""; document.body.classList.add("has-bottom-nav"); + // Palette (theme) switcher — вверху экрана + app.appendChild(renderPaletteSwitcher()); + // Greeting + bell (placeholder) const greetingEl = el(`
@@ -683,7 +741,7 @@ function renderRoleChooser() {