diff --git a/frontend/textbooks/geometry_11_hub.html b/frontend/textbooks/geometry_11_hub.html index 9c75c8c..c1da767 100644 --- a/frontend/textbooks/geometry_11_hub.html +++ b/frontend/textbooks/geometry_11_hub.html @@ -131,6 +131,75 @@ main{max-width:1100px;margin:0 auto;padding:32px 24px 60px} .fin-placeholder{padding:24px 18px;background:linear-gradient(135deg,var(--pri-soft),rgba(103,232,249,.08));border:1.5px dashed var(--pri);border-radius:14px;text-align:center;color:var(--text)} .fin-placeholder h3{font-family:'Outfit',sans-serif;color:var(--pri-d);margin-bottom:8px;font-size:1.1rem} .fin-placeholder p{color:var(--muted);font-size:.92rem;line-height:1.55} + +.fin-section-title{font-family:'Outfit',sans-serif;font-size:1.18rem;font-weight:800;color:var(--text);margin:8px 0 14px;letter-spacing:-.005em;display:flex;align-items:center;gap:9px} +.fin-section-title svg{width:20px;height:20px;stroke:var(--pri);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} + +/* CHEAT SHEET */ +.cheat-grid{display:grid;grid-template-columns:1fr;gap:14px;margin-bottom:28px} +@media(min-width:680px){.cheat-grid{grid-template-columns:1fr 1fr}} +@media(min-width:1000px){.cheat-grid{grid-template-columns:repeat(4,1fr)}} +.cheat-card{border:1.5px solid var(--border);border-radius:13px;padding:14px 16px;background:var(--card);position:relative;overflow:hidden} +.cheat-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px} +.cheat-card.c1::before{background:linear-gradient(180deg,var(--ch1),var(--ch1-d))} +.cheat-card.c2::before{background:linear-gradient(180deg,var(--ch2),var(--ch2-d))} +.cheat-card.c3::before{background:linear-gradient(180deg,var(--ch3),var(--ch3-d))} +.cheat-card.c4::before{background:linear-gradient(180deg,var(--ch4),var(--ch4-d))} +.cheat-head{display:flex;align-items:center;gap:9px;margin-bottom:9px;padding-left:6px} +.cheat-badge{font-size:.7rem;font-weight:800;padding:2px 8px;border-radius:99px;color:#fff;letter-spacing:.05em;text-transform:uppercase} +.cheat-card.c1 .cheat-badge{background:var(--ch1)} +.cheat-card.c2 .cheat-badge{background:var(--ch2)} +.cheat-card.c3 .cheat-badge{background:var(--ch3)} +.cheat-card.c4 .cheat-badge{background:var(--ch4)} +.cheat-title{font-weight:800;color:var(--text);font-size:.98rem} +.cheat-list{list-style:none;padding-left:6px;margin:0} +.cheat-list li{padding:6px 0;border-bottom:1px dashed var(--border);font-size:.92rem;line-height:1.5;color:var(--text)} +.cheat-list li:last-child{border-bottom:0} + +/* BOSS PROGRESS */ +.boss-overall-bar{background:linear-gradient(135deg,rgba(8,145,178,.08),rgba(103,232,249,.06));border:1px solid var(--border);border-radius:12px;padding:13px 16px;margin:6px 0 18px;display:flex;gap:14px;align-items:center;flex-wrap:wrap} +.boss-overall-bar .lab{font-weight:700;font-size:.95rem;color:var(--text);min-width:200px} +.boss-overall-bar .bar{flex:1;min-width:160px;height:9px;background:rgba(8,145,178,.14);border-radius:5px;overflow:hidden} +.boss-overall-bar .fill{height:100%;background:linear-gradient(90deg,var(--pri),#67e8f9,#f59e0b);transition:width .5s;border-radius:5px} + +/* BOSS CARDS */ +.boss-card{background:var(--card);border:2px solid var(--border);border-radius:14px;padding:16px;margin-bottom:14px;transition:border-color .35s,box-shadow .35s,transform .2s} +.boss-card.solved{border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.18)} +.boss-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;flex-wrap:wrap} +.boss-tag{font-size:.7rem;font-weight:800;padding:3px 9px;border-radius:99px;background:rgba(8,145,178,.14);color:var(--pri-d);letter-spacing:.04em;text-transform:uppercase} +html.dark .boss-tag{color:#67e8f9} +.boss-title{font-family:'Outfit',sans-serif;font-weight:800;color:var(--text);font-size:1.02rem;flex:1;min-width:0} +.boss-q{padding:12px 14px;background:rgba(8,145,178,.06);border-radius:10px;font-size:.96rem;line-height:1.55;margin-bottom:10px;color:var(--text)} +.boss-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:6px} +.boss-input{padding:8px 12px;border:1.5px solid var(--border);border-radius:8px;background:var(--card);color:var(--text);font-family:'JetBrains Mono',monospace;width:130px;text-align:center;font-size:.95rem;transition:border-color .15s} +.boss-input:focus{outline:0;border-color:var(--pri);box-shadow:0 0 0 3px var(--pri-soft)} +.boss-btn{padding:8px 16px;border-radius:9px;background:var(--card);color:var(--text);border:1.5px solid var(--border);font-weight:700;font-size:.88rem;cursor:pointer;font-family:inherit;transition:background .15s,border-color .15s,transform .1s} +.boss-btn:hover{background:var(--pri-soft);border-color:var(--pri)} +.boss-btn:active{transform:scale(.96)} +.boss-btn.primary{background:linear-gradient(135deg,var(--pri),#0891b2);color:#fff;border-color:transparent} +.boss-btn.primary:hover{filter:brightness(1.08)} +.boss-fb{padding:10px 14px;border-radius:9px;font-weight:600;font-size:.88rem;margin-top:8px;display:none;line-height:1.45} +.boss-fb.ok{display:block;background:#d1fae5;color:#065f46;border-left:4px solid #10b981} +.boss-fb.fail{display:block;background:#fee2e2;color:#7f1d1d;border-left:4px solid #dc2626} +html.dark .boss-fb.ok{background:rgba(16,185,129,.18);color:#a7f3d0} +html.dark .boss-fb.fail{background:rgba(220,38,38,.18);color:#fecaca} +.boss-hint-txt{margin-top:8px;padding:9px 13px;background:rgba(245,158,11,.12);border-left:3px solid #f59e0b;border-radius:6px;font-size:.86rem;color:var(--text);display:none;line-height:1.5} +.boss-hint-txt.show{display:block} + +/* FINAL CTA */ +.final-cta{margin-top:24px;padding:18px 20px;border-radius:14px;background:linear-gradient(135deg,#fef3c7,#fde68a);border:1.5px solid #fbbf24;display:none;align-items:center;gap:14px;flex-wrap:wrap} +.final-cta.show{display:flex} +html.dark .final-cta{background:linear-gradient(135deg,rgba(245,158,11,.18),rgba(217,119,6,.15));border-color:#d97706} +.final-cta-icon{width:48px;height:48px;border-radius:12px;background:linear-gradient(135deg,#fbbf24,#f59e0b);display:flex;align-items:center;justify-content:center;flex-shrink:0} +.final-cta-icon svg{width:28px;height:28px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} +.final-cta-txt{flex:1;min-width:180px} +.final-cta-title{font-weight:800;color:#92400e;font-size:1.05rem;font-family:'Outfit',sans-serif} +html.dark .final-cta-title{color:#fde68a} +.final-cta-sub{font-size:.86rem;color:#78350f;margin-top:2px} +html.dark .final-cta-sub{color:#fcd34d} +.final-cta-btn{padding:10px 18px;border-radius:10px;background:linear-gradient(135deg,var(--pri),#0891b2);color:#fff;text-decoration:none;font-weight:800;font-size:.9rem;display:inline-flex;align-items:center;gap:7px;transition:filter .15s} +.final-cta-btn:hover{filter:brightness(1.1)} +.final-cta-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} @@ -262,16 +331,95 @@ main{max-width:1100px;margin:0 auto;padding:32px 24px 60px}
Финал курса
Итоговая проверка по всему курсу
-
Шпаргалка курса и интегрированные боссы (Phase 5). Победи всех — получи «Магистр геометрии 11» и +50 XP.
+
Шпаргалка курса и 9 интегрированных боссов. Победи всех — получи «Магистр геометрии 11» и +100 XP.
-
-

В разработке (Phase 5)

-

Финал курса появится после реализации всех 11 параграфов. Здесь будут: итоговая шпаргалка по 4 разделам и 7 интегрированных боссов на синтез стереометрии и планиметрии.

+ +
+ + Шпаргалка курса
+ +
+
+
+ Р. 1 + Призма и цилиндр +
+
    +
  • Призма: $V = S_{осн} h$
  • +
  • Прямая призма: $S_{бок} = P_{осн} \cdot h$
  • +
  • Параллелепипед: $d^2 = a^2 + b^2 + c^2$
  • +
  • Цилиндр: $V = \pi R^2 h$, $S_{бок} = 2\pi R h$
  • +
+
+
+
+ Р. 2 + Пирамида и конус +
+
    +
  • Пирамида: $V = \dfrac{1}{3} S_{осн} h$
  • +
  • Правильная: $S_{бок} = \dfrac{1}{2} P_{осн} \cdot l$ ($l$ — апофема)
  • +
  • Конус: $V = \dfrac{1}{3} \pi R^2 h$, $S_{бок} = \pi R l$
  • +
  • Связь: $l^2 = R^2 + h^2$
  • +
+
+
+
+ Р. 3 + Сфера и шар +
+
    +
  • Сфера: $(x-a)^2 + (y-b)^2 + (z-c)^2 = R^2$
  • +
  • Шар: $S = 4\pi R^2$, $V = \dfrac{4}{3}\pi R^3$
  • +
  • 5 платоновых тел, Эйлер: $V - E + F = 2$
  • +
  • Двойственность: куб$\leftrightarrow$октаэдр, додекаэдр$\leftrightarrow$икосаэдр
  • +
+
+
+
+ Р. 4 + Повторение +
+
    +
  • Планиметрия: Пифагор, синусов, косинусов, Герон
  • +
  • 3D-векторы: $\vec{a} \cdot \vec{b} = a_1 b_1 + a_2 b_2 + a_3 b_3$
  • +
  • $\cos\alpha = \dfrac{\vec{a}\cdot\vec{b}}{|\vec{a}||\vec{b}|}$
  • +
  • Построения: серединный $\perp$, биссектриса
  • +
+
+
+ +
+ + 9 интегрированных боссов +
+ +
+
Боссов побеждено: 0 / 9
+
+
+ +
+ +
+
+ +
+
+
Курс Геометрия 11 пройден!
+
Вы прошли всю итоговую проверку курса. +100 XP, ачивка «Магистр геометрии 11» получена.
+
+ + К каталогу учебников + + +
+
@@ -380,7 +528,285 @@ function renderProgress(children) { } } -/* FINAL ACCORDION (placeholder content) */ +/* COURSE FINAL — lazy bosses */ +var FIN_BOSS_KEY = 'geometry11_course_bosses'; + +var FIN_BOSSES = [ + { + n: 1, + title: 'Призма + Цилиндр', + tag: 'Раздел 1', + q: 'В правильную 6-угольную призму со стороной основания $a = 4$ и высотой $h = 5$ вписан цилиндр. Найдите радиус цилиндра (округлите до сотых, допуск 0{,}05).', + hint: 'Радиус вписанного цилиндра = апофема правильного 6-угольника: $r = \\dfrac{a\\sqrt{3}}{2} = 2\\sqrt{3} \\approx 3{,}46$.', + ans: 3.46, + tol: 0.05, + step: '0.01' + }, + { + n: 2, + title: 'Пирамида + Угол', + tag: 'Раздел 2', + q: 'Правильная 4-угольная пирамида: сторона основания $a = 6$, высота $h = 4$. Найдите длину апофемы $l$.', + hint: 'Радиус вписанной в квадрат окружности $r = a/2 = 3$. Тогда $l = \\sqrt{r^2 + h^2} = \\sqrt{9 + 16} = 5$.', + ans: 5, + step: '1' + }, + { + n: 3, + title: 'Конус + Развёртка', + tag: 'Раздел 2', + q: 'У конуса радиус основания $R = 4$, образующая $l = 12$. Найдите угол развёртки боковой поверхности в градусах.', + hint: 'Длина дуги развёртки = длина окружности основания: $\\varphi = \\dfrac{360^\\circ \\cdot R}{l} = \\dfrac{360 \\cdot 4}{12}$.', + ans: 120, + step: '1' + }, + { + n: 4, + title: 'Шар + Многогранник', + tag: 'Раздел 3', + q: 'Шар вписан в куб со стороной 6. Найдите объём шара (используйте $\\pi \\approx 3{,}14$; допуск 0{,}5).', + hint: 'Радиус вписанного шара $r = a/2 = 3$. $V = \\dfrac{4}{3}\\pi r^3 = \\dfrac{4}{3} \\cdot 3{,}14 \\cdot 27$.', + ans: 113.04, + tol: 0.5, + step: '0.01' + }, + { + n: 5, + title: 'Сфера + Координаты', + tag: 'Раздел 3 + 4', + q: 'Найдите радиус сферы $x^2 + y^2 + z^2 - 4x - 6y + 2z + 5 = 0$.', + hint: 'Выделите полные квадраты: $(x-2)^2 + (y-3)^2 + (z+1)^2 = 4 + 9 + 1 - 5 = 9$. Значит $R^2 = 9$.', + ans: 3, + step: '1' + }, + { + n: 6, + title: 'Многогранники', + tag: 'Раздел 3', + q: 'Сколько граней у октаэдра?', + hint: 'Октаэдр — один из 5 правильных многогранников; его грани — 8 равных правильных треугольников.', + ans: 8, + step: '1' + }, + { + n: 7, + title: '3D-векторы', + tag: 'Раздел 4', + q: 'Найдите длину вектора $\\vec{v} = (1; 2; 2)$.', + hint: '$|\\vec{v}| = \\sqrt{v_1^2 + v_2^2 + v_3^2} = \\sqrt{1 + 4 + 4}$.', + ans: 3, + step: '1' + }, + { + n: 8, + title: 'Параллелепипед + Диагональ', + tag: 'Раздел 1 + 4', + q: 'В прямоугольном параллелепипеде измерения $1, 2, 2$. Найдите длину главной диагонали.', + hint: '$d = \\sqrt{a^2 + b^2 + c^2} = \\sqrt{1 + 4 + 4}$.', + ans: 3, + step: '1' + }, + { + n: 9, + title: 'Магистр стереометрии', + tag: 'синтез всего курса', + q: 'В куб со стороной 6 вписан правильный тетраэдр (4 вершины тетраэдра — это 4 вершины куба, образующие тетраэдр). Найдите длину ребра тетраэдра (округлите до сотых, допуск 0{,}05).', + hint: 'Ребро такого тетраэдра — это диагональ грани куба: $d = a\\sqrt{2} = 6\\sqrt{2} \\approx 8{,}49$.', + ans: 8.49, + tol: 0.05, + step: '0.01' + } +]; + +function loadFinBossState(){ + try { return JSON.parse(localStorage.getItem(FIN_BOSS_KEY) || '{}') || {}; } + catch(e) { return {}; } +} +function saveFinBossState(s){ + try { localStorage.setItem(FIN_BOSS_KEY, JSON.stringify(s)); } catch(e){} +} + +function finRenderKatex(root){ + if (typeof window.renderMathInElement !== 'function') return; + try { + window.renderMathInElement(root, { + delimiters: [ + {left: '$$', right: '$$', display: true}, + {left: '$', right: '$', display: false} + ], + throwOnError: false + }); + } catch(e){} +} + +function updateFinBossBar(state){ + var won = 0; + for (var k in state) if (state[k]) won++; + var lab = document.getElementById('fin-boss-lab'); + var fill = document.getElementById('fin-boss-fill'); + if (lab) lab.textContent = 'Боссов побеждено: ' + won + ' / ' + FIN_BOSSES.length; + if (fill) fill.style.width = Math.round(won * 100 / FIN_BOSSES.length) + '%'; + return won; +} + +function maybeUnlockMaster(state){ + if (localStorage.getItem(FIN_ACH_KEY) === '1') return; + var won = 0; + for (var k in state) if (state[k]) won++; + if (won < FIN_BOSSES.length) return; + + localStorage.setItem(FIN_ACH_KEY, '1'); + + /* +100 XP — Геометрия 11 объёмнее, чем Алгебра 11 */ + var xp = parseInt(localStorage.getItem('geometry11_xp') || '0', 10) || 0; + localStorage.setItem('geometry11_xp', String(xp + 100)); + + /* trigger global XP system if available */ + try { + if (window.LS && typeof window.LS.addXp === 'function') { + window.LS.addXp(100, 'geometry11-master'); + } else if (typeof window.addXp === 'function') { + window.addXp(100, 'geometry11-master'); + } + } catch(e){} + + /* confetti */ + try { if (typeof window.confetti === 'function') window.confetti({particleCount: 200, spread: 100, origin: {y: .6}}); } catch(e){} + + /* light up ach-strip */ + var strip = document.getElementById('ach-strip'); + var sub = document.getElementById('ach-sub'); + if (strip) strip.classList.add('lit'); + if (sub) sub.textContent = 'Выполнено! Вы — Магистр геометрии 11.'; + + /* show CTA */ + var cta = document.getElementById('final-cta'); + if (cta) cta.classList.add('show'); + + /* refresh XP badge */ + var xpBadge = document.getElementById('hero-xp-badge'); + if (xpBadge) { + var newXp = parseInt(localStorage.getItem('geometry11_xp') || '0', 10) || 0; + xpBadge.style.display = ''; + xpBadge.textContent = newXp + ' XP'; + } +} + +function buildFinBoss(b, state){ + var solvedClass = state[b.n] ? ' solved' : ''; + var step = b.step || '1'; + var displayAns = (typeof b.ans === 'number' && step !== '1') ? b.ans.toFixed(2) : b.ans; + return '
' + + '
' + + '' + b.tag + '' + + 'Босс ' + b.n + '. ' + b.title + '' + + '
' + + '
' + b.q + '
' + + '
' + + '' + + '' + + '' + + '
' + + '
' + b.hint + '
' + + '
' + (state[b.n] ? 'Победа! +15 XP. Босс уже повержен.' : '') + '
' + + '
'; +} + +function bindFinBoss(b){ + var state = loadFinBossState(); + var goBtn = document.getElementById('fin-boss-' + b.n + '-go'); + var hintBtn = document.getElementById('fin-boss-' + b.n + '-hint'); + var inp = document.getElementById('fin-boss-' + b.n + '-inp'); + var fb = document.getElementById('fin-boss-' + b.n + '-fb'); + var hintTx = document.getElementById('fin-boss-' + b.n + '-hinttxt'); + var card = document.getElementById('fin-boss-' + b.n + '-card'); + if (!goBtn) return; + + if (hintBtn) hintBtn.addEventListener('click', function(){ + if (hintTx) hintTx.classList.toggle('show'); + }); + + if (state[b.n]) return; /* already solved */ + + goBtn.addEventListener('click', function(){ + var v = parseFloat((inp.value || '').replace(',', '.')); + if (isNaN(v)) { + fb.className = 'boss-fb fail'; + fb.textContent = 'Введите число.'; + return; + } + var tol = (typeof b.tol === 'number') ? b.tol : 1e-9; + if (Math.abs(v - b.ans) < tol) { + fb.className = 'boss-fb ok'; + fb.textContent = 'Победа! +15 XP. Босс повержен.'; + card.classList.add('solved'); + goBtn.disabled = true; + inp.disabled = true; + + var s = loadFinBossState(); + if (!s[b.n]) { + s[b.n] = true; + saveFinBossState(s); + + /* +15 XP */ + var xp = parseInt(localStorage.getItem('geometry11_xp') || '0', 10) || 0; + localStorage.setItem('geometry11_xp', String(xp + 15)); + try { + if (window.LS && typeof window.LS.addXp === 'function') window.LS.addXp(15, 'fin-boss-' + b.n); + else if (typeof window.addXp === 'function') window.addXp(15, 'fin-boss-' + b.n); + } catch(e){} + + var xpBadge = document.getElementById('hero-xp-badge'); + if (xpBadge) { + var nXp = parseInt(localStorage.getItem('geometry11_xp') || '0', 10) || 0; + xpBadge.style.display = ''; + xpBadge.textContent = nXp + ' XP'; + } + + updateFinBossBar(s); + maybeUnlockMaster(s); + } + } else { + fb.className = 'boss-fb fail'; + fb.textContent = 'Не то. Перепроверь решение и попробуй снова.'; + } + }); + + inp.addEventListener('keydown', function(e){ + if (e.key === 'Enter') { e.preventDefault(); goBtn.click(); } + }); +} + +var FIN_BOSSES_RENDERED = false; +function renderFinBosses(){ + if (FIN_BOSSES_RENDERED) return; + var cont = document.getElementById('fin-bosses-container'); + if (!cont) return; + var state = loadFinBossState(); + var html = ''; + for (var i = 0; i < FIN_BOSSES.length; i++) html += buildFinBoss(FIN_BOSSES[i], state); + cont.innerHTML = html; + for (var j = 0; j < FIN_BOSSES.length; j++) bindFinBoss(FIN_BOSSES[j]); + + var wrap = document.getElementById('course-final'); + finRenderKatex(wrap); + + updateFinBossBar(state); + + /* if already mastered: show CTA */ + if (localStorage.getItem(FIN_ACH_KEY) === '1') { + var cta = document.getElementById('final-cta'); + if (cta) cta.classList.add('show'); + var strip = document.getElementById('ach-strip'); + var sub = document.getElementById('ach-sub'); + if (strip) strip.classList.add('lit'); + if (sub) sub.textContent = 'Выполнено! Вы — Магистр геометрии 11.'; + } + + FIN_BOSSES_RENDERED = true; +} + +/* FINAL ACCORDION */ (function bindFinalAccordion(){ var head = document.getElementById('final-head'); var wrap = document.getElementById('course-final'); @@ -390,6 +816,10 @@ function renderProgress(children) { var willOpen = !wrap.classList.contains('open'); wrap.classList.toggle('open'); head.setAttribute('aria-expanded', willOpen ? 'true' : 'false'); + if (willOpen) { + renderFinBosses(); + finRenderKatex(wrap); + } } head.addEventListener('click', toggle);