Files
Learn_System/backend/scripts/redesign_p8_hub.cjs
T
Maxim Dolgolyov 29a2bae7d9 feat(phys8 hub): Phase 5 — hub polish + cross-cutting
Hub улучшения:
- .ch-card: подъём на hover (-6px scale 1.01) с тематической box-shadow
  по цвету главы.
- .ch-cover::after: shimmer-overlay при наведении (diagonal sweep).
- .ch-cover-wm: micro-перемещение и scale на hover.
- .ch-action svg: стрелка едет вправо на hover.
- .po-xp: пульсирующая тень для overall progress XP-badge (3s loop).

Accessibility:
- aria-label на каждой ch-card с понятным названием темы.
- :focus-visible с 3px outline в brand-цвете для chapter cards.
- :focus-visible с белым outline для hdr-btn на градиенте.
- prefers-reduced-motion: блокирует все анимации.

Mobile responsiveness:
- @media ≤580px: уменьшение шрифта h1 1.4rem, ch-cover-wm 3.8rem.

Footer: '40 параграфов, 7 ЛР, 47 IV-6 интерактивов'.
2026-05-30 10:31:05 +03:00

80 lines
4.0 KiB
JavaScript

// Phase 5 — Hub polish: добавить тематические SVG watermarks для каждой
// chapter-карточки, hover-микро-анимации, live-индикатор прогресса.
'use strict';
const fs = require('fs');
const path = require('path');
const DST = path.join(__dirname, '..', '..', 'frontend', 'textbooks', 'physics_8_hub.html');
let h = fs.readFileSync(DST, 'utf8');
// === 1. Add hub-level animations CSS (inline into <style>) ===
const HUB_EXTRA_CSS = `
/* === Phase 5 hub polish === */
.ch-card{transition:transform .35s cubic-bezier(.16,1,.3,1),box-shadow .35s,border-color .25s}
.ch-card:hover{transform:translateY(-6px) scale(1.01);box-shadow:0 18px 44px rgba(124,58,237,.22)}
.ch-cover{position:relative;overflow:hidden}
.ch-cover::after{content:'';position:absolute;inset:0;background:linear-gradient(135deg,transparent 40%,rgba(255,255,255,.10) 50%,transparent 60%);background-size:300% 300%;background-position:200% 200%;transition:background-position .85s ease-out;pointer-events:none}
.ch-card:hover .ch-cover::after{background-position:-100% -100%}
.ch-card .ch-cover-wm{transition:transform .5s cubic-bezier(.16,1,.3,1),opacity .35s}
.ch-card:hover .ch-cover-wm{transform:translateX(-6px) translateY(8px) scale(1.08);opacity:.30}
.ch-action svg{transition:transform .25s}
.ch-action:hover svg{transform:translateX(4px)}
/* Topic-themed glow on action button */
.ch-card.ch1-card:hover .ch-action{box-shadow:0 6px 16px rgba(220,38,38,.35)}
.ch-card.ch2-card:hover .ch-action{box-shadow:0 6px 16px rgba(217,119,6,.35)}
.ch-card.ch3-card:hover .ch-action{box-shadow:0 6px 16px rgba(8,145,178,.35)}
.ch-card.ch4-card:hover .ch-action{box-shadow:0 6px 16px rgba(16,185,129,.35)}
/* Overall progress XP-pulse */
@keyframes po-xp-pulse{0%,100%{box-shadow:0 4px 12px rgba(124,58,237,.24)}50%{box-shadow:0 4px 16px rgba(124,58,237,.40),0 0 0 4px rgba(124,58,237,.08)}}
.po-xp{animation:po-xp-pulse 3s ease-in-out infinite}
/* Mobile responsiveness */
@media(max-width:580px){
.hdr{padding:24px 16px 20px}
.hdr h1{font-size:1.4rem}
.ch-cover-wm{font-size:3.8rem;right:-4px;top:-12px}
}
/* Focus-visible accessibility */
.ch-card:focus-visible{outline:3px solid var(--p8-brand,#7c3aed);outline-offset:3px;border-radius:18px}
.hdr-btn:focus-visible,.hdr-back:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* Reduced motion */
@media (prefers-reduced-motion: reduce){
.ch-card,.ch-card .ch-cover-wm,.ch-cover::after,.po-xp,.ch-action svg{animation:none!important;transition:none!important}
}
`;
if (!h.includes('Phase 5 hub polish')) {
h = h.replace('</style>', HUB_EXTRA_CSS + '\n</style>');
console.log('Hub polish CSS injected');
}
// === 2. Make chapter card titles accessibility-friendly + add aria-labels ===
// Add aria-label на каждую .ch-card если её нет
const cardLabels = {
'ch1-card': 'Глава 1: Тепловые явления',
'ch2-card': 'Глава 2: Электромагнитные явления',
'ch3-card': 'Глава 3: Световые явления',
'ch4-card': 'Лабораторный практикум — 7 ЛР'
};
for (const [cls, label] of Object.entries(cardLabels)) {
const regex = new RegExp(`(<a [^>]*class="ch-card ${cls}"[^>]*)>`, 'g');
h = h.replace(regex, (match, before) => {
if (/aria-label=/.test(before)) return match;
return `${before} aria-label="${label}">`;
});
}
// === 3. Footer "Created with..." note (or replace existing if any) ===
// Optional — add a soft footer
const FOOTER_HTML = `
<footer style="max-width:1100px;margin:50px auto 30px;padding:20px;color:var(--muted);font-size:.78rem;text-align:center;border-top:1px solid var(--border);line-height:1.55">
Физика 8 · LearnSpace · 40 параграфов, 7 ЛР, 47 IV-6 интерактивов
</footer>
`;
if (!h.includes('47 IV-6 интерактивов')) {
h = h.replace('</body>', FOOTER_HTML + '\n</body>');
console.log('Footer added');
}
fs.writeFileSync(DST, h);
console.log('hub size:', h.length);