Files
Maxim Dolgolyov bc64828b22 feat(phys9 flagships): F3 тахометр+спидометр + F4 орбита (Wave A продолжение)
F3. Тахометр + спидометр + одометр (§11 в ch1):
- Canvas 640×400 с 3 аналоговыми приборами вверху
  (тахометр a, спидометр v, одометр Δx mod 1000)
- Графики v(t) и a(t) внизу с горизонтальной цель-линией
- Кнопки «Газ»/«Тормоз» удержанием, «Отпустить» — coast-режим
  (лёгкое торможение от трения)
- Slider'ы: a_газа, |a_тормоз|, цель скорости (по умолчанию 16.7 м/с)
- Рекорд скорости в localStorage
- Feedback при достижении цели

F4. Орбитальный конструктор (§17 в ch2):
- Canvas 640×480 (космос со звёздами)
- Планета (Земля) в центре, спутник запускается с r=200
- Slider'ы: M, v₀, угол α
- Кнопки: Запустить/Сброс/«Круговая орбита» (вычисляет v=√(M/r))
- Физика: F=GM/r² (G=1), Эйлер 8 шагов/кадр
- Trail орбиты до 1500 точек
- Классификация: падение/круговая/эллипс/убегание
- Период T через переход через ось x
- Feedback при крайних случаях

Подключение:
- ch1: phys9_flag_F3_dashboard.js + хук на p11
- ch2: phys9-flagships.css + base + F4 + хук на p17

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:10:33 +03:00

