simbiot-harness/video/simbiot-promo/index.html
Simbiot Harness 3fab6193db промо-видео как презентация: слайд-остров hyperframes (7 слайдов, остановки, заметки докладчика)
Тот же index.html: npx hyperframes present — дек, npx hyperframes render — MP4.
Фикс: window.__timelines инициализируется сам (present-рантайм его не создаёт).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:24:19 +00:00

533 lines
39 KiB
HTML
Raw 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 name="viewport" content="width=1920, height=1080" />
<title>Simbiot Harness — промо</title>
<script src="./gsap.min.js"></script>
<style>
@font-face { font-family: "Unbounded"; font-weight: 700; src: url("fonts/unbounded-700-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "Unbounded"; font-weight: 700; src: url("fonts/unbounded-700-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
@font-face { font-family: "Unbounded"; font-weight: 400; src: url("fonts/unbounded-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "Unbounded"; font-weight: 400; src: url("fonts/unbounded-400-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
@font-face { font-family: "Inter"; font-weight: 400; src: url("fonts/inter-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "Inter"; font-weight: 400; src: url("fonts/inter-400-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
@font-face { font-family: "Inter"; font-weight: 600; src: url("fonts/inter-600-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "Inter"; font-weight: 600; src: url("fonts/inter-600-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
@font-face { font-family: "JetBrains Mono"; font-weight: 400; src: url("fonts/jetbrains-mono-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "JetBrains Mono"; font-weight: 400; src: url("fonts/jetbrains-mono-400-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
@font-face { font-family: "JetBrains Mono"; font-weight: 700; src: url("fonts/jetbrains-mono-700-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+2000-206F, U+2190-21FF, U+2200-22FF; }
@font-face { font-family: "JetBrains Mono"; font-weight: 700; src: url("fonts/jetbrains-mono-700-cyrillic.woff2") format("woff2"); unicode-range: U+0400-04FF; }
:root {
--bg: #06080c;
--ink: #eef2f6;
--dim: #a7b0bd;
--mint: #5cffb0;
--violet: #8b7cff;
--amber: #ffb84d;
--rose: #ff6b8b;
--line: rgba(255, 255, 255, 0.08);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 1920px; height: 1080px; overflow: hidden; background: var(--bg); }
body { color: var(--ink); font-family: "Inter", sans-serif; }
#root { position: relative; width: 100%; height: 100%; overflow: hidden; }
.clip { position: absolute; inset: 0; }
.mono { font-family: "JetBrains Mono", monospace; }
.display { font-family: "Unbounded", sans-serif; }
/* ---------- фон ---------- */
#bg { background: radial-gradient(1200px 800px at 50% 40%, #0d1420 0%, var(--bg) 70%); }
#bg-grid {
position: absolute; inset: -120px;
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
background-size: 80px 80px;
mask-image: radial-gradient(ellipse at center, #000 30%, transparent 75%);
}
#bg-glow-a, #bg-glow-b { position: absolute; width: 900px; height: 900px; border-radius: 50%; filter: blur(140px); opacity: 0.35; }
#bg-glow-a { background: var(--mint); left: -300px; top: -350px; opacity: 0.12; }
#bg-glow-b { background: var(--violet); right: -300px; bottom: -400px; opacity: 0.16; }
/* ---------- HUD ---------- */
#hud { pointer-events: none; }
.hud-row { position: absolute; left: 64px; right: 64px; display: flex; justify-content: space-between; align-items: center; font-size: 18px; letter-spacing: 0.12em; color: var(--dim); text-transform: uppercase; }
#hud-top { top: 44px; }
#hud-bot { bottom: 44px; }
.hud-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--mint); margin-right: 14px; box-shadow: 0 0 14px var(--mint); }
.hud-lv { display: flex; gap: 28px; }
.hud-lv span { display: block; }
.hud-lv b { color: var(--mint); font-weight: 400; }
/* ---------- общие ---------- */
.scene { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 140px 160px; }
.kicker { font-size: 22px; letter-spacing: 0.32em; color: var(--mint); text-transform: uppercase; margin-bottom: 28px; }
.h2 { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 76px; letter-spacing: -0.02em; line-height: 1.05; text-align: center; }
.sub { font-size: 30px; color: var(--dim); margin-top: 22px; text-align: center; }
.accent { color: var(--mint); }
/* ---------- S1 интро ---------- */
#s1-ecg { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; }
#s1-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
#s1-title { display: flex; gap: 0.32em; font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 150px; letter-spacing: -0.03em; }
#s1-title .w { display: flex; overflow: hidden; padding: 0 4px 12px; }
#s1-title .ch { display: block; }
#s1-title .w2 .ch { color: var(--mint); }
#s1-tag { font-size: 40px; margin-top: 18px; color: var(--ink); }
#s1-stack { margin-top: 40px; font-size: 22px; color: var(--dim); letter-spacing: 0.14em; display: flex; gap: 22px; }
#s1-stack span { display: block; }
/* ---------- S2 лестница ---------- */
#s2-rows { margin-top: 64px; width: 1500px; display: flex; flex-direction: column; gap: 22px; }
.lvl { display: grid; grid-template-columns: 150px 150px 1fr 260px; align-items: center; gap: 30px; height: 96px; padding: 0 34px; border: 1px solid var(--line); border-radius: 20px; background: rgba(255, 255, 255, 0.025); }
.lvl-name { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 38px; }
.lvl-int { font-size: 26px; color: var(--dim); }
.lvl-bar { position: relative; height: 16px; border-radius: 8px; background: rgba(255, 255, 255, 0.06); }
.lvl-fill { position: absolute; left: 0; top: 0; height: 16px; width: 100%; border-radius: 8px; background: linear-gradient(90deg, var(--mint), var(--violet)); transform-origin: left center; }
.lvl-ctx { font-size: 26px; text-align: right; color: var(--ink); }
.lvl-ctx small { color: var(--dim); font-size: 20px; margin-left: 8px; }
.pulse { position: absolute; left: 0; width: 22px; height: 22px; border-radius: 50%; top: -3px; background: var(--mint); box-shadow: 0 0 24px var(--mint); }
#s2-foot { margin-top: 46px; font-size: 30px; color: var(--dim); display: flex; align-items: center; gap: 18px; }
#s2-foot b { color: var(--ink); font-weight: 600; }
.arrow-up { display: block; width: 40px; height: 40px; }
/* ---------- S3 ES-спина ---------- */
#s3-track-wrap { position: relative; width: 1920px; height: 340px; margin-top: 70px; overflow: hidden; }
#s3-track { position: absolute; left: 0; top: 30px; display: flex; gap: 0; align-items: center; }
.ev { position: relative; width: 340px; height: 230px; flex: 0 0 340px; margin-right: 70px; padding: 26px 28px; border-radius: 22px; border: 1px solid rgba(92, 255, 176, 0.25); background: linear-gradient(160deg, rgba(92, 255, 176, 0.08), rgba(139, 124, 255, 0.05)); }
.ev-seq { font-size: 18px; color: var(--dim); }
.ev-name { font-family: "JetBrains Mono", monospace; font-weight: 700; font-size: 29px; margin-top: 14px; color: var(--ink); }
.ev-sig { font-size: 17px; color: var(--mint); margin-top: 26px; line-height: 1.6; }
.ev-sig span { display: block; color: var(--dim); }
.ev-link { position: absolute; right: -70px; top: 108px; width: 70px; height: 4px; background: linear-gradient(90deg, var(--mint), var(--violet)); }
#s3-verify { margin-top: 30px; font-size: 30px; padding: 18px 34px; border-radius: 14px; background: rgba(0, 0, 0, 0.5); border: 1px solid var(--line); }
#s3-verify .ok { color: var(--mint); }
/* ---------- S4 куб ---------- */
#s4 { display: flex; align-items: center; padding: 0 140px 0 180px; }
#s4-text { width: 760px; }
#s4-text .h2 { text-align: left; font-size: 70px; }
#s4-axes { margin-top: 46px; display: flex; flex-direction: column; gap: 22px; }
.axis { display: flex; align-items: baseline; gap: 22px; font-size: 28px; }
.axis .ax-k { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 32px; color: var(--mint); width: 90px; display: block; }
.axis .ax-v { color: var(--ink); display: block; }
.axis .ax-v small { display: block; color: var(--dim); font-size: 21px; margin-top: 4px; }
#s4-punch { margin-top: 52px; font-size: 34px; font-weight: 600; }
#s4-stage { flex: 1; height: 900px; position: relative; perspective: 2200px; display: flex; align-items: center; justify-content: center; }
#s4-cube { position: relative; width: 0; height: 0; transform-style: preserve-3d; }
.cell { position: absolute; width: 96px; height: 96px; left: -48px; top: -48px; border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.35); }
#s4-label { position: absolute; bottom: 70px; left: 0; right: 0; text-align: center; font-size: 24px; color: var(--dim); letter-spacing: 0.08em; }
#s4-label b { color: var(--mint); font-weight: 400; }
/* ---------- S5 органы чувств ---------- */
#s5-stage { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; }
#s5-lines { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; }
#s5-core { position: absolute; left: 810px; top: 390px; width: 300px; height: 300px; border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; background: radial-gradient(circle, rgba(92, 255, 176, 0.25), rgba(92, 255, 176, 0.03) 70%); border: 2px solid rgba(92, 255, 176, 0.5); }
#s5-core .display { font-weight: 700; font-size: 40px; }
#s5-core .mono { font-size: 18px; color: var(--dim); margin-top: 8px; }
#s5-ring { position: absolute; left: 760px; top: 340px; width: 400px; height: 400px; border-radius: 50%; border: 1px dashed rgba(92, 255, 176, 0.35); }
.node { position: absolute; width: 380px; padding: 24px 28px; border-radius: 20px; background: rgba(12, 18, 28, 0.92); border: 1px solid var(--line); }
.node-t { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 27px; }
.node-d { font-size: 21px; color: var(--dim); margin-top: 8px; line-height: 1.35; }
.node-i { font-size: 18px; color: var(--mint); margin-bottom: 8px; letter-spacing: 0.1em; }
#s5-title { position: absolute; top: 118px; left: 0; right: 0; text-align: center; }
#s5-title .h2 { font-size: 58px; }
/* ---------- S6 AUM ---------- */
#s6 { display: flex; align-items: center; padding: 0 160px; gap: 80px; }
#s6-left { width: 780px; flex: 0 0 780px; }
#s6-left .h2 { text-align: left; font-size: 72px; }
#s6-num { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 210px; color: var(--mint); line-height: 1; margin-top: 30px; display: flex; align-items: baseline; }
#s6-num-cap { font-size: 30px; color: var(--ink); margin-top: 6px; }
#s6-q { margin-top: 36px; font-size: 32px; line-height: 1.4; color: var(--ink); border-left: 4px solid var(--mint); padding-left: 26px; }
#s6-q span { color: var(--dim); display: block; font-size: 22px; margin-top: 10px; }
#s6-chart { width: 800px; height: 546px; flex: 0 0 800px; }
/* ---------- S7 аутро ---------- */
#s7-logo { font-family: "Unbounded", sans-serif; font-weight: 700; font-size: 128px; letter-spacing: -0.03em; }
#s7-logo span { color: var(--mint); }
#s7-term { margin-top: 56px; width: 1320px; border-radius: 18px; overflow: hidden; border: 1px solid var(--line); background: #0b0f16; }
#s7-term-bar { height: 46px; display: flex; align-items: center; gap: 10px; padding: 0 20px; background: rgba(255, 255, 255, 0.04); }
#s7-term-bar i { display: block; width: 14px; height: 14px; border-radius: 50%; }
#s7-cmd { padding: 34px 38px; font-size: 34px; display: flex; flex-wrap: wrap; }
#s7-cmd .p { color: var(--mint); margin-right: 18px; }
#s7-cmd .c { display: block; white-space: pre; opacity: 0; }
#s7-caret { display: block; width: 18px; height: 40px; background: var(--mint); margin-left: 4px; }
#s7-foot { margin-top: 48px; font-size: 30px; color: var(--dim); letter-spacing: 0.08em; }
#s7-foot b { color: var(--ink); font-weight: 600; }
</style>
</head>
<body>
<script type="application/hyperframes-slideshow+json">
{
"slides": [
{
"sceneId": "intro",
"startTime": 0,
"endTime": 5.2,
"fragments": [
1.2,
3.8
],
"notes": "Открываем пульсом: харнес — живой агент, который работает тактами, как сердце. Стек: CQRS, Event Sourcing, Strands, 9router."
},
{
"sceneId": "ladder",
"startTime": 5.2,
"endTime": 13.2,
"fragments": [
6.4,
8.8,
12.3
],
"notes": "Лестница: sec — рефлекс без LLM; min — триаж 256K; hour — дайджест 512K; day — манифест 1M. Тик идемпотентен, занятый уровень поглощает тик, наверх идут только дайджесты."
},
{
"sceneId": "events",
"startTime": 13.2,
"endTime": 21.6,
"fragments": [
14.6,
17.0,
19.4,
20.8
],
"notes": "Состояние — производное от событий. Каждое событие подписано ed25519 и сцеплено prev_sig — подделку хвоста видно сразу, cli.py verify возвращает 0."
},
{
"sceneId": "cube",
"startTime": 21.6,
"endTime": 30.6,
"fragments": [
23.4,
25.6,
26.6,
28.7
],
"notes": "Куб 4×4×4: круг доверия × такт × глубина памяти. Одна таблица политик, а не 64 программы. Круг тика — самый недоверенный вход: просьба правления не исполнится с правами владельца."
},
{
"sceneId": "senses",
"startTime": 30.6,
"endTime": 37.6,
"fragments": [
32.0,
36.4
],
"notes": "Органы чувств: Telegram с батч-триажем, звонки через MCP портала, RAG по базе кооператива, decision-модель clef:27b, ядро Коди, которое доучивается на исходах, и live-дашборд."
},
{
"sceneId": "aum",
"startTime": 37.6,
"endTime": 44.0,
"fragments": [
39.4,
43.2
],
"notes": "Одна метрика — долгосрочная AUM кооператива. Фильтр каждой задачи: добавит ли это ≥1% к AUM в горизонте год+?"
},
{
"sceneId": "outro",
"startTime": 44.0,
"endTime": 50.0,
"fragments": [
49.6
],
"notes": "Установка одной командой: curl … install.sh | bash, затем simbiot wizard с ключом с портала cil.by."
}
],
"slideSequences": []
}
</script>
<div id="root" data-composition-id="main" data-start="0" data-duration="50" data-width="1920" data-height="1080">
<!-- фон на весь ролик -->
<div id="bg" class="clip" data-start="0" data-duration="50" data-track-index="0">
<div id="bg-grid"></div>
<div id="bg-glow-a"></div>
<div id="bg-glow-b"></div>
</div>
<!-- S1 — сердцебиение и имя -->
<section id="s1" class="clip" data-start="0" data-duration="5.2" data-track-index="1">
<div id="s1-in" style="position:absolute;inset:0">
<svg id="s1-ecg" viewBox="0 0 1920 1080">
<path id="s1-ecg-path" d="M0 540 L620 540 L660 540 L690 470 L720 610 L760 300 L800 760 L840 540 L900 540 L1000 540 L1030 500 L1060 580 L1100 540 L1920 540" fill="none" stroke="#5cffb0" stroke-width="4" stroke-linejoin="round" />
</svg>
<div id="s1-center">
<div id="s1-title">
<div class="w w1"><span class="ch">S</span><span class="ch">I</span><span class="ch">M</span><span class="ch">B</span><span class="ch">I</span><span class="ch">O</span><span class="ch">T</span></div>
<div class="w w2"><span class="ch">H</span><span class="ch">A</span><span class="ch">R</span><span class="ch">N</span><span class="ch">E</span><span class="ch">S</span><span class="ch">S</span></div>
</div>
<div id="s1-tag">Агент, который живёт тактами — как человек</div>
<div id="s1-stack" class="mono">
<span>CQRS</span><span>·</span><span>EVENT SOURCING</span><span>·</span><span>STRANDS</span><span>·</span><span>9ROUTER</span>
</div>
</div>
</div>
</section>
<!-- S2 — лестница времени -->
<section id="s2" class="clip scene" data-start="5.2" data-duration="8" data-track-index="1">
<div id="s2-in" style="display:flex;flex-direction:column;align-items:center">
<div class="kicker mono" id="s2-k">01 · Лестница времени</div>
<div class="h2" id="s2-h" style="font-size:60px">Секунда рефлексов. <span class="accent">День размышлений.</span></div>
<div id="s2-rows">
<div class="lvl" id="lv-sec"><div class="lvl-name">sec</div><div class="lvl-int mono">1 с</div><div class="lvl-bar"><div class="lvl-fill" style="width:1%"></div><div class="pulse" id="p-sec"></div></div><div class="lvl-ctx mono">без LLM<small>рефлекс</small></div></div>
<div class="lvl" id="lv-min"><div class="lvl-name">min</div><div class="lvl-int mono">1 мин</div><div class="lvl-bar"><div class="lvl-fill" style="width:25.6%"></div><div class="pulse" id="p-min"></div></div><div class="lvl-ctx mono">256K<small>триаж</small></div></div>
<div class="lvl" id="lv-hour"><div class="lvl-name">hour</div><div class="lvl-int mono">1 ч</div><div class="lvl-bar"><div class="lvl-fill" style="width:51.2%"></div><div class="pulse" id="p-hour"></div></div><div class="lvl-ctx mono">512K<small>дайджест</small></div></div>
<div class="lvl" id="lv-day"><div class="lvl-name">day</div><div class="lvl-int mono">1 д</div><div class="lvl-bar"><div class="lvl-fill" style="width:100%"></div><div class="pulse" id="p-day"></div></div><div class="lvl-ctx mono">1M<small>манифест</small></div></div>
</div>
<div id="s2-foot">
<svg class="arrow-up" viewBox="0 0 40 40"><path d="M20 34 L20 6 M8 18 L20 6 L32 18" stroke="#5cffb0" stroke-width="4" fill="none" stroke-linecap="round" /></svg>
<div>Тик идемпотентен. Задача не прерывается. <b>Наверх идут только дайджесты.</b></div>
</div>
</div>
</section>
<!-- S3 — событийная спина + криптоаудит -->
<section id="s3" class="clip scene" data-start="13.2" data-duration="8.4" data-track-index="1">
<div id="s3-in" style="display:flex;flex-direction:column;align-items:center">
<div class="kicker mono" id="s3-k">02 · Event Sourcing</div>
<div class="h2" id="s3-h">Состояние — <span class="accent">производное от событий</span></div>
<div class="sub" id="s3-sub">Append-only. Каждое событие подписано ed25519 и сцеплено с предыдущим.</div>
<div id="s3-track-wrap" data-layout-allow-overflow>
<div id="s3-track" data-layout-allow-overflow>
<div class="ev"><div class="ev-seq mono">#40211 · tg</div><div class="ev-name">MessageReceived</div><div class="ev-sig mono">sig 7c1e…a90f<span>prev 3b02…e1d4</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40212 · min</div><div class="ev-name">CycleTicked</div><div class="ev-sig mono">sig 0d9a…41bc<span>prev 7c1e…a90f</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40213 · task</div><div class="ev-name">TaskSubmitted</div><div class="ev-sig mono">sig e5f7…02aa<span>prev 0d9a…41bc</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40214 · task</div><div class="ev-name">TaskClaimed</div><div class="ev-sig mono">sig 91c4…7d3e<span>prev e5f7…02aa</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40215 · task</div><div class="ev-name">TaskCompleted</div><div class="ev-sig mono">sig 2ab8…c615<span>prev 91c4…7d3e</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40216 · tg</div><div class="ev-name">DeliverySent</div><div class="ev-sig mono">sig 6f03…9b27<span>prev 2ab8…c615</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40217 · hour</div><div class="ev-name">DigestWritten</div><div class="ev-sig mono">sig c44d…18f0<span>prev 6f03…9b27</span></div><div class="ev-link"></div></div>
<div class="ev"><div class="ev-seq mono">#40218 · day</div><div class="ev-name">AumMeasured</div><div class="ev-sig mono">sig 8e2b…d771<span>prev c44d…18f0</span></div></div>
</div>
</div>
<div id="s3-verify" class="mono">$ cli.py verify <span class="ok">→ цепочка цела ✓ exit 0</span></div>
</div>
</section>
<!-- S4 — куб 4×4×4 -->
<section id="s4" class="clip" data-start="21.6" data-duration="9" data-track-index="1">
<div id="s4-text">
<div class="kicker mono" id="s4-k">03 · Куб политик</div>
<div class="h2" id="s4-h">Кому, когда и&nbsp;насколько глубоко</div>
<div id="s4-axes">
<div class="axis" id="ax1"><span class="ax-k">×4</span><span class="ax-v">круга доверия<small>владелец · правление · свои · остальные</small></span></div>
<div class="axis" id="ax2"><span class="ax-k">×4</span><span class="ax-v">такта<small>sec · min · hour · day</small></span></div>
<div class="axis" id="ax3"><span class="ax-k">×4</span><span class="ax-v">глубины памяти<small>D0 реплика · D1 разговор · D2 эпизоды · D3 архив</small></span></div>
</div>
<div id="s4-punch">Одна таблица политик — <span class="accent">не 64 программы.</span></div>
</div>
<div id="s4-stage">
<div id="s4-cube"></div>
<div id="s4-label" class="mono">круг тика = <b>самый недоверенный вход</b></div>
</div>
</section>
<!-- S5 — органы чувств -->
<section id="s5" class="clip" data-start="30.6" data-duration="7" data-track-index="1">
<div id="s5-stage">
<div id="s5-title"><div class="kicker mono" id="s5-k">04 · Руки и уши</div><div class="h2" id="s5-h">Служит, а не ждёт указки</div></div>
<svg id="s5-lines" viewBox="0 0 1920 1080">
<path class="s5l" d="M960 540 L520 400" stroke="#5cffb0" stroke-opacity="0.45" stroke-width="2" fill="none" />
<path class="s5l" d="M960 540 L1400 400" stroke="#5cffb0" stroke-opacity="0.45" stroke-width="2" fill="none" />
<path class="s5l" d="M960 540 L460 640" stroke="#8b7cff" stroke-opacity="0.45" stroke-width="2" fill="none" />
<path class="s5l" d="M960 540 L1460 640" stroke="#8b7cff" stroke-opacity="0.45" stroke-width="2" fill="none" />
<path class="s5l" d="M960 540 L700 860" stroke="#5cffb0" stroke-opacity="0.45" stroke-width="2" fill="none" />
<path class="s5l" d="M960 540 L1220 860" stroke="#5cffb0" stroke-opacity="0.45" stroke-width="2" fill="none" />
</svg>
<div id="s5-ring"></div>
<div id="s5-core"><div class="display">SIMBIOT</div><div class="mono">ядро тика</div></div>
<div class="node" id="n1" style="left:150px;top:300px"><div class="node-i mono">TELEGRAM</div><div class="node-t">@juno42bot</div><div class="node-d">батч-триаж входящих за один тик</div></div>
<div class="node" id="n2" style="left:1390px;top:300px"><div class="node-i mono">ПОРТАЛ · MCP</div><div class="node-t">Звонки из чата</div><div class="node-d">слоты → jitsi → запись и транскрипт</div></div>
<div class="node" id="n3" style="left:90px;top:560px"><div class="node-i mono">RAG</div><div class="node-t">База знаний</div><div class="node-d">12.5K чанков кооператива</div></div>
<div class="node" id="n4" style="left:1450px;top:560px"><div class="node-i mono">DECISION</div><div class="node-t">clef:27b</div><div class="node-d">выбор без генерации, 0.6 с</div></div>
<div class="node" id="n5" style="left:330px;top:820px"><div class="node-i mono">ЯДРО КОДИ</div><div class="node-t">Учится сам</div><div class="node-d">ученик сменяет чемпиона по log-loss</div></div>
<div class="node" id="n6" style="left:1210px;top:820px"><div class="node-i mono">ДАШБОРД</div><div class="node-t">Всё видно</div><div class="node-d">задачи, лестница, эскалации live</div></div>
</div>
</section>
<!-- S6 — AUM -->
<section id="s6" class="clip" data-start="37.6" data-duration="6.4" data-track-index="1">
<div id="s6-left">
<div class="kicker mono" id="s6-k">05 · Одна цель</div>
<div class="h2" id="s6-h">Долгосрочная AUM кооператива</div>
<div id="s6-num"><span id="s6-val">+0%</span></div><div id="s6-num-cap">к AUM в горизонте год+</div>
<div id="s6-q">«Добавит ли это ≥1% к AUM за год+?»<span>Фильтр каждой задачи на каждом уровне.</span></div>
</div>
<svg id="s6-chart" viewBox="0 0 820 560">
<defs>
<linearGradient id="s6-grad" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#5cffb0" stop-opacity="0.35" /><stop offset="1" stop-color="#5cffb0" stop-opacity="0" /></linearGradient>
</defs>
<g stroke="rgba(255,255,255,0.08)" stroke-width="1">
<line x1="0" y1="140" x2="820" y2="140" /><line x1="0" y1="280" x2="820" y2="280" /><line x1="0" y1="420" x2="820" y2="420" /><line x1="0" y1="559" x2="820" y2="559" />
</g>
<path id="s6-area" d="M0 500 L80 488 L160 492 L240 462 L320 450 L400 404 L480 380 L560 318 L640 270 L720 196 L820 90 L820 560 L0 560 Z" fill="url(#s6-grad)" />
<path id="s6-line" d="M0 500 L80 488 L160 492 L240 462 L320 450 L400 404 L480 380 L560 318 L640 270 L720 196 L820 90" fill="none" stroke="#5cffb0" stroke-width="5" stroke-linejoin="round" stroke-linecap="round" />
<circle id="s6-dot" cx="820" cy="90" r="12" fill="#5cffb0" />
</svg>
</section>
<!-- S7 — аутро -->
<section id="s7" class="clip scene" data-start="44" data-duration="6" data-track-index="1">
<div id="s7-logo">SIMBIOT <span>HARNESS</span></div>
<div id="s7-term">
<div id="s7-term-bar"><i style="background:#ff5f57"></i><i style="background:#febc2e"></i><i style="background:#28c840"></i></div>
<div id="s7-cmd" class="mono"><span class="p">$</span></div>
</div>
<div id="s7-foot">Кооператив 42 · <b>cil.by</b></div>
</section>
<audio id="bgm" src="assets/bgm/bed.wav" data-start="0" data-duration="50" data-track-index="3" data-volume="0.85"></audio>
<!-- HUD поверх всего -->
<div id="hud" class="clip" data-start="0" data-duration="50" data-track-index="2">
<div class="hud-row mono" id="hud-top"><div><span class="hud-dot" id="hud-dot"></span>SIMBIOT · LIVE</div><div id="hud-seq">EVENT #40211</div></div>
<div class="hud-row mono" id="hud-bot"><div>КООПЕРАТИВ 42</div><div class="hud-lv"><span><b>sec</b></span><span>min</span><span>hour</span><span>day</span></div></div>
</div>
</div>
<script>
// ---- куб 4×4×4: x = круг доверия, y = такт, z = глубина памяти
const cube = document.getElementById("s4-cube");
const circleColors = ["#5cffb0", "#8b7cff", "#ffb84d", "#ff6b8b"];
const STEP = 124;
for (let x = 0; x < 4; x++)
for (let y = 0; y < 4; y++)
for (let z = 0; z < 4; z++) {
const c = document.createElement("div");
c.className = "cell c" + x;
c.dataset.x = x; c.dataset.y = y; c.dataset.z = z;
const a = 0.16 + z * 0.1;
c.style.background = circleColors[x] + Math.round(a * 255).toString(16).padStart(2, "0");
c.style.borderColor = circleColors[x];
cube.appendChild(c);
}
// ---- набор команды по символам (seek-safe: только opacity)
const cmd = document.getElementById("s7-cmd");
const text = "curl -fsSL https://raw.cil.by/simbiot/install.sh | bash";
for (const ch of text) {
const s = document.createElement("span");
s.className = "c";
s.textContent = ch;
cmd.appendChild(s);
}
const caret = document.createElement("span");
caret.id = "s7-caret";
cmd.appendChild(caret);
const tl = gsap.timeline({ paused: true });
// ---------- фон: медленный дрейф ----------
tl.fromTo("#bg-grid", { x: 0, y: 0 }, { x: 80, y: 80, duration: 50, ease: "none" }, 0);
tl.fromTo("#bg-glow-a", { x: 0, y: 0 }, { x: 500, y: 260, duration: 50, ease: "sine.inOut" }, 0);
tl.fromTo("#bg-glow-b", { x: 0, y: 0 }, { x: -520, y: -200, duration: 50, ease: "sine.inOut" }, 0);
// ---------- HUD ----------
tl.fromTo("#hud-top, #hud-bot", { opacity: 0 }, { opacity: 1, duration: 1, ease: "power2.out" }, 2.4);
tl.fromTo("#hud-dot", { scale: 1 }, { scale: 0.4, duration: 0.5, yoyo: true, repeat: 47, ease: "sine.inOut" }, 2.4);
const seq = { n: 40211 };
const seqEl = document.getElementById("hud-seq");
tl.fromTo(seq, { n: 40211 }, { n: 40987, duration: 47, ease: "none", onUpdate: () => { seqEl.textContent = "EVENT #" + Math.round(seq.n); } }, 2.4);
// ---------- S1 ----------
const ecg = document.getElementById("s1-ecg-path");
const ecgLen = ecg.getTotalLength();
tl.fromTo(ecg, { strokeDasharray: ecgLen, strokeDashoffset: ecgLen }, { strokeDashoffset: 0, duration: 1.5, ease: "power2.inOut" }, 0.1);
tl.to("#s1-ecg", { opacity: 0.12, duration: 0.8, ease: "power2.out" }, 1.4);
tl.fromTo("#s1-title .ch", { yPercent: 110 }, { yPercent: 0, duration: 0.7, stagger: 0.04, ease: "power4.out" }, 1.3);
tl.fromTo("#s1-tag", { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, 2.1);
tl.fromTo("#s1-stack span", { opacity: 0, y: 12 }, { opacity: 1, y: 0, duration: 0.4, stagger: 0.06, ease: "power2.out" }, 2.6);
tl.to("#s1-in", { opacity: 0, scale: 1.04, duration: 0.5, ease: "power2.in" }, 4.7);
// ---------- S2 ----------
const S2 = 5.2;
tl.fromTo("#s2-k", { opacity: 0, y: 16 }, { opacity: 1, y: 0, duration: 0.5, ease: "power3.out" }, S2 + 0.1);
tl.fromTo("#s2-h", { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, S2 + 0.2);
tl.fromTo(".lvl", { opacity: 0, x: -60 }, { opacity: 1, x: 0, duration: 0.6, stagger: 0.14, ease: "power3.out" }, S2 + 0.7);
tl.fromTo(".lvl-fill", { scaleX: 0 }, { scaleX: 1, duration: 1.1, stagger: 0.14, ease: "power3.inOut" }, S2 + 1.0);
// пульсы бегут по полосам с разной частотой — разный ритм уровней
const pulseDefs = [["#p-sec", 0.35], ["#p-min", 0.9], ["#p-hour", 1.8], ["#p-day", 3.6]];
const runFrom = S2 + 1.6, runFor = 6.0;
for (const [sel, period] of pulseDefs) {
const reps = Math.max(0, Math.floor(runFor / period) - 1);
const travel = document.querySelector(sel).parentElement.offsetWidth - 22;
tl.fromTo(sel, { x: 0, opacity: 1 }, { x: travel, opacity: 0.2, duration: period, repeat: reps, ease: "none" }, runFrom);
}
tl.fromTo("#s2-foot", { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, S2 + 2.6);
tl.fromTo(".arrow-up", { y: 8 }, { y: -6, duration: 0.6, yoyo: true, repeat: 6, ease: "sine.inOut" }, S2 + 2.8);
tl.to("#s2-in", { opacity: 0, y: -40, duration: 0.5, ease: "power2.in" }, S2 + 7.5);
// ---------- S3 ----------
const S3 = 13.2;
tl.fromTo("#s3-k", { opacity: 0, y: 16 }, { opacity: 1, y: 0, duration: 0.5, ease: "power3.out" }, S3 + 0.1);
tl.fromTo("#s3-h", { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, S3 + 0.2);
tl.fromTo("#s3-sub", { opacity: 0 }, { opacity: 1, duration: 0.6 }, S3 + 0.7);
tl.fromTo("#s3-track", { x: 1920 }, { x: -1520, duration: 7.4, ease: "power1.inOut" }, S3 + 0.6);
tl.fromTo(".ev", { opacity: 0.25, scale: 0.92 }, { opacity: 1, scale: 1, duration: 0.5, stagger: 0.55, ease: "power2.out" }, S3 + 1.2);
tl.fromTo("#s3-verify", { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, S3 + 4.2);
tl.to("#s3-in", { opacity: 0, duration: 0.5, ease: "power2.in" }, S3 + 7.9);
// ---------- S4 ----------
const S4 = 21.6;
tl.fromTo("#s4-k", { opacity: 0, y: 16 }, { opacity: 1, y: 0, duration: 0.5, ease: "power3.out" }, S4 + 0.1);
tl.fromTo("#s4-h", { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, S4 + 0.2);
tl.fromTo(".axis", { opacity: 0, x: -40 }, { opacity: 1, x: 0, duration: 0.5, stagger: 0.35, ease: "power3.out" }, S4 + 1.6);
tl.fromTo("#s4-punch", { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, S4 + 3.4);
tl.fromTo("#s4-label", { opacity: 0 }, { opacity: 1, duration: 0.6 }, S4 + 5.2);
// клетки собираются из «взрыва» в куб
const cells = gsap.utils.toArray(".cell");
cells.forEach((c, i) => {
const x = (+c.dataset.x - 1.5) * STEP, y = (+c.dataset.y - 1.5) * STEP, z = (+c.dataset.z - 1.5) * STEP;
const k = 3.2;
tl.fromTo(c, { x: x * k, y: y * k, z: z * k, opacity: 0 }, { x, y, z, opacity: 1, duration: 1.3, ease: "power3.out" }, S4 + 0.4 + (i % 16) * 0.035);
});
tl.fromTo("#s4-cube", { rotationX: -30, rotationY: -50, rotationZ: 0 }, { rotationX: -18, rotationY: 38, rotationZ: 0, duration: 8.6, ease: "sine.inOut" }, S4 + 0.2);
// подсветка: срез круга «владелец», затем «остальные»
tl.to(".cell:not(.c0)", { opacity: 0.18, duration: 0.5 }, S4 + 4.2);
tl.to(".cell:not(.c0)", { opacity: 1, duration: 0.5 }, S4 + 5.6);
tl.to(".cell:not(.c3)", { opacity: 0.18, duration: 0.5 }, S4 + 6.1);
tl.to(".cell:not(.c3)", { opacity: 1, duration: 0.5 }, S4 + 7.6);
tl.to("#s4-text, #s4-stage", { opacity: 0, duration: 0.5, ease: "power2.in" }, S4 + 8.5);
// ---------- S5 ----------
const S5 = 30.6;
tl.fromTo("#s5-title", { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, S5 + 0.1);
tl.fromTo("#s5-core", { scale: 0.4, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.8, ease: "back.out(1.6)" }, S5 + 0.3);
tl.fromTo("#s5-ring", { scale: 0.6, opacity: 0, rotation: 0 }, { scale: 1, opacity: 1, rotation: 90, duration: 6.4, ease: "power1.out" }, S5 + 0.4);
document.querySelectorAll(".s5l").forEach((p) => { const L = p.getTotalLength(); p.style.strokeDasharray = L; p.style.strokeDashoffset = L; });
tl.to(".s5l", { strokeDashoffset: 0, duration: 0.6, stagger: 0.18, ease: "power2.out" }, S5 + 0.9);
tl.fromTo(".node", { opacity: 0, scale: 0.85 }, { opacity: 1, scale: 1, duration: 0.55, stagger: 0.18, ease: "back.out(1.4)" }, S5 + 1.2);
tl.fromTo("#s5-core", { boxShadow: "0 0 0px rgba(92,255,176,0)" }, { boxShadow: "0 0 90px rgba(92,255,176,0.55)", duration: 0.8, yoyo: true, repeat: 4, ease: "sine.inOut" }, S5 + 1.4);
tl.to("#s5-stage", { opacity: 0, duration: 0.5, ease: "power2.in" }, S5 + 6.5);
// ---------- S6 ----------
const S6 = 37.6;
tl.fromTo("#s6-k", { opacity: 0, y: 16 }, { opacity: 1, y: 0, duration: 0.5, ease: "power3.out" }, S6 + 0.1);
tl.fromTo("#s6-h", { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, S6 + 0.2);
const line = document.getElementById("s6-line");
const lineLen = line.getTotalLength();
tl.fromTo(line, { strokeDasharray: lineLen, strokeDashoffset: lineLen }, { strokeDashoffset: 0, duration: 2.4, ease: "power2.inOut" }, S6 + 0.6);
tl.fromTo("#s6-area", { opacity: 0 }, { opacity: 1, duration: 1.6 }, S6 + 1.4);
tl.fromTo("#s6-dot", { scale: 0, transformOrigin: "50% 50%" }, { scale: 1, duration: 0.5, ease: "back.out(2)" }, S6 + 2.9);
tl.fromTo("#s6-num, #s6-num-cap", { opacity: 0 }, { opacity: 1, duration: 0.4 }, S6 + 0.8);
const val = { v: 0 };
const valEl = document.getElementById("s6-val");
tl.fromTo(val, { v: 0 }, { v: 1, duration: 2.2, ease: "power2.out", onUpdate: () => { valEl.textContent = "+" + val.v.toFixed(1).replace(".0", "") + "%"; } }, S6 + 0.8);
tl.fromTo("#s6-q", { opacity: 0, x: -30 }, { opacity: 1, x: 0, duration: 0.6, ease: "power3.out" }, S6 + 2.8);
tl.to("#s6-left, #s6-chart", { opacity: 0, duration: 0.5, ease: "power2.in" }, S6 + 5.9);
// ---------- S7 ----------
const S7 = 44;
tl.fromTo("#s7-logo", { opacity: 0, scale: 0.92 }, { opacity: 1, scale: 1, duration: 1, ease: "power3.out" }, S7 + 0.1);
tl.fromTo("#s7-term", { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, S7 + 0.7);
tl.to("#s7-cmd .c", { opacity: 1, duration: 0.01, stagger: 0.035 }, S7 + 1.2);
tl.fromTo("#s7-caret", { opacity: 1 }, { opacity: 0, duration: 0.4, yoyo: true, repeat: 10, ease: "steps(1)" }, S7 + 1.2);
tl.fromTo("#s7-foot", { opacity: 0 }, { opacity: 1, duration: 0.8 }, S7 + 3.4);
window.__timelines = window.__timelines || {};
window.__timelines["main"] = tl;
</script>
</body>
</html>