Ролик Shkor Labs для сайта (video/shkor-labs-site): 7 сцен по shkor.com — метод, ритм, доверие, лабы, тарифы; hyperframes 1920×1080, 77 с, голос Kokoro am_michael; тайминги анимаций по фразам озвучки; произношение «Shkor» одним слогом (espeak читал «эс-эйч-кор»)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
31383403a1
commit
a96ead77db
13 changed files with 1157 additions and 0 deletions
5
video/shkor-labs-site/.gitignore
vendored
Normal file
5
video/shkor-labs-site/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.work/
|
||||
renders/
|
||||
.hyperframes/
|
||||
assets/vo/
|
||||
assets/bgm/
|
||||
109
video/shkor-labs-site/CLAUDE.md
Normal file
109
video/shkor-labs-site/CLAUDE.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# HyperFrames Composition Project
|
||||
|
||||
## Skills — USE THESE FIRST
|
||||
|
||||
**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
|
||||
|
||||
**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
|
||||
|
||||
- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
|
||||
- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
|
||||
- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
|
||||
- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
|
||||
- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
|
||||
- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
|
||||
- `/music-to-video` — a **music track** (audio file, video to pull audio from, or one generated from a mood brief) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
|
||||
- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
|
||||
- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
|
||||
|
||||
**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
|
||||
|
||||
The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-audio`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
|
||||
|
||||
**Changing how real footage or images look or reveal?** Load `/media-use` and read its `references/media-treatments.md` before editing, even when the request only says dark, flat, boring, retro, private, or “make the reveal cooler.” It governs how footage is treated, never whether media may be used. Use canonical media treatments and seek-safe motion; do not improvise equivalent CSS/SVG filters or overlays.
|
||||
|
||||
> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
|
||||
|
||||
> **Using a HyperFrames plugin?** Load skills from that installed bundle and follow
|
||||
> its `hyperframes/references/plugin-installation.md` execution rules. Update via
|
||||
> the plugin manager, not the standalone commands below.
|
||||
>
|
||||
> **Standalone skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
|
||||
> the specific skill you need (the `/hyperframes` router does this automatically before
|
||||
> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
|
||||
> everything already installed — neither pulls the full set. Restart the agent session so
|
||||
> newly installed skills load.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
npm run dev # human-operated foreground preview (blocks until stopped)
|
||||
npx hyperframes preview --background # agent-safe persistent Studio preview
|
||||
npx hyperframes preview --status # verify the persistent preview is listening
|
||||
npx hyperframes preview --stop # stop it when review is finished
|
||||
npm run check # lint + runtime + layout + motion + contrast (one command)
|
||||
npm run render # render to MP4
|
||||
npm run publish # publish and get a shareable link
|
||||
npx hyperframes lint --verbose # include info-level findings
|
||||
npx hyperframes lint --json # machine-readable output for CI
|
||||
npx hyperframes docs <topic> # reference docs in terminal
|
||||
```
|
||||
|
||||
> **Agents must use `npx hyperframes preview --background` for Studio handoff.** Do not rely
|
||||
> on a shell/tool `run_in_background` wrapper around `npm run dev`: that foreground process
|
||||
> remains owned by the invoking session and can disappear while the browser stays open,
|
||||
> leaving refreshes at `ERR_CONNECTION_TIMED_OUT`. Verify with `preview --status`, keep it
|
||||
> alive through review, and stop it explicitly with `preview --stop` afterward.
|
||||
|
||||
> **Back from the desktop app.** Once this project was opened in the HyperFrames desktop app, run `npx hyperframes catch-up` before your next change here: it lists what the person asked Framey in the app and which files changed since.
|
||||
|
||||
> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
|
||||
|
||||
## Documentation
|
||||
|
||||
**For quick reference**, use the local CLI docs command (no network required):
|
||||
|
||||
```bash
|
||||
npx hyperframes docs <topic>
|
||||
```
|
||||
|
||||
Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
|
||||
|
||||
**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
|
||||
|
||||
```
|
||||
https://hyperframes.heygen.com/llms.txt
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `index.html` — main composition (root timeline)
|
||||
- `compositions/` — sub-compositions referenced via `data-composition-src`
|
||||
- `meta.json` — project metadata (id, name)
|
||||
- `transcript.json` — whisper word-level transcript (if generated)
|
||||
|
||||
## Linting — ALWAYS RUN AFTER CHANGES
|
||||
|
||||
After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
|
||||
|
||||
```bash
|
||||
npm run check
|
||||
```
|
||||
|
||||
Fix all errors before presenting the result. Warnings should be reviewed before rendering.
|
||||
|
||||
## Key Rules
|
||||
|
||||
1. Every timed element needs `data-start` and a duration. `data-start` is what marks it as timed; `data-track-index` is an optional Studio display lane the render never reads
|
||||
2. Give timed visual elements `class="clip"`. The framework keys visibility off `data-start`, not the class, but the shared `.clip` CSS is what gives a scene its full-frame box, and `lint` warns without it
|
||||
3. Register one paused root timeline per composition on `window.__timelines`:
|
||||
```js
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["composition-id"] = gsap.timeline({ paused: true });
|
||||
```
|
||||
Scene timelines manually added to this root must not be paused. A paused
|
||||
child does not advance when the root is seeked. The runtime activates
|
||||
registered composition siblings, not arbitrary nested scene timelines.
|
||||
4. A video with sound keeps it on the `<video>` (`data-has-audio="true"`, no `muted`). Use a separate `<audio>` for music, voiceover, replacement audio, J/L cuts, or audio detached in Studio. Silent footage and b-roll: `muted`.
|
||||
5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
|
||||
6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
|
||||
127
video/shkor-labs-site/build.py
Normal file
127
video/shkor-labs-site/build.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Ролик Shkor Labs для сайта (shkor.com, секция Film): сценарий → озвучка Kokoro → hyperframes → MP4.
|
||||
|
||||
venv/bin/python video/shkor-labs-site/build.py # озвучка (с кэшем) + index.html + check + рендер
|
||||
venv/bin/python video/shkor-labs-site/build.py --no-render
|
||||
|
||||
Голос и обработка — как у ежедневных роликов (video/daily/daily.py: tts по предложениям, am_michael ×1.1,
|
||||
loudnorm), музыка — подложка из video/daily/music. Длины сцен и появление элементов считаются по
|
||||
таймингам фраз (template.tpl: at(сцена, фраза, доля)), поэтому правка текста не ломает синхронизацию.
|
||||
Факты в тексте — только то, что есть на shkor.com (метод, ритмы, доверие, лабы, тарифы).
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO = os.path.abspath(os.path.join(HERE, "..", ".."))
|
||||
sys.path.insert(0, os.path.join(REPO, "video", "daily"))
|
||||
import daily # noqa: E402 (tts, bgm_bed, sh, HF, VOICE, SPEED)
|
||||
|
||||
OUT = os.path.join(REPO, "out", "shkor-labs-film-en.mp4")
|
||||
THEME = "gold" # музыка как у enterprise-EN, который понравился Alex
|
||||
|
||||
SCENES = [
|
||||
"Every business runs on routine that nobody has time for. Shkor Labs builds the autopilot for it.",
|
||||
"It starts with a mirror. Messages, tasks, calls and payments become one signed stream of events, "
|
||||
"a living twin of the company. Every change is rehearsed on the twin before it touches a customer.",
|
||||
"Then the routine goes to an agent that runs on a heartbeat. "
|
||||
"Every second, minute, hour and day: reflexes, triage, execution and planning.",
|
||||
"And you can trust it with real work. Every step is signed. "
|
||||
"Its rights come from verified identity, not from a message. "
|
||||
"When it isn't sure, it hands the decision to a person, with the full story.",
|
||||
"We don't sell what we don't run. Shkor Labs is a network of real businesses inside Cooperative 42, "
|
||||
"each one a founder plus AI agents, testing the autopilot every day.",
|
||||
"Build it yourself with Autopilot: your own server, an agent, and a workspace with OpenCode and Claude Code, "
|
||||
"for ninety-nine dollars a month. Or build it with us in the Lab. "
|
||||
"And builders with traction get paid roles in the studio.",
|
||||
"Shkor Labs. Autopilot for any business. Start at shkor dot com.",
|
||||
]
|
||||
# произношение для синтезатора (текст сценария не меняется): espeak читает «Shkor» как
|
||||
# «эс-эйч-кор» (ˌɛsˈeɪtʃkˈɔːɹ), а «Schkor» — как надо, одним слогом (ʃkˈɔːɹ)
|
||||
PRONOUNCE = {r"\bShkor\b": "Schkor", r"\bshkor\b": "schkor"}
|
||||
# сколько фраз ждёт шаблон в каждой сцене (at(i, k) берёт k-ю фразу)
|
||||
EXPECT = [2, 3, 2, 4, 2, 3, 3]
|
||||
|
||||
|
||||
def voice(i, text, work):
|
||||
"""Озвучка сцены с кэшем по тексту/голосу: неизменённые сцены не синтезируются заново."""
|
||||
for pat, rep in PRONOUNCE.items():
|
||||
text = re.sub(pat, rep, text)
|
||||
wav = os.path.join(HERE, "assets", "vo", f"v{i + 1}.wav")
|
||||
key = hashlib.sha256(f"{daily.VOICE}|{daily.SPEED}|{text}".encode()).hexdigest()[:16]
|
||||
meta = wav + ".json"
|
||||
if os.path.exists(wav) and os.path.exists(meta):
|
||||
m = json.load(open(meta))
|
||||
if m.get("key") == key:
|
||||
return m["dur"], m["sents"]
|
||||
dur, sents = daily.tts(text, wav, work)
|
||||
json.dump({"key": key, "dur": dur, "sents": sents}, open(meta, "w"))
|
||||
return dur, sents
|
||||
|
||||
|
||||
def build():
|
||||
work = os.path.join(HERE, ".work")
|
||||
os.makedirs(work, exist_ok=True)
|
||||
os.makedirs(os.path.join(HERE, "assets", "vo"), exist_ok=True)
|
||||
os.makedirs(os.path.join(HERE, "assets", "bgm"), exist_ok=True)
|
||||
timing, t = [], 0.0
|
||||
for i, text in enumerate(SCENES):
|
||||
dur, sents = voice(i, text, work)
|
||||
if len(sents) != EXPECT[i]:
|
||||
raise SystemExit(f"сцена {i + 1}: {len(sents)} фраз, шаблон ждёт {EXPECT[i]} — поправь текст или EXPECT")
|
||||
lead, tail = 0.45, (2.8 if i == len(SCENES) - 1 else 0.75)
|
||||
vo = t + lead
|
||||
timing.append({"start": round(t, 2), "dur": round(lead + dur + tail, 2), "vo": round(vo, 2), "vo_dur": round(dur, 2),
|
||||
"sents": [{"t0": round(vo + x["t0"], 2), "t1": round(vo + x["t1"], 2)} for x in sents]})
|
||||
daily.log(f"scene {i + 1}: vo {dur:.1f}s, {len(sents)} sentences")
|
||||
t += lead + dur + tail
|
||||
total = round(t, 2)
|
||||
daily.bgm_bed(total, os.path.join(HERE, "assets", "bgm", "bed.wav"), THEME)
|
||||
audio = [f' <audio id="bgm" src="assets/bgm/bed.wav" data-start="0" data-duration="{total}" data-track-index="3" data-volume="0.14"></audio>']
|
||||
for i, tm in enumerate(timing):
|
||||
audio.append(f' <audio id="vo{i + 1}" src="assets/vo/v{i + 1}.wav" data-start="{tm["vo"]}" '
|
||||
f'data-duration="{tm["vo_dur"]}" data-track-index="4" data-volume="1"></audio>')
|
||||
html = open(os.path.join(HERE, "template.tpl")).read()
|
||||
for i, tm in enumerate(timing):
|
||||
html = html.replace(f"@S{i + 1}_START", str(tm["start"])).replace(f"@S{i + 1}_DUR", str(tm["dur"]))
|
||||
html = html.replace("@AUDIO", "\n".join(audio)).replace("@TIMING", json.dumps(timing)).replace("@TOTAL", str(total))
|
||||
open(os.path.join(HERE, "index.html"), "w").write(html)
|
||||
json.dump({"total": total, "scenes": timing}, open(os.path.join(work, "timing.json"), "w"), indent=1)
|
||||
daily.log(f"index.html: {total:.1f}s")
|
||||
return total
|
||||
|
||||
|
||||
def check():
|
||||
out = subprocess.run(daily.HF + ["check", "--json"], cwd=HERE, capture_output=True, text=True, timeout=900,
|
||||
stdin=subprocess.DEVNULL).stdout
|
||||
rep = json.loads(out[out.index("{"):])
|
||||
summary = {s: {"errors": (rep.get(s) or {}).get("errorCount", 0), "warnings": (rep.get(s) or {}).get("warningCount", 0)}
|
||||
for s in ("lint", "runtime", "layout", "motion", "contrast")}
|
||||
findings = []
|
||||
for s in ("lint", "runtime", "layout", "motion", "contrast"):
|
||||
for f in (rep.get(s) or {}).get("findings", [])[:12]:
|
||||
findings.append(f"{s}: {str(f.get('severity') or '')} {str(f.get('code') or f.get('rule') or '')} "
|
||||
f"{str(f.get('message') or '')[:170]}")
|
||||
return summary, findings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--no-render", action="store_true")
|
||||
args = ap.parse_args()
|
||||
build()
|
||||
summary, findings = check()
|
||||
print(json.dumps(summary))
|
||||
print("\n".join(findings))
|
||||
if any(v["errors"] for v in summary.values()):
|
||||
raise SystemExit("hyperframes check: есть ошибки — рендер не запускаю")
|
||||
if not args.no_render:
|
||||
os.makedirs(os.path.dirname(OUT), exist_ok=True)
|
||||
daily.render(HERE, OUT)
|
||||
daily.log(f"render: {OUT}")
|
||||
BIN
video/shkor-labs-site/fonts/inter-400-latin.woff2
Normal file
BIN
video/shkor-labs-site/fonts/inter-400-latin.woff2
Normal file
Binary file not shown.
BIN
video/shkor-labs-site/fonts/inter-600-latin.woff2
Normal file
BIN
video/shkor-labs-site/fonts/inter-600-latin.woff2
Normal file
Binary file not shown.
BIN
video/shkor-labs-site/fonts/jetbrains-mono-400-latin.woff2
Normal file
BIN
video/shkor-labs-site/fonts/jetbrains-mono-400-latin.woff2
Normal file
Binary file not shown.
BIN
video/shkor-labs-site/fonts/space-grotesk-latin.woff2
Normal file
BIN
video/shkor-labs-site/fonts/space-grotesk-latin.woff2
Normal file
Binary file not shown.
11
video/shkor-labs-site/gsap.min.js
vendored
Normal file
11
video/shkor-labs-site/gsap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
video/shkor-labs-site/hyperframes.json
Normal file
12
video/shkor-labs-site/hyperframes.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "https://hyperframes.heygen.com/schema/hyperframes.json",
|
||||
"registry": "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry",
|
||||
"paths": {
|
||||
"blocks": "compositions",
|
||||
"components": "compositions/components",
|
||||
"assets": "assets"
|
||||
},
|
||||
"media": {
|
||||
"autoProxy": true
|
||||
}
|
||||
}
|
||||
442
video/shkor-labs-site/index.html
Normal file
442
video/shkor-labs-site/index.html
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<title>Shkor Labs — autopilot for any business</title>
|
||||
<script src="./gsap.min.js"></script>
|
||||
<style>
|
||||
@font-face { font-family: "Space Grotesk"; font-weight: 300 700; src: url("fonts/space-grotesk-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-weight: 400; src: url("fonts/inter-400-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-weight: 600; src: url("fonts/inter-600-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "JetBrains Mono"; font-weight: 400; src: url("fonts/jetbrains-mono-400-latin.woff2") format("woff2"); }
|
||||
|
||||
/* палитра shkor.com v2 */
|
||||
:root {
|
||||
--bg: #050506; --bg1: #0b0c0f; --bg2: #111318;
|
||||
--fg: #f2f3f5; --fg2: #b4b8c2; --fg3: #80869a;
|
||||
--acid: #c6ff4d; --acid-dim: rgba(198, 255, 77, 0.12); --cyan: #5ce1e6;
|
||||
--line: rgba(255, 255, 255, 0.08); --line2: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { width: 1920px; height: 1080px; overflow: hidden; background: var(--bg); }
|
||||
body { color: var(--fg); font-family: "Inter", sans-serif; -webkit-font-smoothing: antialiased; }
|
||||
#root { position: relative; width: 100%; height: 100%; overflow: hidden; }
|
||||
.clip { position: absolute; inset: 0; }
|
||||
.mono { font-family: "JetBrains Mono", monospace; }
|
||||
.hl { color: var(--acid); }
|
||||
|
||||
/* фон */
|
||||
#bg { background: radial-gradient(1300px 800px at 82% -10%, rgba(198, 255, 77, 0.07), transparent 60%),
|
||||
radial-gradient(1000px 700px at -10% 110%, rgba(92, 225, 230, 0.06), transparent 60%), var(--bg); }
|
||||
#bg-grid { position: absolute; inset: -160px;
|
||||
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
|
||||
background-size: 80px 80px; opacity: 0.55;
|
||||
mask-image: radial-gradient(ellipse 70% 60% at 60% 40%, #000 0%, transparent 75%); }
|
||||
#bg-glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; left: 1100px; top: -520px; background: var(--acid); filter: blur(200px); opacity: 0.07; }
|
||||
|
||||
/* HUD */
|
||||
.hud-row { position: absolute; left: 96px; right: 96px; display: flex; justify-content: space-between; align-items: center;
|
||||
font-size: 18px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg3); }
|
||||
#hud-top { top: 44px; }
|
||||
#hud-top .brand { display: flex; align-items: center; gap: 14px; color: var(--fg2); }
|
||||
#hud-top .brand svg { width: 30px; height: 30px; }
|
||||
#hud-bot { bottom: 54px; }
|
||||
.chap { display: flex; gap: 34px; }
|
||||
.chap span { color: #7d818d; }
|
||||
#hud-prog { position: absolute; left: 96px; right: 96px; bottom: 34px; height: 3px; background: rgba(255, 255, 255, 0.06); border-radius: 2px; }
|
||||
#hud-prog-fill { width: 100%; height: 3px; background: var(--acid); transform-origin: left center; border-radius: 2px; }
|
||||
|
||||
/* общие элементы сцен */
|
||||
.in { position: absolute; inset: 0; padding: 150px 160px 140px; display: flex; flex-direction: column; justify-content: center; }
|
||||
.k { display: flex; align-items: center; gap: 16px; font: 400 22px/1 "JetBrains Mono", monospace; letter-spacing: 0.18em; text-transform: uppercase; color: var(--acid); margin-bottom: 26px; }
|
||||
.k::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--acid); box-shadow: 0 0 18px var(--acid); }
|
||||
h2 { font: 700 84px/1.02 "Space Grotesk", sans-serif; letter-spacing: -0.03em; max-width: 1600px; }
|
||||
.sub { margin-top: 22px; font-size: 30px; line-height: 1.45; color: var(--fg2); max-width: 1300px; }
|
||||
.card { position: relative; border-radius: 26px; background: linear-gradient(180deg, var(--bg2), var(--bg1)); box-shadow: inset 0 0 0 1px var(--line2); padding: 38px 36px; overflow: hidden; }
|
||||
.card h3 { font: 600 38px/1.1 "Space Grotesk", sans-serif; letter-spacing: -0.01em; }
|
||||
.card p { margin-top: 14px; font-size: 24px; line-height: 1.45; color: var(--fg3); }
|
||||
.card.on { box-shadow: inset 0 0 0 1px rgba(198, 255, 77, 0.55), 0 30px 80px -30px rgba(198, 255, 77, 0.35); }
|
||||
.ghost { position: absolute; top: 26px; right: 30px; font: 700 76px/1 "Space Grotesk", sans-serif; letter-spacing: -0.04em; color: #111318; -webkit-text-stroke: 1px rgba(255, 255, 255, 0.16); }
|
||||
.ico { width: 52px; height: 52px; padding: 12px; border-radius: 14px; color: var(--acid); background: var(--acid-dim); margin-bottom: 26px; }
|
||||
.ico svg { width: 28px; height: 28px; display: block; }
|
||||
|
||||
/* S1 — крючок */
|
||||
#s1-in { padding-right: 860px; }
|
||||
#s1-a { font: 500 54px/1.2 "Space Grotesk", sans-serif; color: var(--fg2); letter-spacing: -0.01em; }
|
||||
#s1-h { margin-top: 34px; font: 700 132px/0.98 "Space Grotesk", sans-serif; letter-spacing: -0.035em; }
|
||||
#s1-h em { font-style: normal; color: var(--acid); }
|
||||
#s1-by { margin-top: 44px; font-size: 22px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg3); }
|
||||
#s1-ring { position: absolute; right: 150px; top: 50%; width: 620px; height: 620px; margin-top: -310px; }
|
||||
#s1-ring .rip { position: absolute; inset: 0; border: 2px solid rgba(198, 255, 77, 0.35); border-radius: 50%; }
|
||||
|
||||
/* S2 — метод */
|
||||
.cards3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 56px; }
|
||||
.cards3 .card { height: 420px; }
|
||||
.ev { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.evl { display: flex; justify-content: space-between; align-items: center; height: 44px; padding: 0 16px; border-radius: 10px; background: rgba(255, 255, 255, 0.03); box-shadow: inset 0 0 0 1px var(--line); font-size: 18px; color: var(--fg2); }
|
||||
.evl b { font-weight: 400; color: var(--acid); }
|
||||
.flow { margin-top: 26px; display: flex; align-items: center; gap: 14px; font-size: 18px; }
|
||||
.pill { padding: 10px 16px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line2); color: var(--fg2); }
|
||||
.pill.ok { color: #0a0d02; background: var(--acid); box-shadow: none; }
|
||||
.pill.up { color: var(--cyan); box-shadow: inset 0 0 0 1px rgba(92, 225, 230, 0.5); }
|
||||
.arrow { color: var(--fg3); }
|
||||
|
||||
/* S3 — ритм */
|
||||
#s3-in { padding-right: 900px; }
|
||||
.ticks { margin-top: 48px; display: flex; flex-direction: column; gap: 14px; width: 820px; }
|
||||
.tick { display: grid; grid-template-columns: 96px 210px 1fr; align-items: center; height: 76px; padding: 0 22px; border-radius: 14px; background: rgba(255, 255, 255, 0.025); box-shadow: inset 0 0 0 1px var(--line); font-size: 24px; }
|
||||
.tick .tg { justify-self: start; padding: 6px 14px; border-radius: 9px; background: var(--acid); color: #0a0d02; font: 400 20px "JetBrains Mono", monospace; }
|
||||
.tick b { font: 600 28px "Space Grotesk", sans-serif; }
|
||||
.tick span:last-child { color: var(--fg3); }
|
||||
#s3-orbit { position: absolute; right: 150px; top: 50%; width: 720px; height: 720px; margin-top: -360px; }
|
||||
.orb { position: absolute; border-radius: 50%; border: 2px dashed rgba(92, 225, 230, 0.45); }
|
||||
.orb.o1 { inset: 250px; border-color: rgba(198, 255, 77, 0.7); }
|
||||
.orb.o2 { inset: 170px; border-color: rgba(198, 255, 77, 0.5); }
|
||||
.orb.o3 { inset: 90px; }
|
||||
.orb.o4 { inset: 10px; border-color: rgba(92, 225, 230, 0.3); }
|
||||
#s3-core { position: absolute; left: 50%; top: 50%; width: 190px; height: 190px; margin: -95px 0 0 -95px; border-radius: 50%;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
background: radial-gradient(circle, rgba(198, 255, 77, 0.28), rgba(198, 255, 77, 0.03) 70%); box-shadow: inset 0 0 0 2px var(--acid); }
|
||||
#s3-core b { font: 700 30px "Space Grotesk", sans-serif; }
|
||||
#s3-core small { font: 400 15px "JetBrains Mono", monospace; letter-spacing: 0.1em; color: var(--fg3); margin-top: 4px; text-transform: uppercase; }
|
||||
.wave { position: absolute; left: 50%; top: 50%; width: 190px; height: 190px; margin: -95px 0 0 -95px; border-radius: 50%; border: 2px solid var(--acid); opacity: 0; }
|
||||
|
||||
/* S4 — доверие */
|
||||
.cards3.t .card { height: 470px; }
|
||||
.term { margin-top: 26px; padding: 22px 24px; border-radius: 16px; background: #020203; box-shadow: inset 0 0 0 1px var(--line2); font: 400 22px/1.7 "JetBrains Mono", monospace; color: var(--fg2); }
|
||||
.term .ok { color: var(--acid); }
|
||||
.circles { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.circ { display: flex; align-items: center; gap: 14px; font-size: 22px; color: var(--fg2); }
|
||||
.circ i { flex: 0 0 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; font: 400 17px "JetBrains Mono", monospace; font-style: normal; color: #0a0d02; background: var(--acid); }
|
||||
.circ:nth-child(2) i { background: rgba(198, 255, 77, 0.8); }
|
||||
.circ:nth-child(3) i { background: rgba(198, 255, 77, 0.62); }
|
||||
.circ:nth-child(4) i { background: rgba(255, 255, 255, 0.18); color: var(--fg); }
|
||||
.esc { margin-top: 26px; display: flex; flex-direction: column; gap: 12px; }
|
||||
.esc .pill { align-self: flex-start; font-size: 20px; }
|
||||
|
||||
/* S5 — лабы */
|
||||
#s5-grid { margin-top: 48px; display: grid; grid-template-columns: 1.35fr 1fr 1fr 1fr; grid-template-rows: 190px 190px; gap: 22px; }
|
||||
.lab { position: relative; padding: 26px 28px; border-radius: 22px; background: var(--bg1); box-shadow: inset 0 0 0 1px var(--line2); display: flex; flex-direction: column; justify-content: flex-end; }
|
||||
.lab .t { font: 400 16px "JetBrains Mono", monospace; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg3); position: absolute; top: 24px; left: 28px; }
|
||||
.lab .n { font: 600 34px/1.1 "Space Grotesk", sans-serif; }
|
||||
.lab .d { margin-top: 6px; font-size: 19px; line-height: 1.35; color: var(--fg3); }
|
||||
.lab.core { grid-row: span 2; background: radial-gradient(500px 360px at 0% 100%, rgba(198, 255, 77, 0.16), transparent 70%), var(--bg1); box-shadow: inset 0 0 0 1px rgba(198, 255, 77, 0.45); }
|
||||
.lab.core .t { color: var(--acid); }
|
||||
.lab.core .n { font-size: 64px; }
|
||||
.lab.core .d { font-size: 22px; color: var(--fg2); }
|
||||
|
||||
/* S6 — тарифы-лестница */
|
||||
#s6-cols { margin-top: 52px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line2); border-radius: 26px; overflow: hidden; box-shadow: 0 0 0 1px var(--line2); }
|
||||
.plan { position: relative; background: var(--bg); padding: 40px 36px 40px; height: 440px; display: flex; flex-direction: column; }
|
||||
.plan .pk { font: 400 18px/1 "JetBrains Mono", monospace; letter-spacing: 0.16em; text-transform: uppercase; color: var(--acid); margin-bottom: 14px; }
|
||||
.plan h3 { font: 600 40px/1.1 "Space Grotesk", sans-serif; }
|
||||
.plan .pp { margin-top: auto; padding-top: 24px; border-top: 1px solid var(--line); font: 600 36px/1.1 "Space Grotesk", sans-serif; }
|
||||
.plan .pp span { display: block; margin-top: 8px; font: 400 20px "Inter", sans-serif; color: var(--fg3); }
|
||||
.plan.p1 .pp { color: var(--acid); }
|
||||
.plan.p3 .pk, .plan.p3 h3, .plan.p3 .pp { color: var(--fg2); }
|
||||
.plan.p3 .pk { color: var(--fg3); }
|
||||
.plan.p3 .ico { color: var(--fg3); background: rgba(255, 255, 255, 0.05); }
|
||||
.plan .glow { position: absolute; inset: 0; background: radial-gradient(520px 320px at 0% 0%, rgba(198, 255, 77, 0.14), transparent 70%); opacity: 0; }
|
||||
|
||||
/* S7 — финал */
|
||||
#s7-in { align-items: center; text-align: center; }
|
||||
#s7-logo { width: 230px; height: 230px; }
|
||||
#s7-name { margin-top: 30px; font: 700 128px/1 "Space Grotesk", sans-serif; letter-spacing: -0.035em; }
|
||||
#s7-tag { margin-top: 22px; font: 600 52px/1.1 "Space Grotesk", sans-serif; color: var(--acid); }
|
||||
#s7-cta { margin-top: 54px; display: flex; gap: 18px; align-items: center; }
|
||||
#s7-cta .url { padding: 18px 30px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line2); font: 400 30px "JetBrains Mono", monospace; color: var(--fg); }
|
||||
#s7-cta .btn { padding: 18px 34px; border-radius: 999px; background: var(--acid); color: #0a0d02; font: 600 30px "Inter", sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" data-composition-id="main" data-start="0" data-duration="77.38" data-width="1920" data-height="1080">
|
||||
<div id="bg" class="clip" data-start="0" data-duration="77.38" data-track-index="0">
|
||||
<div id="bg-grid"></div>
|
||||
<div id="bg-glow"></div>
|
||||
</div>
|
||||
|
||||
<!-- S1: крючок -->
|
||||
<section id="s1" class="clip" data-start="0.0" data-duration="7.29" data-track-index="1">
|
||||
<div class="in" id="s1-in">
|
||||
<div id="s1-a">Every business runs on routine<br />nobody has time for.</div>
|
||||
<h1 id="s1-h">Autopilot<br />for <em>any</em> business.</h1>
|
||||
<p id="s1-by" class="mono">Shkor Labs · R&D for autonomous business</p>
|
||||
</div>
|
||||
<div id="s1-ring">
|
||||
<div class="rip" id="s1-rip1"></div><div class="rip" id="s1-rip2"></div>
|
||||
<svg class="logo" viewBox="0 0 200 200" width="620" height="620">
|
||||
<g class="spin" id="s1-spin"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="7" stroke-dasharray="20 27" stroke-linecap="round" /></g>
|
||||
<circle id="s1-dot" cx="100" cy="100" r="30" fill="#c6ff4d" />
|
||||
</svg>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S2: метод -->
|
||||
<section id="s2" class="clip" data-start="7.29" data-duration="12.77" data-track-index="1">
|
||||
<div class="in" id="s2-in">
|
||||
<p class="k" id="s2-k">01 — Method</p>
|
||||
<h2 id="s2-h">Mirror. Rehearse. <span class="hl">Autopilot.</span></h2>
|
||||
<div class="cards3">
|
||||
<div class="card" id="s2-c1">
|
||||
<span class="ghost">01</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3v18M5 7l7-4 7 4M5 17l7 4 7-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Mirror</h3>
|
||||
<div class="ev mono">
|
||||
<div class="evl">MessageReceived<b>signed</b></div>
|
||||
<div class="evl">TaskCreated<b>signed</b></div>
|
||||
<div class="evl">PaymentReceived<b>signed</b></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="s2-c2">
|
||||
<span class="ghost">02</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M4 12a8 8 0 1 0 2.3-5.6M4 4v4h4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Rehearse</h3>
|
||||
<p>Every change is tried on the twin and its real history first.</p>
|
||||
<div class="flow mono"><span class="pill">change</span><span class="arrow">→</span><span class="pill ok" id="s2-ok">safe</span><span class="pill up" id="s2-up">ask a person</span></div>
|
||||
</div>
|
||||
<div class="card" id="s2-c3">
|
||||
<span class="ghost">03</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M5 19 19 5M9 5h10v10" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Autopilot</h3>
|
||||
<p>The routine goes to an agent with real tools, and every action feeds back into the twin.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S3: ритм -->
|
||||
<section id="s3" class="clip" data-start="20.06" data-duration="9.31" data-track-index="1">
|
||||
<div class="in" id="s3-in">
|
||||
<p class="k" id="s3-k">02 — The autopilot</p>
|
||||
<h2 id="s3-h">Not a chatbot.<br /><span class="hl">A heartbeat.</span></h2>
|
||||
<div class="ticks">
|
||||
<div class="tick" id="tk1"><span class="tg">1s</span><b>Reflexes</b><span>telemetry, alerts</span></div>
|
||||
<div class="tick" id="tk2"><span class="tg">1m</span><b>Triage</b><span>inbox, routing, quick fixes</span></div>
|
||||
<div class="tick" id="tk3"><span class="tg">1h</span><b>Execution</b><span>tasks end to end</span></div>
|
||||
<div class="tick" id="tk4"><span class="tg">1d</span><b>Planning</b><span>the plan for tomorrow</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="s3-orbit">
|
||||
<div class="orb o4" id="ob4"></div><div class="orb o3" id="ob3"></div><div class="orb o2" id="ob2"></div><div class="orb o1" id="ob1"></div>
|
||||
<div class="wave" id="wv1"></div><div class="wave" id="wv2"></div><div class="wave" id="wv3"></div><div class="wave" id="wv4"></div>
|
||||
<div id="s3-core"><b>Autopilot</b><small>Simbiot core</small></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S4: доверие -->
|
||||
<section id="s4" class="clip" data-start="29.37" data-duration="12.36" data-track-index="1">
|
||||
<div class="in" id="s4-in">
|
||||
<p class="k" id="s4-k">03 — Trust</p>
|
||||
<h2 id="s4-h">Trusted with <span class="hl">real work.</span></h2>
|
||||
<div class="cards3 t">
|
||||
<div class="card" id="s4-t1">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3 4 6v6c0 4.5 3.4 8.3 8 9 4.6-.7 8-4.5 8-9V6l-8-3Z M9 12l2 2 4-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Every step signed</h3>
|
||||
<p>A tamper-evident log of everything it did, and why.</p>
|
||||
<div class="term"><div>$ simbiot verify</div><div class="ok" id="s4-ok">✓ chain intact</div></div>
|
||||
</div>
|
||||
<div class="card" id="s4-t2">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M15 7a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM5 21c0-3.9 3.1-7 7-7s7 3.1 7 7" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Rights from identity</h3>
|
||||
<p>Never from what a message says.</p>
|
||||
<div class="circles">
|
||||
<div class="circ"><i>1</i>Owner — full tools</div>
|
||||
<div class="circ"><i>2</i>Board — work, no secrets</div>
|
||||
<div class="circ"><i>3</i>Members — scoped</div>
|
||||
<div class="circ"><i>4</i>Everyone else — reply only</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="s4-t3">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 19V5M5 12l7-7 7 7" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Knows its limits</h3>
|
||||
<p>When it isn't sure, a person decides, with the full story attached.</p>
|
||||
<div class="esc mono">
|
||||
<span class="pill" id="s4-e1">agent · not sure</span>
|
||||
<span class="pill up" id="s4-e2">↑ person · decides</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S5: лабы -->
|
||||
<section id="s5" class="clip" data-start="41.73" data-duration="12.99" data-track-index="1">
|
||||
<div class="in" id="s5-in">
|
||||
<p class="k" id="s5-k">04 — The labs</p>
|
||||
<h2 id="s5-h">We don't sell what <span class="hl">we don't run.</span></h2>
|
||||
<p class="sub" id="s5-sub">Real businesses inside Cooperative 42 — each a founder plus AI agents.</p>
|
||||
<div id="s5-grid">
|
||||
<div class="lab core"><span class="t">Core · autopilot</span><div class="n">Simbiot</div><div class="d">The agent harness that runs the cooperative itself.</div></div>
|
||||
<div class="lab"><span class="t">Media</span><div class="n">ReelsUp</div></div>
|
||||
<div class="lab"><span class="t">Marketing</span><div class="n">Avatar</div></div>
|
||||
<div class="lab"><span class="t">Consulting</span><div class="n">Mainbeam</div></div>
|
||||
<div class="lab"><span class="t">Construction</span><div class="n">MalyarKa</div></div>
|
||||
<div class="lab"><span class="t">Fintech</span><div class="n">Vybirai</div></div>
|
||||
<div class="lab"><span class="t">+ more</span><div class="n">GroupSign · DEIP</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S6: тарифы -->
|
||||
<section id="s6" class="clip" data-start="54.72" data-duration="15.23" data-track-index="1">
|
||||
<div class="in" id="s6-in">
|
||||
<p class="k" id="s6-k">05 — Plans</p>
|
||||
<h2 id="s6-h">One studio. <span class="hl">Choose how close we work.</span></h2>
|
||||
<div id="s6-cols">
|
||||
<div class="plan p1" id="pl1"><div class="glow" id="pg1"></div><span class="ghost">01</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M4 17 9 12l4 4 7-8M15 8h5v5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Autopilot</span><h3>Build it yourself</h3>
|
||||
<div class="pp">$99<span>per month</span></div></div>
|
||||
<div class="plan p2" id="pl2"><div class="glow" id="pg2"></div><span class="ghost">02</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M8 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm8 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM3 19c0-2.8 2.2-5 5-5s5 2.2 5 5m-2-5c.9-.6 2-1 3-1h2c2.8 0 5 2.2 5 5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Lab</span><h3>Build it with us</h3>
|
||||
<div class="pp">By application<span>pay as you grow</span></div></div>
|
||||
<div class="plan p3" id="pl3"><div class="glow" id="pg3"></div><span class="ghost">03</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3l2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.8L12 3Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Studio</span><h3>Paid to build</h3>
|
||||
<div class="pp">By invitation<span>earned, not bought</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S7: финал -->
|
||||
<section id="s7" class="clip" data-start="69.95" data-duration="7.43" data-track-index="1">
|
||||
<div class="in" id="s7-in">
|
||||
<svg class="logo" id="s7-logo" viewBox="0 0 200 200">
|
||||
<g class="spin" id="s7-spin"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="8" stroke-dasharray="20 27" stroke-linecap="round" /></g>
|
||||
<circle id="s7-dot" cx="100" cy="100" r="30" fill="#c6ff4d" />
|
||||
</svg>
|
||||
<div id="s7-name">Shkor Labs</div>
|
||||
<div id="s7-tag">Autopilot for any business.</div>
|
||||
<div id="s7-cta"><span class="url">shkor.com</span><span class="btn">Start now →</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- звук: музыка + озвучка по сценам (вставляется build.py) -->
|
||||
<audio id="bgm" src="assets/bgm/bed.wav" data-start="0" data-duration="77.38" data-track-index="3" data-volume="0.14"></audio>
|
||||
<audio id="vo1" src="assets/vo/v1.wav" data-start="0.45" data-duration="6.09" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo2" src="assets/vo/v2.wav" data-start="7.74" data-duration="11.57" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo3" src="assets/vo/v3.wav" data-start="20.51" data-duration="8.11" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo4" src="assets/vo/v4.wav" data-start="29.82" data-duration="11.16" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo5" src="assets/vo/v5.wav" data-start="42.18" data-duration="11.79" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo6" src="assets/vo/v6.wav" data-start="55.17" data-duration="14.03" data-track-index="4" data-volume="1"></audio>
|
||||
<audio id="vo7" src="assets/vo/v7.wav" data-start="70.4" data-duration="4.18" data-track-index="4" data-volume="1"></audio>
|
||||
|
||||
<div id="hud" class="clip" data-start="0" data-duration="77.38" data-track-index="2">
|
||||
<div class="hud-row mono" id="hud-top">
|
||||
<div class="brand"><svg viewBox="0 0 200 200"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="12" stroke-dasharray="20 27" stroke-linecap="round" /><circle cx="100" cy="100" r="30" fill="#c6ff4d" /></svg>Shkor Labs</div>
|
||||
<div>R&D for autonomous business</div>
|
||||
</div>
|
||||
<div class="hud-row mono" id="hud-bot">
|
||||
<div class="chap"><span id="c1">Method</span><span id="c2">Rhythm</span><span id="c3">Trust</span><span id="c4">Labs</span><span id="c5">Plans</span></div>
|
||||
<div>shkor.com</div>
|
||||
</div>
|
||||
<div id="hud-prog"><div id="hud-prog-fill"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// тайминги сцен и фраз — из build.py (озвучка Kokoro по предложениям)
|
||||
const TM = [{"start": 0.0, "dur": 7.29, "vo": 0.45, "vo_dur": 6.09, "sents": [{"t0": 0.45, "t1": 4.06}, {"t0": 4.28, "t1": 6.54}]}, {"start": 7.29, "dur": 12.77, "vo": 7.74, "vo_dur": 11.57, "sents": [{"t0": 7.74, "t1": 8.89}, {"t0": 9.11, "t1": 15.38}, {"t0": 15.6, "t1": 19.31}]}, {"start": 20.06, "dur": 9.31, "vo": 20.51, "vo_dur": 8.11, "sents": [{"t0": 20.51, "t1": 23.54}, {"t0": 23.76, "t1": 28.62}]}, {"start": 29.37, "dur": 12.36, "vo": 29.82, "vo_dur": 11.16, "sents": [{"t0": 29.82, "t1": 31.68}, {"t0": 31.9, "t1": 33.02}, {"t0": 33.24, "t1": 36.62}, {"t0": 36.84, "t1": 40.98}]}, {"start": 41.73, "dur": 12.99, "vo": 42.18, "vo_dur": 11.79, "sents": [{"t0": 42.18, "t1": 43.53}, {"t0": 43.75, "t1": 53.97}]}, {"start": 54.72, "dur": 15.23, "vo": 55.17, "vo_dur": 14.03, "sents": [{"t0": 55.17, "t1": 64.34}, {"t0": 64.56, "t1": 65.93}, {"t0": 66.15, "t1": 69.2}]}, {"start": 69.95, "dur": 7.43, "vo": 70.4, "vo_dur": 4.18, "sents": [{"t0": 70.4, "t1": 71.2}, {"t0": 71.42, "t1": 72.99}, {"t0": 73.21, "t1": 74.58}]}];
|
||||
const TOTAL = 77.38;
|
||||
const at = (i, k = 0, f = 0) => { const s = TM[i].sents[Math.min(k, TM[i].sents.length - 1)]; return s.t0 + (s.t1 - s.t0) * f; };
|
||||
const beg = (i) => TM[i].start;
|
||||
const fin = (i) => TM[i].start + TM[i].dur;
|
||||
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
const pop = (sel, t, from = { opacity: 0, y: 30 }, d = 0.7) =>
|
||||
tl.fromTo(sel, from, { opacity: 1, x: 0, y: 0, scale: 1, duration: d, ease: "power3.out" }, t);
|
||||
const leave = (sel, i) => tl.to(sel, { opacity: 0, y: -24, duration: 0.45, ease: "power2.in" }, fin(i) - 0.5);
|
||||
|
||||
// фон и HUD
|
||||
tl.fromTo("#bg-grid", { x: 0, y: 0 }, { x: 160, y: 80, duration: TOTAL, ease: "none" }, 0);
|
||||
tl.fromTo("#bg-glow", { x: 0, y: 0 }, { x: -520, y: 260, duration: TOTAL, ease: "sine.inOut" }, 0);
|
||||
tl.fromTo("#hud-top, #hud-bot, #hud-prog", { opacity: 0 }, { opacity: 1, duration: 0.8 }, beg(1) - 0.3);
|
||||
tl.fromTo("#hud-prog-fill", { scaleX: 0 }, { scaleX: 1, duration: TOTAL - beg(1), ease: "none" }, beg(1));
|
||||
[["#c1", 1], ["#c2", 2], ["#c3", 3], ["#c4", 4], ["#c5", 5]].forEach(([sel, i]) => {
|
||||
tl.to(sel, { color: "#c6ff4d", duration: 0.3 }, beg(i));
|
||||
tl.to(sel, { color: "#7d818d", duration: 0.3 }, fin(i));
|
||||
});
|
||||
|
||||
// S1 — крючок
|
||||
pop("#s1-a", at(0, 0) - 0.2, { opacity: 0, y: 30 }, 0.8);
|
||||
tl.to("#s1-a", { opacity: 0.4, duration: 0.5 }, at(0, 1) - 0.1);
|
||||
pop("#s1-h", at(0, 1), { opacity: 0, y: 40 }, 0.9);
|
||||
tl.fromTo("#s1-ring", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 1.0, ease: "back.out(1.4)" }, at(0, 1) + 0.2);
|
||||
tl.fromTo("#s1-ring svg", { rotation: 0 }, { rotation: 300, duration: fin(0) - at(0, 1), ease: "none" }, at(0, 1));
|
||||
tl.fromTo(["#s1-rip1", "#s1-rip2"], { scale: 0.55, opacity: 0.8 }, { scale: 1.6, opacity: 0, duration: 2.4, stagger: 1.2, repeat: 1, ease: "power1.out" }, at(0, 1) + 0.6);
|
||||
pop("#s1-by", at(0, 1) + 1.0, { opacity: 0, y: 12 }, 0.6);
|
||||
leave("#s1-in, #s1-ring", 0);
|
||||
|
||||
// S2 — метод
|
||||
pop("#s2-k", beg(1) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s2-h", beg(1) + 0.2);
|
||||
pop("#s2-c1", at(1, 0), { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s2-c1 .evl", { opacity: 0, x: -30 }, { opacity: 1, x: 0, duration: 0.45, stagger: (at(1, 1, 1) - at(1, 1)) / 3.4, ease: "power3.out" }, at(1, 1));
|
||||
tl.to("#s2-c1", { boxShadow: "inset 0 0 0 1px rgba(198,255,77,0.55), 0 30px 80px -30px rgba(198,255,77,0.35)", duration: 0.4 }, at(1, 1));
|
||||
pop("#s2-c2", at(1, 2), { opacity: 0, y: 50 }, 0.6);
|
||||
tl.to("#s2-c1", { boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.14), 0 0 0 0 rgba(0,0,0,0)", duration: 0.4 }, at(1, 2));
|
||||
tl.to("#s2-c2", { boxShadow: "inset 0 0 0 1px rgba(198,255,77,0.55), 0 30px 80px -30px rgba(198,255,77,0.35)", duration: 0.4 }, at(1, 2) + 0.3);
|
||||
tl.fromTo("#s2-ok", { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1, duration: 0.35, ease: "back.out(2)" }, at(1, 2, 0.45));
|
||||
tl.fromTo("#s2-up", { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1, duration: 0.35, ease: "back.out(2)" }, at(1, 2, 0.7));
|
||||
pop("#s2-c3", at(1, 2, 0.85), { opacity: 0, y: 50 }, 0.6);
|
||||
leave("#s2-in", 1);
|
||||
|
||||
// S3 — ритм
|
||||
pop("#s3-k", beg(2) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s3-h", beg(2) + 0.2);
|
||||
tl.fromTo(".orb", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 0.7, stagger: 0.1, ease: "power3.out" }, at(2, 0, 0.3));
|
||||
tl.fromTo("#s3-core", { opacity: 0, scale: 0.6 }, { opacity: 1, scale: 1, duration: 0.8, ease: "back.out(1.6)" }, at(2, 0, 0.45));
|
||||
tl.fromTo(".orb", { rotation: 0 }, { rotation: 40, duration: fin(2) - at(2, 0), ease: "none" }, at(2, 0));
|
||||
const tw = (at(2, 1, 1) - at(2, 1)) / 4;
|
||||
["#tk1", "#tk2", "#tk3", "#tk4"].forEach((sel, n) => {
|
||||
const t = at(2, 1) + tw * n;
|
||||
pop(sel, t, { opacity: 0, x: -40 }, 0.45);
|
||||
tl.fromTo(`#wv${n + 1}`, { opacity: 0.9, scale: 1 }, { opacity: 0, scale: 1.4 + n * 0.8, duration: 1.1, ease: "power2.out" }, t + 0.1);
|
||||
tl.to(`#ob${n + 1}`, { borderColor: "#c6ff4d", duration: 0.2, yoyo: true, repeat: 1 }, t + 0.1);
|
||||
});
|
||||
leave("#s3-in, #s3-orbit", 2);
|
||||
|
||||
// S4 — доверие
|
||||
pop("#s4-k", beg(3) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s4-h", at(3, 0));
|
||||
pop("#s4-t1", at(3, 1) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-ok", { opacity: 0 }, { opacity: 1, duration: 0.3 }, at(3, 1, 0.8) + 0.3);
|
||||
pop("#s4-t2", at(3, 2) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-t2 .circ", { opacity: 0, x: -20 }, { opacity: 1, x: 0, duration: 0.35, stagger: 0.18, ease: "power3.out" }, at(3, 2) + 0.4);
|
||||
pop("#s4-t3", at(3, 3) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-e1", { opacity: 0, x: -20 }, { opacity: 1, x: 0, duration: 0.35 }, at(3, 3) + 0.4);
|
||||
tl.fromTo("#s4-e2", { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.45, ease: "back.out(1.8)" }, at(3, 3, 0.55));
|
||||
leave("#s4-in", 3);
|
||||
|
||||
// S5 — лабы
|
||||
pop("#s5-k", beg(4) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s5-h", at(4, 0));
|
||||
pop("#s5-sub", at(4, 1), { opacity: 0, y: 16 }, 0.6);
|
||||
tl.fromTo("#s5-grid .lab", { opacity: 0, y: 40, scale: 0.96 }, { opacity: 1, y: 0, scale: 1, duration: 0.55, stagger: 0.16, ease: "power3.out" }, at(4, 1) + 0.3);
|
||||
leave("#s5-in", 4);
|
||||
|
||||
// S6 — тарифы
|
||||
pop("#s6-k", beg(5) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s6-h", beg(5) + 0.2);
|
||||
tl.fromTo("#s6-cols", { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, beg(5) + 0.5);
|
||||
[["#pg1", 0], ["#pg2", 1], ["#pg3", 2]].forEach(([sel, k]) => {
|
||||
tl.to(sel, { opacity: 1, duration: 0.4 }, at(5, k));
|
||||
if (k < 2) tl.to(sel, { opacity: 0, duration: 0.4 }, at(5, k + 1));
|
||||
});
|
||||
tl.fromTo("#pl1 .pp", { scale: 1 }, { scale: 1.06, duration: 0.35, yoyo: true, repeat: 1, ease: "sine.inOut", transformOrigin: "left center" }, at(5, 0, 0.8));
|
||||
leave("#s6-in", 5);
|
||||
|
||||
// S7 — финал
|
||||
tl.fromTo("#s7-logo", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 0.8, ease: "back.out(1.5)" }, beg(6) + 0.1);
|
||||
tl.fromTo("#s7-logo", { rotation: 0 }, { rotation: 360, duration: fin(6) - beg(6), ease: "none" }, beg(6));
|
||||
pop("#s7-name", at(6, 0) - 0.1);
|
||||
pop("#s7-tag", at(6, 1) - 0.1);
|
||||
pop("#s7-cta", at(6, 2) - 0.1, { opacity: 0, y: 20 }, 0.6);
|
||||
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["main"] = tl;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
5
video/shkor-labs-site/meta.json
Normal file
5
video/shkor-labs-site/meta.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"id": "shkor-labs-site-en",
|
||||
"name": "shkor-labs-site-en",
|
||||
"createdAt": "2026-10-19T10:30:00.000Z"
|
||||
}
|
||||
11
video/shkor-labs-site/package.json
Normal file
11
video/shkor-labs-site/package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "shkor-labs-site-en",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "npx --yes hyperframes@0.8.168 preview",
|
||||
"check": "npx --yes hyperframes@0.8.168 check",
|
||||
"render": "npx --yes hyperframes@0.8.168 render",
|
||||
"publish": "npx --yes hyperframes@0.8.168 publish"
|
||||
}
|
||||
}
|
||||
435
video/shkor-labs-site/template.tpl
Normal file
435
video/shkor-labs-site/template.tpl
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<title>Shkor Labs — autopilot for any business</title>
|
||||
<script src="./gsap.min.js"></script>
|
||||
<style>
|
||||
@font-face { font-family: "Space Grotesk"; font-weight: 300 700; src: url("fonts/space-grotesk-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-weight: 400; src: url("fonts/inter-400-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-weight: 600; src: url("fonts/inter-600-latin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "JetBrains Mono"; font-weight: 400; src: url("fonts/jetbrains-mono-400-latin.woff2") format("woff2"); }
|
||||
|
||||
/* палитра shkor.com v2 */
|
||||
:root {
|
||||
--bg: #050506; --bg1: #0b0c0f; --bg2: #111318;
|
||||
--fg: #f2f3f5; --fg2: #b4b8c2; --fg3: #80869a;
|
||||
--acid: #c6ff4d; --acid-dim: rgba(198, 255, 77, 0.12); --cyan: #5ce1e6;
|
||||
--line: rgba(255, 255, 255, 0.08); --line2: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { width: 1920px; height: 1080px; overflow: hidden; background: var(--bg); }
|
||||
body { color: var(--fg); font-family: "Inter", sans-serif; -webkit-font-smoothing: antialiased; }
|
||||
#root { position: relative; width: 100%; height: 100%; overflow: hidden; }
|
||||
.clip { position: absolute; inset: 0; }
|
||||
.mono { font-family: "JetBrains Mono", monospace; }
|
||||
.hl { color: var(--acid); }
|
||||
|
||||
/* фон */
|
||||
#bg { background: radial-gradient(1300px 800px at 82% -10%, rgba(198, 255, 77, 0.07), transparent 60%),
|
||||
radial-gradient(1000px 700px at -10% 110%, rgba(92, 225, 230, 0.06), transparent 60%), var(--bg); }
|
||||
#bg-grid { position: absolute; inset: -160px;
|
||||
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
|
||||
background-size: 80px 80px; opacity: 0.55;
|
||||
mask-image: radial-gradient(ellipse 70% 60% at 60% 40%, #000 0%, transparent 75%); }
|
||||
#bg-glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; left: 1100px; top: -520px; background: var(--acid); filter: blur(200px); opacity: 0.07; }
|
||||
|
||||
/* HUD */
|
||||
.hud-row { position: absolute; left: 96px; right: 96px; display: flex; justify-content: space-between; align-items: center;
|
||||
font-size: 18px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg3); }
|
||||
#hud-top { top: 44px; }
|
||||
#hud-top .brand { display: flex; align-items: center; gap: 14px; color: var(--fg2); }
|
||||
#hud-top .brand svg { width: 30px; height: 30px; }
|
||||
#hud-bot { bottom: 54px; }
|
||||
.chap { display: flex; gap: 34px; }
|
||||
.chap span { color: #7d818d; }
|
||||
#hud-prog { position: absolute; left: 96px; right: 96px; bottom: 34px; height: 3px; background: rgba(255, 255, 255, 0.06); border-radius: 2px; }
|
||||
#hud-prog-fill { width: 100%; height: 3px; background: var(--acid); transform-origin: left center; border-radius: 2px; }
|
||||
|
||||
/* общие элементы сцен */
|
||||
.in { position: absolute; inset: 0; padding: 150px 160px 140px; display: flex; flex-direction: column; justify-content: center; }
|
||||
.k { display: flex; align-items: center; gap: 16px; font: 400 22px/1 "JetBrains Mono", monospace; letter-spacing: 0.18em; text-transform: uppercase; color: var(--acid); margin-bottom: 26px; }
|
||||
.k::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--acid); box-shadow: 0 0 18px var(--acid); }
|
||||
h2 { font: 700 84px/1.02 "Space Grotesk", sans-serif; letter-spacing: -0.03em; max-width: 1600px; }
|
||||
.sub { margin-top: 22px; font-size: 30px; line-height: 1.45; color: var(--fg2); max-width: 1300px; }
|
||||
.card { position: relative; border-radius: 26px; background: linear-gradient(180deg, var(--bg2), var(--bg1)); box-shadow: inset 0 0 0 1px var(--line2); padding: 38px 36px; overflow: hidden; }
|
||||
.card h3 { font: 600 38px/1.1 "Space Grotesk", sans-serif; letter-spacing: -0.01em; }
|
||||
.card p { margin-top: 14px; font-size: 24px; line-height: 1.45; color: var(--fg3); }
|
||||
.card.on { box-shadow: inset 0 0 0 1px rgba(198, 255, 77, 0.55), 0 30px 80px -30px rgba(198, 255, 77, 0.35); }
|
||||
.ghost { position: absolute; top: 26px; right: 30px; font: 700 76px/1 "Space Grotesk", sans-serif; letter-spacing: -0.04em; color: #111318; -webkit-text-stroke: 1px rgba(255, 255, 255, 0.16); }
|
||||
.ico { width: 52px; height: 52px; padding: 12px; border-radius: 14px; color: var(--acid); background: var(--acid-dim); margin-bottom: 26px; }
|
||||
.ico svg { width: 28px; height: 28px; display: block; }
|
||||
|
||||
/* S1 — крючок */
|
||||
#s1-in { padding-right: 860px; }
|
||||
#s1-a { font: 500 54px/1.2 "Space Grotesk", sans-serif; color: var(--fg2); letter-spacing: -0.01em; }
|
||||
#s1-h { margin-top: 34px; font: 700 132px/0.98 "Space Grotesk", sans-serif; letter-spacing: -0.035em; }
|
||||
#s1-h em { font-style: normal; color: var(--acid); }
|
||||
#s1-by { margin-top: 44px; font-size: 22px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg3); }
|
||||
#s1-ring { position: absolute; right: 150px; top: 50%; width: 620px; height: 620px; margin-top: -310px; }
|
||||
#s1-ring .rip { position: absolute; inset: 0; border: 2px solid rgba(198, 255, 77, 0.35); border-radius: 50%; }
|
||||
|
||||
/* S2 — метод */
|
||||
.cards3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 56px; }
|
||||
.cards3 .card { height: 420px; }
|
||||
.ev { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.evl { display: flex; justify-content: space-between; align-items: center; height: 44px; padding: 0 16px; border-radius: 10px; background: rgba(255, 255, 255, 0.03); box-shadow: inset 0 0 0 1px var(--line); font-size: 18px; color: var(--fg2); }
|
||||
.evl b { font-weight: 400; color: var(--acid); }
|
||||
.flow { margin-top: 26px; display: flex; align-items: center; gap: 14px; font-size: 18px; }
|
||||
.pill { padding: 10px 16px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line2); color: var(--fg2); }
|
||||
.pill.ok { color: #0a0d02; background: var(--acid); box-shadow: none; }
|
||||
.pill.up { color: var(--cyan); box-shadow: inset 0 0 0 1px rgba(92, 225, 230, 0.5); }
|
||||
.arrow { color: var(--fg3); }
|
||||
|
||||
/* S3 — ритм */
|
||||
#s3-in { padding-right: 900px; }
|
||||
.ticks { margin-top: 48px; display: flex; flex-direction: column; gap: 14px; width: 820px; }
|
||||
.tick { display: grid; grid-template-columns: 96px 210px 1fr; align-items: center; height: 76px; padding: 0 22px; border-radius: 14px; background: rgba(255, 255, 255, 0.025); box-shadow: inset 0 0 0 1px var(--line); font-size: 24px; }
|
||||
.tick .tg { justify-self: start; padding: 6px 14px; border-radius: 9px; background: var(--acid); color: #0a0d02; font: 400 20px "JetBrains Mono", monospace; }
|
||||
.tick b { font: 600 28px "Space Grotesk", sans-serif; }
|
||||
.tick span:last-child { color: var(--fg3); }
|
||||
#s3-orbit { position: absolute; right: 150px; top: 50%; width: 720px; height: 720px; margin-top: -360px; }
|
||||
.orb { position: absolute; border-radius: 50%; border: 2px dashed rgba(92, 225, 230, 0.45); }
|
||||
.orb.o1 { inset: 250px; border-color: rgba(198, 255, 77, 0.7); }
|
||||
.orb.o2 { inset: 170px; border-color: rgba(198, 255, 77, 0.5); }
|
||||
.orb.o3 { inset: 90px; }
|
||||
.orb.o4 { inset: 10px; border-color: rgba(92, 225, 230, 0.3); }
|
||||
#s3-core { position: absolute; left: 50%; top: 50%; width: 190px; height: 190px; margin: -95px 0 0 -95px; border-radius: 50%;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
background: radial-gradient(circle, rgba(198, 255, 77, 0.28), rgba(198, 255, 77, 0.03) 70%); box-shadow: inset 0 0 0 2px var(--acid); }
|
||||
#s3-core b { font: 700 30px "Space Grotesk", sans-serif; }
|
||||
#s3-core small { font: 400 15px "JetBrains Mono", monospace; letter-spacing: 0.1em; color: var(--fg3); margin-top: 4px; text-transform: uppercase; }
|
||||
.wave { position: absolute; left: 50%; top: 50%; width: 190px; height: 190px; margin: -95px 0 0 -95px; border-radius: 50%; border: 2px solid var(--acid); opacity: 0; }
|
||||
|
||||
/* S4 — доверие */
|
||||
.cards3.t .card { height: 470px; }
|
||||
.term { margin-top: 26px; padding: 22px 24px; border-radius: 16px; background: #020203; box-shadow: inset 0 0 0 1px var(--line2); font: 400 22px/1.7 "JetBrains Mono", monospace; color: var(--fg2); }
|
||||
.term .ok { color: var(--acid); }
|
||||
.circles { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.circ { display: flex; align-items: center; gap: 14px; font-size: 22px; color: var(--fg2); }
|
||||
.circ i { flex: 0 0 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; font: 400 17px "JetBrains Mono", monospace; font-style: normal; color: #0a0d02; background: var(--acid); }
|
||||
.circ:nth-child(2) i { background: rgba(198, 255, 77, 0.8); }
|
||||
.circ:nth-child(3) i { background: rgba(198, 255, 77, 0.62); }
|
||||
.circ:nth-child(4) i { background: rgba(255, 255, 255, 0.18); color: var(--fg); }
|
||||
.esc { margin-top: 26px; display: flex; flex-direction: column; gap: 12px; }
|
||||
.esc .pill { align-self: flex-start; font-size: 20px; }
|
||||
|
||||
/* S5 — лабы */
|
||||
#s5-grid { margin-top: 48px; display: grid; grid-template-columns: 1.35fr 1fr 1fr 1fr; grid-template-rows: 190px 190px; gap: 22px; }
|
||||
.lab { position: relative; padding: 26px 28px; border-radius: 22px; background: var(--bg1); box-shadow: inset 0 0 0 1px var(--line2); display: flex; flex-direction: column; justify-content: flex-end; }
|
||||
.lab .t { font: 400 16px "JetBrains Mono", monospace; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg3); position: absolute; top: 24px; left: 28px; }
|
||||
.lab .n { font: 600 34px/1.1 "Space Grotesk", sans-serif; }
|
||||
.lab .d { margin-top: 6px; font-size: 19px; line-height: 1.35; color: var(--fg3); }
|
||||
.lab.core { grid-row: span 2; background: radial-gradient(500px 360px at 0% 100%, rgba(198, 255, 77, 0.16), transparent 70%), var(--bg1); box-shadow: inset 0 0 0 1px rgba(198, 255, 77, 0.45); }
|
||||
.lab.core .t { color: var(--acid); }
|
||||
.lab.core .n { font-size: 64px; }
|
||||
.lab.core .d { font-size: 22px; color: var(--fg2); }
|
||||
|
||||
/* S6 — тарифы-лестница */
|
||||
#s6-cols { margin-top: 52px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line2); border-radius: 26px; overflow: hidden; box-shadow: 0 0 0 1px var(--line2); }
|
||||
.plan { position: relative; background: var(--bg); padding: 40px 36px 40px; height: 440px; display: flex; flex-direction: column; }
|
||||
.plan .pk { font: 400 18px/1 "JetBrains Mono", monospace; letter-spacing: 0.16em; text-transform: uppercase; color: var(--acid); margin-bottom: 14px; }
|
||||
.plan h3 { font: 600 40px/1.1 "Space Grotesk", sans-serif; }
|
||||
.plan .pp { margin-top: auto; padding-top: 24px; border-top: 1px solid var(--line); font: 600 36px/1.1 "Space Grotesk", sans-serif; }
|
||||
.plan .pp span { display: block; margin-top: 8px; font: 400 20px "Inter", sans-serif; color: var(--fg3); }
|
||||
.plan.p1 .pp { color: var(--acid); }
|
||||
.plan.p3 .pk, .plan.p3 h3, .plan.p3 .pp { color: var(--fg2); }
|
||||
.plan.p3 .pk { color: var(--fg3); }
|
||||
.plan.p3 .ico { color: var(--fg3); background: rgba(255, 255, 255, 0.05); }
|
||||
.plan .glow { position: absolute; inset: 0; background: radial-gradient(520px 320px at 0% 0%, rgba(198, 255, 77, 0.14), transparent 70%); opacity: 0; }
|
||||
|
||||
/* S7 — финал */
|
||||
#s7-in { align-items: center; text-align: center; }
|
||||
#s7-logo { width: 230px; height: 230px; }
|
||||
#s7-name { margin-top: 30px; font: 700 128px/1 "Space Grotesk", sans-serif; letter-spacing: -0.035em; }
|
||||
#s7-tag { margin-top: 22px; font: 600 52px/1.1 "Space Grotesk", sans-serif; color: var(--acid); }
|
||||
#s7-cta { margin-top: 54px; display: flex; gap: 18px; align-items: center; }
|
||||
#s7-cta .url { padding: 18px 30px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line2); font: 400 30px "JetBrains Mono", monospace; color: var(--fg); }
|
||||
#s7-cta .btn { padding: 18px 34px; border-radius: 999px; background: var(--acid); color: #0a0d02; font: 600 30px "Inter", sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" data-composition-id="main" data-start="0" data-duration="@TOTAL" data-width="1920" data-height="1080">
|
||||
<div id="bg" class="clip" data-start="0" data-duration="@TOTAL" data-track-index="0">
|
||||
<div id="bg-grid"></div>
|
||||
<div id="bg-glow"></div>
|
||||
</div>
|
||||
|
||||
<!-- S1: крючок -->
|
||||
<section id="s1" class="clip" data-start="@S1_START" data-duration="@S1_DUR" data-track-index="1">
|
||||
<div class="in" id="s1-in">
|
||||
<div id="s1-a">Every business runs on routine<br />nobody has time for.</div>
|
||||
<h1 id="s1-h">Autopilot<br />for <em>any</em> business.</h1>
|
||||
<p id="s1-by" class="mono">Shkor Labs · R&D for autonomous business</p>
|
||||
</div>
|
||||
<div id="s1-ring">
|
||||
<div class="rip" id="s1-rip1"></div><div class="rip" id="s1-rip2"></div>
|
||||
<svg class="logo" viewBox="0 0 200 200" width="620" height="620">
|
||||
<g class="spin" id="s1-spin"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="7" stroke-dasharray="20 27" stroke-linecap="round" /></g>
|
||||
<circle id="s1-dot" cx="100" cy="100" r="30" fill="#c6ff4d" />
|
||||
</svg>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S2: метод -->
|
||||
<section id="s2" class="clip" data-start="@S2_START" data-duration="@S2_DUR" data-track-index="1">
|
||||
<div class="in" id="s2-in">
|
||||
<p class="k" id="s2-k">01 — Method</p>
|
||||
<h2 id="s2-h">Mirror. Rehearse. <span class="hl">Autopilot.</span></h2>
|
||||
<div class="cards3">
|
||||
<div class="card" id="s2-c1">
|
||||
<span class="ghost">01</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3v18M5 7l7-4 7 4M5 17l7 4 7-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Mirror</h3>
|
||||
<div class="ev mono">
|
||||
<div class="evl">MessageReceived<b>signed</b></div>
|
||||
<div class="evl">TaskCreated<b>signed</b></div>
|
||||
<div class="evl">PaymentReceived<b>signed</b></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="s2-c2">
|
||||
<span class="ghost">02</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M4 12a8 8 0 1 0 2.3-5.6M4 4v4h4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Rehearse</h3>
|
||||
<p>Every change is tried on the twin and its real history first.</p>
|
||||
<div class="flow mono"><span class="pill">change</span><span class="arrow">→</span><span class="pill ok" id="s2-ok">safe</span><span class="pill up" id="s2-up">ask a person</span></div>
|
||||
</div>
|
||||
<div class="card" id="s2-c3">
|
||||
<span class="ghost">03</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M5 19 19 5M9 5h10v10" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Autopilot</h3>
|
||||
<p>The routine goes to an agent with real tools, and every action feeds back into the twin.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S3: ритм -->
|
||||
<section id="s3" class="clip" data-start="@S3_START" data-duration="@S3_DUR" data-track-index="1">
|
||||
<div class="in" id="s3-in">
|
||||
<p class="k" id="s3-k">02 — The autopilot</p>
|
||||
<h2 id="s3-h">Not a chatbot.<br /><span class="hl">A heartbeat.</span></h2>
|
||||
<div class="ticks">
|
||||
<div class="tick" id="tk1"><span class="tg">1s</span><b>Reflexes</b><span>telemetry, alerts</span></div>
|
||||
<div class="tick" id="tk2"><span class="tg">1m</span><b>Triage</b><span>inbox, routing, quick fixes</span></div>
|
||||
<div class="tick" id="tk3"><span class="tg">1h</span><b>Execution</b><span>tasks end to end</span></div>
|
||||
<div class="tick" id="tk4"><span class="tg">1d</span><b>Planning</b><span>the plan for tomorrow</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="s3-orbit">
|
||||
<div class="orb o4" id="ob4"></div><div class="orb o3" id="ob3"></div><div class="orb o2" id="ob2"></div><div class="orb o1" id="ob1"></div>
|
||||
<div class="wave" id="wv1"></div><div class="wave" id="wv2"></div><div class="wave" id="wv3"></div><div class="wave" id="wv4"></div>
|
||||
<div id="s3-core"><b>Autopilot</b><small>Simbiot core</small></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S4: доверие -->
|
||||
<section id="s4" class="clip" data-start="@S4_START" data-duration="@S4_DUR" data-track-index="1">
|
||||
<div class="in" id="s4-in">
|
||||
<p class="k" id="s4-k">03 — Trust</p>
|
||||
<h2 id="s4-h">Trusted with <span class="hl">real work.</span></h2>
|
||||
<div class="cards3 t">
|
||||
<div class="card" id="s4-t1">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3 4 6v6c0 4.5 3.4 8.3 8 9 4.6-.7 8-4.5 8-9V6l-8-3Z M9 12l2 2 4-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Every step signed</h3>
|
||||
<p>A tamper-evident log of everything it did, and why.</p>
|
||||
<div class="term"><div>$ simbiot verify</div><div class="ok" id="s4-ok">✓ chain intact</div></div>
|
||||
</div>
|
||||
<div class="card" id="s4-t2">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M15 7a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM5 21c0-3.9 3.1-7 7-7s7 3.1 7 7" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Rights from identity</h3>
|
||||
<p>Never from what a message says.</p>
|
||||
<div class="circles">
|
||||
<div class="circ"><i>1</i>Owner — full tools</div>
|
||||
<div class="circ"><i>2</i>Board — work, no secrets</div>
|
||||
<div class="circ"><i>3</i>Members — scoped</div>
|
||||
<div class="circ"><i>4</i>Everyone else — reply only</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="s4-t3">
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 19V5M5 12l7-7 7 7" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<h3>Knows its limits</h3>
|
||||
<p>When it isn't sure, a person decides, with the full story attached.</p>
|
||||
<div class="esc mono">
|
||||
<span class="pill" id="s4-e1">agent · not sure</span>
|
||||
<span class="pill up" id="s4-e2">↑ person · decides</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S5: лабы -->
|
||||
<section id="s5" class="clip" data-start="@S5_START" data-duration="@S5_DUR" data-track-index="1">
|
||||
<div class="in" id="s5-in">
|
||||
<p class="k" id="s5-k">04 — The labs</p>
|
||||
<h2 id="s5-h">We don't sell what <span class="hl">we don't run.</span></h2>
|
||||
<p class="sub" id="s5-sub">Real businesses inside Cooperative 42 — each a founder plus AI agents.</p>
|
||||
<div id="s5-grid">
|
||||
<div class="lab core"><span class="t">Core · autopilot</span><div class="n">Simbiot</div><div class="d">The agent harness that runs the cooperative itself.</div></div>
|
||||
<div class="lab"><span class="t">Media</span><div class="n">ReelsUp</div></div>
|
||||
<div class="lab"><span class="t">Marketing</span><div class="n">Avatar</div></div>
|
||||
<div class="lab"><span class="t">Consulting</span><div class="n">Mainbeam</div></div>
|
||||
<div class="lab"><span class="t">Construction</span><div class="n">MalyarKa</div></div>
|
||||
<div class="lab"><span class="t">Fintech</span><div class="n">Vybirai</div></div>
|
||||
<div class="lab"><span class="t">+ more</span><div class="n">GroupSign · DEIP</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S6: тарифы -->
|
||||
<section id="s6" class="clip" data-start="@S6_START" data-duration="@S6_DUR" data-track-index="1">
|
||||
<div class="in" id="s6-in">
|
||||
<p class="k" id="s6-k">05 — Plans</p>
|
||||
<h2 id="s6-h">One studio. <span class="hl">Choose how close we work.</span></h2>
|
||||
<div id="s6-cols">
|
||||
<div class="plan p1" id="pl1"><div class="glow" id="pg1"></div><span class="ghost">01</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M4 17 9 12l4 4 7-8M15 8h5v5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Autopilot</span><h3>Build it yourself</h3>
|
||||
<div class="pp">$99<span>per month</span></div></div>
|
||||
<div class="plan p2" id="pl2"><div class="glow" id="pg2"></div><span class="ghost">02</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M8 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm8 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM3 19c0-2.8 2.2-5 5-5s5 2.2 5 5m-2-5c.9-.6 2-1 3-1h2c2.8 0 5 2.2 5 5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Lab</span><h3>Build it with us</h3>
|
||||
<div class="pp">By application<span>pay as you grow</span></div></div>
|
||||
<div class="plan p3" id="pl3"><div class="glow" id="pg3"></div><span class="ghost">03</span>
|
||||
<div class="ico"><svg viewBox="0 0 24 24"><path d="M12 3l2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.8L12 3Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></div>
|
||||
<span class="pk">Studio</span><h3>Paid to build</h3>
|
||||
<div class="pp">By invitation<span>earned, not bought</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- S7: финал -->
|
||||
<section id="s7" class="clip" data-start="@S7_START" data-duration="@S7_DUR" data-track-index="1">
|
||||
<div class="in" id="s7-in">
|
||||
<svg class="logo" id="s7-logo" viewBox="0 0 200 200">
|
||||
<g class="spin" id="s7-spin"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="8" stroke-dasharray="20 27" stroke-linecap="round" /></g>
|
||||
<circle id="s7-dot" cx="100" cy="100" r="30" fill="#c6ff4d" />
|
||||
</svg>
|
||||
<div id="s7-name">Shkor Labs</div>
|
||||
<div id="s7-tag">Autopilot for any business.</div>
|
||||
<div id="s7-cta"><span class="url">shkor.com</span><span class="btn">Start now →</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- звук: музыка + озвучка по сценам (вставляется build.py) -->
|
||||
@AUDIO
|
||||
|
||||
<div id="hud" class="clip" data-start="0" data-duration="@TOTAL" data-track-index="2">
|
||||
<div class="hud-row mono" id="hud-top">
|
||||
<div class="brand"><svg viewBox="0 0 200 200"><circle cx="100" cy="100" r="78" fill="none" stroke="#c6ff4d" stroke-width="12" stroke-dasharray="20 27" stroke-linecap="round" /><circle cx="100" cy="100" r="30" fill="#c6ff4d" /></svg>Shkor Labs</div>
|
||||
<div>R&D for autonomous business</div>
|
||||
</div>
|
||||
<div class="hud-row mono" id="hud-bot">
|
||||
<div class="chap"><span id="c1">Method</span><span id="c2">Rhythm</span><span id="c3">Trust</span><span id="c4">Labs</span><span id="c5">Plans</span></div>
|
||||
<div>shkor.com</div>
|
||||
</div>
|
||||
<div id="hud-prog"><div id="hud-prog-fill"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// тайминги сцен и фраз — из build.py (озвучка Kokoro по предложениям)
|
||||
const TM = @TIMING;
|
||||
const TOTAL = @TOTAL;
|
||||
const at = (i, k = 0, f = 0) => { const s = TM[i].sents[Math.min(k, TM[i].sents.length - 1)]; return s.t0 + (s.t1 - s.t0) * f; };
|
||||
const beg = (i) => TM[i].start;
|
||||
const fin = (i) => TM[i].start + TM[i].dur;
|
||||
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
const pop = (sel, t, from = { opacity: 0, y: 30 }, d = 0.7) =>
|
||||
tl.fromTo(sel, from, { opacity: 1, x: 0, y: 0, scale: 1, duration: d, ease: "power3.out" }, t);
|
||||
const leave = (sel, i) => tl.to(sel, { opacity: 0, y: -24, duration: 0.45, ease: "power2.in" }, fin(i) - 0.5);
|
||||
|
||||
// фон и HUD
|
||||
tl.fromTo("#bg-grid", { x: 0, y: 0 }, { x: 160, y: 80, duration: TOTAL, ease: "none" }, 0);
|
||||
tl.fromTo("#bg-glow", { x: 0, y: 0 }, { x: -520, y: 260, duration: TOTAL, ease: "sine.inOut" }, 0);
|
||||
tl.fromTo("#hud-top, #hud-bot, #hud-prog", { opacity: 0 }, { opacity: 1, duration: 0.8 }, beg(1) - 0.3);
|
||||
tl.fromTo("#hud-prog-fill", { scaleX: 0 }, { scaleX: 1, duration: TOTAL - beg(1), ease: "none" }, beg(1));
|
||||
[["#c1", 1], ["#c2", 2], ["#c3", 3], ["#c4", 4], ["#c5", 5]].forEach(([sel, i]) => {
|
||||
tl.to(sel, { color: "#c6ff4d", duration: 0.3 }, beg(i));
|
||||
tl.to(sel, { color: "#7d818d", duration: 0.3 }, fin(i));
|
||||
});
|
||||
|
||||
// S1 — крючок
|
||||
pop("#s1-a", at(0, 0) - 0.2, { opacity: 0, y: 30 }, 0.8);
|
||||
tl.to("#s1-a", { opacity: 0.4, duration: 0.5 }, at(0, 1) - 0.1);
|
||||
pop("#s1-h", at(0, 1), { opacity: 0, y: 40 }, 0.9);
|
||||
tl.fromTo("#s1-ring", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 1.0, ease: "back.out(1.4)" }, at(0, 1) + 0.2);
|
||||
tl.fromTo("#s1-ring svg", { rotation: 0 }, { rotation: 300, duration: fin(0) - at(0, 1), ease: "none" }, at(0, 1));
|
||||
tl.fromTo(["#s1-rip1", "#s1-rip2"], { scale: 0.55, opacity: 0.8 }, { scale: 1.6, opacity: 0, duration: 2.4, stagger: 1.2, repeat: 1, ease: "power1.out" }, at(0, 1) + 0.6);
|
||||
pop("#s1-by", at(0, 1) + 1.0, { opacity: 0, y: 12 }, 0.6);
|
||||
leave("#s1-in, #s1-ring", 0);
|
||||
|
||||
// S2 — метод
|
||||
pop("#s2-k", beg(1) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s2-h", beg(1) + 0.2);
|
||||
pop("#s2-c1", at(1, 0), { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s2-c1 .evl", { opacity: 0, x: -30 }, { opacity: 1, x: 0, duration: 0.45, stagger: (at(1, 1, 1) - at(1, 1)) / 3.4, ease: "power3.out" }, at(1, 1));
|
||||
tl.to("#s2-c1", { boxShadow: "inset 0 0 0 1px rgba(198,255,77,0.55), 0 30px 80px -30px rgba(198,255,77,0.35)", duration: 0.4 }, at(1, 1));
|
||||
pop("#s2-c2", at(1, 2), { opacity: 0, y: 50 }, 0.6);
|
||||
tl.to("#s2-c1", { boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.14), 0 0 0 0 rgba(0,0,0,0)", duration: 0.4 }, at(1, 2));
|
||||
tl.to("#s2-c2", { boxShadow: "inset 0 0 0 1px rgba(198,255,77,0.55), 0 30px 80px -30px rgba(198,255,77,0.35)", duration: 0.4 }, at(1, 2) + 0.3);
|
||||
tl.fromTo("#s2-ok", { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1, duration: 0.35, ease: "back.out(2)" }, at(1, 2, 0.45));
|
||||
tl.fromTo("#s2-up", { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1, duration: 0.35, ease: "back.out(2)" }, at(1, 2, 0.7));
|
||||
pop("#s2-c3", at(1, 2, 0.85), { opacity: 0, y: 50 }, 0.6);
|
||||
leave("#s2-in", 1);
|
||||
|
||||
// S3 — ритм
|
||||
pop("#s3-k", beg(2) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s3-h", beg(2) + 0.2);
|
||||
tl.fromTo(".orb", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 0.7, stagger: 0.1, ease: "power3.out" }, at(2, 0, 0.3));
|
||||
tl.fromTo("#s3-core", { opacity: 0, scale: 0.6 }, { opacity: 1, scale: 1, duration: 0.8, ease: "back.out(1.6)" }, at(2, 0, 0.45));
|
||||
tl.fromTo(".orb", { rotation: 0 }, { rotation: 40, duration: fin(2) - at(2, 0), ease: "none" }, at(2, 0));
|
||||
const tw = (at(2, 1, 1) - at(2, 1)) / 4;
|
||||
["#tk1", "#tk2", "#tk3", "#tk4"].forEach((sel, n) => {
|
||||
const t = at(2, 1) + tw * n;
|
||||
pop(sel, t, { opacity: 0, x: -40 }, 0.45);
|
||||
tl.fromTo(`#wv${n + 1}`, { opacity: 0.9, scale: 1 }, { opacity: 0, scale: 1.4 + n * 0.8, duration: 1.1, ease: "power2.out" }, t + 0.1);
|
||||
tl.to(`#ob${n + 1}`, { borderColor: "#c6ff4d", duration: 0.2, yoyo: true, repeat: 1 }, t + 0.1);
|
||||
});
|
||||
leave("#s3-in, #s3-orbit", 2);
|
||||
|
||||
// S4 — доверие
|
||||
pop("#s4-k", beg(3) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s4-h", at(3, 0));
|
||||
pop("#s4-t1", at(3, 1) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-ok", { opacity: 0 }, { opacity: 1, duration: 0.3 }, at(3, 1, 0.8) + 0.3);
|
||||
pop("#s4-t2", at(3, 2) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-t2 .circ", { opacity: 0, x: -20 }, { opacity: 1, x: 0, duration: 0.35, stagger: 0.18, ease: "power3.out" }, at(3, 2) + 0.4);
|
||||
pop("#s4-t3", at(3, 3) - 0.1, { opacity: 0, y: 50 }, 0.6);
|
||||
tl.fromTo("#s4-e1", { opacity: 0, x: -20 }, { opacity: 1, x: 0, duration: 0.35 }, at(3, 3) + 0.4);
|
||||
tl.fromTo("#s4-e2", { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.45, ease: "back.out(1.8)" }, at(3, 3, 0.55));
|
||||
leave("#s4-in", 3);
|
||||
|
||||
// S5 — лабы
|
||||
pop("#s5-k", beg(4) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s5-h", at(4, 0));
|
||||
pop("#s5-sub", at(4, 1), { opacity: 0, y: 16 }, 0.6);
|
||||
tl.fromTo("#s5-grid .lab", { opacity: 0, y: 40, scale: 0.96 }, { opacity: 1, y: 0, scale: 1, duration: 0.55, stagger: 0.16, ease: "power3.out" }, at(4, 1) + 0.3);
|
||||
leave("#s5-in", 4);
|
||||
|
||||
// S6 — тарифы
|
||||
pop("#s6-k", beg(5) + 0.1, { opacity: 0, y: 16 }, 0.5);
|
||||
pop("#s6-h", beg(5) + 0.2);
|
||||
tl.fromTo("#s6-cols", { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, beg(5) + 0.5);
|
||||
[["#pg1", 0], ["#pg2", 1], ["#pg3", 2]].forEach(([sel, k]) => {
|
||||
tl.to(sel, { opacity: 1, duration: 0.4 }, at(5, k));
|
||||
if (k < 2) tl.to(sel, { opacity: 0, duration: 0.4 }, at(5, k + 1));
|
||||
});
|
||||
tl.fromTo("#pl1 .pp", { scale: 1 }, { scale: 1.06, duration: 0.35, yoyo: true, repeat: 1, ease: "sine.inOut", transformOrigin: "left center" }, at(5, 0, 0.8));
|
||||
leave("#s6-in", 5);
|
||||
|
||||
// S7 — финал
|
||||
tl.fromTo("#s7-logo", { opacity: 0, scale: 0.7 }, { opacity: 1, scale: 1, duration: 0.8, ease: "back.out(1.5)" }, beg(6) + 0.1);
|
||||
tl.fromTo("#s7-logo", { rotation: 0 }, { rotation: 360, duration: fin(6) - beg(6), ease: "none" }, beg(6));
|
||||
pop("#s7-name", at(6, 0) - 0.1);
|
||||
pop("#s7-tag", at(6, 1) - 0.1);
|
||||
pop("#s7-cta", at(6, 2) - 0.1, { opacity: 0, y: 20 }, 0.6);
|
||||
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["main"] = tl;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue