dsh-hyperframes 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.en.md +35 -0
  2. package/README.md +35 -0
  3. package/cordis.patch.yml +7 -0
  4. package/lib/index.d.ts +35 -0
  5. package/lib/index.js +74 -0
  6. package/package.json +63 -0
  7. package/skills/gsap/SKILL.md +213 -0
  8. package/skills/gsap/references/effects.md +297 -0
  9. package/skills/gsap/scripts/extract-audio-data.py +188 -0
  10. package/skills/hyperframes/SKILL.md +366 -0
  11. package/skills/hyperframes/data-in-motion.md +19 -0
  12. package/skills/hyperframes/house-style.md +71 -0
  13. package/skills/hyperframes/palettes/bold-energetic.md +14 -0
  14. package/skills/hyperframes/palettes/clean-corporate.md +14 -0
  15. package/skills/hyperframes/palettes/dark-premium.md +14 -0
  16. package/skills/hyperframes/palettes/jewel-rich.md +14 -0
  17. package/skills/hyperframes/palettes/monochrome.md +14 -0
  18. package/skills/hyperframes/palettes/nature-earth.md +14 -0
  19. package/skills/hyperframes/palettes/neon-electric.md +14 -0
  20. package/skills/hyperframes/palettes/pastel-soft.md +14 -0
  21. package/skills/hyperframes/palettes/warm-editorial.md +14 -0
  22. package/skills/hyperframes/patterns.md +118 -0
  23. package/skills/hyperframes/references/audio-reactive.md +76 -0
  24. package/skills/hyperframes/references/captions.md +132 -0
  25. package/skills/hyperframes/references/css-patterns.md +373 -0
  26. package/skills/hyperframes/references/dynamic-techniques.md +90 -0
  27. package/skills/hyperframes/references/motion-principles.md +69 -0
  28. package/skills/hyperframes/references/transcript-guide.md +151 -0
  29. package/skills/hyperframes/references/transitions/catalog.md +117 -0
  30. package/skills/hyperframes/references/transitions/css-3d.md +12 -0
  31. package/skills/hyperframes/references/transitions/css-blur.md +51 -0
  32. package/skills/hyperframes/references/transitions/css-cover.md +43 -0
  33. package/skills/hyperframes/references/transitions/css-destruction.md +95 -0
  34. package/skills/hyperframes/references/transitions/css-dissolve.md +66 -0
  35. package/skills/hyperframes/references/transitions/css-distortion.md +45 -0
  36. package/skills/hyperframes/references/transitions/css-grid.md +10 -0
  37. package/skills/hyperframes/references/transitions/css-light.md +49 -0
  38. package/skills/hyperframes/references/transitions/css-mechanical.md +30 -0
  39. package/skills/hyperframes/references/transitions/css-other.md +25 -0
  40. package/skills/hyperframes/references/transitions/css-push.md +41 -0
  41. package/skills/hyperframes/references/transitions/css-radial.md +37 -0
  42. package/skills/hyperframes/references/transitions/css-scale.md +24 -0
  43. package/skills/hyperframes/references/transitions.md +112 -0
  44. package/skills/hyperframes/references/tts.md +75 -0
  45. package/skills/hyperframes/references/typography.md +175 -0
  46. package/skills/hyperframes/scripts/animation-map.mjs +596 -0
  47. package/skills/hyperframes/scripts/contrast-report.mjs +335 -0
  48. package/skills/hyperframes/visual-styles.md +211 -0
  49. package/skills/hyperframes-cli/SKILL.md +152 -0
  50. package/skills/hyperframes-registry/SKILL.md +106 -0
  51. package/skills/hyperframes-registry/examples/add-block.md +51 -0
  52. package/skills/hyperframes-registry/examples/add-component.md +73 -0
  53. package/skills/hyperframes-registry/references/demo-html-pattern.md +54 -0
  54. package/skills/hyperframes-registry/references/discovery.md +53 -0
  55. package/skills/hyperframes-registry/references/install-locations.md +45 -0
  56. package/skills/hyperframes-registry/references/wiring-blocks.md +91 -0
  57. package/skills/hyperframes-registry/references/wiring-components.md +77 -0
  58. package/skills/website-to-hyperframes/SKILL.md +125 -0
  59. package/skills/website-to-hyperframes/references/step-1-capture.md +74 -0
  60. package/skills/website-to-hyperframes/references/step-2-design.md +178 -0
  61. package/skills/website-to-hyperframes/references/step-3-script.md +96 -0
  62. package/skills/website-to-hyperframes/references/step-4-storyboard.md +246 -0
  63. package/skills/website-to-hyperframes/references/step-5-vo.md +42 -0
  64. package/skills/website-to-hyperframes/references/step-6-build.md +229 -0
  65. package/skills/website-to-hyperframes/references/step-7-validate.md +114 -0
  66. package/skills/website-to-hyperframes/references/techniques.md +387 -0
