From 1aa95a6776116c576765d61fdfce9a190f7bb562 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Tue, 23 Jun 2026 10:37:41 +0300 Subject: [PATCH] =?UTF-8?q?fix(dashboard):=20hero=20=C2=AB=D0=9B=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=B8=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=BD=D1=8F=C2=BB=20=D0=B2=D0=B8=D0=B4=D0=B5=D0=BD=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D0=BB=D0=B0=D0=B1=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hero-карточка #hc-lab имела href="/lab", но loadLabOfDay меняет его на /lab?sim= → CSS [href="/lab"] больше не матчит, карточка оставалась видной. Прячем по стабильному id: #hc-lab/#hc-pet/#hc-read добавлены в FEATURE_WIDGETS (lab/pet/textbooks). .hero-row переведён на grid auto-fit (minmax 240) — сетка сама подстраивается под видимые карточки без дыры; syncHeroRow прячет весь ряд, если карточек не осталось (мобайл-медиазапрос не трогаем — без инлайн-колонок). Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/dashboard.html | 14 +++++++++++++- js/api.js | 7 ++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/dashboard.html b/frontend/dashboard.html index 6f3b6eb..60ba7e3 100644 --- a/frontend/dashboard.html +++ b/frontend/dashboard.html @@ -81,7 +81,7 @@ } .ab-btn:hover { background: rgba(255,255,255,0.25); } /* ── Hero cards row (Reading · Lab of day · Pet) ── */ - .hero-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; } + .hero-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; } .hero-card { position: relative; border-radius: 18px; padding: 18px 20px; display: flex; flex-direction: column; min-height: 196px; @@ -3683,6 +3683,17 @@ col.style.display = any ? '' : 'none'; } + /* Hero-ряд (чтение/лаборатория/питомец): карточки скрываются по фиче (через CSS). + Подгоняем число колонок под видимые карточки и прячем весь ряд, если пусто. */ + function syncHeroRow() { + const row = document.getElementById('hero-row'); + if (!row) return; + const vis = [...row.querySelectorAll('.hero-card')] + .filter(c => getComputedStyle(c).display !== 'none'); + row.style.display = vis.length ? '' : 'none'; + // ширину колонок под число карточек делает CSS (auto-fit), мобайл не трогаем. + } + /* ══ WIDGET: Last results (compact, 5 items) ══════════════════════ */ function loadLastResultsWidget(rows) { const w = document.getElementById('w-last-results'); @@ -4300,6 +4311,7 @@ loadLabOfDay(); loadPetHero(); loadFlashcardWidget(); + syncHeroRow(); // спрятать карточки отключённых модулей и подогнать сетку } /* ══ WIDGET: Flashcard review (random card from pool) ════════════════ */ diff --git a/js/api.js b/js/api.js index 66498f1..900fabc 100644 --- a/js/api.js +++ b/js/api.js @@ -854,9 +854,14 @@ const FEATURE_HREFS = { sitemap: ['/sitemap', '/sitemap.html'], }; /* Контейнеры виджетов-модулей (дашборд и т.п.) — прячем блок целиком, а не только - ссылку, иначе остаётся пустой блок (напр. виджет флеш-карт #w-flashcard). */ + ссылку, иначе остаётся пустой блок (напр. виджет флеш-карт #w-flashcard). + Hero-карточки дашборда: у lab JS меняет href на /lab?sim=… → [href="/lab"] не + матчит, поэтому прячем по СТАБИЛЬНОМУ id #hc-lab (аналогично pet/чтение). */ const FEATURE_WIDGETS = { flashcards: ['#w-flashcard'], + lab: ['#hc-lab'], + pet: ['#hc-pet'], + textbooks: ['#hc-read'], }; /* Инъекция CSS, прячущего отключённые фичи. Ставится синхронно из localStorage-кэша на ранней загрузке (ДО построения сайдбара/виджетов) — против мигания (FOUC),