2201 lines
170 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Физика 9 · Глава 1 · «Основы кинематики»</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<link rel="stylesheet" href="/css/phys-textbook-widgets.css">
<link rel="stylesheet" href="/css/phys9-flagships.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys.js?v=20260530" defer></script>
<script src="/js/phys9_palette.js?v=20260530" defer></script>
<script src="/js/phys9_legacy.js?v=20260530" defer></script>
<script src="/js/phys9_finals.js?v=20260530" defer></script>
<script src="/js/phys9_ch1_widgets.js?v=20260530" defer></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800;900&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#fafafa; --card:#fff; --card-soft:#f8fafc; --text:#0f172a; --ink:#0f172a; --muted:#64748b;
--border:#e2e8f0; --sh:0 1px 3px rgba(0,0,0,.06); --sh2:0 4px 14px rgba(0,0,0,.08);
--pri:#2563eb; --pri2:#1d4ed8; --pri-soft:#dbeafe;
--acc:#60a5fa; --acc2:#2563eb; --acc-soft:#dbeafe;
--ok:#10b981; --ok-bg:#d1fae5; --warn:#f59e0b; --warn-bg:#fef3c7;
--bad:#ef4444; --fail:#dc2626; --fail-bg:#fee2e2;
}
.dark{--bg:#0a0e1a; --card:#0f1727; --card-soft:#13192a; --text:#dbeafe; --ink:#dbeafe; --muted:#7c8fab; --border:#1e2a44}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{font-family:'Inter',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.55;font-size:15px}
button,input,select,textarea{font-family:inherit;font-size:inherit}
button{cursor:pointer;border:0;background:transparent;color:inherit}
a{color:inherit;text-decoration:none}
.ic{width:16px;height:16px;display:inline-block;flex-shrink:0;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vertical-align:middle}
.hdr{position:relative;background:linear-gradient(110deg,#1e3a8a 0%,#2563eb 55%,#60a5fa 100%);color:#fff;padding:46px 22px 30px;overflow:hidden;border-bottom:2px solid rgba(255,255,255,.2);min-height:130px}
.hdr::before{content:'ГЛАВА 1';position:absolute;right:-12px;top:50%;transform:translateY(-50%);font-family:'Unbounded',sans-serif;font-size:clamp(5rem,15vw,11rem);font-weight:900;letter-spacing:-.04em;color:transparent;-webkit-text-stroke:1.5px rgba(255,255,255,.12);line-height:1;pointer-events:none;user-select:none;z-index:0}
.hdr-row{position:relative;z-index:1;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.hdr h1{font-family:'Unbounded',sans-serif;font-size:1.5rem;font-weight:900;letter-spacing:-.01em;line-height:1.3;padding-top:4px}
.hdr-sub{font-size:.85rem;opacity:.88;margin-top:6px;font-weight:500;line-height:1.4}
.hdr-side{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.hdr-btn{padding:7px 12px;border-radius:9px;background:rgba(255,255,255,.14);color:#fff;font-weight:600;font-size:.82rem;display:inline-flex;align-items:center;gap:6px;transition:background .15s;text-decoration:none}
.hdr-btn:hover{background:rgba(255,255,255,.24)}
.main{max-width:1240px;margin:0 auto;padding:22px;width:100%;display:grid;grid-template-columns:1fr 280px;gap:24px}
@media(max-width:980px){.main{grid-template-columns:1fr;padding:14px}}
.col-main{min-width:0}
.hero{background:linear-gradient(135deg,var(--pri-soft) 0%,var(--acc-soft) 50%,var(--pri-soft) 100%);background-size:200% 200%;animation:heroShift 12s ease-in-out infinite;border:1px solid var(--border);border-radius:18px;padding:24px 22px;margin-bottom:24px;position:relative;overflow:hidden}
@keyframes heroShift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
.hero::before{content:'v';position:absolute;right:0;top:-30px;font-size:clamp(2rem,12vw,8rem);font-weight:900;color:var(--pri);opacity:.10;line-height:1;pointer-events:none;font-family:'Unbounded',sans-serif}
.hero h2{font-family:'Unbounded',sans-serif;font-size:1.55rem;font-weight:800;color:var(--pri2);margin-bottom:10px;letter-spacing:-.01em}
.hero p{font-size:.95rem;color:var(--text);opacity:.88;margin-bottom:14px;max-width:640px}
.hero-row{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.btn-primary{padding:11px 22px;background:linear-gradient(135deg,var(--pri),var(--pri2));color:#fff;border-radius:11px;font-weight:700;font-size:.92rem;display:inline-flex;align-items:center;gap:8px;box-shadow:var(--sh2);transition:transform .15s,box-shadow .15s}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 8px 28px rgba(0,0,0,.18)}
.hero-progress{flex:1;min-width:200px;max-width:280px}
.hp-label{font-size:.74rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;display:block;margin-bottom:5px}
.hp-bar{height:8px;background:rgba(0,0,0,.12);border-radius:5px;overflow:hidden}
.hp-fill{height:100%;background:linear-gradient(90deg,var(--pri),var(--acc));border-radius:5px;width:0%;transition:width .6s cubic-bezier(.16,1,.3,1)}
.hp-text{font-size:.78rem;color:var(--muted);font-weight:700;margin-top:4px;display:block}
.hero-xp-badge{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:linear-gradient(135deg,var(--warn,#f59e0b),var(--pri));color:#fff;border-radius:99px;font-size:.82rem;font-weight:800;letter-spacing:.02em;box-shadow:0 4px 12px rgba(0,0,0,.18);font-family:'Unbounded',sans-serif}
.psel{margin-bottom:24px}
.psel-title{font-size:.72rem;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px}
.psel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
.psel-card{background:var(--card);border:1.5px solid var(--border);border-radius:13px;padding:14px;cursor:pointer;transition:transform .2s,box-shadow .2s,border-color .2s;text-align:left;position:relative}
.psel-card:hover{transform:translateY(-3px);box-shadow:var(--sh2);border-color:var(--pri)}
.psel-card.active{border-color:var(--pri);background:linear-gradient(135deg,var(--pri-soft),var(--card));box-shadow:var(--sh2)}
.psel-card.active::after{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--pri),var(--acc));border-radius:13px 13px 0 0}
.psel-num{font-family:'Unbounded',sans-serif;font-size:.72rem;font-weight:800;color:var(--pri);text-transform:uppercase;letter-spacing:.08em;margin-bottom:5px}
.psel-name{font-size:.86rem;font-weight:700;color:var(--text);line-height:1.3;margin-bottom:8px}
.psel-prog{height:4px;background:rgba(0,0,0,.10);border-radius:3px;overflow:hidden}
.psel-prog-fill{height:100%;background:var(--pri);width:0%;transition:width .4s}
.psel-card.final{background:linear-gradient(135deg,var(--acc-soft),var(--pri-soft))}
.psel-card.final .psel-num{color:var(--warn)}
.sec[id="sec-p1"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p2"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p3"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p4"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p5"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p6"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p7"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p8"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p9"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p10"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p11"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p12"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p13"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-p14"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec[id="sec-final1"]{ --sec-acc:#2563eb; --sec-acc-d:#1d4ed8; --sec-acc-soft:#dbeafe; }
.sec{display:none;position:relative;animation:fadeIn .35s ease}
.sec.active{display:block}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.sec::before{content:attr(data-watermark);position:absolute;right:-20px;top:10%;font-family:'Unbounded',sans-serif;font-size:clamp(6rem,18vw,14rem);font-weight:900;color:transparent;-webkit-text-stroke:1.5px var(--sec-acc-soft,var(--pri-soft));line-height:1;pointer-events:none;user-select:none;z-index:0;opacity:.35}
.sec-header{margin-bottom:22px;padding-bottom:14px;border-bottom:2px solid var(--sec-acc-soft,var(--pri-soft));position:relative;z-index:1}
.sec-num{display:inline-block;padding:4px 10px;background:linear-gradient(135deg,var(--sec-acc,var(--pri)),var(--sec-acc-d,var(--pri2)));color:#fff;border-radius:7px;font-family:'Unbounded',sans-serif;font-size:.78rem;font-weight:800;letter-spacing:.04em;margin-bottom:8px}
.sec-h{font-family:'Unbounded',sans-serif;font-size:1.6rem;font-weight:800;color:var(--sec-acc-d,var(--pri2));letter-spacing:-.01em;line-height:1.25}
.card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:18px 20px;margin-bottom:16px;box-shadow:0 1px 3px rgba(0,0,0,.04),0 8px 24px rgba(0,0,0,.04);position:relative;z-index:1;transition:transform .25s cubic-bezier(.16,1,.3,1),box-shadow .25s}
.card:hover{transform:translateY(-2px);box-shadow:0 4px 10px rgba(0,0,0,.06),0 16px 36px rgba(0,0,0,.08)}
.card-header{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding-bottom:10px;border-bottom:1px dashed var(--border)}
.card-icon{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff}
.card-icon.theory{background:#8b5cf6}.card-icon.example{background:#10b981}.card-icon.lab{background:#0891b2}.card-icon.rule{background:#ec4899}
.card-icon .ic{width:18px;height:18px}
.card-title{font-family:'Unbounded',sans-serif;font-size:.82rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);flex:1}
.card-num{font-size:.74rem;font-weight:700;color:var(--muted);background:var(--sec-acc-soft,var(--pri-soft));padding:3px 7px;border-radius:5px}
.card-body{font-size:.94rem;line-height:1.65}
.card-body p{margin-bottom:8px}
.card-body p:last-child{margin-bottom:0}
.btn{padding:8px 16px;border-radius:8px;background:var(--card);color:var(--text);border:1.5px solid var(--border);font-weight:600;font-size:.88rem;transition:background .15s,border-color .15s,transform .1s}
.btn:hover{background:var(--sec-acc-soft,var(--pri-soft));border-color:var(--sec-acc,var(--pri))}
.btn:active{transform:scale(.96)}
.btn.primary{background:var(--sec-acc,var(--pri));color:#fff;border-color:var(--sec-acc,var(--pri))}
.btn.primary:hover{background:var(--sec-acc-d,var(--pri2));border-color:var(--sec-acc-d,var(--pri2))}
.col-side{position:sticky;top:14px;align-self:start;height:fit-content;max-height:calc(100vh - 28px);overflow-y:auto}
.sidecard{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:16px;margin-bottom:14px;box-shadow:var(--sh)}
.sidecard h4{font-family:'Unbounded',sans-serif;font-size:.74rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--border)}
.sidecard-row{margin-bottom:8px;font-size:.86rem;line-height:1.6}
.sidecard-row b{color:var(--pri);font-weight:700}
.sidecard-row:last-child{margin-bottom:0}
@media(max-width:980px){.col-side{position:static;max-height:none}}
.xp-card{background:linear-gradient(135deg,var(--acc-soft),var(--pri-soft));border:1.5px solid var(--acc);border-radius:12px;padding:14px;margin-bottom:14px}
.xp-card-title{font-size:.68rem;font-weight:800;color:var(--acc2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:8px;display:flex;align-items:center;justify-content:space-between}
.xp-level{font-size:1.1rem;font-weight:900;color:var(--acc2);font-family:'Unbounded',sans-serif}
.xp-bar{height:9px;background:rgba(0,0,0,.10);border-radius:6px;overflow:hidden;margin:7px 0}
.xp-fill{height:100%;background:linear-gradient(90deg,var(--acc),var(--pri));border-radius:6px;transition:width .5s cubic-bezier(.4,0,.2,1)}
.xp-nums{font-size:.74rem;color:var(--muted);display:flex;justify-content:space-between}
.sec-nav{display:flex;gap:10px;margin-top:24px;padding-top:20px;border-top:1px solid var(--border);justify-content:space-between;flex-wrap:wrap}
.foot{text-align:center;padding:30px 16px;color:var(--muted);font-size:.78rem;border-top:1px solid var(--border);margin-top:30px}
.ach-popup{position:fixed;top:80px;right:18px;background:linear-gradient(135deg,var(--pri),var(--acc));color:#fff;padding:12px 18px;border-radius:11px;font-weight:700;font-size:.9rem;box-shadow:0 8px 28px rgba(0,0,0,.32);z-index:1002;display:none;align-items:center;gap:8px;max-width:340px}
.ach-popup.show{display:flex}
.col-side-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.42);z-index:9990;display:none}
.col-side-backdrop.show{display:block}
@media(min-width:981px){#sidebar-btn{display:none}.col-side-backdrop.show{display:none}}
@media(max-width:980px){
.col-side{position:fixed;top:0;right:0;height:100vh;width:300px;max-width:88vw;background:var(--bg);box-shadow:-12px 0 24px rgba(0,0,0,.18);padding:18px 16px;overflow-y:auto;transform:translateX(100%);transition:transform .25s ease;z-index:9991;max-height:none}
.col-side.open{transform:none}
}
.search-modal{position:fixed;inset:0;background:rgba(15,23,42,.55);backdrop-filter:blur(4px);z-index:9993;display:none;align-items:flex-start;justify-content:center;padding-top:14vh}
.search-modal.show{display:flex}
.search-box{background:var(--bg);border:1px solid var(--border);border-radius:14px;width:560px;max-width:92vw;max-height:70vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 24px 64px rgba(0,0,0,.4)}
.search-input{padding:14px 16px;font-size:1rem;border:0;border-bottom:1px solid var(--border);background:transparent;color:var(--text);outline:none}
.search-results{flex:1;overflow-y:auto;padding:6px 0}
.search-row{display:block;padding:8px 16px;cursor:pointer;border-bottom:1px solid var(--border);text-align:left;background:transparent;border:0;width:100%;color:var(--text)}
.search-row:hover,.search-row.active{background:var(--sec-acc-soft,var(--pri-soft))}
.search-row .sr-kind{font-size:.7rem;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}
.search-row .sr-title{font-weight:700;font-size:.92rem;color:var(--text)}
.search-row .sr-desc{font-size:.8rem;color:var(--muted);margin-top:2px}
.search-empty{padding:20px;text-align:center;color:var(--muted);font-size:.88rem}
.search-foot{padding:8px 14px;border-top:1px solid var(--border);font-size:.74rem;color:var(--muted);display:flex;gap:14px}
.search-foot kbd{padding:2px 6px;background:var(--card);border:1px solid var(--border);border-radius:4px;font-family:'JetBrains Mono',monospace;font-size:.72rem}
.psel-card{position:relative}
.psel-card .psel-done{position:absolute;top:6px;right:6px;width:18px;height:18px;border-radius:50%;background:#10b981;display:none;align-items:center;justify-content:center;box-shadow:0 2px 6px rgba(16,185,129,.45);z-index:2}
.psel-card .psel-done svg{width:11px;height:11px;stroke:#fff;fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.psel-card.done .psel-done{display:flex}
/* === MONOLITH CSS (migrated from physics_9.html) === */
:root{
--pri:#1d4ed8; --pri2:#1e40af;
--acc:#0ea5e9;
--ok:#10b981; --ok-bg:#d1fae5;
--fail:#ef4444; --fail-bg:#fee2e2;
--warn:#f59e0b; --warn-bg:#fef3c7;
--bg:#eff6ff; --card:#fff;
--text:#1e293b; --muted:#64748b;
--border:#dbeafe;
--sh:0 2px 10px rgba(30,64,175,.08)
}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);overflow-x:hidden}
.dark{--bg:#0f172a;--card:#1e293b;--text:#e2e8f0;--muted:#94a3b8;--border:#1e3a5f}
/* ── Шапка ── */
.hdr{background:linear-gradient(135deg,#1e40af 0%,#0284c7 55%,#0ea5e9 100%);color:#fff;padding:18px 20px 16px;text-align:center}
.hdr h1{font-size:1.3rem;font-weight:900}
.hdr p{font-size:.8rem;opacity:.85;margin-top:3px}
/* ── Табы ── */
.tabs{display:flex;flex-wrap:wrap;gap:4px;padding:8px 10px;background:var(--card);border-bottom:1px solid var(--border)}
.tabs::-webkit-scrollbar{display:none}
.tab{padding:8px 14px;border:2px solid var(--border);border-radius:10px;font-size:.74rem;font-weight:700;cursor:pointer;white-space:nowrap;transition:.18s;background:var(--card);color:var(--muted);flex-shrink:0}
.tab:hover{border-color:var(--pri);color:var(--pri)}
.tab.active{background:var(--pri);color:#fff;border-color:var(--pri)}
/* ── Контент ── */
.content{max-width:780px;margin:0 auto;padding:16px 14px;display:none}
.content.active{display:block}
/* ── Справочник: карточки формул ── */
.section-title{font-size:1.05rem;font-weight:800;margin-bottom:12px;color:var(--pri);display:flex;align-items:center;gap:8px}
.section-title i{opacity:.7}
.formula-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px}
@media(max-width:560px){.formula-grid{grid-template-columns:1fr}}
.fcard{background:var(--card);border:2px solid var(--border);border-radius:14px;padding:16px 18px;box-shadow:var(--sh);transition:transform .18s,box-shadow .18s}
.fcard:hover{transform:translateY(-2px);box-shadow:0 6px 22px rgba(29,78,216,.12)}
.fcard.highlight{border-color:var(--pri);background:linear-gradient(135deg,rgba(29,78,216,.04),rgba(14,165,233,.04))}
.fcard h3{font-size:.8rem;font-weight:700;color:var(--pri);text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px}
.fcard .main-f{font-size:1.05rem;font-weight:700;text-align:center;margin:8px 0;padding:10px;background:rgba(29,78,216,.06);border-radius:9px}
.fcard p{font-size:.83rem;color:var(--muted);line-height:1.7;margin-top:6px}
.fcard ul{font-size:.83rem;color:var(--muted);line-height:1.8;padding-left:18px;margin-top:6px}
/* ── Пример задачи ── */
.example-box{background:var(--card);border:2px solid #bfdbfe;border-left:5px solid var(--pri);border-radius:12px;padding:18px 20px;margin-bottom:20px;box-shadow:var(--sh)}
.example-box h3{font-size:.88rem;font-weight:700;color:var(--pri);margin-bottom:10px}
.example-box .cond{font-size:.87rem;background:rgba(29,78,216,.05);border-radius:8px;padding:10px 14px;line-height:1.8;margin-bottom:10px}
.example-box .sol{font-size:.86rem;line-height:1.9}
.given-table{width:100%;border-collapse:collapse;margin:8px 0;font-size:.82rem}
.given-table td{padding:4px 10px;border:1px solid var(--border)}
.given-table tr:first-child td{background:rgba(29,78,216,.04)}
.given-table tr:last-child td{background:rgba(16,185,129,.05)}
.given-table td:first-child{font-weight:700;width:38%;color:var(--pri)}
/* ── Вопросы (теоретические) ── */
.q-list{font-size:.85rem;line-height:1.9;color:var(--muted);padding-left:20px}
.q-list li{margin-bottom:4px}
/* ── Задачи: интерактив ── */
.score-bar{display:flex;gap:10px;align-items:center;justify-content:center;margin-bottom:14px;font-size:.85rem;font-weight:600}
.chip{padding:5px 14px;border-radius:50px;display:flex;align-items:center;gap:5px}
.chip-ok{background:var(--ok-bg);color:#065f46}
.chip-tot{background:var(--card);color:var(--muted);border:1px solid var(--border)}
.prog-wrap{width:100%;height:6px;background:var(--border);border-radius:3px;overflow:hidden;margin-bottom:16px}
.prog-fill{height:100%;background:linear-gradient(90deg,var(--pri),var(--acc));border-radius:3px;transition:width .4s}
.task-card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:20px 22px;box-shadow:var(--sh);margin-bottom:12px}
.task-num{font-size:.72rem;font-weight:700;color:var(--acc);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px}
.task-text{font-size:.97rem;font-weight:700;line-height:1.85;margin-bottom:14px}
.task-hint{font-size:.8rem;color:var(--muted);margin-top:4px;margin-bottom:12px;display:flex;align-items:flex-start;gap:6px}
.task-hint i{margin-top:2px;color:var(--warn);flex-shrink:0}
.ans-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.ans-inp{width:110px;padding:11px 10px;border:2px solid var(--border);border-radius:10px;font-size:1.05rem;font-family:'JetBrains Mono',monospace;text-align:center;outline:none;background:var(--card);color:var(--text);transition:.18s}
.ans-inp:focus{border-color:var(--pri);box-shadow:0 0 0 3px rgba(29,78,216,.12)}
.unit-lbl{font-size:.82rem;color:var(--muted);font-weight:600;white-space:nowrap}
.btn{padding:11px 20px;border:none;border-radius:10px;font-weight:700;font-size:.84rem;cursor:pointer;transition:.18s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.btn:active{transform:scale(.96)}
.btn-pri{background:var(--pri);color:#fff}.btn-pri:hover{background:var(--pri2)}
.btn-ghost{background:transparent;border:2px solid var(--border);color:var(--muted)}.btn-ghost:hover{border-color:var(--pri);color:var(--pri)}
.btn-next{background:var(--ok);color:#fff}.btn-next:hover{filter:brightness(1.1)}
.feedback{padding:13px 18px;border-radius:11px;font-size:.87rem;font-weight:600;display:none;line-height:1.7;margin-top:10px}
.feedback.show{display:block;animation:pop .28s ease}
.fb-ok{background:var(--ok-bg);color:#065f46}
.fb-fail{background:var(--fail-bg);color:#991b1b}
@keyframes pop{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:scale(1)}}
/* ── Итог ── */
.summary{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:28px;text-align:center;box-shadow:var(--sh);display:none}
.summary.show{display:block;animation:pop .35s ease}
.summary h2{font-size:1.2rem;font-weight:800;margin-bottom:8px}
.big-score{font-size:3.5rem;font-weight:900;color:var(--pri);line-height:1;margin:10px 0}
.sum-grade{color:var(--muted);font-size:.9rem;margin-bottom:20px}
.sum-btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
/* ── Справочник (плавающая кнопка) ── */
.ref-toggle{position:fixed;bottom:16px;right:16px;z-index:60;width:46px;height:46px;border-radius:13px;background:var(--pri);color:#fff;border:none;cursor:pointer;display:grid;place-items:center;font-size:1.1rem;box-shadow:0 4px 14px rgba(29,78,216,.3)}
.ref-panel{position:fixed;bottom:72px;right:16px;z-index:60;width:300px;max-height:72vh;overflow-y:auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:16px 18px;box-shadow:0 8px 30px rgba(0,0,0,.15);display:none;font-size:.8rem;line-height:1.85;scrollbar-width:thin}
.ref-panel.show{display:block;animation:pop .2s ease}
.ref-panel h3{font-size:.84rem;font-weight:700;color:var(--pri);margin:12px 0 4px}.ref-panel h3:first-child{margin-top:0}
.ref-panel .rf{background:rgba(29,78,216,.06);border-radius:8px;padding:6px 10px;margin:3px 0;text-align:center}
/* ── Para-hero баннеры ── */
.para-hero{border-radius:18px;padding:22px 24px;margin-bottom:22px;position:relative;overflow:hidden}
.para-hero::after{content:'';position:absolute;right:-28px;top:-28px;width:150px;height:150px;border-radius:50%;opacity:.13;pointer-events:none}
.ph-31{background:linear-gradient(135deg,#1e3a8a 0%,#1d4ed8 55%,#3b82f6 100%);color:#fff}
.ph-31::after{background:#bfdbfe}
.ph-32{background:linear-gradient(135deg,#0c4a6e 0%,#0369a1 55%,#0ea5e9 100%);color:#fff}
.ph-32::after{background:#bae6fd}
.ph-33{background:linear-gradient(135deg,#064e3b 0%,#065f46 55%,#10b981 100%);color:#fff}
.ph-33::after{background:#a7f3d0}
.ph-34{background:linear-gradient(135deg,#78350f 0%,#92400e 55%,#d97706 100%);color:#fff}
.ph-34::after{background:#fde68a}
.ph-35{background:linear-gradient(135deg,#4c1d95 0%,#6d28d9 55%,#8b5cf6 100%);color:#fff}
.ph-35::after{background:#ddd6fe}
.ph-36{background:linear-gradient(135deg,#134e4a 0%,#0f766e 55%,#2dd4bf 100%);color:#fff}
.ph-36::after{background:#99f6e4}
.para-hero .ph-label{font-size:.7rem;font-weight:700;opacity:.7;letter-spacing:.1em;text-transform:uppercase;margin-bottom:5px}
.para-hero h2{font-size:1.12rem;font-weight:900;margin-bottom:8px;line-height:1.3}
.para-hero .ph-formula{display:inline-block;font-size:1rem;background:rgba(255,255,255,.17);border-radius:10px;padding:7px 16px;margin:2px 0 8px;font-weight:700;border:1px solid rgba(255,255,255,.22)}
.para-hero .ph-desc{font-size:.79rem;opacity:.87;line-height:1.65;margin-bottom:10px}
.para-hero .ph-tags{display:flex;flex-wrap:wrap;gap:6px}
.para-hero .ph-tag{background:rgba(255,255,255,.17);border:1px solid rgba(255,255,255,.25);border-radius:20px;padding:3px 11px;font-size:.7rem;font-weight:700}
/* ── Запомни! ── */
.remember-box{background:linear-gradient(135deg,rgba(239,68,68,.06),rgba(220,38,38,.03));border:2px solid rgba(239,68,68,.3);border-radius:13px;padding:14px 17px;margin:16px 0}
.remember-box-title{font-weight:800;font-size:.82rem;color:#b91c1c;margin-bottom:8px;display:flex;align-items:center;gap:7px}
.dark .remember-box{border-color:rgba(239,68,68,.4);background:rgba(239,68,68,.07)}
.dark .remember-box-title{color:#fca5a5}
.remember-box ul{padding-left:18px;margin:0}
.remember-box li,.remember-box p{font-size:.83rem;color:var(--text);line-height:1.9;margin:0}
/* ── Частые ошибки ── */
.mistakes-box{background:linear-gradient(135deg,rgba(245,158,11,.06),rgba(251,191,36,.03));border:2px solid rgba(245,158,11,.35);border-radius:13px;padding:14px 17px;margin:16px 0}
.mistakes-box-title{font-weight:800;font-size:.82rem;color:#92400e;margin-bottom:8px;display:flex;align-items:center;gap:7px}
.dark .mistakes-box{border-color:rgba(245,158,11,.4);background:rgba(245,158,11,.07)}
.dark .mistakes-box-title{color:#fcd34d}
.mistakes-box ul{padding-left:18px;margin:0}
.mistakes-box li{font-size:.83rem;color:var(--text);line-height:1.9}
/* ── Шаги решения ── */
.sol-steps{list-style:none;padding:0;margin:8px 0}
.sol-steps li{display:flex;align-items:flex-start;gap:10px;margin-bottom:10px;font-size:.86rem;line-height:1.75}
.step-n{min-width:24px;height:24px;border-radius:50%;background:var(--pri);color:#fff;font-size:.69rem;font-weight:800;display:grid;place-items:center;margin-top:1px;flex-shrink:0}
/* ── Интерактивные схемы ── */
.idiag{background:var(--card);border:2px solid var(--border);border-radius:14px;padding:16px 18px;margin:14px 0;box-shadow:var(--sh)}
.idiag h3{font-size:.79rem;font-weight:700;color:var(--pri);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px;display:flex;align-items:center;gap:6px}
.idiag-2col{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:14px 0}
@media(max-width:560px){.idiag-2col{grid-template-columns:1fr}}
.slider-row{display:flex;align-items:center;gap:10px;margin:8px 0;font-size:.82rem;flex-wrap:wrap}
.slider-lbl{min-width:90px;font-weight:600;color:var(--text);flex-shrink:0}
.slider-val{min-width:72px;font-weight:800;color:var(--pri);font-family:'JetBrains Mono',monospace;font-size:.82rem;flex-shrink:0}
input[type=range]{flex:1;min-width:100px;accent-color:var(--pri);cursor:pointer}
.idiag-result{background:rgba(29,78,216,.08);border-radius:10px;padding:10px 14px;margin-top:10px;font-size:.9rem;font-weight:700;text-align:center;font-family:'JetBrains Mono',monospace;letter-spacing:.02em;border:1px solid rgba(29,78,216,.15)}
.work-pos{color:#065f46;font-weight:900}.work-zero{color:#92400e;font-weight:900}.work-neg{color:#991b1b;font-weight:900}
/* ── Цепочка вывода формулы ── */
.fchain{display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:rgba(29,78,216,.04);border:1px solid var(--border);border-radius:11px;padding:11px 15px;margin:10px 0;font-size:.82rem}
.fchain-step{background:var(--card);border:1.5px solid var(--border);border-radius:8px;padding:4px 12px;font-family:'JetBrains Mono',monospace;font-size:.8rem;font-weight:600}
.fchain-arrow{color:var(--muted);font-weight:700}
.fchain-note{font-size:.73rem;color:var(--muted);font-style:italic}
/* ── Объяснение по-человечески ── */
.student-box{background:linear-gradient(135deg,rgba(254,243,199,.7),rgba(255,237,213,.7));border:1.5px solid #f59e0b;border-radius:14px;padding:16px 18px;margin:16px 0;line-height:1.75}
.dark .student-box{background:linear-gradient(135deg,rgba(120,80,0,.18),rgba(100,50,0,.18));border-color:#d97706}
.student-box-title{font-weight:800;font-size:.88rem;color:#92400e;margin-bottom:10px;display:flex;align-items:center;gap:7px}
.dark .student-box-title{color:#fbbf24}
.student-box p{margin:0 0 9px;font-size:.84rem;color:var(--text)}
.student-box p:last-child{margin-bottom:0}
.student-box b{color:#92400e}
.dark .student-box b{color:#fbbf24}
/* ── Тема ── */
.theme-btn{position:fixed;top:12px;right:12px;z-index:60;width:38px;height:38px;border-radius:10px;background:var(--card);border:1px solid var(--border);cursor:pointer;display:grid;place-items:center;font-size:1rem;box-shadow:var(--sh);color:var(--text)}
/* ── Para badge (сложные задачи) ── */
.para-badge{display:inline-flex;align-items:center;padding:2px 8px;background:rgba(29,78,216,.13);color:var(--pri);border-radius:6px;font-size:.68rem;font-weight:800;margin-left:7px;letter-spacing:.03em}
.para-badge.b32{background:rgba(14,165,233,.13);color:#0284c7}
.para-badge.b33{background:rgba(16,185,129,.13);color:#059669}
.para-badge.b34{background:rgba(245,158,11,.13);color:#d97706}
.para-badge.b35{background:rgba(109,40,217,.13);color:#6d28d9}
.para-badge.b36{background:rgba(15,118,110,.13);color:#0f766e}
/* ── §1–14 Кинематика Para-heroes ── */
.ph-1{background:linear-gradient(135deg,#7f1d1d 0%,#dc2626 55%,#f97316 100%);color:#fff}
.ph-1::after{background:#fed7aa}
.ph-2{background:linear-gradient(135deg,#134e4a 0%,#0d9488 55%,#2dd4bf 100%);color:#fff}
.ph-2::after{background:#99f6e4}
.ph-3{background:linear-gradient(135deg,#500724 0%,#be185d 55%,#f472b6 100%);color:#fff}
.ph-3::after{background:#fce7f3}
.ph-4{background:linear-gradient(135deg,#431407 0%,#b45309 55%,#fbbf24 100%);color:#fff}
.ph-4::after{background:#fde68a}
.ph-5{background:linear-gradient(135deg,#1e3a8a 0%,#1d4ed8 55%,#60a5fa 100%);color:#fff}
.ph-5::after{background:#bfdbfe}
.ph-6{background:linear-gradient(135deg,#14532d 0%,#15803d 55%,#4ade80 100%);color:#fff}
.ph-6::after{background:#bbf7d0}
.ph-7{background:linear-gradient(135deg,#2e1065 0%,#7c3aed 55%,#c4b5fd 100%);color:#fff}
.ph-7::after{background:#ede9fe}
.ph-8{background:linear-gradient(135deg,#082f49 0%,#0284c7 55%,#7dd3fc 100%);color:#fff}
.ph-8::after{background:#e0f2fe}
.ph-9{background:linear-gradient(135deg,#1a2e05 0%,#4d7c0f 55%,#a3e635 100%);color:#fff}
.ph-9::after{background:#d9f99d}
.ph-10{background:linear-gradient(135deg,#4c0519 0%,#be123c 55%,#fb7185 100%);color:#fff}
.ph-10::after{background:#ffe4e6}
.ph-11{background:linear-gradient(135deg,#1e1b4b 0%,#3730a3 55%,#a5b4fc 100%);color:#fff}
.ph-11::after{background:#e0e7ff}
.ph-12{background:linear-gradient(135deg,#7c2d12 0%,#c2410c 55%,#fb923c 100%);color:#fff}
.ph-12::after{background:#ffedd5}
.ph-13{background:linear-gradient(135deg,#2e1065 0%,#6d28d9 55%,#ddd6fe 100%);color:#fff}
.ph-13::after{background:#f5f3ff}
.ph-14{background:linear-gradient(135deg,#164e63 0%,#0e7490 55%,#67e8f9 100%);color:#fff}
.ph-14::after{background:#cffafe}
.para-badge.b1{background:rgba(220,38,38,.13);color:#dc2626}
.para-badge.b2{background:rgba(13,148,136,.13);color:#0d9488}
.para-badge.b3{background:rgba(190,24,93,.13);color:#be185d}
.para-badge.b4{background:rgba(180,83,9,.13);color:#b45309}
.para-badge.b5{background:rgba(29,78,216,.13);color:#1d4ed8}
.para-badge.b6{background:rgba(21,128,61,.13);color:#15803d}
.para-badge.b7{background:rgba(124,58,237,.13);color:#7c3aed}
.para-badge.b8{background:rgba(2,132,199,.13);color:#0284c7}
.para-badge.b9{background:rgba(77,124,15,.13);color:#4d7c0f}
.para-badge.b10{background:rgba(190,18,60,.13);color:#be123c}
.para-badge.b11{background:rgba(55,48,163,.13);color:#3730a3}
.para-badge.b12{background:rgba(194,65,12,.13);color:#c2410c}
.para-badge.b13{background:rgba(109,40,217,.13);color:#6d28d9}
.para-badge.b14{background:rgba(14,116,144,.13);color:#0e7490}
/* ── §1521 Para-heroes ── */
.ph-15{background:linear-gradient(135deg,#7c2d12 0%,#c2410c 55%,#f97316 100%);color:#fff}
.ph-15::after{background:#fed7aa}
.ph-16{background:linear-gradient(135deg,#881337 0%,#be123c 55%,#f43f5e 100%);color:#fff}
.ph-16::after{background:#fecdd3}
.ph-17{background:linear-gradient(135deg,#4a044e 0%,#7e22ce 55%,#d946ef 100%);color:#fff}
.ph-17::after{background:#f5d0fe}
.ph-18{background:linear-gradient(135deg,#082f49 0%,#155e75 55%,#22d3ee 100%);color:#fff}
.ph-18::after{background:#a5f3fc}
.ph-19{background:linear-gradient(135deg,#500724 0%,#9d174d 55%,#f472b6 100%);color:#fff}
.ph-19::after{background:#fbcfe8}
.ph-20{background:linear-gradient(135deg,#1c1917 0%,#44403c 55%,#a8a29e 100%);color:#fff}
.ph-20::after{background:#e7e5e4}
.ph-21{background:linear-gradient(135deg,#1e1b4b 0%,#3730a3 55%,#818cf8 100%);color:#fff}
.ph-21::after{background:#c7d2fe}
.ph-22{background:linear-gradient(135deg,#0c4a6e 0%,#0369a1 55%,#38bdf8 100%);color:#fff}
.ph-22::after{background:#bae6fd}
.ph-23{background:linear-gradient(135deg,#14532d 0%,#166534 55%,#4ade80 100%);color:#fff}
.ph-23::after{background:#bbf7d0}
.ph-24{background:linear-gradient(135deg,#3b0764 0%,#7e22ce 55%,#c084fc 100%);color:#fff}
.ph-24::after{background:#e9d5ff}
.ph-25{background:linear-gradient(135deg,#052e16 0%,#065f46 55%,#34d399 100%);color:#fff}
.ph-25::after{background:#a7f3d0}
.ph-26{background:linear-gradient(135deg,#2e1065 0%,#6d28d9 55%,#c084fc 100%);color:#fff}
.ph-26::after{background:#e9d5ff}
.ph-27{background:linear-gradient(135deg,#431407 0%,#b45309 55%,#fbbf24 100%);color:#fff}
.ph-27::after{background:#fde68a}
.ph-28{background:linear-gradient(135deg,#0f2027 0%,#203a43 55%,#2c5364 100%);color:#fff}
.ph-28::after{background:#a5f3fc}
.ph-29{background:linear-gradient(135deg,#001845 0%,#0041a8 55%,#0099ff 100%);color:#fff}
.ph-29::after{background:#bfdbfe}
.ph-30{background:linear-gradient(135deg,#064e3b 0%,#065f46 55%,#34d399 100%);color:#fff}
.ph-30::after{background:#a7f3d0}
.para-badge.b15{background:rgba(194,65,12,.13);color:#c2410c}
.para-badge.b16{background:rgba(190,18,60,.13);color:#be123c}
.para-badge.b17{background:rgba(126,34,206,.13);color:#7e22ce}
.para-badge.b18{background:rgba(21,94,117,.13);color:#155e75}
.para-badge.b19{background:rgba(157,23,77,.13);color:#9d174d}
.para-badge.b20{background:rgba(68,64,60,.13);color:#44403c}
.para-badge.b21{background:rgba(55,48,163,.13);color:#3730a3}
.para-badge.b22{background:rgba(3,105,161,.13);color:#0369a1}
.para-badge.b23{background:rgba(22,101,52,.13);color:#166534}
.para-badge.b24{background:rgba(126,34,206,.13);color:#7e22ce}
.para-badge.b25{background:rgba(6,95,70,.13);color:#065f46}
.para-badge.b26{background:rgba(109,40,217,.13);color:#6d28d9}
.para-badge.b27{background:rgba(180,83,9,.13);color:#b45309}
.para-badge.b28{background:rgba(32,58,67,.13);color:#203a43}
.para-badge.b29{background:rgba(0,65,168,.13);color:#0041a8}
.para-badge.b30{background:rgba(6,95,70,.13);color:#065f46}
/* ── Misc ── */
.dark .ans-inp{background:#0f172a;color:#e2e8f0}
.dark .fcard{background:#1e293b}.dark .example-box{background:#1e293b}
.katex{font-size:1em!important}
.info-badge{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:20px;font-size:.72rem;font-weight:700;background:rgba(14,165,233,.12);color:#0284c7;margin-left:8px}
hr.divider{border:none;border-top:1px solid var(--border);margin:20px 0}
/* ── Навигация по задачам ── */
.nav-dots{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:14px}
.nav-dot{min-width:30px;height:30px;padding:0 6px;border-radius:7px;border:2px solid var(--border);background:var(--card);font-size:.72rem;font-weight:700;cursor:pointer;display:grid;place-items:center;transition:.15s;color:var(--muted);font-family:'JetBrains Mono',monospace}
.nav-dot:hover{border-color:var(--pri);color:var(--pri)}
.nav-dot.nd-cur{background:var(--pri);border-color:var(--pri);color:#fff}
.nav-dot.nd-ok{background:var(--ok-bg);border-color:var(--ok);color:#065f46}
.nav-dot.nd-fail{background:var(--fail-bg);border-color:var(--fail);color:#991b1b}
/* ── Life-examples grid ── */
.life-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px;margin:14px 0}
.life-item{background:var(--card);border:1.5px solid var(--border);border-radius:12px;padding:12px 10px;text-align:center}
.life-item .li-icon{font-size:1.9rem;margin-bottom:5px}
.life-item .li-title{font-size:.79rem;font-weight:700;color:var(--text);margin-bottom:3px}
.life-item .li-desc{font-size:.71rem;color:var(--muted);line-height:1.55}
/* ── Insight (physics aha) box ── */
.insight-box{background:linear-gradient(135deg,rgba(99,102,241,.07),rgba(139,92,246,.04));border:2px solid rgba(99,102,241,.22);border-radius:13px;padding:14px 17px;margin:16px 0}
.insight-title{font-weight:800;font-size:.82rem;color:#4f46e5;margin-bottom:7px;display:flex;align-items:center;gap:7px}
.dark .insight-box{background:rgba(99,102,241,.08);border-color:rgba(139,92,246,.3)}
.dark .insight-title{color:#a5b4fc}
.insight-box p{font-size:.83rem;color:var(--text);line-height:1.8;margin:0 0 6px}
.insight-box p:last-child{margin:0}
/* ── μ table ── */
.mu-tbl{width:100%;border-collapse:collapse;font-size:.8rem;margin:8px 0}
.mu-tbl th{background:rgba(68,64,60,.1);padding:5px 8px;text-align:center;font-weight:700;border:1px solid var(--border)}
.mu-tbl td{padding:4px 8px;text-align:center;border:1px solid var(--border)}
.mu-tbl tr:hover td{background:rgba(29,78,216,.04)}
/* ── Solve-steps ── */
.solve-box{background:var(--card);border:1.5px solid var(--border);border-radius:12px;padding:14px 18px;margin:14px 0}
.solve-box h4{font-size:.82rem;font-weight:800;color:var(--pri);margin-bottom:10px;display:flex;align-items:center;gap:6px}
/* ── Canvas physics panels ── */
.cv-wrap{position:relative;margin:10px 0}
.cv-wrap canvas{width:100%;border-radius:10px;display:block}
.cv-playbtn{margin-top:6px;padding:7px 18px;border:none;border-radius:8px;background:var(--pri);color:#fff;font-weight:700;font-size:.8rem;cursor:pointer;transition:.15s}
.cv-playbtn:hover{filter:brightness(1.1)}
/* ── Para-pills ── */
.para-pill{padding:6px 13px;border:2px solid var(--border);border-radius:10px;font-size:.74rem;font-weight:700;cursor:pointer;white-space:nowrap;transition:.18s;background:var(--card);color:var(--muted);flex-shrink:0}
.para-pill:hover{border-color:var(--pri);color:var(--pri)}
.para-pill.active{background:var(--pri);color:#fff;border-color:var(--pri)}
/* ── MCQ ── */
.mcq-opts{display:flex;flex-direction:column;gap:8px;margin-top:4px}
.mcq-opt{width:100%;text-align:left;padding:11px 16px;border:2px solid var(--border);border-radius:10px;background:var(--card);color:var(--text);font-size:.9rem;font-weight:500;cursor:pointer;transition:.18s;line-height:1.5;font-family:inherit}
.mcq-opt:hover:not(:disabled){border-color:var(--pri);background:rgba(29,78,216,.05);color:var(--text)}
.mcq-opt:disabled{cursor:default}
.mcq-opt.mcq-cor{border-color:var(--ok)!important;background:var(--ok-bg)!important;color:#065f46!important;font-weight:700}
.mcq-opt.mcq-wrong{border-color:var(--fail)!important;background:var(--fail-bg)!important;color:#991b1b!important}
/* ── Def / info box ── */
.def-box{background:rgba(29,78,216,.05);border-left:4px solid var(--pri);border-radius:10px;padding:12px 16px;margin-bottom:16px;font-size:.87rem;line-height:1.8}
/* ── Лаб. №11 ── */
.ph-lab{background:linear-gradient(135deg,#7f1d1d 0%,#b91c1c 55%,#ef4444 100%);color:#fff}
.ph-lab::after{background:#fca5a5}
.lab11-tbl{width:100%;border-collapse:collapse;font-size:.83rem;font-family:'JetBrains Mono',monospace}
.lab11-tbl th{background:rgba(29,78,216,.07);padding:7px 8px;text-align:center;font-weight:700;font-size:.74rem;border:1px solid var(--border)}
.lab11-tbl td{padding:6px 8px;text-align:center;border:1px solid var(--border);background:var(--card)}
.lab11-tbl tr:hover td{background:rgba(29,78,216,.04)}
.lab11-tbl tr.lab11-avg td{background:rgba(29,78,216,.09);font-weight:800;color:var(--pri)}
/* ── Тетрадные вычисления (Лаб. №11) ── */
.nb-wrap{
background-color:#fffef2;
background-image:
linear-gradient(90deg,transparent 33px,rgba(239,68,68,.22) 33px,rgba(239,68,68,.22) 35px,transparent 35px),
repeating-linear-gradient(transparent 0,transparent 26px,#bfdbfe 26px,#bfdbfe 27px);
border:1px solid #fde68a;border-radius:13px;
padding:14px 18px 14px 46px;
font-size:.82rem;line-height:27px;color:var(--text);
margin:16px 0;overflow:hidden
}
.dark .nb-wrap{
background-color:#14120a;
background-image:
linear-gradient(90deg,transparent 33px,rgba(185,28,28,.30) 33px,rgba(185,28,28,.30) 35px,transparent 35px),
repeating-linear-gradient(transparent 0,transparent 26px,rgba(30,58,95,.75) 26px,rgba(30,58,95,.75) 27px);
border-color:#422006
}
.nb-hdr{font-size:.87rem;font-weight:800;color:#b45309;letter-spacing:.03em;margin-bottom:1px}
.dark .nb-hdr{color:#fbbf24}
.nb-dado{display:grid;grid-template-columns:1fr 1fr;gap:0 16px;margin-bottom:4px}
@media(max-width:440px){.nb-dado{grid-template-columns:1fr}}
.nb-clbl{font-weight:800;color:var(--pri);text-decoration:underline;text-underline-offset:2px}
.nb-div{border:none;border-top:1.5px solid #fde68a;margin:4px 0}
.dark .nb-div{border-color:#422006}
.nb-sh{font-weight:800;color:var(--pri);margin:2px 0}
.nb-step{margin:2px 0}
.nb-step b{color:#1e293b;font-weight:700}
.dark .nb-step b{color:#e2e8f0}
.nb-i{display:block;padding-left:18px}
.nb-v{color:#1d4ed8;font-weight:800;font-family:'JetBrains Mono',monospace}
.dark .nb-v{color:#93c5fd}
.nb-box{display:inline-block;background:rgba(29,78,216,.11);border:1.5px solid rgba(29,78,216,.22);
border-radius:5px;padding:0 7px;font-weight:800;font-family:'JetBrains Mono',monospace;color:#1d4ed8}
.dark .nb-box{background:rgba(147,197,253,.11);border-color:rgba(147,197,253,.28);color:#93c5fd}
.nb-ok{color:#065f46;font-weight:800}.nb-bad{color:#991b1b;font-weight:800}
.nb-ans{border-top:2px solid #fde68a;margin-top:6px;padding-top:4px;font-weight:800;font-size:.85rem}
.dark .nb-ans{border-color:#422006}
/* === END MONOLITH CSS === */
</style>
</head>
<body>
<header class="hdr">
<div class="hdr-row">
<div>
<h1>Физика 9 · Глава 1</h1>
<div class="hdr-sub">Механическое движение · векторы · путь и перемещение · равноускоренное движение · движение по окружности</div>
</div>
<div class="hdr-side">
<a href="/textbook/physics-9" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К физике 9</a>
<button id="search-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg> Поиск</button>
<button id="sidebar-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="14" y2="18"/></svg> Шпаргалка</button>
<button id="theme-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg><span id="theme-lab">Тёмная</span></button>
</div>
</div>
</header>
<main class="main">
<div class="col-main">
<section class="hero">
<h2>Кинематика — как описывать движение</h2>
<p>Раздел физики, изучающий движение тел без выяснения причин, его вызывающих. Изучаем векторы, скорость, ускорение и графики движения.</p>
<div class="hero-row">
<button class="btn-primary" onclick="goTo('p1')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 1</button>
<div class="hero-progress">
<span class="hp-label">Прогресс по главе</span>
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
<span id="hero-hp-text" class="hp-text">0%</span>
</div>
<div id="hero-xp-badge" class="hero-xp-badge"></div>
</div>
</section>
<section class="psel">
<div class="psel-title">Параграфы главы</div>
<div id="psel-grid" class="psel-grid"></div>
</section>
<section id="sec-p1" class="sec" data-watermark="движ."><div class="sec-header"><span class="sec-num">§ 1</span><h2 class="sec-h">Механическое движение</h2></div><div id="p1-body"></div></section>
<section id="sec-p2" class="sec" data-watermark="СО"><div class="sec-header"><span class="sec-num">§ 2</span><h2 class="sec-h">Относительность движения. Система отсчёта</h2></div><div id="p2-body"></div></section>
<section id="sec-p3" class="sec" data-watermark="&vec;a"><div class="sec-header"><span class="sec-num">§ 3</span><h2 class="sec-h">Скалярные и векторные величины. Действия над векторами</h2></div><div id="p3-body"></div></section>
<section id="sec-p4" class="sec" data-watermark="a_x"><div class="sec-header"><span class="sec-num">§ 4</span><h2 class="sec-h">Проекция вектора на ось</h2></div><div id="p4-body"></div></section>
<section id="sec-p5" class="sec" data-watermark="&Delta;r"><div class="sec-header"><span class="sec-num">§ 5</span><h2 class="sec-h">Путь и перемещение</h2></div><div id="p5-body"></div></section>
<section id="sec-p6" class="sec" data-watermark="v&middot;t"><div class="sec-header"><span class="sec-num">§ 6</span><h2 class="sec-h">Равномерное прямолинейное движение. Скорость</h2></div><div id="p6-body"></div></section>
<section id="sec-p7" class="sec" data-watermark="v(t)"><div class="sec-header"><span class="sec-num">§ 7</span><h2 class="sec-h">Графическое представление равномерного движения</h2></div><div id="p7-body"></div></section>
<section id="sec-p8" class="sec" data-watermark="&lang;v&rang;"><div class="sec-header"><span class="sec-num">§ 8</span><h2 class="sec-h">Неравномерное движение. Средняя и мгновенная скорость</h2></div><div id="p8-body"></div></section>
<section id="sec-p9" class="sec" data-watermark="v_1+v_2"><div class="sec-header"><span class="sec-num">§ 9</span><h2 class="sec-h">Сложение скоростей</h2></div><div id="p9-body"></div></section>
<section id="sec-p10" class="sec" data-watermark="a"><div class="sec-header"><span class="sec-num">§ 10</span><h2 class="sec-h">Ускорение</h2></div><div id="p10-body"></div></section>
<section id="sec-p11" class="sec" data-watermark="v_0+at"><div class="sec-header"><span class="sec-num">§ 11</span><h2 class="sec-h">Скорость при равноускоренном движении</h2></div><div id="p11-body"></div></section>
<section id="sec-p12" class="sec" data-watermark="at&sup2;/2"><div class="sec-header"><span class="sec-num">§ 12</span><h2 class="sec-h">Перемещение, координата и путь при равноускоренном движении</h2></div><div id="p12-body"></div></section>
<section id="sec-p13" class="sec" data-watermark="&omega;R"><div class="sec-header"><span class="sec-num">§ 13</span><h2 class="sec-h">Линейная и угловая скорости</h2></div><div id="p13-body"></div></section>
<section id="sec-p14" class="sec" data-watermark="v&sup2;/R"><div class="sec-header"><span class="sec-num">§ 14</span><h2 class="sec-h">Ускорение точки при движении по окружности</h2></div><div id="p14-body"></div></section>
<section id="sec-final1" class="sec" data-watermark="&#9733;"><div class="sec-header"><span class="sec-num" style="background:linear-gradient(135deg,#2563eb,#60a5fa)"></span><h2 class="sec-h">Финал главы</h2></div><div id="final1-body"></div></section>
</div>
<aside class="col-side" id="col-side"><div id="sidebar-content"></div></aside>
<div class="col-side-backdrop" id="col-side-backdrop"></div>
</main>
<footer class="foot">Интерактивный учебник «Физика 9» · Глава 1 · «Основы кинематики» · LearnSpace</footer>
<div id="ach-popup" class="ach-popup"><svg class="ic" viewBox="0 0 24 24" style="width:22px;height:22px"><polygon points="12,2 22,20 2,20"/></svg><span id="ach-text">Достижение!</span></div>
<div id="search-modal" class="search-modal" role="dialog">
<div class="search-box">
<input type="text" id="search-input" class="search-input" placeholder="Поиск…" autocomplete="off">
<div id="search-results" class="search-results"></div>
<div class="search-foot"><span><kbd>↑↓</kbd> навигация</span><span><kbd>Enter</kbd> открыть</span><span><kbd>Esc</kbd> закрыть</span></div>
</div>
</div>
<script>
'use strict';
const STATE = { current:'p1', progress:{}, achievements:new Map(), xp:0, level:1 };
const TOTAL_PARAS = 15;
const _TB_SLUG = 'physics-9-ch1';
const PARAS = [
{ id:"p1", num:"§ 1", name:"Механическое движение", sub:"материальная точка" },
{ id:"p2", num:"§ 2", name:"Относительность движения. Система отсчёта", sub:"СО · относительность" },
{ id:"p3", num:"§ 3", name:"Скалярные и векторные величины. Действия над векторами", sub:"$\\vec a + \\vec b$" },
{ id:"p4", num:"§ 4", name:"Проекция вектора на ось", sub:"$a_x = a\\cos\\alpha$" },
{ id:"p5", num:"§ 5", name:"Путь и перемещение", sub:"$s$ vs $\\Delta\\vec r$" },
{ id:"p6", num:"§ 6", name:"Равномерное прямолинейное движение. Скорость", sub:"$\\Delta\\vec r = \\vec v t$" },
{ id:"p7", num:"§ 7", name:"Графическое представление равномерного движения", sub:"графики $v(t)$, $x(t)$" },
{ id:"p8", num:"§ 8", name:"Неравномерное движение. Средняя и мгновенная скорость", sub:"$\\langle v\\rangle = s/t$" },
{ id:"p9", num:"§ 9", name:"Сложение скоростей", sub:"$\\vec v_{1,3} = \\vec v_{1,2} + \\vec v_{2,3}$" },
{ id:"p10", num:"§ 10", name:"Ускорение", sub:"$\\vec a = \\Delta\\vec v/\\Delta t$" },
{ id:"p11", num:"§ 11", name:"Скорость при равноускоренном движении", sub:"$\\vec v = \\vec v_0 + \\vec a t$" },
{ id:"p12", num:"§ 12", name:"Перемещение, координата и путь при равноускоренном движении", sub:"$x = x_0 + v_0 t + at^2/2$" },
{ id:"p13", num:"§ 13", name:"Линейная и угловая скорости", sub:"$v = \\omega R$" },
{ id:"p14", num:"§ 14", name:"Ускорение точки при движении по окружности", sub:"$a_n = v^2/R$" },
{ id:"final1", num:'\u2605', name:'Финал главы', sub:"Итоги · боссы главы 1", final:true }
];
PARAS.forEach(p => { STATE.progress[p.id] = 0; });
function calcLevel(xp){ return Math.floor(Math.sqrt((xp||0)/100))+1; }
function _xpForLevel(lv){ return (lv-1)*(lv-1)*100; }
const ACH_LABELS = {
start:"Начало главы 1!",
p1_done:"Механическое движение освоен!",
p2_done:"Относительность движения. Система отсчёта освоен!",
p3_done:"Скалярные и векторные величины. Действия над векторами освоен!",
p4_done:"Проекция вектора на ось освоен!",
p5_done:"Путь и перемещение освоен!",
p6_done:"Равномерное прямолинейное движение. Скорость освоен!",
p7_done:"Графическое представление равномерного движения освоен!",
p8_done:"Неравномерное движение. Средняя и мгновенная скорость освоен!",
p9_done:"Сложение скоростей освоен!",
p10_done:"Ускорение освоен!",
p11_done:"Скорость при равноускоренном движении освоен!",
p12_done:"Перемещение, координата и путь при равноускоренном движении освоен!",
p13_done:"Линейная и угловая скорости освоен!",
p14_done:"Ускорение точки при движении по окружности освоен!",
ch1_done:"Глава 1 пройдена!"
};
function loadProgress(){
try{
const s=localStorage.getItem('physics9_ch1_progress'); if(s) Object.assign(STATE.progress, JSON.parse(s));
const a=localStorage.getItem('physics9_ch1_achievements');
if(a){ const p=JSON.parse(a); if(Array.isArray(p)) p.forEach(id=>STATE.achievements.set(id, ACH_LABELS[id]||id)); else if(p&&typeof p==='object'){ for(const[id,t] of Object.entries(p)) STATE.achievements.set(id,(t&&t!==id)?t:(ACH_LABELS[id]||id)); } }
STATE.xp=+(localStorage.getItem('physics9_xp')||0); STATE.level=calcLevel(STATE.xp);
}catch(e){}
}
function saveProgress(){
try{
localStorage.setItem('physics9_ch1_progress', JSON.stringify(STATE.progress));
localStorage.setItem('physics9_ch1_achievements', JSON.stringify(Object.fromEntries(STATE.achievements)));
localStorage.setItem('physics9_xp', String(STATE.xp));
}catch(e){}
}
function bumpProgress(key, delta){
STATE.progress[key]=Math.max(0,Math.min(100,(STATE.progress[key]||0)+delta));
saveProgress(); refreshProgressUI();
if(STATE.progress[key]>=50) markParaRead(key);
}
const _markedRead=new Set();
let _pendingProgressBody=null, _progressTimer=null;
function _flushProgress(){
const body=_pendingProgressBody; _pendingProgressBody=null; if(!body) return;
const tok=(window.LS&&LS.getToken)?LS.getToken():''; if(!tok) return;
fetch('/api/textbooks/'+_TB_SLUG+'/progress',{method:'POST',headers:{'Content-Type':'application/json','Authorization':'Bearer '+tok},body:JSON.stringify(body),keepalive:true}).catch(()=>{});
}
function _queueProgress(patch){ _pendingProgressBody=Object.assign(_pendingProgressBody||{},patch); if(_progressTimer) clearTimeout(_progressTimer); _progressTimer=setTimeout(_flushProgress, 600); }
function markLastPara(id){ _queueProgress({last_para:id}); }
function markParaRead(id){ if(_markedRead.has(id)) return; _markedRead.add(id); _queueProgress({mark_read:id}); }
window.addEventListener('beforeunload', _flushProgress);
function loadServerReadState(){
const tok=(window.LS&&LS.getToken)?LS.getToken():''; if(!tok) return;
fetch('/api/textbooks/'+_TB_SLUG,{headers:{'Authorization':'Bearer '+tok}}).then(r=>r.ok?r.json():null).then(d=>{
if(!d||!d.progress) return;
(d.progress.read||[]).forEach(k=>{_markedRead.add(k); if((STATE.progress[k]||0)<50) STATE.progress[k]=100;});
saveProgress(); refreshProgressUI();
}).catch(()=>{});
}
function addXp(n,src){
if(!n) return;
const prev=STATE.level; STATE.xp=Math.max(0,(STATE.xp||0)+n); STATE.level=calcLevel(STATE.xp);
saveProgress(); refreshProgressUI();
if(window.LS&&window.LS.xp) window.LS.xp.add(n,'physics9-ch1-'+(src||'misc'));
if(STATE.level>prev){
const pop=document.getElementById('ach-popup');
if(pop){ document.getElementById('ach-text').textContent='Уровень '+STATE.level+'!'; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'),2600); }
}
}
function refreshProgressUI(){
const total=Math.round(Object.values(STATE.progress).reduce((a,b)=>a+b,0)/TOTAL_PARAS);
const f=document.getElementById('hero-hp-fill'); if(f) f.style.width=total+'%';
const t=document.getElementById('hero-hp-text'); if(t) t.textContent=total+'% пройдено';
document.querySelectorAll('[data-prog-card]').forEach(el=>{ const k=el.dataset.progCard; const fl=el.querySelector('.psel-prog-fill'); if(fl) fl.style.width=(STATE.progress[k]||0)+'%'; });
const xpBadge=document.getElementById('hero-xp-badge');
if(xpBadge){ xpBadge.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:13px;height:13px"><polygon points="12 2 22 20 2 20"/></svg> Ур. '+STATE.level+' \xb7 '+(STATE.xp||0)+' XP'; }
if(STATE.current && document.getElementById('sidebar-content')){ try{ buildSidebar(STATE.current); }catch(e){} }
refreshDoneMarks();
}
function refreshDoneMarks(){
try{
document.querySelectorAll('.psel-card').forEach(c=>{
const id = c.dataset.id || c.dataset.progCard;
if(!id) return;
const pct = +STATE.progress[id] || 0;
if(!c.querySelector('.psel-done')){
const s = document.createElement('span');
s.className = 'psel-done';
s.setAttribute('title','Прочитано');
s.innerHTML = '<svg viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>';
c.appendChild(s);
}
c.classList.toggle('done', pct >= 50);
});
}catch(e){}
}
function achievement(id,text){
if(STATE.achievements.has(id)) return;
STATE.achievements.set(id, text||ACH_LABELS[id]||id); saveProgress();
const pop=document.getElementById('ach-popup');
if(pop){ document.getElementById('ach-text').textContent=text||ACH_LABELS[id]||id; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'),3300); }
addXp(20,'ach-'+id);
}
function buildParaSelector(){
const g=document.getElementById('psel-grid'); g.innerHTML='';
PARAS.forEach(p=>{
const card=document.createElement('div');
card.className='psel-card'+(p.final?' final':'');
card.dataset.id=p.id; card.dataset.progCard=p.id;
card.innerHTML='<div class="psel-num">'+p.num+'</div><div class="psel-name">'+p.name+'</div><div class="psel-prog"><div class="psel-prog-fill"></div></div>';
card.addEventListener('click', ()=>goTo(p.id));
g.appendChild(card);
});
}
const BUILT=new Set();
const BUILDERS = { p1:()=>build_p1(), p2:()=>build_p2(), p3:()=>build_p3(), p4:()=>build_p4(), p5:()=>build_p5(), p6:()=>build_p6(), p7:()=>build_p7(), p8:()=>build_p8(), p9:()=>build_p9(), p10:()=>build_p10(), p11:()=>build_p11(), p12:()=>build_p12(), p13:()=>build_p13(), p14:()=>build_p14(), final1:()=>build_final1() };
function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } }
function _makeTaskBlock(sec){
return ''
+ '<div class="legacy-tasks" id="ptab-' + sec + '" style="margin-top:20px;padding:16px 18px;background:var(--card,#fff);border:1.5px solid var(--border,#e2e8f0);border-radius:14px">'
+ '<div class="score-bar" style="display:flex;gap:10px;align-items:center;margin-bottom:10px;flex-wrap:wrap">'
+ '<div style="font-weight:700;color:var(--text)">Задачи параграфа</div>'
+ '<div class="chip chip-ok" style="margin-left:auto;padding:3px 10px;border-radius:99px;background:#dcfce7;color:#065f46;font-weight:700;font-size:.82rem"><span id="ok' + sec + '">0</span>&nbsp;верно</div>'
+ '<div class="chip chip-tot" style="padding:3px 10px;border-radius:99px;background:rgba(15,23,42,.06);color:var(--muted);font-weight:700;font-size:.82rem"><span id="cur' + sec + '">0</span>/<span id="max' + sec + '">?</span></div>'
+ '<button class="btn" onclick="if(window.resetTasks)window.resetTasks(\'' + sec + '\')" style="padding:5px 11px;font-size:.78rem;border-radius:8px;background:transparent;border:1px solid var(--border);color:var(--text)">Заново</button>'
+ '</div>'
+ '<div class="prog-wrap" style="height:5px;background:rgba(0,0,0,.07);border-radius:3px;overflow:hidden;margin-bottom:10px"><div id="prog' + sec + '" style="height:100%;width:0%;background:linear-gradient(90deg,var(--sec-acc,#2563eb),var(--sec-acc-d,#1d4ed8));transition:width .4s"></div></div>'
+ '<div class="nav-dots" id="navDots' + sec + '" style="display:flex;gap:5px;flex-wrap:wrap;margin-bottom:10px"></div>'
+ '<div id="taskArea' + sec + '"></div>'
+ '<div class="feedback" id="fb' + sec + '" style="margin-top:8px"></div>'
+ '<div style="display:flex;gap:10px;margin-top:10px;justify-content:flex-end"><button class="btn primary" id="nextBtn' + sec + '" onclick="if(window.nextTask)window.nextTask(\'' + sec + '\')" style="display:none;padding:8px 16px;border-radius:9px;background:var(--sec-acc,#2563eb);color:#fff;border:0;font-weight:700">Следующая &rarr;</button></div>'
+ '<div class="summary" id="sum' + sec + '" style="display:none;text-align:center;padding:16px;margin-top:10px;background:linear-gradient(135deg,var(--sec-acc-soft,#dbeafe),var(--card));border-radius:11px"><div style="font-weight:700;margin-bottom:6px">Параграф пройден!</div><div class="big-score" id="sumScore' + sec + '" style="font-size:1.6rem;font-weight:900;color:var(--sec-acc-d,#1d4ed8)"></div><div class="sum-grade" id="sumGrade' + sec + '" style="margin:6px 0;color:var(--muted)"></div></div>'
+ '</div>';
}
function _injectTasks(id){
if(!id || !id.startsWith('p')) return;
if(!window.POOLS || !window.POOLS[id]) return;
var body = document.getElementById(id + '-body');
if(!body || body.querySelector('.legacy-tasks')) return;
body.insertAdjacentHTML('beforeend', _makeTaskBlock(id));
setTimeout(function(){ try { if(window.renderTask) window.renderTask(id); if(window.renderNav) window.renderNav(id); } catch(e){} try { if(window.PHYS9_FINALS_INIT && /^final\d+$/.test(id)) window.PHYS9_FINALS_INIT(id); } catch(e){ console.warn("phys9 final init:", e.message); } try { if(window.PHYS9_CH1_WIDGETS && window.PHYS9_CH1_WIDGETS[id]) window.PHYS9_CH1_WIDGETS[id](); } catch(e){ console.warn('phys9 widget init:', e.message); } try { if(window.PHYS9_FLAG_BASE){ if(id==='p5') window.PHYS9_FLAG_BASE.mount('F1','p5'); else if(id==='p9') window.PHYS9_FLAG_BASE.mount('F2','p9'); else if(id==='p11') window.PHYS9_FLAG_BASE.mount('F3','p11'); } } catch(e){ console.warn('phys9 flag init:', e.message); } }, 60);
}
var _origEnsureBuilt = ensureBuilt;
ensureBuilt = function(id){ _origEnsureBuilt(id); _injectTasks(id); };
function goTo(id){
STATE.current=id; ensureBuilt(id);
document.querySelectorAll('.sec').forEach(s=>s.classList.remove('active'));
const el=document.getElementById('sec-'+id); if(el) el.classList.add('active');
document.querySelectorAll('.psel-card').forEach(c=>c.classList.toggle('active', c.dataset.id===id));
buildSidebar(id);
window.scrollTo({top:0,behavior:'smooth'});
if((STATE.progress[id]||0)<10) bumpProgress(id, 10);
if(window.renderMathInElement) setTimeout(()=>renderMath(el), 0);
// Auto-init legacy simulations: call upd<N>() / startAnim<N>() / draw<N>() if defined in phys9_legacy.js.
if(id.startsWith('p')){
const n = id.slice(1);
setTimeout(()=>{
['upd','startAnim','init','draw'].forEach(prefix=>{
const fn = window[prefix + n];
if(typeof fn === 'function'){ try{ fn(); }catch(e){ console.warn(prefix + n + ' init:', e.message); } }
});
}, 50);
} else if(id.startsWith('lr')){
const n = id.slice(2);
setTimeout(()=>{
['updLab','drawLab'].forEach(prefix=>{
const fn = window[prefix + n];
if(typeof fn === 'function'){ try{ fn(); }catch(e){} }
});
}, 50);
}
markLastPara(id);
}
const SIDEBARS = {
p1:{title:"Шпаргалка §1",rows:[["Кинематика","описывает движение без причин"],["Мат. точка","тело с пренебр. размерами"],["Поступательное","все точки движутся одинаково"]]},
p2:{title:"Шпаргалка §2",rows:[["СО","тело отсчёта + оси + часы"],["Относ.","скорость, путь, траектория"],["Земля","чаще всего тело отсчёта"]]},
p3:{title:"Шпаргалка §3",rows:[["Скаляр","число"],["Вектор","число + направление"],["$\\vec a + \\vec b$","правило треугольника / параллелограмма"]]},
p4:{title:"Шпаргалка §4",rows:[["Проекция","$a_x = a\\cos\\alpha$"],["Знак","зависит от $\\alpha$"],["Сумма","$(\\vec a + \\vec b)_x = a_x + b_x$"]]},
p5:{title:"Шпаргалка §5",rows:[["Путь","скаляр $s \\ge 0$"],["Перемещ.","вектор $\\Delta\\vec r$"],["$s \\ge |\\Delta\\vec r|$",""]]},
p6:{title:"Шпаргалка §6",rows:[["$\\vec v = \\text{const}$","равномерное"],["$\\Delta\\vec r = \\vec v t$",""],["$x = x_0 + v_x t$","координата"]]},
p7:{title:"Шпаргалка §7",rows:[["$v(t)$","прямая"],["$x(t)$","наклонная прямая"],["Площадь","под $v(t)$ = путь"]]},
p8:{title:"Шпаргалка §8",rows:[["Средняя","$\\langle v\\rangle = s/t$"],["Мгновенная","предел $\\Delta s/\\Delta t$"],["Спидометр","показывает мгн. $v$"]]},
p9:{title:"Шпаргалка §9",rows:[["$\\vec v_{1,3} = \\vec v_{1,2} + \\vec v_{2,3}$",""],["Лодка/река","$\\vec v_{л,б} = \\vec v_{л,в} + \\vec v_{в,б}$"],["По теч.","скорости складываются"]]},
p10:{title:"Шпаргалка §10",rows:[["$\\vec a = \\Delta\\vec v/\\Delta t$",""],["Ед.","м/с²"],["Знак","совпадает с $\\Delta\\vec v$"]]},
p11:{title:"Шпаргалка §11",rows:[["$\\vec v = \\vec v_0 + \\vec a t$",""],["Проекция","$v_x = v_{0x} + a_x t$"],["",""]]},
p12:{title:"Шпаргалка §12",rows:[["$\\Delta\\vec r = \\vec v_0 t + \\vec a t^2/2$",""],["$v^2 - v_0^2 = 2a_x\\Delta x$","без $t$"],["",""]]},
p13:{title:"Шпаргалка §13",rows:[["$\\omega = 2\\pi/T$",""],["$v = \\omega R$",""],["$\\omega$","рад/с"]]},
p14:{title:"Шпаргалка §14",rows:[["$a_n = v^2/R$",""],["$a_n = \\omega^2 R$",""],["К центру","направление"]]},
final1:{title:"Финал главы 1",rows:[["§§114","теория главы 1"],["Награда","+50 XP"]]}
};
const TIPS=[
{sec:"p1",html:"Кинематика — раздел физики о движении без причин. Мат. точка — тело, размерами которого можно пренебречь."},
{sec:"p2",html:"СО = тело отсчёта + система координат + часы. Скорость, путь и траектория зависят от выбора СО."},
{sec:"p3",html:"Скаляры — число (масса, путь). Векторы — число + направление (сила, скорость). Сумма векторов: правило треугольника или параллелограмма."},
{sec:"p4",html:"Проекция вектора $\\vec a$ на ось: $a_x = a\\cos\\alpha$. Знак зависит от угла $\\alpha$. Сумма проекций = проекция суммы."},
{sec:"p5",html:"Путь $s$ — скаляр $\\ge 0$. Перемещение $\\Delta\\vec r$ — вектор. Всегда $s \\ge |\\Delta\\vec r|$."},
{sec:"p6",html:"Равномерное движение: $\\vec v = \\text{const}$. $\\Delta\\vec r = \\vec v t$, координата $x = x_0 + v_x t$."},
{sec:"p7",html:"График $v(t)$ — прямая параллельная оси $t$. График $x(t)$ — наклонная прямая. Площадь под $v(t)$ = пройденный путь."},
{sec:"p8",html:"Средняя скорость: $\\langle v\\rangle = s/t$. Мгновенная — предел $\\Delta s/\\Delta t$ при $\\Delta t \\to 0$. Спидометр показывает мгновенную."},
{sec:"p9",html:"Закон сложения скоростей: $\\vec v_{1,3} = \\vec v_{1,2} + \\vec v_{2,3}$. По течению — скорости складываются, против — вычитаются."},
{sec:"p10",html:"Ускорение: $\\vec a = \\Delta\\vec v / \\Delta t$. Единица м/с². Направление совпадает с $\\Delta\\vec v$."},
{sec:"p11",html:"При равноускоренном движении: $\\vec v = \\vec v_0 + \\vec a t$. В проекциях: $v_x = v_{0x} + a_x t$."},
{sec:"p12",html:"Перемещение: $\\Delta\\vec r = \\vec v_0 t + \\vec a t^2/2$. Без времени: $v^2 - v_0^2 = 2a_x\\Delta x$."},
{sec:"p13",html:"Угловая скорость $\\omega = 2\\pi/T = 2\\pi\\nu$ (рад/с). Связь с линейной: $v = \\omega R$."},
{sec:"p14",html:"Центростремит. ускорение: $a_n = v^2/R = \\omega^2 R$. Направлено к центру окружности."},
{sec:"final1",html:"Финал главы 1 — интегрированные задачи по §§1–14. В разработке (Phase 1+)."}
];
function buildSidebar(id){
const box=document.getElementById('sidebar-content');
const sb=SIDEBARS[id]||SIDEBARS[PARAS[0].id];
let html='';
const xpForLv=_xpForLevel(STATE.level), xpNext=_xpForLevel(STATE.level+1);
const xpInLv=STATE.xp-xpForLv, xpRange=xpNext-xpForLv;
const xpPct=xpRange>0?Math.round(xpInLv/xpRange*100):100;
html+='<div class="xp-card"><div class="xp-card-title"><span>XP-прогресс</span><span class="xp-level">Ур. '+STATE.level+'</span></div><div class="xp-bar"><div class="xp-fill" style="width:'+xpPct+'%"></div></div><div class="xp-nums"><span>'+STATE.xp+' XP</span><span>'+xpNext+' XP</span></div></div>';
html+='<div class="sidecard"><h4>'+sb.title+'</h4>';
sb.rows.forEach(([k,v])=>{ html+='<div class="sidecard-row"><b>'+k+'</b>'+(v?' \u2014 '+v:'')+'</div>'; });
html+='</div>';
const tip=TIPS.find(t=>t.sec===id)||TIPS[0];
if(tip){
html+='<div class="sidecard" style="background:linear-gradient(135deg,var(--warn-bg,#fef3c7),var(--pri-soft));border-color:var(--warn,#f59e0b)"><h4 style="color:#92400e;display:flex;align-items:center;gap:6px"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px"><polygon points="12,2 22,20 2,20"/></svg>Подсказка</h4><div class="sidecard-row" style="margin-bottom:0;font-size:.84rem;line-height:1.55">'+tip.html+'</div></div>';
}
if(STATE.achievements.size>0){
html+='<div class="sidecard"><h4>Достижения <span style="color:var(--warn);float:right">'+STATE.achievements.size+'</span></h4>';
[...STATE.achievements.values()].slice(-4).forEach(text=>{ html+='<div class="sidecard-row" style="font-size:.78rem;color:var(--ok)">&#10003; '+text+'</div>'; });
html+='</div>';
}
box.innerHTML=html;
if(window.renderMathInElement) try{ renderMath(box); }catch(e){}
}
function initTheme(){
const t=localStorage.getItem('physics9_ch1_theme')||'light';
if(t==='dark') document.documentElement.classList.add('dark');
document.getElementById('theme-lab').textContent=t==='dark'?'Светлая':'Тёмная';
document.getElementById('theme-btn').addEventListener('click', ()=>{
document.documentElement.classList.toggle('dark');
const dark=document.documentElement.classList.contains('dark');
localStorage.setItem('physics9_ch1_theme', dark?'dark':'light');
document.getElementById('theme-lab').textContent=dark?'Светлая':'Тёмная';
});
}
function renderMath(root){ if(window.renderMathInElement){ try{ renderMathInElement(root, {delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false}); }catch(e){} } }
const ICONS = {
theory:'<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>',
example:'<svg class="ic" viewBox="0 0 24 24"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 13c1 1 2 2 2 4h4c0-2 1-3 2-4a7 7 0 0 0-4-13z"/></svg>',
lab:'<svg class="ic" viewBox="0 0 24 24"><path d="M10 2v7.5L4.5 19a2 2 0 0 0 1.7 3h11.6a2 2 0 0 0 1.7-3L14 9.5V2"/><line x1="9" y1="2" x2="15" y2="2"/></svg>',
rule:'<svg class="ic" viewBox="0 0 24 24"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>',
};
function makeCard(kind, title, num, body){
const labels = {theory:'Теория',example:'Пример',lab:'Лабораторная работа',rule:'Правило'};
return '<div class="card"><div class="card-header"><div class="card-icon '+kind+'">'+ICONS[kind]+'</div><div class="card-title">'+(labels[kind]||'')+(title&&title!==labels[kind]?' \xb7 '+title:'')+'</div>'+(num?'<div class="card-num">'+num+'</div>':'')+'</div><div class="card-body">'+body+'</div></div>';
}
function secNav(prev, next){
const NAMES = {p1:'\xA71',p2:'\xA72',p3:'\xA73',p4:'\xA74',p5:'\xA75',p6:'\xA76',p7:'\xA77',p8:'\xA78',p9:'\xA79',p10:'\xA710',p11:'\xA711',p12:'\xA712',p13:'\xA713',p14:'\xA714',final1:'Финал'};
let h='<div class="sec-nav">';
h+=prev?'<button class="btn" onclick="goTo(\''+prev+'\')"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> '+NAMES[prev]+'</button>':'<span></span>';
h+=next?'<button class="btn primary" onclick="goTo(\''+next+'\')">'+NAMES[next]+' <svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></button>':'<span></span>';
h+='</div>'; return h;
}
function readButton(paraId){
const p = PARAS.find(x => x.id === paraId);
const labelTail = p && p.final ? 'финал' : (p ? p.num : '?');
return '<div style="margin-top:18px;display:flex;justify-content:center">'
+'<button class="btn primary" id="'+paraId+'-read-btn">'
+'<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>'
+' Я прочитал — '+labelTail+' (+10 XP)'
+'</button></div>';
}
function wireReadBtn(paraId){
const btn = document.getElementById(paraId+'-read-btn'); if(!btn) return;
btn.addEventListener('click', ()=>{
addXp(10, paraId+'-read'); bumpProgress(paraId, 30);
btn.textContent='Прочитано! +10 XP'; btn.disabled=true; btn.style.opacity=.6;
const aId = paraId+'_done';
if(ACH_LABELS[aId]) achievement(aId);
});
}
/* ===== STUB BUILDERS — наполнение в Phase 5 ===== */
function build_p1(){
const box = document.getElementById('p1-body');
let html = '';
html += makeCard('theory', "Механическое движение", "§1", `
<div class="para-hero ph-1">
<div class="ph-label">§1 · Физика 9 кл</div>
<h2>Механическое движение. Материальная точка</h2>
<div class="ph-formula">где? куда? с какой скоростью?</div>
<div class="ph-desc">Кинематика описывает движение тел — без выяснения причин. Тело движется = меняет положение. Материальная точка — модель, когда размер тела не важен.</div>
<div class="ph-tags"><span class="ph-tag"> положение тела</span><span class="ph-tag">〰 траектория</span><span class="ph-tag"> виды движения</span></div>
</div>
<div class="section-title"> §1. Механическое движение</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Материальная точка</h3>
<div class="main-f">не важно как выглядит — важно где находится</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:3px 10px;font-size:.76rem;margin:8px 0 6px">
<span style="color:#059669;font-weight:700"> точка</span><span style="color:#dc2626;font-weight:700"> не точка</span>
<span>самолёт в перелёте</span><span>самолёт на посадке</span>
<span>Земля вокруг Солнца</span><span>Земля при вращении</span>
<span>поезд на маршруте</span><span>колесо поезда</span>
</div>
<p> <b>Когда можно считать тело точкой?</b> Спроси себя: важно ли, где именно на теле приложена сила или откуда мерить расстояние? Если нет — это точка. Самолёт летит из Москвы в Сочи: 1400 км, а сам самолёт — 70 м. Размер самолёта в сотни раз меньше пути — берём как точку. Но если самолёт заходит на посадку — нам важно, где нос, где хвост, как он наклонён. Уже не точка.</p>
</div>
<div class="fcard">
<h3>Траектория</h3>
<div class="main-f">след, который оставляет тело при движении</div>
<p><b>Прямолинейная</b> — прямая (поезд по рельсам). <b>Криволинейная</b> — кривая (мяч в полёте).</p>
<p style="margin-top:6px;font-size:.8rem;color:var(--muted)"> <b>Важно:</b> траектория зависит от того, <em>кто смотрит</em>. Представь: ты едешь в поезде и бросаешь мяч прямо вверх. Ты видишь — мяч летит вертикально вверх и падает обратно в руки. Но твой друг стоит на платформе и смотрит в окно — он видит, что мяч описывает дугу (параболу), потому что мяч ещё и едет вместе с поездом. Одно движение, два наблюдателя — две разные траектории. Траектория — не свойство мяча, а свойство наблюдателя.</p>
</div>
<div class="fcard">
<h3>Виды механического движения</h3>
<div class="main-f">поступательное · вращательное · колебательное</div>
<p><b>Поступательное:</b> все точки тела движутся параллельно — тело не вращается (лифт, поезд). <b>Вращательное:</b> каждая точка описывает окружность (колесо). <b>Колебательное:</b> тело раз за разом возвращается назад (маятник).</p>
</div>
<div class="fcard">
<h3>Задача кинематики</h3>
<div class="main-f">где? куда? с какой скоростью?</div>
<p>Кинематика отвечает на вопросы <em>где находится</em> и <em>как движется</em>, но не <em>почему</em>. Почему тело разгоняется или тормозит — это уже динамика (§15).</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Кинематика — это как GPS-навигатор: он показывает где ты, куда едешь и с какой скоростью. Но ему всё равно, <b>почему</b> ты туда едешь и что движет машиной. Сначала учим <b>КАК</b> движется (кинематика, §1–14), потом <b>ПОЧЕМУ</b> (динамика, §15).</p>
<p>Механическое движение — это просто <b>изменение места</b>: был здесь, стал там. Звучит очевидно, но физика требует точности: относительно чего? в какой момент времени? с каким телом сравниваем?</p>
</div>
<div class="idiag">
<h3> Анимация: виды движения</h3>
<div class="cv-wrap"><canvas id="cv1" style="height:160px"></canvas></div>
<button class="cv-playbtn" onclick="startAnim1()">▶ Запустить снова</button>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Поезд</div><div class="li-desc">Поступательное — все точки движутся параллельно, тело не вращается</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Земля</div><div class="li-desc">Вращательное движение вокруг оси + поступательное по орбите</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Струна</div><div class="li-desc">Колебательное движение — периодически возвращается в исходное положение</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Волчок</div><div class="li-desc">Сочетание вращательного и поступательного движений</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Материальная точка — это <b>модель</b>, а не реальный объект.</li>
<li>Траектория <b>относительна</b>: зависит от системы отсчёта.</li>
<li>Кинематика описывает движение, <b>не объясняет</b> его причины.</li>
</ul>
</div>
<ol class="q-list">
<li>Можно ли считать Луну материальной точкой при описании её движения вокруг Земли?</li>
<li>Приведи пример тела, совершающего одновременно поступательное и вращательное движение.</li>
<li>Что изучает кинематика? Чем она отличается от динамики?</li>
</ol>
`);
html += secNav(null, 'p2');
html += readButton('p1');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p1');
}
function build_p2(){
const box = document.getElementById('p2-body');
let html = '';
html += makeCard('theory', "Относительность движения. Система отсчёта", "§2", `
<div class="para-hero ph-2">
<div class="ph-label">§2 · Физика 9 кл</div>
<h2>Относительность движения. Система отсчёта</h2>
<div class="ph-formula">от чего · куда · когда = система отсчёта</div>
<div class="ph-desc">Движение относительно: один и тот же объект в разных системах отсчёта движется по-разному. Система отсчёта — тело + координатная сетка + часы.</div>
<div class="ph-tags"><span class="ph-tag"> относительность</span><span class="ph-tag"> тело отсчёта</span><span class="ph-tag">⏱ часы</span></div>
</div>
<div class="section-title"> §2. Относительность движения. Система отсчёта</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Система отсчёта (СО)</h3>
<div class="main-f">от чего считать · куда · когда</div>
<p>Чтобы описать движение, нужны: <b>тело отсчёта</b> (относительно чего считать), <b>координатная система</b> (куда двигаться) и <b>часы</b> (когда).</p>
</div>
<div class="fcard">
<h3>Относительность траектории</h3>
<div class="main-f">разные наблюдатели — разные пути</div>
<p>Ты в поезде бросаешь мяч вертикально вверх и ловишь его — для тебя он полетел прямо вверх и вернулся. Твой друг на платформе смотрит в окно: он видит, что мяч летел по дуге вперёд и вниз — потому что поезд двигался, пока мяч был в воздухе. <b>Никто не ошибается</b> — просто каждый описывает движение из своей системы отсчёта.</p>
</div>
<div class="fcard">
<h3>Координата точки</h3>
<div class="main-f">$x, y, z$ — числа вдоль осей</div>
<p>Представь ось — это линейка, у которой есть ноль и направления «+» и «−». Координата — это просто число на этой линейке: насколько далеко от нуля и в какую сторону. Например, $x = -3\\,\\text{м}$ значит «3 метра влево от начала». По одному числу можно точно сказать, где находится точка — больше ничего не нужно.</p>
</div>
<div class="fcard">
<h3>Тело отсчёта</h3>
<div class="main-f">то, относительно чего считаем</div>
<p>Тело отсчёта — это то, что ты считаешь <em>неподвижным</em> в своей задаче. Чаще всего это Земля — стоишь на ней, от неё и меряешь. Но можно выбрать любое: вагон поезда, самолёт, другую планету. Выбор не меняет физику — он меняет <b>удобство расчётов</b>. Задача про падающий камень в движущемся поезде решается проще в системе поезда, чем в системе Земли.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Ты едешь в поезде и смотришь на пассажира напротив — он неподвижен. Выгляни в окно — деревья мчатся назад. Это и есть относительность движения.</p>
<p><b>Без системы отсчёта вопрос «движется ли тело?» не имеет смысла.</b> Ты сейчас неподвижен относительно Земли, но летишь со скоростью 30 км/с вокруг Солнца.</p>
</div>
<div class="idiag">
<h3> Интерактив: поезд и платформа</h3>
<div class="slider-row">
<span class="slider-lbl">Скорость пассажира (в вагоне):</span>
<input type="range" min="0" max="10" value="5" id="sl2v" oninput="upd2()">
<span class="slider-val" id="v2v">5 м/с</span>
</div>
<div class="cv-wrap"><canvas id="cv2" style="height:160px"></canvas></div>
<div class="idiag-result" id="res2">Скорость пассажира относительно земли = — м/с</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Движение всегда <b>относительно</b>: нужно указывать систему отсчёта.</li>
<li>СО = тело отсчёта + координатная система + часы.</li>
<li>Одно и то же тело в разных СО имеет разные траектории и скорости.</li>
</ul>
</div>
<ol class="q-list">
<li>Пассажир в поезде бросает мяч вертикально вверх. Опишите траекторию мяча в СО поезда и в СО Земли.</li>
<li>Является ли движение абсолютным понятием? Обоснуй ответ.</li>
</ol>
`);
html += secNav('p1', 'p3');
html += readButton('p2');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p2');
}
function build_p3(){
const box = document.getElementById('p3-body');
let html = '';
html += makeCard('theory', "Скалярные и векторные величины. Действия над векторами", "§3", `
<div class="para-hero ph-3">
<div class="ph-label">§3 · Физика 9 кл</div>
<h2>Скалярные и векторные величины. Действия над векторами</h2>
<div class="ph-formula">$\\vec{c} = \\vec{a} + \\vec{b};\\quad |\\vec{b}| = |k||\\vec{a}|$</div>
<div class="ph-desc">Скаляр — только число. Вектор — число и направление. Складывают векторы по правилу параллелограмма или треугольника.</div>
<div class="ph-tags"><span class="ph-tag"> скаляр: масса, путь</span><span class="ph-tag"> вектор: скорость, сила</span><span class="ph-tag">▱ правило параллелограмма</span></div>
</div>
<div class="section-title"> §3. Скалярные и векторные величины</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Векторное сложение</h3>
<div class="main-f">$\\vec{c} = \\vec{a} + \\vec{b}$ (правило параллелограмма)</div>
<p>Идёшь на север 3 шага, поворачиваешь на восток 4 шага — ты сместился на 5 шагов на северо-восток. Это и есть сложение двух векторов. <b>Правило треугольника:</b> приставь начало второго вектора к концу первого — стрелка от самого начала до самого конца и есть сумма. <b>Правило параллелограмма:</b> оба вектора из одной точки — диагональ параллелограмма и есть сумма.</p>
</div>
<div class="fcard">
<h3>Умножение на скаляр</h3>
<div class="main-f">$\\vec{b} = k\\vec{a};\\quad |\\vec{b}| = |k||\\vec{a}|$</div>
<p>$k > 0$: вектор в том же направлении. $k < 0$: вектор в обратном направлении. Модуль = $|k|$ × модуль исходного.</p>
</div>
<div class="fcard">
<h3>Вычитание векторов</h3>
<div class="main-f">$\\vec{d} = \\vec{a} - \\vec{b} = \\vec{a} + (-\\vec{b})$</div>
<p>Вычесть вектор — значит прибавить противоположный. Шёл 5 м на север, потом «отнять» 3 м на север — то же, что прибавить 3 м на юг, итого 2 м на север. <b>Графически:</b> отложи оба вектора из одной точки — разность смотрит из конца $\\vec{b}$ в конец $\\vec{a}$. Пригодится при нахождении изменения скорости: $\\Delta\\vec{v} = \\vec{v} - \\vec{v}_0$.</p>
</div>
<div class="fcard">
<h3>Три важных случая</h3>
<div class="main-f" style="font-size:.78rem;text-align:left;padding:6px 8px">
0°: $|\\vec{c}| = |\\vec{a}|+|\\vec{b}|$<br>
180°: $|\\vec{c}| = \\big||\\vec{a}|-|\\vec{b}|\\big|$<br>
90°: $|\\vec{c}| = \\sqrt{|\\vec{a}|^2+|\\vec{b}|^2}$
</div>
<p>Если векторы в <b>одну сторону</b> — складывай числами. <b>Навстречу</b> — вычитай. <b>Перпендикулярно</b> — теорема Пифагора. Любой другой угол — формула параллелограмма.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Самолёт летит на восток 500 км/ч, боковой ветер 120 км/ч с севера. Нельзя сказать «итоговая скорость 620 км/ч» — надо сложить <em>векторно</em>: $\\sqrt{500^2 + 120^2} \\approx 514$ км/ч и немного на юг. Именно поэтому пилоты учитывают ветер при прокладке курса.</p>
<p>Правило простое: если направления совпадают — складывай числами. Если нет — только по правилу параллелограмма или треугольника.</p>
</div>
<div class="idiag">
<h3> Интерактив: сложение векторов</h3>
<div class="slider-row">
<span class="slider-lbl">|a|:</span>
<input type="range" min="20" max="100" value="60" id="sl3a" oninput="upd3()">
<span class="slider-val" id="v3a">60</span>
</div>
<div class="slider-row">
<span class="slider-lbl">|b|:</span>
<input type="range" min="20" max="100" value="50" id="sl3b" oninput="upd3()">
<span class="slider-val" id="v3b">50</span>
</div>
<div class="slider-row">
<span class="slider-lbl">Угол α:</span>
<input type="range" min="0" max="180" value="60" id="sl3ang" oninput="upd3()">
<span class="slider-val" id="v3ang">60°</span>
</div>
<div class="cv-wrap"><canvas id="cv3" style="height:180px"></canvas></div>
<div class="idiag-result" id="res3">|c| = —</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Модуль суммы ≠ сумма модулей (только если оба вектора в одну сторону).</li>
<li>Вектора складывают геометрически, не числами.</li>
<li>Сумма всегда: $|\\vec{a}|-|\\vec{b}| \\leq |\\vec{c}| \\leq |\\vec{a}|+|\\vec{b}|$</li>
</ul>
</div>
<ol class="q-list">
<li>Можно ли сложить вектор и скаляр? Почему?</li>
<li>При каком угле между двумя равными векторами их сумма равна одному из них?</li>
</ol>
`);
html += secNav('p2', 'p4');
html += readButton('p3');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p3');
}
function build_p4(){
const box = document.getElementById('p4-body');
let html = '';
html += makeCard('theory', "Проекция вектора на ось", "§4", `
<div class="para-hero ph-4">
<div class="ph-label">§4 · Физика 9 кл</div>
<h2>Проекция вектора на ось</h2>
<div class="ph-formula">$a_x = a\\cos\\varphi$</div>
<div class="ph-desc">Проекция вектора на ось — его «тень» на ось. Знак зависит от направления: угол острый — плюс, тупой — минус. Позволяет переводить векторные задачи в скалярные по осям.</div>
<div class="ph-tags"><span class="ph-tag">$a_x = a\\cos\\varphi$</span><span class="ph-tag"> острый угол</span><span class="ph-tag"> тупой угол</span></div>
</div>
<div class="section-title"> §4. Проекция вектора на ось</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Проекция на ось Ox</h3>
<div class="main-f">$a_x = a\\cos\\varphi$</div>
<p>$\\varphi$ — угол между вектором и осью Ox. Если вектор «наклонён» в сторону оси (угол острый, до 90°) — проекция <b>положительная</b>. Если «отклонился» от неё (угол тупой, больше 90°) — <b>отрицательная</b>. Перпендикулярен оси — проекция нулевая: вся «сила» вектора уходит в другую ось. Проверь себя: $a_x = 10\\cos 60° = 5$ (острый → плюс), $a_x = 10\\cos 120° = -5$ (тупой → минус).</p>
</div>
<div class="fcard">
<h3>Проекции в 2D</h3>
<div class="main-f">$a_x = a\\cos\\varphi;\\quad a_y = a\\sin\\varphi$</div>
<p>Любой вектор можно разложить на две составляющие — горизонтальную и вертикальную. Пример: сила 10 Н под углом 37° к горизонту → $F_x = 10\\cos 37° = 8$ Н (горизонталь), $F_y = 10\\sin 37° = 6$ Н (вертикаль). Теперь вместо одного вектора под углом — два числа, с которыми считать проще. И проверка: $\\sqrt{8^2 + 6^2} = \\sqrt{100} = 10$ Н </p>
</div>
<div class="fcard">
<h3>Сложение через проекции</h3>
<div class="main-f">$c_x = a_x + b_x;\\quad c_y = a_y + b_y$</div>
<p>Чтобы сложить два вектора под произвольным углом: найди проекции каждого на обе оси, сложи проекции числами, восстанови вектор по теореме Пифагора. Это <b>аналитический метод</b> — точнее, чем рисовать на бумаге.</p>
</div>
<div class="fcard">
<h3>Восстановление вектора</h3>
<div class="main-f">$a = \\sqrt{a_x^2 + a_y^2}$</div>
<p>Из проекций находим модуль (по теореме Пифагора) и направление ($\\varphi$). Метод компонент — основной в физике.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Представь: солнце светит сбоку, вектор — карандаш. Тень карандаша на стене — это и есть проекция. Если карандаш параллелен стене — тень максимальная. Перпендикулярен — тень нулевая.</p>
<p>В физике проекции — способ «разобрать» вектор на составляющие. Движение под углом = горизонтальная часть + вертикальная часть. Каждую решаем отдельно!</p>
</div>
<div class="idiag">
<h3> Интерактив: проекция вектора</h3>
<div class="slider-row">
<span class="slider-lbl">Угол φ:</span>
<input type="range" min="0" max="180" value="37" id="sl4phi" oninput="upd4()">
<span class="slider-val" id="v4phi">37°</span>
</div>
<div class="slider-row">
<span class="slider-lbl">|a|:</span>
<input type="range" min="30" max="100" value="70" id="sl4a" oninput="upd4()">
<span class="slider-val" id="v4a">70</span>
</div>
<div class="cv-wrap"><canvas id="cv4" style="height:160px"></canvas></div>
<div class="idiag-result" id="res4">ax = — | ay = —</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$a_x = a\\cos\\varphi$ — проекция на ось.</li>
<li>Знак проекции зависит от направления вектора относительно оси.</li>
<li>$a = \\sqrt{a_x^2 + a_y^2}$ — восстановление модуля из проекций.</li>
</ul>
</div>
<ol class="q-list">
<li>Может ли проекция вектора быть больше его модуля? Равна модулю? Равна нулю?</li>
<li>Вектор $|\\vec{a}| = 10$ направлен под $60°$ к оси Ox. Найди $a_x$ и $a_y$.</li>
</ol>
`);
html += secNav('p3', 'p5');
html += readButton('p4');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p4');
}
function build_p5(){
const box = document.getElementById('p5-body');
let html = '';
html += makeCard('theory', "Путь и перемещение", "§5", `
<div class="para-hero ph-5">
<div class="ph-label">§5 · Физика 9 кл</div>
<h2>Путь и перемещение</h2>
<div class="ph-formula">$s \\geq |\\Delta\\vec{r}|$</div>
<div class="ph-desc">Путь — длина траектории (скаляр, всегда ≥ 0). Перемещение — вектор из начальной точки в конечную. Путь всегда ≥ модуля перемещения.</div>
<div class="ph-tags"><span class="ph-tag"> путь s — скаляр</span><span class="ph-tag"> перемещение Δr — вектор</span><span class="ph-tag">s ≥ |Δr|</span></div>
</div>
<div class="section-title"> §5. Путь и перемещение</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Путь s</h3>
<div class="main-f">длина траектории</div>
<p><b>Скалярная</b> величина — только число, без направления. Всегда ≥ 0: «минусового» пути не бывает. Одометр в машине считает путь: даже если ты вернулся на старт — он накрутил столько, сколько ты проехал. Зависит от <em>маршрута</em>, а не только от начальной и конечной точек.</p>
</div>
<div class="fcard">
<h3>Перемещение $\\Delta\\vec{r}$</h3>
<div class="main-f">$\\Delta\\vec{r} = \\vec{r}_2 - \\vec{r}_1$</div>
<p><b>Векторная</b> величина — имеет и число, и направление. Натяни верёвку напрямую от старта до финиша: её длина и направление — это и есть перемещение. Не важно, как ты шёл — зигзагами или по прямой: перемещение одно и то же, если начало и конец совпадают.</p>
</div>
<div class="fcard">
<h3>Проекции перемещения</h3>
<div class="main-f">$\\Delta r_x = x_2 - x_1;\\quad \\Delta r_y = y_2 - y_1$</div>
<p>Проекция перемещения — просто разность координат: где был минус где стал. Переехал с отметки $x_1 = 20\\,\\text{м}$ на $x_2 = 8\\,\\text{м}$: $\\Delta r_x = 8 - 20 = -12\\,\\text{м}$. Минус значит «двигался в сторону уменьшения оси» — то есть назад. Никакой тайны: минус — это просто направление.</p>
</div>
<div class="fcard">
<h3>Соотношение пути и перемещения</h3>
<div class="main-f">$s \\geq |\\Delta\\vec{r}|$</div>
<p>Равенство достигается только при прямолинейном движении в одну сторону — тогда маршрут совпадает с прямой от старта до финиша. Стоит хоть раз повернуть или вернуться — путь сразу стал длиннее перемещения. Это как разница между прямой дорогой и объездом: расстояние по прямой — перемещение, по дороге — путь.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Ты вышел из дома (точка A), дошёл до магазина (B, 500 м), вернулся домой (A). Путь = 1000 м. Перемещение = 0 (начальная и конечная точка совпадают)!</p>
<p>GPS-навигатор считает <b>путь</b> (сколько проехал). Рулетка между двумя точками — это <b>перемещение</b>. Одометр в машине — путь. Смещение в прямом смысле — перемещение.</p>
</div>
<div class="idiag">
<h3> Интерактив: путь и перемещение</h3>
<div class="slider-row">
<span class="slider-lbl">Сегмент 1 (м):</span>
<input type="range" min="0" max="200" value="120" id="sl5s1" oninput="upd5()">
<span class="slider-val" id="v5s1">120 м</span>
</div>
<div class="slider-row">
<span class="slider-lbl">Сегмент 2 (м, назад):</span>
<input type="range" min="0" max="200" value="60" id="sl5s2" oninput="upd5()">
<span class="slider-val" id="v5s2">60 м</span>
</div>
<div class="cv-wrap"><canvas id="cv5" style="height:130px"></canvas></div>
<div class="idiag-result" id="res5">Путь = — м | Перемещение = — м</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Путь — скаляр (длина), перемещение — вектор (смещение).</li>
<li>$s \\geq |\\Delta\\vec{r}|$ — путь всегда не меньше модуля перемещения.</li>
<li>При движении «туда-обратно»: $s > 0$, но $\\Delta\\vec{r}$ может быть = $\\vec{0}$.</li>
</ul>
</div>
<ol class="q-list">
<li>При каком условии путь равен модулю перемещения?</li>
<li>Тело прошло путь $s = 100\\,\\text{м}$. Может ли его перемещение быть равно нулю?</li>
</ol>
`);
html += secNav('p4', 'p6');
html += readButton('p5');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p5');
}
function build_p6(){
const box = document.getElementById('p6-body');
let html = '';
html += makeCard('theory', "Равномерное прямолинейное движение. Скорость", "§6", `
<div class="para-hero ph-6">
<div class="ph-label">§6 · Физика 9 кл</div>
<h2>Равномерное прямолинейное движение. Скорость</h2>
<div class="ph-formula">$v = \\Delta r / \\Delta t;\\quad x = x_0 + v_x t$</div>
<div class="ph-desc">Равномерное движение — скорость постоянна по модулю и направлению. Скорость — векторная величина: показывает быстроту и направление изменения положения.</div>
<div class="ph-tags"><span class="ph-tag">$v = \\text{const}$</span><span class="ph-tag">$x = x_0 + vt$</span><span class="ph-tag">[v] = м/с</span></div>
</div>
<div class="section-title"> §6. Равномерное прямолинейное движение</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Скорость (вектор)</h3>
<div class="main-f">$\\vec{v} = \\Delta\\vec{r}/\\Delta t$</div>
<p>Скорость — вектор: у неё есть <b>и число</b> («60 км/ч»), <b>и направление</b> («на север»). Направлена туда, куда движется тело в данный момент. При равномерном движении оба параметра не меняются — ни быстрее/медленнее, ни поворотов. Стоит сказать только «скорость 20 м/с» без направления — это уже не вектор, а только его модуль.</p>
</div>
<div class="fcard">
<h3>Закон движения</h3>
<div class="main-f">$x = x_0 + v_x t$</div>
<p>Три части: <b>где стоял</b> ($x_0$) + <b>куда движешься</b> ($v_x \\cdot t$). Если $v_x > 0$ — координата растёт (движение в сторону «+»). Если $v_x < 0$ — убывает (движение назад). Пример: $x = 100 - 5t$ → начал на отметке 100 м и едет назад со скоростью 5 м/с. Через 20 с будет на нуле, потом «уйдёт» в отрицательные координаты.</p>
</div>
<div class="fcard">
<h3>Перевод единиц</h3>
<div class="main-f">$1\\,\\text{м/с} = 3{,}6\\,\\text{км/ч}$</div>
<p>$v\\,[\\text{м/с}] = v\\,[\\text{км/ч}] / 3{,}6$. Пример: 72 км/ч = 72/3.6 = 20 м/с. Часто нужно на экзамене!</p>
</div>
<div class="fcard">
<h3>Путь при равномерном движении</h3>
<div class="main-f">$s = |v_x| \\cdot t$</div>
<p>Путь = скорость × время. Перемещение: $\\Delta r_x = v_x t$ (со знаком). Путь всегда ≥ 0.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Равномерное движение — идеализация, но очень полезная. Поезд «Москва–Петербург» на перегоне между остановками, самолёт в крейсерском полёте, свет в вакууме — всё это приближённо равномерное движение.</p>
<p>На графике $x(t)$ — прямая линия. <b>Наклон = скорость</b>: проведи прямую круче — едешь быстрее, положе — медленнее, горизонталь — стоишь. По одной прямой можно мгновенно прочитать скорость: $v_x = \\Delta x / \\Delta t$ — возьми любые два момента на прямой.</p>
</div>
<div class="idiag">
<h3> Интерактив: равномерное движение</h3>
<div class="slider-row">
<span class="slider-lbl">v, м/с:</span>
<input type="range" min="-20" max="20" value="10" id="sl6v" oninput="upd6()">
<span class="slider-val" id="v6v">10 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">x₀, м:</span>
<input type="range" min="-50" max="50" value="0" id="sl6x0" oninput="upd6()">
<span class="slider-val" id="v6x0">0 м</span>
</div>
<div class="cv-wrap"><canvas id="cv6" style="height:180px"></canvas></div>
<div class="idiag-result" id="res6">x(5с) = —</div>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Самолёт</div><div class="li-desc">Крейсерский полёт — ~равномерное движение: v ≈ const</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Корабль</div><div class="li-desc">На спокойной воде — близко к равномерному</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Земля</div><div class="li-desc">Движение по орбите ≈ равномерное (скорость почти постоянна)</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Свет</div><div class="li-desc">В вакууме движется строго равномерно: $c = 3\\cdot10^8$ м/с</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$v = \\text{const}$ — ни по модулю, ни по направлению не меняется.</li>
<li>$x = x_0 + v_x t$ — закон движения (линейный!)</li>
<li>$1\\,\\text{м/с} = 3{,}6\\,\\text{км/ч}$</li>
</ul>
</div>
<ol class="q-list">
<li>Автомобиль движется равномерно. Закон движения: $x = 100 + 15t$ (м). Найдите начальную координату и скорость.</li>
<li>Поезд прошёл 180 км за 2 часа. Найдите скорость в м/с и км/ч.</li>
</ol>
`);
html += secNav('p5', 'p7');
html += readButton('p6');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p6');
}
function build_p7(){
const box = document.getElementById('p7-body');
let html = '';
html += makeCard('theory', "Графическое представление равномерного движения", "§7", `
<div class="para-hero ph-7">
<div class="ph-label">§7 · Физика 9 кл</div>
<h2>Графическое представление равномерного движения</h2>
<div class="ph-formula">$v(t) = \\text{const};\\quad x(t) = x_0 + vt$</div>
<div class="ph-desc">График v(t) — горизонтальная прямая. График x(t) — наклонная прямая. Площадь под v(t) = перемещение. Наклон x(t) = скорость.</div>
<div class="ph-tags"><span class="ph-tag"> v(t) — горизонталь</span><span class="ph-tag"> x(t) — прямая</span><span class="ph-tag">S = Δr (площадь)</span></div>
</div>
<div class="section-title"> §7. Графики равномерного движения</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>График v(t)</h3>
<div class="main-f">горизонтальная прямая</div>
<p>Скорость не меняется — горизонтальная прямая. Прямая <b>выше нуля</b>: едешь «вперёд». <b>Ниже нуля</b>: едешь «назад». <b>На нуле</b>: стоишь. Ширина прямоугольника под графиком — это время $\\Delta t$, высота — скорость $v_x$. Площадь = $v_x \\cdot \\Delta t$ = перемещение. Это не просто формула — это прямо следует из рисунка!</p>
</div>
<div class="fcard">
<h3>График x(t)</h3>
<div class="main-f">наклонная прямая</div>
<p>$x = x_0 + v_x t$ — прямая линия на графике. <b>Крутой наклон</b> вверх = большая скорость вперёд. <b>Горизонталь</b> = тело стоит ($v = 0$). <b>Наклон вниз</b> = движение назад ($v_x < 0$). Точка, где прямая пересекает ось $x$ — это начальная координата $x_0$. По наклону прямой можно найти скорость: $v_x = \\Delta x / \\Delta t$.</p>
</div>
<div class="fcard">
<h3>Площадь под v(t)</h3>
<div class="main-f">$\\Delta r_x = v_x \\cdot \\Delta t$ = площадь</div>
<p>Площадь фигуры под графиком v(t) = перемещение — это универсальное правило, работает для <b>любого движения</b>, не только равномерного. При равномерном фигура — прямоугольник: $S = v \\cdot \\Delta t = \\Delta r$. При неравномерном — любая фигура: считаем её площадь.</p>
</div>
<div class="fcard">
<h3>Встреча двух тел</h3>
<div class="main-f">$x_1(t) = x_2(t)$</div>
<p>Два тела движутся и «встречаются», когда их координаты совпадают: $x_1(t) = x_2(t)$. На графике x(t) это просто <b>точка пересечения двух прямых</b>. Координата встречи — по оси $x$ в точке пересечения, время встречи — по оси $t$. Если прямые параллельны — тела движутся с одинаковой скоростью и никогда не встретятся (или всегда рядом, если совпадают).</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Почему площадь под v(t) = перемещение? Представь: едешь 3 м/с в течение 5 секунд. Прямоугольник: ширина 5 с, высота 3 м/с. Площадь = 5 × 3 = 15 м — именно столько проехал!</p>
<p><b>Наклон x(t) = скорость</b>: крутая линия — едешь быстро, пологая — медленно, горизонтальная — стоишь. Линии идут вниз — едешь в обратную сторону (отрицательная v).</p>
</div>
<div class="idiag">
<h3> Интерактив: графики двух тел</h3>
<div class="slider-row">
<span class="slider-lbl">v₁, м/с:</span>
<input type="range" min="-15" max="15" value="10" id="sl7v1" oninput="upd7()">
<span class="slider-val" id="v7v1">10 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">x₀₁, м:</span>
<input type="range" min="-100" max="100" value="0" id="sl7x1" oninput="upd7()">
<span class="slider-val" id="v7x1">0 м</span>
</div>
<div class="slider-row">
<span class="slider-lbl">v₂, м/с:</span>
<input type="range" min="-15" max="15" value="-5" id="sl7v2" oninput="upd7()">
<span class="slider-val" id="v7v2">-5 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">x₀₂, м:</span>
<input type="range" min="-100" max="100" value="75" id="sl7x2" oninput="upd7()">
<span class="slider-val" id="v7x2">75 м</span>
</div>
<div class="cv-wrap"><canvas id="cv7" style="height:200px"></canvas></div>
<div class="idiag-result" id="res7">Встреча: t = — с, x = — м</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Наклон графика x(t) = скорость $v_x$ (с учётом знака!).</li>
<li>Площадь под v(t) = перемещение $\\Delta r_x$.</li>
<li>Пересечение x(t) двух тел = момент встречи.</li>
</ul>
</div>
<ol class="q-list">
<li>Как по графику x(t) определить скорость тела?</li>
<li>Два тела движутся навстречу. Как выглядит их встреча на графике x(t)?</li>
</ol>
`);
html += secNav('p6', 'p8');
html += readButton('p7');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p7');
}
function build_p8(){
const box = document.getElementById('p8-body');
let html = '';
html += makeCard('theory', "Неравномерное движение. Средняя и мгновенная скорость", "§8", `
<div class="para-hero ph-8">
<div class="ph-label">§8 · Физика 9 кл</div>
<h2>Неравномерное движение. Средняя и мгновенная скорость</h2>
<div class="ph-formula">$\\langle v \\rangle = s/\\Delta t;\\quad \\langle\\vec{v}\\rangle = \\Delta\\vec{r}/\\Delta t$</div>
<div class="ph-desc">Средняя скорость — отношение пути ко времени (скаляр). Средняя скорость (вектор) — отношение перемещения ко времени. Мгновенная — предел при Δt→0.</div>
<div class="ph-tags"><span class="ph-tag">⟨v⟩ = s/Δt</span><span class="ph-tag">v_мгн — в данный момент</span><span class="ph-tag">Δt → 0</span></div>
</div>
<div class="section-title"> §8. Средняя и мгновенная скорость</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Средняя скорость пути (скаляр)</h3>
<div class="main-f">$\\langle v \\rangle = s / \\Delta t$</div>
<p>Весь пройденный путь, делённый на всё затраченное время. Всегда ≥ 0 — отрицательного «пути» не бывает. Важно: если ехал медленно долго, а потом быстро чуть-чуть — средняя скорость ближе к медленной, а не к их среднему. <b>Спидометр</b> в машине показывает мгновенную скорость, а не среднюю за поездку.</p>
</div>
<div class="fcard">
<h3>Средняя скорость (вектор)</h3>
<div class="main-f">$\\langle\\vec{v}\\rangle = \\Delta\\vec{r}/\\Delta t$</div>
<p>Вектор перемещения, делённый на время. Направлена от начальной точки к конечной. Если ты сделал круг и вернулся — перемещение нулевое, значит и средняя векторная скорость нулевая, хотя весь маршрут ты реально ехал! Именно поэтому важно различать «скорость пути» и «скорость перемещения».</p>
</div>
<div class="fcard">
<h3>Мгновенная скорость</h3>
<div class="main-f">скорость в данный миг</div>
<p>Скорость именно в данный миг — как спидометр в машине: показывает не «сколько в среднем», а «прямо сейчас». Направлена всегда по касательной к траектории: именно туда полетит тело, если в этот момент убрать все силы. Поэтому мяч, оторвавшись от ракетки, летит по касательной, а не продолжает дугу.</p>
</div>
<div class="fcard">
<h3>Средняя скорость за два участка</h3>
<div class="main-f">$\\langle v\\rangle = \\dfrac{s_1+s_2}{t_1+t_2} = \\dfrac{2v_1 v_2}{v_1+v_2}$</div>
<p>Если два участка <b>равны по длине</b>: средняя скорость = гармоническое среднее, а <b>не среднеарифметическое</b>! Почему? На медленном участке тратишь больше времени — он «перевешивает». Пример: 60 км туда за 1 ч, 60 км обратно за 2 ч. Средняя = 120 / 3 = 40 км/ч, а не (60+30)/2 = 45 км/ч.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Маршрут A→B→A: 100 км туда, 100 км обратно. Туда 100 км/ч (1 час), обратно 50 км/ч (2 часа). Средняя скорость = 200 км / 3 ч ≈ 67 км/ч, а <b>НЕ</b> (100+50)/2 = 75 км/ч!</p>
<p>Среднеарифметическое скоростей не даёт среднюю скорость — нужно делить <b>весь путь / всё время</b>. А мгновенная скорость — это просто то, что показывает спидометр прямо сейчас.</p>
</div>
<div class="idiag">
<h3> Интерактив: средняя скорость</h3>
<div class="slider-row">
<span class="slider-lbl">v₁, км/ч:</span>
<input type="range" min="10" max="120" value="60" id="sl8v1" oninput="upd8()">
<span class="slider-val" id="v8v1">60 км/ч</span>
</div>
<div class="slider-row">
<span class="slider-lbl">v₂, км/ч:</span>
<input type="range" min="10" max="120" value="40" id="sl8v2" oninput="upd8()">
<span class="slider-val" id="v8v2">40 км/ч</span>
</div>
<div class="cv-wrap"><canvas id="cv8" style="height:140px"></canvas></div>
<div class="idiag-result" id="res8">⟨v⟩ = — | (v₁+v₂)/2 = —</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>Средняя скорость = <b>весь путь / всё время</b>.</li>
<li>$\\langle v\\rangle \\neq (v_1+v_2)/2$ в общем случае!</li>
<li>Мгновенная скорость направлена по касательной к траектории.</li>
</ul>
</div>
<ol class="q-list">
<li>Рысь пробежала первую половину пути со скоростью 3 м/с, вторую — со скоростью 6 м/с. Найдите среднюю скорость.</li>
<li>Куда направлена мгновенная скорость тела при движении по окружности?</li>
</ol>
`);
html += secNav('p7', 'p9');
html += readButton('p8');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p8');
}
function build_p9(){
const box = document.getElementById('p9-body');
let html = '';
html += makeCard('theory', "Сложение скоростей", "§9", `
<div class="para-hero ph-9">
<div class="ph-label">§9 · Физика 9 кл</div>
<h2>Сложение скоростей</h2>
<div class="ph-formula">$\\vec{v} = \\vec{v}' + \\vec{u}$</div>
<div class="ph-desc">Скорость тела в неподвижной СО = скорость тела относительно подвижной СО + скорость подвижной СО. Применяется при движении лодки в реке, самолёта в потоке.</div>
<div class="ph-tags"><span class="ph-tag"> лодка в реке</span><span class="ph-tag"> самолёт в ветре</span><span class="ph-tag">$\\vec{v} = \\vec{v}' + \\vec{u}$</span></div>
</div>
<div class="section-title"> §9. Сложение скоростей</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Закон сложения скоростей</h3>
<div class="main-f">$\\vec{v} = \\vec{v}' + \\vec{u}$</div>
<p>Три скорости: $\\vec{v}'$ — скорость лодки <em>относительно воды</em> (как гребёт мотор), $\\vec{u}$ — скорость течения <em>воды относительно берега</em>, $\\vec{v}$ — итоговая скорость лодки <em>относительно берега</em>. Сложи первые два вектора — получишь третий. Именно так навигаторы кораблей и самолётов считают реальный курс с учётом ветра/течения.</p>
</div>
<div class="fcard">
<h3>Лодка поперёк реки</h3>
<div class="main-f">$v = \\sqrt{v'^2 + u^2}$</div>
<p>Лодка гребёт перпендикулярно берегу ($v'$ — поперечная скорость), течение несёт вдоль реки ($u$ — продольная). Два вектора под углом 90° → суммарная скорость по теореме Пифагора: $v = \\sqrt{v'^2 + u^2}$. Лодка движется наискосок — не туда, куда гребёт! Берег она пересечёт в другом месте.</p>
</div>
<div class="fcard">
<h3>Время переправы</h3>
<div class="main-f">$t = d/v'$</div>
<p>Время пересечения реки шириной $d$ зависит <em>только</em> от поперечной скорости $v'$: $t = d/v'$. Сколько бы ни было течение — оно сносит лодку <em>вдоль</em>, но не замедляет переправу. Хочешь оказаться точно напротив? Гребись под углом против течения, чтобы боковые скорости скомпенсировались.</p>
</div>
<div class="fcard">
<h3>Снос течением</h3>
<div class="main-f">$\\Delta x = u \\cdot t = u \\cdot d/v'$</div>
<p>Пока лодка пересекала реку за время $t = d/v'$, течение успело снести её на $\\Delta x = u \\cdot t$. Широкая река + быстрое течение = большой снос. Пример: $d = 80$ м, $v' = 4$ м/с, $u = 3$ м/с → $t = 20$ с, снос = $3 \\cdot 20 = 60$ м! Почти столько же, сколько ширина реки.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Плывёшь поперёк реки: для тебя берег движется прямо назад. Но кто-то с берега видит, что тебя несёт течением. Твоя «настоящая» скорость (относительно берега) — диагональ параллелограмма.</p>
<p>Самолёт летит на восток, ветер с севера — он отклоняется. Пилот должен корректировать курс, направляя нос немного севернее. Это и есть сложение скоростей на практике.</p>
</div>
<div class="idiag">
<h3> Интерактив: лодка в реке</h3>
<div class="slider-row">
<span class="slider-lbl">v' (лодка), м/с:</span>
<input type="range" min="1" max="10" value="4" id="sl9vb" oninput="upd9()">
<span class="slider-val" id="v9vb">4 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">u (течение), м/с:</span>
<input type="range" min="0" max="8" value="3" id="sl9vu" oninput="upd9()">
<span class="slider-val" id="v9vu">3 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">Ширина реки, м:</span>
<input type="range" min="20" max="200" value="80" id="sl9d" oninput="upd9()">
<span class="slider-val" id="v9d">80 м</span>
</div>
<div class="cv-wrap"><canvas id="cv9" style="height:180px"></canvas></div>
<div class="idiag-result" id="res9">v = — м/с | t = — с | снос = — м</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$\\vec{v} = \\vec{v}' + \\vec{u}$ — складываем <b>векторно</b>.</li>
<li>Время переправы зависит только от $v'$ (скорость поперёк).</li>
<li>Снос = $u \\cdot t$ (течение × время).</li>
</ul>
</div>
<ol class="q-list">
<li>Лодка плывёт со скоростью 4 м/с поперёк реки, течение 3 м/с. Найдите скорость лодки относительно берега.</li>
<li>Самолёт летит со скоростью 600 км/ч при встречном ветре 100 км/ч. Какова его скорость относительно земли?</li>
</ol>
`);
html += secNav('p8', 'p10');
html += readButton('p9');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p9');
}
function build_p10(){
const box = document.getElementById('p10-body');
let html = '';
html += makeCard('theory', "Ускорение", "§10", `
<div class="para-hero ph-10">
<div class="ph-label">§10 · Физика 9 кл</div>
<h2>Ускорение</h2>
<div class="ph-formula">$\\vec{a} = \\Delta\\vec{v}/\\Delta t$</div>
<div class="ph-desc">Ускорение характеризует быстроту изменения скорости. Это вектор — направлен туда, куда изменяется скорость. При торможении — против движения.</div>
<div class="ph-tags"><span class="ph-tag">$[a] = \\text{м/с}^2$</span><span class="ph-tag">⬆ разгон: a ∥ v</span><span class="ph-tag">⬇ торможение: a против v</span></div>
</div>
<div class="section-title"> §10. Ускорение</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Ускорение</h3>
<div class="main-f">$\\vec{a} = \\Delta\\vec{v}/\\Delta t$</div>
<p>Ускорение показывает, <em>насколько быстро меняется скорость</em>. Единица: 1 м/с² — это «на 1 м/с за каждую секунду». $a = 5\\,\\text{м/с}^2$: скорость прибавляется на 5 м/с каждую секунду. Важно: ускорение — <b>вектор</b>. Оно может менять и модуль скорости (разгон/торможение), и её направление (повороты).</p>
</div>
<div class="fcard">
<h3>Ускорение при разгоне</h3>
<div class="main-f">$\\vec{a} \\uparrow\\uparrow \\vec{v}$ (сонаправлены)</div>
<p>Ускорение направлено <b>туда же, куда движется тело</b> — скорость растёт. Машина стартует: ускорение вперёд → скорость растёт с каждой секундой. Чем дольше разгоняешься с постоянным ускорением — тем быстрее едешь. При $a = 5\\,\\text{м/с}^2$ через 4 с скорость: $0 + 5 \\cdot 4 = 20$ м/с.</p>
</div>
<div class="fcard">
<h3>Ускорение при торможении</h3>
<div class="main-f">$\\vec{a} \\uparrow\\downarrow \\vec{v}$ (противоположны)</div>
<p>Машина едет вперёд ($v > 0$), нажимаешь тормоз: ускорение направлено назад ($a < 0$). Каждую секунду скорость уменьшается на $|a|$ м/с. Через $t = v_0 / |a|$ секунд — полная остановка. Запомни: ускорение со знаком «минус» — не значит «едет назад», это значит «тормозит».</p>
</div>
<div class="fcard">
<h3>Изменение скорости</h3>
<div class="main-f">$\\Delta\\vec{v} = \\vec{v} - \\vec{v}_0 = \\vec{a}\\cdot\\Delta t$</div>
<p>Изменение скорости — это вектор, направленный вдоль ускорения. $\\Delta\\vec{v} = \\vec{a} \\cdot \\Delta t$: умножь ускорение на время — получишь, как изменилась скорость. При разгоне $\\Delta v > 0$ (скорость выросла), при торможении $\\Delta v < 0$ (упала). Это та же физика, просто записанная векторно.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Ускорение — это «изменение скорости в секунду». $a = 3\\,\\text{м/с}^2$ означает: каждую секунду скорость растёт на 3 м/с. Начал с 0 → через 1 с: 3 м/с → через 2 с: 6 м/с → через 3 с: 9 м/с.</p>
<p>Важно: ускорение НЕ означает «быстро едет». Большое ускорение = быстро <b>разгоняется</b>. Черепаха может ехать быстро (v большая), но с нулевым ускорением (равномерно).</p>
</div>
<div class="idiag">
<h3> Интерактив: ускорение</h3>
<div class="slider-row">
<span class="slider-lbl">v₀, м/с:</span>
<input type="range" min="0" max="30" value="0" id="sl10v0" oninput="upd10()">
<span class="slider-val" id="v10v0">0 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">a, м/с²:</span>
<input type="range" min="-10" max="10" value="3" id="sl10a" oninput="upd10()">
<span class="slider-val" id="v10a">3 м/с²</span>
</div>
<div class="cv-wrap"><canvas id="cv10" style="height:160px"></canvas></div>
<div class="idiag-result" id="res10">v(5с) = —</div>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Ракета</div><div class="li-desc">При взлёте a = 3g ≈ 30 м/с². Космонавт «весит» в 3 раза больше</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Формула-1</div><div class="li-desc">a ≈ 15 м/с² при разгоне (0–100 км/ч за 2 с)</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Свободное падение</div><div class="li-desc">g ≈ 9,8 м/с² — ускорение при падении на Землю</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Аварийное торможение</div><div class="li-desc">a ≈ 8 м/с² (против движения). 100 км/ч → 0 за ~3,5 с</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$a = \\Delta v / \\Delta t$ — изменение скорости за единицу времени.</li>
<li>Ускорение вдоль скорости → разгон; против → торможение.</li>
<li>Ускорение ≠ большая скорость! Это <b>быстрота изменения</b> скорости.</li>
</ul>
</div>
<ol class="q-list">
<li>Автомобиль разогнался с 0 до 20 м/с за 5 с. Найдите ускорение.</li>
<li>Тело движется с $v_0 = 15$ м/с и тормозит с ускорением $a = 3\\,\\text{м/с}^2$. Через сколько секунд оно остановится?</li>
</ol>
`);
html += secNav('p9', 'p11');
html += readButton('p10');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p10');
}
function build_p11(){
const box = document.getElementById('p11-body');
let html = '';
html += makeCard('theory', "Скорость при равноускоренном движении", "§11", `
<div class="para-hero ph-11">
<div class="ph-label">§11 · Физика 9 кл</div>
<h2>Скорость при равноускоренном движении</h2>
<div class="ph-formula">$v = v_0 + at;\\quad \\langle v \\rangle = (v_0 + v)/2$</div>
<div class="ph-desc">При равноускоренном движении скорость меняется линейно: каждую секунду добавляется a м/с. Средняя скорость = полусумма начальной и конечной.</div>
<div class="ph-tags"><span class="ph-tag">$v = v_0 + at$</span><span class="ph-tag">$v(t)$ — прямая</span><span class="ph-tag">$\\langle v\\rangle = (v_0+v)/2$</span></div>
</div>
<div class="section-title"> §11. Скорость при равноускоренном движении</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Скорость</h3>
<div class="main-f">$v_x = v_{0x} + a_x t$</div>
<p>Скорость прибавляет по $a$ каждую секунду — значит, меняется <b>равномерно</b>. График v(t) — прямая линия. Крутой наклон вверх = большое ускорение (быстрый разгон). Наклон вниз = замедление. По наклону прямой сразу видно $a_x$: $a_x = \\Delta v / \\Delta t$.</p>
</div>
<div class="fcard">
<h3>Средняя скорость</h3>
<div class="main-f">$\\langle v_x \\rangle = (v_{0x} + v_x)/2$</div>
<p>Для равноускоренного движения это <b>точная формула</b>, не приближение. Почему работает? Скорость меняется равномерно — как температура воздуха от утра до вечера. «Средняя за день» = (утром + вечером) / 2. Здесь то же самое: скорость менялась по прямой — среднее точно посередине.</p>
</div>
<div class="fcard">
<h3>График v(t) — прямая</h3>
<div class="main-f">наклон = $a_x$; пересечение = $v_{0x}$</div>
<p>$a > 0$: прямая идёт вверх (разгон). $a < 0$: вниз (торможение). Точка, где прямая пересекает ось $t$ — это момент, когда $v = 0$: тело остановилось или развернулось. После этого момента скорость меняет знак — тело начинает двигаться в обратную сторону.</p>
</div>
<div class="fcard">
<h3>Площадь под v(t)</h3>
<div class="main-f">трапеция = $\\Delta r = \\langle v\\rangle \\cdot t$</div>
<p>Под прямой v(t) при равноускоренном движении — трапеция (или треугольник при $v_0 = 0$). Площадь этой фигуры = перемещение. Формула трапеции: $(v_0 + v)/2 \\cdot t$ — это то же самое, что средняя скорость × время. Удобная проверка: посчитай перемещение двумя способами и сравни.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>$v = v_0 + at$ — каждую секунду скорость меняется на $a$. Начал с 5 м/с, $a = 3$ м/с²: через 1 с — 8 м/с, через 2 с — 11 м/с, через 3 с — 14 м/с. Просто прибавляй $a$ каждую секунду.</p>
<p>График $v(t)$ — прямая линия. Наклонена вверх = разгон. Наклонена вниз = торможение. Пересекает ось $t$ — это момент остановки. Закрашенная площадь под графиком = пройденный путь!</p>
</div>
<div class="idiag">
<h3> Интерактив: v(t) при равноускоренном движении</h3>
<div class="slider-row">
<span class="slider-lbl">v₀, м/с:</span>
<input type="range" min="-20" max="20" value="0" id="sl11v0" oninput="upd11()">
<span class="slider-val" id="v11v0">0 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">a, м/с²:</span>
<input type="range" min="-5" max="5" value="2" id="sl11a" oninput="upd11()">
<span class="slider-val" id="v11a">2 м/с²</span>
</div>
<div class="cv-wrap"><canvas id="cv11" style="height:180px"></canvas></div>
<div class="idiag-result" id="res11">v(5с) = — м/с | ⟨v⟩ = — м/с</div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$v = v_0 + at$ — линейная зависимость от времени.</li>
<li>$\\langle v\\rangle = (v_0 + v)/2$ — строго для равноускоренного движения.</li>
<li>График v(t) — прямая; наклон = $a$.</li>
</ul>
</div>
<ol class="q-list">
<li>Тело начало движение с $v_0 = 4$ м/с, $a = 2\\,\\text{м/с}^2$. Найдите скорость через 5 с.</li>
<li>Поезд затормозил с $v_0 = 20$ м/с до остановки за 50 с. Найдите ускорение.</li>
</ol>
`);
html += secNav('p10', 'p12');
html += readButton('p11');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p11');
}
function build_p12(){
const box = document.getElementById('p12-body');
let html = '';
html += makeCard('theory', "Перемещение, координата и путь при равноускоренном движении", "§12", `
<div class="para-hero ph-12">
<div class="ph-label">§12 · Физика 9 кл</div>
<h2>Перемещение и координата при равноускоренном движении</h2>
<div class="ph-formula">$x = x_0 + v_0 t + \\tfrac{at^2}{2};\\quad v^2 = v_0^2 + 2a\\Delta r$</div>
<div class="ph-desc">Координата при равноускоренном движении — квадратичная функция времени (парабола). Формула «без t» связывает скорость, ускорение и перемещение напрямую.</div>
<div class="ph-tags"><span class="ph-tag">парабола x(t)</span><span class="ph-tag">$v^2 = v_0^2 + 2as$</span><span class="ph-tag">квадратичная зависимость</span></div>
</div>
<div class="section-title"> §12. Перемещение при равноускоренном движении</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Перемещение</h3>
<div class="main-f">$\\Delta r_x = v_{0x}t + \\dfrac{a_x t^2}{2}$</div>
<p>При $a > 0$: расстояние нарастает всё быстрее — это парабола. Первую секунду проехал немного, вторую — больше, третью — ещё больше. Почему? Ускорение каждую секунду добавляет не просто постоянную прибавку к пути, а «нарастающую»: $1^2, 2^2, 3^2$... При $a = 0$ — прямая линия (равномерное движение). При $a \\ne 0$ — парабола.</p>
</div>
<div class="fcard">
<h3>Координата</h3>
<div class="main-f">$x = x_0 + v_{0x}t + \\dfrac{a_x t^2}{2}$</div>
<p>График x(t) — парабола: сначала пологая, потом всё круче (при $a > 0$). Вершина параболы — это точка, где $v = 0$: мяч, брошенный вверх, достиг максимальной высоты. После вершины парабола идёт вниз — тело движется обратно. Нашёл вершину на графике — нашёл максимальное смещение.</p>
</div>
<div class="fcard">
<h3>Формула «без t»</h3>
<div class="main-f">$v_x^2 = v_{0x}^2 + 2a_x\\Delta r_x$</div>
<p>Спасает, когда в задаче <b>не дано время</b>. Машина тормозит с 72 км/ч (= 20 м/с) до нуля при $a = -4\\,\\text{м/с}^2$: тормозной путь $s = v_0^2 / (2|a|) = 400 / 8 = 50$ м — и никакого $t$! Запомни: если в задаче нет $t$ и не нужно его найти, сразу бери эту формулу.</p>
</div>
<div class="fcard">
<h3>Таблица сравнения</h3>
<div class="main-f" style="font-size:.78rem;text-align:left;padding:6px 8px">
Равном.: $\\Delta r = vt$<br>
Равноуск.: $\\Delta r = v_0 t + at^2/2$<br>
«без t»: $v^2 = v_0^2 + 2as$
</div>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Формула $x = x_0 + v_0 t + \\frac{at^2}{2}$ — это три слагаемых: <b>где стоял</b> ($x_0$) + <b>куда уже шёл</b> ($v_0 t$) + <b>куда добавило ускорение</b> ($at^2/2$). При $v_0=0$, $x_0=0$ остаётся только $at^2/2$ — парабола.</p>
<p>Формула «без $t$»: $v^2 = v_0^2 + 2a\\Delta r$ спасает когда в задаче <b>не дано время</b>. Торможение до нуля: $0 = v_0^2 - 2|a|s$, значит $s = v_0^2/(2|a|)$.</p>
</div>
<div class="idiag">
<h3> Интерактив: x(t) при равноускоренном движении</h3>
<div class="slider-row">
<span class="slider-lbl">v₀, м/с:</span>
<input type="range" min="0" max="20" value="10" id="sl12v0" oninput="upd12()">
<span class="slider-val" id="v12v0">10 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">a, м/с²:</span>
<input type="range" min="-5" max="5" value="-2" id="sl12a" oninput="upd12()">
<span class="slider-val" id="v12a">-2 м/с²</span>
</div>
<div class="cv-wrap"><canvas id="cv12" style="height:200px"></canvas></div>
<div class="idiag-result" id="res12">Δr(5с) = — м | v(5с) = — м/с</div>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Тормозной путь</div><div class="li-desc">При скорости 60 км/ч ≈ 17 м/с и a = 8 м/с²: s = 17²/16 ≈ 18 м</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Свободное падение</div><div class="li-desc">Мяч падает с h = 20 м: t = √(2h/g) ≈ 2 с, v = gt ≈ 20 м/с</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Старт ракеты</div><div class="li-desc">a = 30 м/с². Через 10 с: v = 300 м/с, s = 1500 м</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Горнолыжник</div><div class="li-desc">Разгоняется вниз: a ≈ 5 м/с², за 10 с набирает 50 м/с ≈ 180 км/ч!</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$x = x_0 + v_0 t + at^2/2$ — уравнение движения (парабола).</li>
<li>$v^2 = v_0^2 + 2a\\Delta r$ — когда нет времени в условии.</li>
<li>Вершина параболы — точка остановки ($v = 0$).</li>
</ul>
</div>
<ol class="q-list">
<li>Тело $v_0 = 10$ м/с, $a = -2\\,\\text{м/с}^2$. Найдите перемещение за 4 с.</li>
<li>Автомобиль тормозит: $v_0 = 20$ м/с, $a = -4\\,\\text{м/с}^2$. Какой тормозной путь до полной остановки?</li>
</ol>
`);
html += secNav('p11', 'p13');
html += readButton('p12');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p12');
}
function build_p13(){
const box = document.getElementById('p13-body');
let html = '';
html += makeCard('theory', "Линейная и угловая скорости", "§13", `
<div class="para-hero ph-13">
<div class="ph-label">§13 · Физика 9 кл</div>
<h2>Криволинейное движение. Угловая и линейная скорости</h2>
<div class="ph-formula">$\\omega = 2\\pi/T;\\quad v = \\omega R;\\quad \\nu = 1/T$</div>
<div class="ph-desc">При движении по окружности вводится угловая скорость ω. Линейная скорость тем больше, чем дальше точка от оси. Все точки тела имеют одинаковое ω.</div>
<div class="ph-tags"><span class="ph-tag">$\\omega$ = рад/с</span><span class="ph-tag">$v = \\omega R$</span><span class="ph-tag">$T = 1/\\nu$</span></div>
</div>
<div class="section-title"> §13. Движение по окружности</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Угловая скорость</h3>
<div class="main-f">$\\omega = \\Delta\\varphi/\\Delta t = 2\\pi/T = 2\\pi\\nu$</div>
<p>Угол, на который поворачивается тело за одну секунду — в радианах. Один полный оборот = $2\\pi \\approx 6{,}28$ рад. Вентилятор делает 10 оборотов в секунду: $\\omega = 10 \\cdot 2\\pi \\approx 63$ рад/с. Все точки колеса вращаются с одной $\\omega$ — одинаковый угол за одинаковое время, но скорость разная: у края быстрее, у центра — медленнее.</p>
</div>
<div class="fcard">
<h3>Линейная скорость</h3>
<div class="main-f">$v = \\omega R$</div>
<p>При одной и той же угловой скорости точки, <em>дальше от оси</em>, проходят больший путь за оборот — значит, движутся <b>быстрее</b>. Велосипедное колесо: ступица и обод вращаются с одним $\\omega$, но скорость обода в 10 раз выше, чем точки в 10 раз ближе к центру. Именно поэтому резина на внешнем крае стирается быстрее.</p>
</div>
<div class="fcard">
<h3>Период и частота</h3>
<div class="main-f">$T = 2\\pi/\\omega;\\quad \\nu = 1/T;\\quad \\omega = 2\\pi\\nu$</div>
<p>Период $T$ — сколько секунд на один полный оборот. Частота $\\nu$ — сколько оборотов в секунду. Они обратны: $T = 1/\\nu$. Пример: мотор 3000 об/мин = 50 об/с → $\\nu = 50$ Гц, $T = 0{,}02$ с. Секундная стрелка: $T = 60$ с, $\\nu = 1/60$ Гц. Перевод в $\\omega$: умножь $\\nu$ на $2\\pi$.</p>
</div>
<div class="fcard">
<h3>Длина дуги</h3>
<div class="main-f">$s = R\\cdot\\Delta\\varphi$</div>
<p>Дуга = радиус × угол (в радианах). Легко запомнить: 1 рад — это угол, при котором дуга равна радиусу. Полный оборот: $\\Delta\\varphi = 2\\pi$ рад → $s = 2\\pi R$ — длина окружности. Знакомая формула! $2\\pi R$ — это просто частный случай $s = R \\cdot \\Delta\\varphi$ при полном обороте.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Велосипедное колесо: все спицы вращаются с одной угловой скоростью ω (одинаковый угол в секунду). Но конец спицы (обод) движется намного быстрее, чем её центр — потому что $v = \\omega R$ и $R$ больше.</p>
<p>Часовые стрелки: угловая скорость секундной стрелки в 60 раз больше минутной. Но линейная скорость зависит ещё и от длины стрелки.</p>
</div>
<div class="idiag">
<h3> Интерактив: движение по окружности</h3>
<div class="slider-row">
<span class="slider-lbl">R, м:</span>
<input type="range" min="0.1" max="5" step="0.1" value="1" id="sl13r" oninput="upd13()">
<span class="slider-val" id="v13r">1 м</span>
</div>
<div class="slider-row">
<span class="slider-lbl">ν, об/с:</span>
<input type="range" min="0.1" max="5" step="0.1" value="1" id="sl13nu" oninput="upd13()">
<span class="slider-val" id="v13nu">1 об/с</span>
</div>
<div class="cv-wrap"><canvas id="cv13" style="height:180px"></canvas></div>
<div class="idiag-result" id="res13">ω = — рад/с | v = — м/с | T = — с</div>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Колесо обозрения</div><div class="li-desc">Все кабинки вращаются с одинаковым ω, но внешние движутся быстрее</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Шестерёнки</div><div class="li-desc">Разные ω, но на точках касания линейные скорости одинаковы</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Земля</div><div class="li-desc">Один оборот за 24 ч = ω = 7,27·10⁻⁵ рад/с. На экваторе v = 465 м/с!</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Виниловая пластинка</div><div class="li-desc">33 об/мин. Внешние дорожки длиннее, но воспроизводятся с той же скоростью</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$\\omega = 2\\pi\\nu = 2\\pi/T$ — угловая скорость.</li>
<li>$v = \\omega R$ — линейная скорость точки на расстоянии R от оси.</li>
<li>$1\\,\\text{об} = 2\\pi\\,\\text{рад}$; $1\\,\\text{Гц} = 1\\,\\text{об/с}$.</li>
</ul>
</div>
<ol class="q-list">
<li>Вентилятор вращается с частотой 10 Гц. Найдите ω и T.</li>
<li>Точка на диске радиусом 0,5 м вращается с ω = 20 рад/с. Найдите линейную скорость.</li>
</ol>
`);
html += secNav('p12', 'p14');
html += readButton('p13');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p13');
}
function build_p14(){
const box = document.getElementById('p14-body');
let html = '';
html += makeCard('theory', "Ускорение точки при движении по окружности", "§14", `
<div class="para-hero ph-14">
<div class="ph-label">§14 · Физика 9 кл</div>
<h2>Ускорение при движении по окружности</h2>
<div class="ph-formula">$a_c = v^2/R = \\omega^2 R$</div>
<div class="ph-desc">Даже при постоянной скорости на окружности есть ускорение — центростремительное. Оно направлено к центру и изменяет направление скорости, но не её модуль.</div>
<div class="ph-tags"><span class="ph-tag">$a_c = v^2/R$</span><span class="ph-tag">→ к центру</span><span class="ph-tag">⊥ скорости</span></div>
</div>
<div class="section-title"> §14. Центростремительное ускорение</div>
<div class="formula-grid">
<div class="fcard highlight">
<h3>Центростремительное ускорение</h3>
<div class="main-f">$a_c = v^2/R = \\omega^2 R$</div>
<p>Направлено к центру окружности и <b>перпендикулярно скорости</b>. Изменяет только направление скорости — заставляет тело «поворачивать», не разгоняя и не тормозя. Крутой поворот на большой скорости: маленький $R$ и большое $v$ → огромное $a_c$ → «тебя вдавливает в кресло». При увеличении радиуса поворота — $a_c$ падает.</p>
</div>
<div class="fcard">
<h3>Эквивалентные формулы</h3>
<div class="main-f">$a_c = \\omega^2 R = \\omega v = \\dfrac{4\\pi^2 R}{T^2}$</div>
<p>Три формулы — одна физика, разные «входные данные». Знаешь скорость и радиус → $a_c = v^2/R$. Знаешь угловую скорость и радиус → $a_c = \\omega^2 R$. Знаешь период и радиус → $a_c = 4\\pi^2 R / T^2$. Выбирай ту, где уже есть нужные данные — не нужно переводить лишний раз.</p>
</div>
<div class="fcard">
<h3>Направление</h3>
<div class="main-f">всегда к центру кривизны</div>
<p>Даже если скорость по модулю не меняется, <b>направление всё время поворачивает</b> — значит, есть ускорение. Его называют «нормальным» (⊥ к траектории) или центростремительным (к центру). При <em>равномерном</em> движении по окружности только оно и есть: $a_\\tau = 0$. Тело едет с постоянной скоростью, но постоянно ускоряется!</p>
</div>
<div class="fcard">
<h3>Полное ускорение при неравномерном</h3>
<div class="main-f">$a = \\sqrt{a_c^2 + a_\\tau^2}$</div>
<p>Машина разгоняется в повороте: $a_c$ меняет <em>направление</em> скорости (к центру дуги), $a_\\tau$ меняет <em>модуль</em> скорости (вдоль движения). Оба действуют одновременно и перпендикулярны друг другу → полное ускорение: теорема Пифагора $a = \\sqrt{a_c^2 + a_\\tau^2}$. Водитель «давит на газ в вираже» — чувствует оба одновременно.</p>
</div>
</div>
<div class="student-box">
<div class="student-box-title"> Как это понять?</div>
<p>Крутишь камень на верёвке — верёвка постоянно тянет к центру. Уберёшь руку (уберёшь центростремительную силу) — камень полетит по прямой. Ускорение меняет <b>направление</b> скорости, заставляя тело «поворачивать».</p>
<p>Луна на орбите: скорость ~1 км/с, но она постоянно «падает» к Земле. Это и есть центростремительное ускорение — оно удерживает Луну на орбите.</p>
</div>
<div class="idiag">
<h3> Интерактив: центростремительное ускорение</h3>
<div class="slider-row">
<span class="slider-lbl">v, м/с:</span>
<input type="range" min="1" max="30" value="10" id="sl14v" oninput="upd14()">
<span class="slider-val" id="v14v">10 м/с</span>
</div>
<div class="slider-row">
<span class="slider-lbl">R, м:</span>
<input type="range" min="1" max="50" value="10" id="sl14r" oninput="upd14()">
<span class="slider-val" id="v14r">10 м</span>
</div>
<div class="cv-wrap"><canvas id="cv14" style="height:180px"></canvas></div>
<div class="idiag-result" id="res14">a_c = — м/с²</div>
</div>
<div class="life-grid">
<div class="life-item"><div class="li-icon"></div><div class="li-title">Американские горки</div><div class="li-desc">В петле a_c = v²/R. При высокой скорости — ощущение «перегрузки»</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">МКС</div><div class="li-desc">v ≈ 7,7 км/с, R = 6770 км → a_c ≈ 8,7 м/с² ≈ g</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Гоночный поворот</div><div class="li-desc">200 км/ч, R = 100 м → a_c = 31 м/с² ≈ 3g. Нужна прижимная сила</div></div>
<div class="life-item"><div class="li-icon"></div><div class="li-title">Земля вокруг Солнца</div><div class="li-desc">v = 30 км/с, R = 1,5·10¹¹ м → a_c = 6·10⁻³ м/с²</div></div>
</div>
<div class="remember-box">
<div class="remember-box-title"> Запомни!</div>
<ul>
<li>$a_c = v^2/R = \\omega^2 R$ — к центру, ⊥ скорости.</li>
<li>При равномерном движении по окружности ускорение ≠ 0!</li>
<li>Чем больше $v$ и меньше $R$ — тем больше $a_c$.</li>
</ul>
</div>
<ol class="q-list">
<li>Автомобиль движется в повороте со скоростью 20 м/с, радиус 50 м. Найдите центростремительное ускорение.</li>
<li>Спутник летит по круговой орбите. Ускорение равно $g = 9{,}8\\,\\text{м/с}^2$, радиус 6 400 км. Найдите скорость спутника.</li>
</ol>
`);
html += secNav('p13', 'final1');
html += readButton('p14');
box.innerHTML = html;
renderMath(box);
wireReadBtn('p14');
}
function build_final1(){
const box = document.getElementById('final1-body');
let html = '';
html += makeCard('theory', "Финал главы 1", "★", `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Равномерное движение</h3>
<div class="main-f">$\\vec{v} = \\text{const}$</div>
<p>$\\Delta\\vec{r} = \\vec{v}\\,t$ · $x = x_0 + v_x t$ · $s = vt$</p>
</div>
<div class="fcard"><h3>Равноускоренное</h3>
<div class="main-f">$\\vec{v} = \\vec{v}_0 + \\vec{a}\\,t$</div>
<p>$\\Delta\\vec{r} = \\vec{v}_0 t + \\dfrac{\\vec{a} t^2}{2}$ · $v^2 - v_0^2 = 2a_x\\Delta x$</p>
</div>
<div class="fcard"><h3>По окружности</h3>
<div class="main-f">$a_n = \\dfrac{v^2}{R} = \\omega^2 R$</div>
<p>$\\omega = \\dfrac{2\\pi}{T} = 2\\pi\\nu$ · $v = \\omega R$</p>
</div>
</div>
<div class="section-title"><svg class="ic" viewBox="0 0 24 24" style="width:18px;height:18px;display:inline-block;vertical-align:-3px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> Интегрированные задачи</div>
<div class="task-card">
<div class="task-num">Задача 1</div>
<div class="task-text">Автомобиль за $t_1 = 20$ с разгоняется до $v_1 = 20$ м/с, далее едет $t_2 = 60$ с с постоянной скоростью. Найдите средний модуль скорости за всё время движения. Начальная скорость $v_0 = 0$.</div>
<div class="task-hint">Сложите путь на каждом участке: $s_1 = v_1 t_1 / 2$, $s_2 = v_1 t_2$. Средняя $\\langle v\\rangle = (s_1 + s_2)/(t_1 + t_2)$.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q1" step="any"><span class="unit-lbl">м/с</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q1', 17.5, 'м/с', 0.5)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 2</div>
<div class="task-text">Тело движется с ускорением $a = 2$ м/с². Через $t = 5$ с его скорость стала $v = 14$ м/с. Найдите начальную скорость тела.</div>
<div class="task-hint">$v = v_0 + at$, откуда $v_0 = v - at$.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q2" step="any"><span class="unit-lbl">м/с</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q2', 4, 'м/с', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 3</div>
<div class="task-text">Шарик движется по окружности радиуса $R = 0{,}5$ м с периодом $T = 2{,}0$ с. Найдите модуль центростремительного ускорения.</div>
<div class="task-hint">$a_n = \\dfrac{4\\pi^2 R}{T^2}$. Подставьте $\\pi \\approx 3{,}14$.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q3" step="any"><span class="unit-lbl">м/с²</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q3', 4.93, 'м/с²', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 4</div>
<div class="task-text">Катер движется по реке со скоростью $v_к = 5$ м/с относительно воды. Скорость течения $v_р = 2$ м/с. Найдите модуль скорости катера относительно берега при движении против течения.</div>
<div class="task-hint">Против течения скорости вычитаются: $v = v_к - v_р$.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q4" step="any"><span class="unit-lbl">м/с</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q4', 3, 'м/с', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 5 (повышенный уровень)</div>
<div class="task-text">Поезд проходит мимо пешехода за $t_1 = 8$ с, а мимо платформы длиной $L = 200$ м — за $t_2 = 18$ с. Найдите скорость поезда. Поезд движется равномерно.</div>
<div class="task-hint">За $t_1$ поезд проходит свою длину $\\ell$, за $t_2$ — $\\ell + L$. Имеем $\\ell = v t_1$ и $\\ell + L = v t_2$. Отсюда $v = L/(t_2 - t_1)$.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q5" step="any"><span class="unit-lbl">м/с</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q5', 20, 'м/с', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q5"></div>
</div>
`);
html += secNav('p14', null);
html += readButton('final1');
box.innerHTML = html;
renderMath(box);
wireReadBtn('final1');
}
/* ===== Search ===== */
const SEARCH_INDEX = (function(){
const arr=[];
PARAS.forEach(p=>arr.push({kind: p.id.startsWith('lr')?'Лабораторная':(p.final?'Финал':'Параграф'),title:p.num+' '+p.name,desc:p.sub||'',sec:p.id}));
return arr;
})();
function initSearch(){
const modal=document.getElementById('search-modal'),inp=document.getElementById('search-input'),out=document.getElementById('search-results'),btn=document.getElementById('search-btn');
if(!modal||!inp||!out) return;
let cur=0,rows=[];
function score(q,it){ const t=(it.title+' '+it.desc).toLowerCase(); if(t.includes(q)) return 100+(it.title.toLowerCase().startsWith(q)?50:0); let s=0; q.split(/\s+/).forEach(w=>{if(w&&t.includes(w))s+=10;}); return s; }
function rank(q){ q=q.trim().toLowerCase(); if(!q) return SEARCH_INDEX.slice(0,12); return SEARCH_INDEX.map(it=>({it,s:score(q,it)})).filter(x=>x.s>0).sort((a,b)=>b.s-a.s).slice(0,20).map(x=>x.it); }
function render(){ cur=0; if(!rows.length){out.innerHTML='<div class="search-empty">Ничего не найдено</div>';return;} out.innerHTML=rows.map((r,i)=>'<button class="search-row'+(i===0?' active':'')+'" data-i="'+i+'"><div class="sr-kind">'+r.kind+'</div><div class="sr-title">'+r.title+'</div>'+(r.desc?'<div class="sr-desc">'+(r.desc.length>90?r.desc.slice(0,90)+'…':r.desc)+'</div>':'')+'</button>').join(''); out.querySelectorAll('.search-row').forEach(b=>b.addEventListener('click',()=>{cur=+b.dataset.i;pick();})); }
function pick(){ const r=rows[cur]; if(!r) return; close(); goTo(r.sec); }
function move(d){ const items=out.querySelectorAll('.search-row'); if(!items.length) return; items[cur]&&items[cur].classList.remove('active'); cur=(cur+d+items.length)%items.length; items[cur].classList.add('active'); items[cur].scrollIntoView({block:'nearest'}); }
function open(){ modal.classList.add('show'); inp.value=''; rows=rank(''); render(); setTimeout(()=>inp.focus(),50); }
function close(){ modal.classList.remove('show'); }
btn&&btn.addEventListener('click',open);
modal.addEventListener('click',e=>{if(e.target===modal)close();});
inp.addEventListener('input',()=>{rows=rank(inp.value);render();});
inp.addEventListener('keydown',e=>{ if(e.key==='ArrowDown'){e.preventDefault();move(1);}else if(e.key==='ArrowUp'){e.preventDefault();move(-1);}else if(e.key==='Enter'){e.preventDefault();pick();}else if(e.key==='Escape'){e.preventDefault();close();} });
document.addEventListener('keydown',e=>{ if((e.ctrlKey||e.metaKey)&&(e.key==='k'||e.key==='K')){ e.preventDefault(); if(modal.classList.contains('show')) close(); else open(); } });
}
function initSidebarToggle(){
const side=document.getElementById('col-side'),back=document.getElementById('col-side-backdrop'),btn=document.getElementById('sidebar-btn');
if(!side||!btn) return;
function open(){ side.classList.add('open'); back.classList.add('show'); }
function close(){ side.classList.remove('open'); back.classList.remove('show'); }
btn.addEventListener('click',()=>{ if(side.classList.contains('open')) close(); else open(); });
back.addEventListener('click',close);
document.addEventListener('keydown',e=>{ if(e.key==='Escape') close(); });
}
function init(){
loadProgress(); initTheme(); initSidebarToggle(); initSearch();
buildParaSelector(); refreshProgressUI(); loadServerReadState(); goTo(PARAS[0].id);
setTimeout(()=>achievement('start'), 600);
if(window.LS&&window.LS.xp){
window.LS.xp.load().then(function(s){ if(s&&s.xp>STATE.xp){ STATE.xp=s.xp; STATE.level=calcLevel(STATE.xp); saveProgress(); refreshProgressUI(); if(STATE.current) buildSidebar(STATE.current); } });
}
}
document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>