package/README.en.md ADDED
@@ -0,0 +1,35 @@
1
+ [中文](README.md)
2
+
3
+ # dsh-hyperframes
4
+
5
+ DSH (DeepSeek Harness) video-creation skill plugin: installing it registers the five official HyperFrames by HeyGen skills into DSH (video from HTML: compositions, GSAP animation, captions, voiceovers, audio-reactive visuals, website-to-video).
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ dsh plugin --profile web add dsh-hyperframes
11
+ ```
12
+
13
+ After restarting, say "turn this website into a HyperFrames video" to trigger it.
14
+
15
+ ## Skills
16
+
17
+ | Skill | Purpose |
18
+ | :-- | :-- |
19
+ | `hyperframes` | HTML video compositions: visual styles/palettes/captions/audio-reactive/transitions |
20
+ | `hyperframes-cli` | `npx hyperframes` CLI (init/lint/inspect/preview/render/transcribe/tts/doctor) |
21
+ | `hyperframes-registry` | `hyperframes add` registry block installation and wiring |
22
+ | `website-to-hyperframes` | Seven-step website-to-video pipeline |
23
+ | `gsap` | GSAP animation API reference (tweens/timelines/easing/performance) |
24
+
25
+ ## Requirements
26
+
27
+ Node.js ≥ 22 + FFmpeg (`npx hyperframes`).
28
+
29
+ ## Porting notes
30
+
31
+ Ported from the official OpenAI Codex HyperFrames by HeyGen plugin cache: frontmatter converted to the DSH format, Codex-only `agents/` stripped, and all internal references verified.
32
+
33
+ ## License
34
+
35
+ MIT for the porting arrangement; skill content copyright remains with HeyGen.
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ [English](README.en.md)
2
+
3
+ # dsh-hyperframes
4
+
5
+ DSH(DeepSeek Harness)视频创作技能插件:**安装即把 HyperFrames by HeyGen 官方移植技能五件套注册进 DSH**(HTML 写视频:合成、GSAP 动画、字幕、配音、音频响应、网址转视频)。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ dsh plugin --profile web add dsh-hyperframes
11
+ ```
12
+
13
+ 重启后说「把这个网址做成 HyperFrames 视频」即可触发。
14
+
15
+ ## 技能清单
16
+
17
+ | 技能 | 用途 |
18
+ | :-- | :-- |
19
+ | `hyperframes` | HTML 视频合成:视觉风格/调色板/字幕/音频响应/转场 |
20
+ | `hyperframes-cli` | `npx hyperframes` 命令行(init/lint/inspect/preview/render/transcribe/tts/doctor)|
21
+ | `hyperframes-registry` | `hyperframes add` 注册表组件安装与接线 |
22
+ | `website-to-hyperframes` | 网址转视频七步流水线 |
23
+ | `gsap` | GSAP 动画 API 参考(tween/timeline/缓动/性能)|
24
+
25
+ ## 依赖
26
+
27
+ Node.js ≥ 22 + FFmpeg(`npx hyperframes`)。
28
+
29
+ ## 移植说明
30
+
31
+ 技能移植自 OpenAI Codex 官方 HyperFrames by HeyGen 插件缓存:frontmatter 已转换为 DSH 格式,codex 专属 `agents/` 已剔除,全部内部引用校验。
32
+
33
+ ## License
34
+
35
+ MIT(移植编排);技能内容版权归 HeyGen。
@@ -0,0 +1,7 @@
1
+ # dsh-hyperframes 组合包补丁:把HyperFrames 技能插件行插入 profile。
2
+ # 插件加载即把技能注册进 ctx.skills(技能目录实时可见),无需配置。
3
+ #
4
+ - insert:
5
+ - id: hyperframes-skills
6
+ name: 'dsh-hyperframes'
7
+ config: {}
package/lib/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /** cordis 服务注入:apply 里要用 ctx.skills,必须显式声明。 */
2
+ export declare const inject: string[];
3
+ /** 技能注册定义(最小面)。 */
4
+ export interface SkillRegistration {
5
+ name: string;
6
+ description: string;
7
+ content: string;
8
+ resourceBase: {
9
+ kind: 'directory';
10
+ path: string;
11
+ };
12
+ source?: string;
13
+ }
14
+ /** 插件所需的最小 ctx 面。 */
15
+ export interface SkillsPluginContext {
16
+ skills: {
17
+ register(definition: SkillRegistration): () => void;
18
+ };
19
+ on?(event: string, listener: () => void): () => void;
20
+ }
21
+ /** 随包分发的技能清单。 */
22
+ export declare const SKILL_NAMES: readonly ["hyperframes", "hyperframes-cli", "hyperframes-registry", "website-to-hyperframes", "gsap"];
23
+ /** 打包技能目录的绝对路径。 */
24
+ export declare function bundledSkillsDir(): string;
25
+ /** 拆分 SKILL.md 的 frontmatter 与正文。 */
26
+ export declare function parseSkillFile(text: string): {
27
+ name: string;
28
+ description: string;
29
+ content: string;
30
+ };
31
+ /**
32
+ * 插件入口:把技能注册进技能注册表。
33
+ * 单个技能文件缺失只告警,不影响其余技能与宿主启动。
34
+ */
35
+ export declare function apply(ctx: SkillsPluginContext): void;
package/lib/index.js ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * dsh-hyperframes —— HyperFrames by HeyGen 视频创作技能插件:加载即把技能注册进 ctx.skills。
3
+ *
4
+ * 技能正文与资源随包分发(skills/ 目录),resourceBase 指向打包目录,
5
+ * 技能正文里的相对引用(rules/、references/ 等)由技能加载器解析。
6
+ *
7
+ * @module dsh-hyperframes
8
+ */
9
+ import { readFileSync } from 'node:fs';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { join } from 'node:path';
12
+ import YAML from 'yaml';
13
+ /** cordis 服务注入:apply 里要用 ctx.skills,必须显式声明。 */
14
+ export const inject = ['skills'];
15
+ /** 随包分发的技能清单。 */
16
+ export const SKILL_NAMES = ["hyperframes", "hyperframes-cli", "hyperframes-registry", "website-to-hyperframes", "gsap"];
17
+ /** 打包技能目录的绝对路径。 */
18
+ export function bundledSkillsDir() {
19
+ return fileURLToPath(new URL('../skills/', import.meta.url));
20
+ }
21
+ /** 拆分 SKILL.md 的 frontmatter 与正文。 */
22
+ export function parseSkillFile(text) {
23
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
24
+ if (!match)
25
+ return { name: '', description: '', content: text };
26
+ let name = '';
27
+ let description = '';
28
+ try {
29
+ const parsed = YAML.parse(match[1]);
30
+ if (typeof parsed === 'object' && parsed !== null) {
31
+ const record = parsed;
32
+ if (typeof record.name === 'string')
33
+ name = record.name;
34
+ if (typeof record.description === 'string')
35
+ description = record.description;
36
+ }
37
+ }
38
+ catch { /* 保留空值,由调用方处理 */ }
39
+ return { name, description, content: text.slice(match[0].length).trimStart() };
40
+ }
41
+ /**
42
+ * 插件入口:把技能注册进技能注册表。
43
+ * 单个技能文件缺失只告警,不影响其余技能与宿主启动。
44
+ */
45
+ export function apply(ctx) {
46
+ const disposers = [];
47
+ for (const skillName of SKILL_NAMES) {
48
+ try {
49
+ const dir = join(bundledSkillsDir(), skillName);
50
+ const text = readFileSync(join(dir, 'SKILL.md'), 'utf8');
51
+ const parsed = parseSkillFile(text);
52
+ if (parsed.name === '' || parsed.description === '' || parsed.content === '') {
53
+ console.warn('[dsh-hyperframes] 技能 ' + skillName + ' 的 frontmatter 不完整,已跳过。');
54
+ continue;
55
+ }
56
+ disposers.push(ctx.skills.register({
57
+ name: parsed.name,
58
+ description: parsed.description,
59
+ content: parsed.content,
60
+ resourceBase: { kind: 'directory', path: dir },
61
+ source: 'runtime',
62
+ }));
63
+ }
64
+ catch (error) {
65
+ console.warn('[dsh-hyperframes] 技能 ' + skillName + ' 加载失败:' + (error instanceof Error ? error.message : String(error)));
66
+ }
67
+ }
68
+ if (typeof ctx.on === 'function') {
69
+ ctx.on('dispose', () => {
70
+ for (const dispose of disposers)
71
+ dispose();
72
+ });
73
+ }
74
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "dsh-hyperframes",
3
+ "version": "0.1.0",
4
+ "description": "DSH 视频创作技能插件:注册 HyperFrames by HeyGen 官方移植技能五件套(hyperframes / hyperframes-cli / hyperframes-registry / website-to-hyperframes / gsap),安装即用。",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/index.d.ts",
11
+ "default": "./lib/index.js"
12
+ },
13
+ "./cordis.patch.yml": "./cordis.patch.yml",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "lib",
18
+ "skills",
19
+ "cordis.patch.yml",
20
+ "README.md",
21
+ "README.en.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.json",
25
+ "prepare": "tsc -p tsconfig.json",
26
+ "typecheck": "tsc -p tsconfig.json --noEmit",
27
+ "test": "pnpm run build && node --test \"test/*.test.mjs\"",
28
+ "prepublishOnly": "pnpm run build"
29
+ },
30
+ "dsh": {
31
+ "bundle": {
32
+ "patch": "./cordis.patch.yml"
33
+ }
34
+ },
35
+ "keywords": [
36
+ "dsh",
37
+ "deepseek-harness",
38
+ "plugin",
39
+ "skills",
40
+ "video"
41
+ ],
42
+ "license": "MIT",
43
+ "engines": {
44
+ "node": ">=20"
45
+ },
46
+ "dependencies": {
47
+ "yaml": "^2.9.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^24.0.0",
51
+ "typescript": "^5.6.0"
52
+ },
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "https://github.com/STARDUSTLC666/dsh-hyperframes"
56
+ },
57
+ "bugs": {
58
+ "url": "https://github.com/STARDUSTLC666/dsh-hyperframes/issues"
59
+ },
60
+ "homepage": "https://github.com/STARDUSTLC666/dsh-hyperframes#readme",
61
+ "author": "stardustlc",
62
+ "packageManager": "pnpm@11.7.0"
63
+ }
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: gsap
3
+ description: "GSAP animation reference for HyperFrames. Covers gsap.to(), from(), fromTo(), easing, stagger, defaults, timelines (gsap.timeline(), position parameter, labels, nesting, playback), and performance (transforms, will-change, quickTo). Use when writing GSAP animations in HyperFrames compositions. 中文:在 HyperFrames 合成里写 GSAP 动画时使用。"
4
+ compatibility: Pure reference; GSAP ships inside HyperFrames compositions, no local install needed.
5
+ allowed-tools: Bash
6
+ ---
7
+
8
+ # GSAP
9
+
10
+ ## Core Tween Methods
11
+
12
+ - **gsap.to(targets, vars)** — animate from current state to `vars`. Most common.
13
+ - **gsap.from(targets, vars)** — animate from `vars` to current state (entrances).
14
+ - **gsap.fromTo(targets, fromVars, toVars)** — explicit start and end.
15
+ - **gsap.set(targets, vars)** — apply immediately (duration 0).
16
+
17
+ Always use **camelCase** property names (e.g. `backgroundColor`, `rotationX`).
18
+
19
+ ## Common vars
20
+
21
+ - **duration** — seconds (default 0.5).
22
+ - **delay** — seconds before start.
23
+ - **ease** — `"power1.out"` (default), `"power3.inOut"`, `"back.out(1.7)"`, `"elastic.out(1, 0.3)"`, `"none"`.
24
+ - **stagger** — number `0.1` or object: `{ amount: 0.3, from: "center" }`, `{ each: 0.1, from: "random" }`.
25
+ - **overwrite** — `false` (default), `true`, or `"auto"`.
26
+ - **repeat** — number or `-1` for infinite. **yoyo** — alternates direction with repeat.
27
+ - **onComplete**, **onStart**, **onUpdate** — callbacks.
28
+ - **immediateRender** — default `true` for from()/fromTo(). Set `false` on later tweens targeting the same property+element to avoid overwrite.
29
+
30
+ ## Transforms and CSS
31
+
32
+ Prefer GSAP's **transform aliases** over raw `transform` string:
33
+
34
+ | GSAP property | Equivalent |
35
+ | --------------------------- | ------------------- |
36
+ | `x`, `y`, `z` | translateX/Y/Z (px) |
37
+ | `xPercent`, `yPercent` | translateX/Y in % |
38
+ | `scale`, `scaleX`, `scaleY` | scale |
39
+ | `rotation` | rotate (deg) |
40
+ | `rotationX`, `rotationY` | 3D rotate |
41
+ | `skewX`, `skewY` | skew |
42
+ | `transformOrigin` | transform-origin |
43
+
44
+ - **autoAlpha** — prefer over `opacity`. At 0: also sets `visibility: hidden`.
45
+ - **CSS variables** — `"--hue": 180`.
46
+ - **svgOrigin** _(SVG only)_ — global SVG coordinate space origin. Don't combine with `transformOrigin`.
47
+ - **Directional rotation** — `"360_cw"`, `"-170_short"`, `"90_ccw"`.
48
+ - **clearProps** — `"all"` or comma-separated; removes inline styles on complete.
49
+ - **Relative values** — `"+=20"`, `"-=10"`, `"*=2"`.
50
+
51
+ ## Function-Based Values
52
+
53
+ ```javascript
54
+ gsap.to(".item", {
55
+ x: (i, target, targets) => i * 50,
56
+ stagger: 0.1,
57
+ });
58
+ ```
59
+
60
+ ## Easing
61
+
62
+ Built-in eases: `power1`–`power4`, `back`, `bounce`, `circ`, `elastic`, `expo`, `sine`. Each has `.in`, `.out`, `.inOut`.
63
+
64
+ ## Defaults
65
+
66
+ ```javascript
67
+ gsap.defaults({ duration: 0.6, ease: "power2.out" });
68
+ ```
69
+
70
+ ## Controlling Tweens
71
+
72
+ ```javascript
73
+ const tween = gsap.to(".box", { x: 100 });
74
+ tween.pause();
75
+ tween.play();
76
+ tween.reverse();
77
+ tween.kill();
78
+ tween.progress(0.5);
79
+ tween.time(0.2);
80
+ ```
81
+
82
+ ## gsap.matchMedia() (Responsive + Accessibility)
83
+
84
+ Runs setup only when a media query matches; auto-reverts when it stops matching.
85
+
86
+ ```javascript
87
+ let mm = gsap.matchMedia();
88
+ mm.add(
89
+ {
90
+ isDesktop: "(min-width: 800px)",
91
+ reduceMotion: "(prefers-reduced-motion: reduce)",
92
+ },
93
+ (context) => {
94
+ const { isDesktop, reduceMotion } = context.conditions;
95
+ gsap.to(".box", {
96
+ rotation: isDesktop ? 360 : 180,
97
+ duration: reduceMotion ? 0 : 2,
98
+ });
99
+ },
100
+ );
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Timelines
106
+
107
+ ### Creating a Timeline
108
+
109
+ ```javascript
110
+ const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" } });
111
+ tl.to(".a", { x: 100 }).to(".b", { y: 50 }).to(".c", { opacity: 0 });
112
+ ```
113
+
114
+ ### Position Parameter
115
+
116
+ Third argument controls placement:
117
+
118
+ - **Absolute**: `1` — at 1s
119
+ - **Relative**: `"+=0.5"` — after end; `"-=0.2"` — before end
120
+ - **Label**: `"intro"`, `"intro+=0.3"`
121
+ - **Alignment**: `"<"` — same start as previous; `">"` — after previous ends; `"<0.2"` — 0.2s after previous starts
122
+
123
+ ```javascript
124
+ tl.to(".a", { x: 100 }, 0);
125
+ tl.to(".b", { y: 50 }, "<"); // same start as .a
126
+ tl.to(".c", { opacity: 0 }, "<0.2"); // 0.2s after .b starts
127
+ ```
128
+
129
+ ### Labels
130
+
131
+ ```javascript
132
+ tl.addLabel("intro", 0);
133
+ tl.to(".a", { x: 100 }, "intro");
134
+ tl.addLabel("outro", "+=0.5");
135
+ tl.play("outro");
136
+ tl.tweenFromTo("intro", "outro");
137
+ ```
138
+
139
+ ### Timeline Options
140
+
141
+ - **paused: true** — create paused; call `.play()` to start.
142
+ - **repeat**, **yoyo** — apply to whole timeline.
143
+ - **defaults** — vars merged into every child tween.
144
+
145
+ ### Nesting Timelines
146
+
147
+ ```javascript
148
+ const master = gsap.timeline();
149
+ const child = gsap.timeline();
150
+ child.to(".a", { x: 100 }).to(".b", { y: 50 });
151
+ master.add(child, 0);
152
+ ```
153
+
154
+ ### Playback Control
155
+
156
+ `tl.play()`, `tl.pause()`, `tl.reverse()`, `tl.restart()`, `tl.time(2)`, `tl.progress(0.5)`, `tl.kill()`.
157
+
158
+ ---
159
+
160
+ ## Performance
161
+
162
+ ### Prefer Transform and Opacity
163
+
164
+ Animating `x`, `y`, `scale`, `rotation`, `opacity` stays on the compositor. Avoid `width`, `height`, `top`, `left` when transforms achieve the same effect.
165
+
166
+ ### will-change
167
+
168
+ ```css
169
+ will-change: transform;
170
+ ```
171
+
172
+ Only on elements that actually animate.
173
+
174
+ ### gsap.quickTo() for Frequent Updates
175
+
176
+ ```javascript
177
+ let xTo = gsap.quickTo("#id", "x", { duration: 0.4, ease: "power3" }),
178
+ yTo = gsap.quickTo("#id", "y", { duration: 0.4, ease: "power3" });
179
+ container.addEventListener("mousemove", (e) => {
180
+ xTo(e.pageX);
181
+ yTo(e.pageY);
182
+ });
183
+ ```
184
+
185
+ ### Stagger > Many Tweens
186
+
187
+ Use `stagger` instead of separate tweens with manual delays.
188
+
189
+ ### Cleanup
190
+
191
+ Pause or kill off-screen animations.
192
+
193
+ ---
194
+
195
+ ## References (loaded on demand)
196
+
197
+ - **[references/effects.md](references/effects.md)** — Drop-in effects: typewriter text, audio visualizer. Read when needing ready-made effect patterns for HyperFrames.
198
+
199
+ ## Best Practices
200
+
201
+ - Use camelCase property names; prefer transform aliases and autoAlpha.
202
+ - Prefer timelines over chaining with delay; use the position parameter.
203
+ - Add labels with `addLabel()` for readable sequencing.
204
+ - Pass defaults into timeline constructor.
205
+ - Store tween/timeline return value when controlling playback.
206
+
207
+ ## Do Not
208
+
209
+ - Animate layout properties (width/height/top/left) when transforms suffice.
210
+ - Use both svgOrigin and transformOrigin on the same SVG element.
211
+ - Chain animations with delay when a timeline can sequence them.
212
+ - Create tweens before the DOM exists.
213
+ - Skip cleanup — always kill tweens when no longer needed.