@autoaiai/aicut 0.0.0-stage → 0.1.7

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 (146) hide show
  1. package/LICENSE +21 -0
  2. package/MANUAL.md +84 -0
  3. package/README.md +36 -2
  4. package/SPEC.md +221 -0
  5. package/THIRD_PARTY_NOTICES.md +10 -0
  6. package/TRADEMARK.md +25 -0
  7. package/bin/aicut.mjs +264 -0
  8. package/package.json +89 -6
  9. package/product.json +5 -0
  10. package/skills/aicut/LICENSE +21 -0
  11. package/skills/aicut/SKILL.md +66 -0
  12. package/skills/aicut/references/commands.md +72 -0
  13. package/skills/aicut/references/film-format.md +119 -0
  14. package/skills/aicut/references/recipes.md +184 -0
  15. package/skills/aicut/references/troubleshooting.md +57 -0
  16. package/skills/aicut-motion/LICENSE +21 -0
  17. package/skills/aicut-motion/SKILL.md +255 -0
  18. package/skills/aicut-motion/references/design-systems/README.md +25 -0
  19. package/skills/aicut-motion/references/design-systems/bold-poster.md +62 -0
  20. package/skills/aicut-motion/references/design-systems/data-instrument.md +71 -0
  21. package/skills/aicut-motion/references/design-systems/drafting-table.md +76 -0
  22. package/skills/aicut-motion/references/design-systems/editorial-ink.md +83 -0
  23. package/skills/aicut-motion/references/design-systems/riso-halftone.md +70 -0
  24. package/skills/aicut-motion/references/design-systems/storybook-scene.md +75 -0
  25. package/skills/aicut-motion/references/design-systems/swiss-kinetic.md +67 -0
  26. package/skills/aicut-motion/references/pages.md +258 -0
  27. package/src/film-doc.d.mts +204 -0
  28. package/src/film-doc.mjs +1225 -0
  29. package/src/host.d.mts +35 -0
  30. package/src/host.mjs +542 -0
  31. package/src/look.d.mts +2 -0
  32. package/src/look.mjs +358 -0
  33. package/src/media-links.mjs +68 -0
  34. package/src/of-filters.mjs +237 -0
  35. package/src/overrides.mjs +75 -0
  36. package/src/render.mjs +202 -0
  37. package/src/seekable.mjs +101 -0
  38. package/src/shared.d.mts +27 -0
  39. package/src/shared.mjs +391 -0
  40. package/src/timeline.mjs +1158 -0
  41. package/studio/client.mjs +311 -0
  42. package/studio/server/atomic.mjs +41 -0
  43. package/studio/server/bridge.js +89 -0
  44. package/studio/server/browse.mjs +104 -0
  45. package/studio/server/captions.mjs +502 -0
  46. package/studio/server/chat.mjs +49 -0
  47. package/studio/server/closure.mjs +407 -0
  48. package/studio/server/compound.mjs +133 -0
  49. package/studio/server/custom-services.mjs +299 -0
  50. package/studio/server/derived.mjs +225 -0
  51. package/studio/server/examples.mjs +89 -0
  52. package/studio/server/exports.mjs +1621 -0
  53. package/studio/server/fetch-error.mjs +14 -0
  54. package/studio/server/fetch-github.mjs +181 -0
  55. package/studio/server/fetch-repo.mjs +399 -0
  56. package/studio/server/files.mjs +628 -0
  57. package/studio/server/film-subtitle.mjs +869 -0
  58. package/studio/server/film.mjs +109 -0
  59. package/studio/server/folder-picker.mjs +199 -0
  60. package/studio/server/fonts.mjs +308 -0
  61. package/studio/server/get.mjs +700 -0
  62. package/studio/server/heard.mjs +108 -0
  63. package/studio/server/hidden.mjs +85 -0
  64. package/studio/server/history-migrate.mjs +239 -0
  65. package/studio/server/history-store.mjs +538 -0
  66. package/studio/server/history.mjs +682 -0
  67. package/studio/server/html-deck.mjs +168 -0
  68. package/studio/server/html-film.mjs +686 -0
  69. package/studio/server/html-pages.mjs +604 -0
  70. package/studio/server/http.mjs +40 -0
  71. package/studio/server/jianying.mjs +289 -0
  72. package/studio/server/keys.mjs +126 -0
  73. package/studio/server/main.mjs +120 -0
  74. package/studio/server/markers.mjs +80 -0
  75. package/studio/server/nle.mjs +537 -0
  76. package/studio/server/ops.mjs +506 -0
  77. package/studio/server/page-links.mjs +98 -0
  78. package/studio/server/pageframes.mjs +335 -0
  79. package/studio/server/pages.mjs +197 -0
  80. package/studio/server/prefs.mjs +56 -0
  81. package/studio/server/project-fonts.mjs +263 -0
  82. package/studio/server/project-settings.mjs +130 -0
  83. package/studio/server/projects.mjs +457 -0
  84. package/studio/server/providers/azure.mjs +100 -0
  85. package/studio/server/providers/brave.mjs +55 -0
  86. package/studio/server/providers/common.mjs +321 -0
  87. package/studio/server/providers/contract.mjs +98 -0
  88. package/studio/server/providers/doubao.mjs +65 -0
  89. package/studio/server/providers/edge-drm.mjs +263 -0
  90. package/studio/server/providers/edge-speech.mjs +292 -0
  91. package/studio/server/providers/edge-tts.mjs +112 -0
  92. package/studio/server/providers/elevenlabs.mjs +144 -0
  93. package/studio/server/providers/fal.mjs +212 -0
  94. package/studio/server/providers/google.mjs +201 -0
  95. package/studio/server/providers/groq.mjs +97 -0
  96. package/studio/server/providers/index.mjs +284 -0
  97. package/studio/server/providers/local-mdx.mjs +293 -0
  98. package/studio/server/providers/local-whisper.mjs +847 -0
  99. package/studio/server/providers/mdx-net.mjs +275 -0
  100. package/studio/server/providers/openai.mjs +131 -0
  101. package/studio/server/providers/pexels.mjs +40 -0
  102. package/studio/server/providers/pixabay.mjs +53 -0
  103. package/studio/server/providers/tar-bz2.mjs +356 -0
  104. package/studio/server/providers/tavily.mjs +68 -0
  105. package/studio/server/providers/web.mjs +231 -0
  106. package/studio/server/proxies.mjs +151 -0
  107. package/studio/server/recycle.mjs +222 -0
  108. package/studio/server/render-worker.mjs +29 -0
  109. package/studio/server/separate.mjs +44 -0
  110. package/studio/server/server.mjs +1021 -0
  111. package/studio/server/sfx.mjs +321 -0
  112. package/studio/server/skills.mjs +357 -0
  113. package/studio/server/slides.mjs +230 -0
  114. package/studio/server/stage.js +1553 -0
  115. package/studio/server/stock.mjs +122 -0
  116. package/studio/server/subtitle-edits.mjs +234 -0
  117. package/studio/server/subtitle-segments.mjs +602 -0
  118. package/studio/server/template-posters.mjs +68 -0
  119. package/studio/server/templates-page.mjs +93 -0
  120. package/studio/server/templates-styles.mjs +583 -0
  121. package/studio/server/templates.mjs +269 -0
  122. package/studio/server/transcripts.mjs +490 -0
  123. package/studio/server/transition-pages.mjs +43 -0
  124. package/studio/server/trash.mjs +143 -0
  125. package/studio/server/video-models.mjs +226 -0
  126. package/studio/server/watch.mjs +160 -0
  127. package/studio/server/web-agents.mjs +143 -0
  128. package/studio/server/websocket.mjs +82 -0
  129. package/studio/server/zip.mjs +159 -0
  130. package/studio/ui/dist/assets/ExportCenter-F-2vF-lQ.js +1 -0
  131. package/studio/ui/dist/assets/SettingsModal-BgVYguNu.js +2 -0
  132. package/studio/ui/dist/assets/app-icon-BpqHp2uj.png +0 -0
  133. package/studio/ui/dist/assets/es-BRUzvuoM.js +1 -0
  134. package/studio/ui/dist/assets/index-Bhg-9dA3.css +1 -0
  135. package/studio/ui/dist/assets/index-CWur1Iw9.js +1625 -0
  136. package/studio/ui/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  137. package/studio/ui/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  138. package/studio/ui/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  139. package/studio/ui/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  140. package/studio/ui/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  141. package/studio/ui/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  142. package/studio/ui/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  143. package/studio/ui/dist/assets/ja-Cth-uDcW.js +1 -0
  144. package/studio/ui/dist/assets/ko-upvw591D.js +1 -0
  145. package/studio/ui/dist/assets/zh-CN-BCfJFazB.js +1 -0
  146. package/studio/ui/dist/index.html +23 -0
@@ -0,0 +1,184 @@
1
+ # Recipes
2
+
3
+ Copy these, then change the words. Each is a whole file (or a whole `<section>`) and follows the rules in
4
+ [film-format.md](film-format.md).
5
+
6
+ ## A title card, editable in Studio
7
+
8
+ A page with no `width`/`height` is the whole stage. Text lives in DOM elements, so the person can select it in Studio
9
+ and retype it — a headline painted into a canvas cannot be edited that way.
10
+
11
+ ```html
12
+ <!doctype html>
13
+ <html>
14
+ <head>
15
+ <meta charset="utf-8">
16
+ <style>
17
+ html, body { margin: 0; height: 100%; background: transparent; }
18
+ .card { position: absolute; inset: 0; display: grid; place-content: center; gap: 28px;
19
+ font-family: system-ui, "Noto Sans SC", sans-serif; color: #fff; text-align: center; }
20
+ h1 { margin: 0; font-size: 132px; letter-spacing: -0.035em; line-height: 1; }
21
+ p { margin: 0; font-size: 44px; letter-spacing: 0.01em; opacity: 0.72; }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <div class="card">
26
+ <h1>Aura Pods</h1>
27
+ <p>quiet, by design</p>
28
+ </div>
29
+ <script type="module">
30
+ const card = document.querySelector('.card');
31
+ const clamp01 = (x) => Math.min(1, Math.max(0, x));
32
+ const ease = (x) => 1 - Math.pow(1 - clamp01(x), 3);
33
+ window.film = {
34
+ duration: 4,
35
+ ready: document.fonts.ready,
36
+ frame(t) {
37
+ const inn = ease(t / 0.9); // 0 → 1 over the first 0.9 s
38
+ const out = 1 - ease((t - 3.2) / 0.6); // 1 → 0 over the last 0.8 s
39
+ card.style.opacity = String(Math.min(inn, out));
40
+ card.style.transform = `translateY(${(1 - inn) * 28}px)`;
41
+ },
42
+ };
43
+ </script>
44
+ </body>
45
+ </html>
46
+ ```
47
+
48
+ In `film.html`, a page without a `duration` needs `#t=0,length`; this one has `duration: 4`, so `#t=0,4` also works
49
+ and says the same thing:
50
+
51
+ ```html
52
+ <section>
53
+ <iframe src="title.html" at="0" style="left: 0; top: 0; width: 1920px; height: 1080px"></iframe>
54
+ </section>
55
+ ```
56
+
57
+ ## A canvas shot, driven by t
58
+
59
+ Canvas is for what DOM cannot draw. Repaint the whole frame every call and let `t` decide everything — no
60
+ `Math.random()`, no `x += v`, no loop.
61
+
62
+ ```html
63
+ <!doctype html>
64
+ <html>
65
+ <head>
66
+ <meta charset="utf-8">
67
+ <style>html, body { margin: 0; height: 100%; background: #0b0b0f; }
68
+ canvas { display: block; width: 100%; height: 100%; }</style>
69
+ </head>
70
+ <body>
71
+ <canvas id="c"></canvas>
72
+ <script type="module">
73
+ const c = document.querySelector('#c');
74
+ const g = c.getContext('2d', { alpha: false });
75
+ const fit = () => {
76
+ const dpr = devicePixelRatio || 1;
77
+ c.width = Math.round(innerWidth * dpr);
78
+ c.height = Math.round(innerHeight * dpr);
79
+ };
80
+ fit();
81
+ addEventListener('resize', fit);
82
+ const ease = (x) => 1 - Math.pow(1 - Math.min(1, Math.max(0, x)), 3);
83
+
84
+ window.film = {
85
+ duration: 5,
86
+ frame(t) {
87
+ const k = ease(t / 1.1);
88
+ g.setTransform(1, 0, 0, 1, 0, 0);
89
+ g.fillStyle = '#0b0b0f';
90
+ g.fillRect(0, 0, c.width, c.height);
91
+
92
+ // a ring that draws itself, then breathes — all from t
93
+ const r = Math.min(c.width, c.height) * (0.12 + 0.03 * Math.sin(t * 1.6));
94
+ g.strokeStyle = 'rgba(127, 212, 255, 0.9)';
95
+ g.lineWidth = Math.max(2, c.width * 0.004);
96
+ g.beginPath();
97
+ g.arc(c.width / 2, c.height / 2, r, -Math.PI / 2, -Math.PI / 2 + k * Math.PI * 2);
98
+ g.stroke();
99
+ },
100
+ };
101
+ </script>
102
+ </body>
103
+ </html>
104
+ ```
105
+
106
+ ## Picture-in-picture, voice-over, a hit, and subtitles
107
+
108
+ The first track is on top: the title covers the footage while it is opaque, and the footage covers nothing. The
109
+ voice-over and the music sit in the last track, on film seconds. This one runs 7.5 s: the title for 4, the reel from
110
+ 1.5 to 7.5, the music to the end — no clip outlasts the film and nothing is black.
111
+
112
+ ```html
113
+ <!doctype html>
114
+ <html>
115
+ <head>
116
+ <meta charset="utf-8">
117
+ <meta name="viewport" content="width=1920, height=1080">
118
+ <style>
119
+ .round { border-radius: 24px; object-fit: cover; }
120
+ </style>
121
+ </head>
122
+ <body>
123
+ <section>
124
+ <iframe src="scenes/title.html" at="0" style="left: 0; top: 0; width: 1920px; height: 1080px"></iframe>
125
+ </section>
126
+ <section>
127
+ <video id="reel" src="assets/reel.mp4#t=4,10" at="1.5" volume="0.8" class="round"
128
+ style="left: 120px; top: 120px; width: 760px; height: 428px"></video>
129
+ </section>
130
+ <section>
131
+ <audio id="vo1" src="assets/vo/1.wav#t=0,6" at="1.5"></audio>
132
+ <audio id="bed" src="assets/bed.mp3#t=0,7.5" volume="0.28"></audio>
133
+ <audio id="hit" src="assets/sfx/hit.wav" at="1.5" volume="0.8"></audio>
134
+ </section>
135
+ </body>
136
+ </html>
137
+ ```
138
+
139
+ - `assets/vo/1.wav` is a 6-second read; `at="1.5"` puts its first word at film second 1.5, where the reel lands.
140
+ - The hit is heard as the reel appears. If it belonged inside a page playing at local time `t = 0.4`, its film second
141
+ would be `1.5 + 0.4 − 0 = 1.9`.
142
+ - `speed="0.5"` on the reel would halve its pace and double its length: `(10 − 4) / 0.5 = 12` seconds, so it would run
143
+ to 13.5 — the music would have to run that long too. Change one, check the other.
144
+
145
+ Words, in the file's own seconds, beside the sound (`assets/vo/1.vtt`):
146
+
147
+ ```vtt
148
+ WEBVTT
149
+
150
+ 00:00:00.200 --> 00:00:02.400
151
+ A pod that disappears in your ear.
152
+
153
+ 00:00:02.400 --> 00:00:05.200
154
+ <00:00:02.400>And <00:00:02.650>nothing <00:00:02.900>else.
155
+ ```
156
+
157
+ Studio makes the film's subtitles from those cues. Do not draw them in a page.
158
+
159
+ ## A music bed that fades under the voice
160
+
161
+ `fade` is the clip's own override entry — no `at`, so no selector:
162
+
163
+ ```html
164
+ <section>
165
+ <audio id="bed" src="assets/bed.mp3#t=8,48" at="0" volume="0.3"
166
+ overrides='[{"fade":[1.5,2]}]'></audio>
167
+ </section>
168
+ ```
169
+
170
+ `1.5` in and `2` out, seconds, ramping the gain (and the picture's opacity, for a clip that has one). Together they
171
+ may not be longer than the clip.
172
+
173
+ ## The order to work in
174
+
175
+ ```sh
176
+ npx -y @autoaiai/aicut@latest open my-film # prints Studio's address — open it
177
+ # write film.html, title.html, scenes/…
178
+ npx -y @autoaiai/aicut@latest look # the whole film, one sheet
179
+ npx -y @autoaiai/aicut@latest look 1.4-2.2 # the beat where the reel lands
180
+ npx -y @autoaiai/aicut@latest look assets/vo/1.wav # what the voice-over sounds like, and how loud
181
+ ```
182
+
183
+ Read the sheet: is the headline inside the frame, does the reel sit where you meant, is any stretch black that
184
+ should not be, is the loudness roughly level? Fix, then look again.
@@ -0,0 +1,57 @@
1
+ # When it does not work
2
+
3
+ Look first, guess second: `npx -y @autoaiai/aicut@latest look <page.html>` and `look <file>` draw what the host actually sees,
4
+ and a page's uncaught errors are reported there.
5
+
6
+ ## The frame is black, or the page is blank
7
+
8
+ | What you see | What it usually is | Do |
9
+ | --- | --- | --- |
10
+ | Nothing at all, no error | `window.film` never set | Set it from a `<script type="module">`, before `load`. A syntax error in the module does this silently. |
11
+ | Half the picture | `frame` throws on some `t` | Draw without try/catch once; the host reports the throw with its line. |
12
+ | Black from a WebGL page | The buffer was cleared before capture | Create the context with `preserveDrawingBuffer: true`. |
13
+ | Text invisible | A web font that never arrived | `ready: document.fonts.load('700 64px Inter')` per face, not just `document.fonts.ready`. |
14
+ | Black where a clip should be | The clip runs past its file | A still or a page without `duration` needs `#t=0,length`; a video's `#t=in,out` must be inside its own length. |
15
+ | A track shows nothing | The track is `hidden` | Only the person changes that. Say so rather than editing it. |
16
+
17
+ ## The picture changes on its own
18
+
19
+ The same `t` must draw the same picture — `look` checks it. Causes, in the order they bite:
20
+
21
+ - `Math.random()`, `Date.now()`, `performance.now()` used as a clock (the host pins them, but only while drawing).
22
+ - Accumulation across calls (`x += v`, a particle array mutated per frame). Compute from `t`, or precompute in
23
+ `ready` and look it up.
24
+ - A CSS animation, transition or WAAPI animation left running: its progress is history.
25
+ - GSAP `to`/`from` (they record start values the first time they run): use `fromTo` with explicit ends.
26
+ - A `<video>` seeked without awaiting `seeked`, so the captured frame is the previous one.
27
+ - A library's own clock: drive it — `timeline.seek(t)`, `animation.currentTime = t * 1000`, `p5.redraw()`.
28
+
29
+ ## Sound and subtitles are off
30
+
31
+ - **A hit lands early or late.** A page has no sound: the sound is a clip in `film.html`. A hit heard at page time
32
+ `t` goes at `at + t − in` film seconds. `speed` changes the length, not the start.
33
+ - **A clip is silent.** `volume="0"`, `muted`, or its track is `muted`/`hidden`. The film's sound is its sound clips
34
+ plus its video clips' own sound.
35
+ - **Subtitles do not appear.** The `.vtt` must sit beside the media with the same name (`assets/vo/1.wav` →
36
+ `assets/vo/1.vtt`), in the file's own seconds, one cue per line. `1.<language>.vtt` is a translation of it.
37
+ - **Subtitles drift after a trim.** They follow the clip's `#t=in,out` and `speed`; do not retime the `.vtt` yourself.
38
+ - **Subtitles are drawn twice.** A page is drawing them. Remove that: Studio draws the film's subtitles.
39
+
40
+ ## Commands
41
+
42
+ - **Exit 2, "not a project".** Run the command inside the film's folder, or name it: `open <folder>`. `look` and
43
+ `render` work on the project around the current folder.
44
+ - **Exit 1 from `render`.** The output says why. Usually no usable `ffmpeg` on `PATH` (install one, or use the
45
+ desktop app, which brings its own), or the film is enormous — lower `--workers`, or render a range to find it.
46
+ - **The first run hangs.** It is downloading a headless Chromium (about 100 MB). Behind a proxy, set `HTTPS_PROXY`
47
+ for that download, or use the desktop app.
48
+ - **An old version keeps answering.** `npx` remembers the first version it fetched for a name: always run
49
+ `npx -y @autoaiai/aicut@latest`, and `--version` to see which one answered.
50
+ - **Studio does not open.** `open` prints the address even when no browser opened by itself; open it by hand.
51
+ `AICUT_NO_BROWSER=1` stops it from ever opening one.
52
+
53
+ ## Editing a film someone else is editing
54
+
55
+ Studio writes `film.html` while the person works. Read it immediately before each change, write back only the part
56
+ you mean to change, keep every `overrides` exactly as it is, and never rewrite the whole file from memory — that
57
+ reverts what they did in the meantime.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AiCut contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,255 @@
1
+ ---
2
+ name: aicut-motion
3
+ description: 'Design motion films that look authored rather than generated — brand films, showreels, kinetic typography, explainers, data stories, product and UI promos, character stories, music videos, abstract loops, title sequences. Use when a film needs art direction — a style, a palette and type system, real transformations, a plan laid out on beats, and a critique of its own frames. Works on AICUT films (film.html and pages with window.film).'
4
+ license: MIT
5
+ ---
6
+
7
+ # Motion films with a direction
8
+
9
+ AICUT already knows how to make a film — `film.html` cutting pages, footage, pictures and sound. This is about
10
+ making one that looks designed: the same prompt, given to a strong model and to a weaker one, should give films that
11
+ look, move and sound almost the same.
12
+
13
+ The gap is rarely taste. It is behaviour:
14
+
15
+ - honour every value in a long prompt;
16
+ - turn vague words into concrete design decisions;
17
+ - design every element properly instead of settling for a placeholder;
18
+ - plan the whole timeline before writing a frame;
19
+ - build one shared system, so everything stays consistent;
20
+ - look at the output and fix it.
21
+
22
+ Read `npx -y @autoaiai/aicut@latest` once before the first film: it is the format and the tools, and it is authoritative. This
23
+ skill is how to decide what to draw.
24
+
25
+ ## Priority order
26
+
27
+ When rules compete, keep this order:
28
+
29
+ 1. **The prompt's own words**: every value, beat, copy line and ban.
30
+ 2. **Look and craft at the style's level**: composition, palette, type, and every element designed properly.
31
+ 3. **Continuity**: real transformations, persistent identity, plausible physics.
32
+ 4. **Rhythm and sound.**
33
+ 5. **Bookkeeping**: ledgers, tables, checks. They serve 1–4 and never replace them.
34
+
35
+ **Helpers are mechanics, not style.** A page's easing function decides how something moves; it never decides what it
36
+ looks like. Never ship a plain box or a default figure as the design, and never carry one film's palette into
37
+ another. Every film gets its own designed look.
38
+
39
+ ## When a request comes in
40
+
41
+ - Any request for a motion piece runs the pipeline. Ask nothing: resolve gaps in stage 1 and say so in 解读.
42
+ - **Each new prompt is a new film**, built in a new folder, even in a conversation that already made one. Reuse
43
+ earlier work only when the person says to change it (修改, 改一下, 在上一版基础上, fix this).
44
+ - **Modes.** The default builds. 只要提示词 / 扩写 / "prompt only" stops after stage 2 and prints the brief.
45
+ - If the message has no idea in it, reply only: “请给我一句话的创意或一段完整的提示词。”
46
+
47
+ ## Stage 0 — read the prompt like a director
48
+
49
+ Three ledgers, before any file is written.
50
+
51
+ - **Spec ledger** `S01…` — one row per value or instruction, quoted exactly: durations, sizes, colours, fonts,
52
+ weights, copy, counts, angles, positions, timings, easing, bans, the loop or ending, characters, every storyboard
53
+ beat. The film's `viewport` and its length come from these rows; a placeholder value from a template must never
54
+ survive. A truncated prompt is completed in the voice and density of its last full section, those rows marked
55
+ `S##*`.
56
+ - **Transformation ledger** `X01…` — every becoming verb (becomes, turns into, gathers, dissolves, unfolds, grows
57
+ into, 变成, 化成, 收拢, 汇聚, 展开) as `source → target · mechanism · start–end s · what is conserved`.
58
+ - **Element ledger** `E01…` — every thing drawn or typed, with its playbook (type, object, character, environment,
59
+ data, UI, transition, texture-light, sound), listing three or more structural features, size and coordinates, how
60
+ it moves, and — for characters — the design sheet and named poses.
61
+
62
+ Each scene also gets its back-to-front layer list.
63
+
64
+ Every value is binding: never round, rename, recolour, re-time or drop one. The last third of a long prompt counts as
65
+ much as the first. If two rows conflict, keep the more specific one and say so in 解读.
66
+
67
+ In the files: constants live at the top of the page that uses them, tagged `// S07`; each builder is tagged `// E03`;
68
+ each beat inside `frame` is tagged `// S31 X02`.
69
+
70
+ ## Stage 1 — fill gaps the way a director does
71
+
72
+ Only where the prompt is silent; never override a ledger row.
73
+
74
+ | Gap | Default |
75
+ | --- | --- |
76
+ | Format | 1920 × 1080 (the film's `<meta name="viewport">`); a stated format is binding |
77
+ | Duration | 15 s for an idea, 30 s for a showreel or brand film; state it as the last clip's end |
78
+ | Ending | A seamless loop for reels and idents (the `t = D` frame equals frame 0, all motion at rest); a resolved final image or end card for stories and promos |
79
+ | Rhythm | Calm 60–90 BPM, brand 110–128, energetic 128–140. Dense pieces have an event on every beat, calm ones on every bar. Holds ≤ 0.5 s when dense, as long as the copy needs when calm |
80
+ | Narrative | One motif or carrier connects the film; each scene grows out of the one before; no unrelated title cards |
81
+ | Camera | Locked and front-on unless the prompt implies movement |
82
+ | Composition | From the style's occupancy and whitespace. Nothing at rest within 150 px of the sides, 90 px of the top and bottom |
83
+ | Typography | One family with character; the payoff word or number in the heaviest weight at the largest size. Latin: Inter, Geist, Space Grotesk, Fraunces. Chinese: Noto Sans SC, Noto Serif SC |
84
+ | Palette | 3–5 colours with roles; the accent foreshadows what comes next |
85
+ | Texture and light | Material per element, scaled to its size; light from a motivated source |
86
+ | Detail | Three recurring micro-details that make the film feel authored (labels, ticks, legends, timecodes, signage) — no new claims, numbers or copy |
87
+ | Captions | On-screen speech, lyrics or subtitles: ≥ 40 px at 1080p, high contrast, lower third, whole line held for its reading window (≈ 0.25 s per Chinese character, ≈ 3 Latin words per second) |
88
+ | Sound | A track that fits the mood, or ambience for an environment-led scene; silent only if asked |
89
+
90
+ ## Stage 2 — the design contract
91
+
92
+ **Where the style comes from:**
93
+
94
+ 1. **The prompt states it** — palette, materials, type, references. The contract comes from the ledger alone.
95
+ 2. **The prompt names a feeling, medium or reference** ("like a newspaper", 水墨, "terminal", "Swiss poster") —
96
+ start from the closest seed in `references/design-systems/` and adapt it.
97
+ 3. **The prompt is a bare idea** — synthesise a contract with the method below. Seeds are starting points, not
98
+ defaults.
99
+
100
+ **Synthesis method:**
101
+
102
+ 1. **Subject → world.** What material world does this subject live in: paper, ink, glass, metal, fabric, screens,
103
+ nature, a city, a lab. Pick one, plus at most one contrasting world to transform into.
104
+ 2. **Audience and mood → energy.** Calm or punchy, warm or precise, playful or serious. Sets tempo, easing,
105
+ overshoot, density.
106
+ 3. **Make it concrete.** Write values, not adjectives: palette hexes with roles; type family, weights, sizes,
107
+ tracking; how lines, fills and shapes are drawn; texture and light per element; occupancy and the edge rule;
108
+ easing per move type; which mechanism changes which scene; signature details; sound palette; bans.
109
+ 4. **Check against slop.** Every choice must be traceable to the subject or the prompt. Generic gradients, glows and
110
+ template layouts are exactly what the contract exists to replace.
111
+
112
+ Seeds: `drafting-table` (process, tools, engineering) · `swiss-kinetic` (brands, launches, statements) ·
113
+ `editorial-ink` (culture, craft, heritage, East Asian) · `data-instrument` (explainers, finance, science) ·
114
+ `bold-poster` (music, sport, youth) · `riso-halftone` (indie, retro, playful) · `storybook-scene` (characters,
115
+ stories, MVs).
116
+
117
+ **Short prompts:** write the full brief first, at that density — a direction paragraph, the contract, the structure
118
+ (tempo, named scenes, scene changes), characters if any, and a scene-by-scene storyboard with timestamps and
119
+ numbers. That brief becomes the ledgers. In prompt-only mode, output it and stop.
120
+
121
+ ## Stage 3 — the timeline before the code
122
+
123
+ 1. One row per scene: `start–end s · name · what the viewer learns · carried element in → out · transition out (X##)`.
124
+ 2. Every event: `t · element (E##) · action · numbers · ids`.
125
+ 3. The key times as a `T` block.
126
+ 4. The sound cues, derived from the same events — this is where each `<audio>` clip goes in `film.html`.
127
+
128
+ Checks before going on:
129
+
130
+ - beats fall on multiples of `60 / BPM`;
131
+ - each scene's exit state is the next scene's entry state (same element, same slot, same colour);
132
+ - no two actions drive one property at once;
133
+ - everything finishes before the end;
134
+ - for a loop, the `t = D` frame equals frame 0 with all motion at rest.
135
+
136
+ ## Stage 4 — design before motion
137
+
138
+ 1. Build each element's geometry from its structural features, at module level, once.
139
+ 2. For characters, draw a **character sheet** first: one still with every character in every named pose, holding its
140
+ props.
141
+ 3. Fix the key compositions as exact pixel layouts: frame 0, the first full frame of each scene or material, the last
142
+ frame. Check each against the contract's occupancy and whitespace.
143
+ 4. Code those static states before the motion between them. A weak still is never rescued by motion. Look at them
144
+ with `look` before going on.
145
+
146
+ ## Element playbooks
147
+
148
+ | Element | Build it | Move it | The usual failure |
149
+ | --- | --- | --- | --- |
150
+ | **Type** | One family; hierarchy by weight and size; tracking set per size; big words on one line, fitted to their stated width; split words keep their spaces; CJK may run vertical | Arrive on `EASE.out`; stagger 0.02–0.06 s; slot clips, slides on rails, scale reveals; readable hold before exit | Words run together, orphan lines, captions too small or low contrast, the payoff not the heaviest type |
151
+ | **Object** | Three or more structural features of the real thing; one shade side for volume; consistent outline policy; built once as a function | Motion from its nature: paper bends at a fold, liquid ripples, metal turns on an axis, light switches | A symbol instead of the thing, floating parts, inconsistent scale between shots |
152
+ | **Character** | A design sheet: silhouette, proportions, colours, face, marks, and named poses — never a stick figure unless asked | Interpolate between named poses, small readable acting beats; feet on the ground, hands on what they hold | The look drifting between shots, hands off held props, limbs through the head, feet off the ground |
153
+ | **Environment** | Layers back to front: sky or wall, far, mid, ground, foreground. Motivated light sources and their light shapes. Weather across the frame in two depths | Ambient life that never stops (weather, lights, small loops); the camera stays still unless asked | A flat backdrop, weather passing through solid objects, missing light logic, edge-to-edge clutter |
154
+ | **Data** | Axes and units first, values exact from the ledger, labels attached to marks, one chart per scene | Axes, then data, then annotation; counters roll with their mark; charts morph through shared slots | Wrong numbers, unlabelled axes, decoration over data, labels ignoring the prompt's wording |
155
+ | **UI / product** | Real screens or faithful reconstructions: crisp rectangles, true proportions, real hierarchy | Cursor-driven or state-driven changes; zoom into the region that changes | Stretched screenshots, fake interface noise, unreadable small text |
156
+ | **Transition** | A physical mechanism: morph, merge, mask or wipe, material change, unfold, match on a shared shape | Hard edges, planned on a beat, the source gone as the target forms | Crossfades, cuts the prompt didn't ask for, things popping in, identity lost across a material change |
157
+ | **Texture and light** | Paper and grain as separate layers (`feTurbulence` + `feDisplacementMap`); halftone and hatching as `<pattern>`; light as shapes (cones, lit windows, reflections) | Seeded and stable, or boiling at a fixed step rate (`stepped`) | One texture on everything, decorative glow, flicker from unseeded noise |
158
+ | **Sound** | A bed (music or ambience) plus one clip per visual hit, placed on the `T` block in `film.html` | Synced to the beats; a loop's tail folds into its start | Silence by omission, noise used as music, hits out of sync |
159
+
160
+ ## Rules that hold in every film
161
+
162
+ 1. **Becoming is real.** Every X row morphs the same object point by point — equal point counts, one path
163
+ interpolated to the other. The source is gone when the target forms, and the target is fully reached: "becomes a
164
+ bar chart" ends as bars. Parts are born at their source and travel. Merges and splits conserve quantity. Never
165
+ fake a transformation with an overlay, a crossfade, or by scaling the whole frame.
166
+ 2. **Identity persists.** An element keeps its colour, its shape and its slot through every scene and material
167
+ change unless the prompt says otherwise. Elements that turn into one another share a slot constant — a lane, a
168
+ baseline, an anchor.
169
+ 3. **Physics and depth are explicit.** Each scene has a back-to-front layer list. Weather respects occluders; things
170
+ behind glass are tinted; reflections mirror their source; shadows share one light direction. Contacts are
171
+ computed, not eyeballed.
172
+ 4. **Space words are coordinates.** On 1920 × 1080: centre (960, 540); the thirds at x ≈ 640 and x ≈ 1280; upper
173
+ y ≈ 360; lower y ≈ 760. Scale for other formats.
174
+ 5. **Energy is even.** On-screen change follows the tempo. Spikes are planned hits; no dead seconds unless the hold
175
+ is planned.
176
+ 6. **Sound by default**, on its own track, never drawn in a page.
177
+ 7. **Finish and check.** Write every scene completely, run the jury, fix until every juror scores 8 or more.
178
+
179
+ ## Stage 5 — build in AICUT
180
+
181
+ ```
182
+ my-film/
183
+ film.html the cut: viewport, tracks, every clip and every sound
184
+ scenes/SceneNN.html one page per shot: window.film = { frame(t), duration, ready }
185
+ lib/… a page's own shared code (easing, geometry), loaded by relative path
186
+ assets/ media, including the sound
187
+ ```
188
+
189
+ **Rules:**
190
+
191
+ - **Time.** `frame(t)` only. Time is the page's own seconds from 0. No CSS animations, no `requestAnimationFrame`
192
+ loop, no `Date`, no `Math.random()` (seed by hand if you need variation), no state carried between frames.
193
+ - **One page per shot.** A five-shot film is five pages cut together in `film.html`, so the person can reorder or
194
+ replace one. Anything the pages share goes in `lib/`.
195
+ - **Placement is `film.html`'s.** `left`, `top`, `width`, `height`, `rotate` on the clip's `style`. Never position the
196
+ page itself from inside, and never animate the clip's box — that is the cut, not the motion.
197
+ - **Easing.** Write it once in `lib/motion.js` and import it everywhere: a `prog(t, start, dur, ease)` clamped to
198
+ 0..1, the four curves below, and a spring that lands on a beat. `references/pages.md` has the file.
199
+ - **Type.** HTML for set type (so the person can edit the words), per-letter spans for per-letter motion, SVG
200
+ `<text>` for pattern fills, outlines and clips. `writing-mode: vertical-rl` for vertical CJK.
201
+ - **Fonts.** System stacks, or a font in `assets/` with `document.fonts.load('700 64px …')` awaited in `ready`.
202
+ Never a font that may not arrive.
203
+ - **Sound.** A music or ambience `<audio>` clip, plus one clip per hit on its own track, all in `film.html`. Generated
204
+ music and effects come from `npx -y @autoaiai/aicut@latest get`, once the person has connected a service.
205
+ - **Completeness.** No TODOs. If space runs out, stop at the end of a file with `// CONTINUE FROM <path>`.
206
+
207
+ ## Stage 6 — the jury
208
+
209
+ Five jurors score 1–10. Each names its worst moment with a timestamp.
210
+
211
+ 1. **SPEC.** Every S, X and E row is implemented with its exact value. Missing or changed ids listed. This score caps
212
+ the total.
213
+ 2. **CONTINUITY.** Every X row is a real transformation that reaches its target, parts born at their source. Identity
214
+ and slots persist through scenes and materials. Physics and depth are correct.
215
+ 3. **RHYTHM & SOUND.** Events land on beats; easing matches the contract; energy is even with no unplanned spikes or
216
+ dead seconds; every hit has its sound; the loop seam is clean.
217
+ 4. **DESIGN.** Hero frames match their layouts; occupancy and whitespace match the contract; every element passes its
218
+ playbook check (look at stills zoomed in on type, faces, hands, props, data labels); the look is designed for this
219
+ film, not a default and not an example's.
220
+ 5. **CRAFT.** Texture and light are per element; the film is deterministic; nothing from the ban list — unrequested
221
+ gradients, glow (bloom, neon halos, lens flares), generic fade-ins, bounce where forbidden, particle bursts,
222
+ camera shake, RGB split, centred-title-over-cards, stock icons and emoji, placeholder copy, anything that reads as
223
+ a template. Motivated light drawn as shapes is allowed.
224
+
225
+ Fix everything below 8, worst first, up to three rounds.
226
+
227
+ **How to look:**
228
+
229
+ ```sh
230
+ npx -y @autoaiai/aicut@latest look # the whole film: contact sheet, sound, loudness, same-t check
231
+ npx -y @autoaiai/aicut@latest look 4.5 # one frame at full size
232
+ npx -y @autoaiai/aicut@latest look 3-6 # a stretch, densely
233
+ TIMES are worth naming: the first frame, each scene's first full frame, the loop seam
234
+ ```
235
+
236
+ Read the PNGs it writes. Trust the stills over the code: a format mismatch, a leftover placeholder, missing audio, a
237
+ flash of the wrong colour at `t = 0`, a bad loop seam.
238
+
239
+ ## Stage 7 — hand it over
240
+
241
+ Reply in this order:
242
+
243
+ 1. **解读** (the person's language, ≤ 6 lines): the style source, the assumptions, the conflicts, the inferred
244
+ `S##*` rows.
245
+ 2. **Ledgers and timeline** in one fenced block, kept for later rounds.
246
+ 3. **Files**, each headed by its path: `film.html`, every `scenes/*.html`, `lib/*.js`.
247
+ 4. **Parity table**: `X## · source → target · mechanism · file`; `E## · playbook · features drawn · file · identity
248
+ kept across materials`; `format · W×H · duration · S##`. Any X row done by overlay, crossfade or whole-frame
249
+ scaling is a failure — fix it before replying.
250
+ 5. **Jury**: five scores, and the three things you are least sure of.
251
+ 6. **运行方法**: `npx -y @autoaiai/aicut@latest open <folder>` and open the address it prints; `look` to check; `render` for
252
+ the MP4 when the person wants the file.
253
+
254
+ **Follow-ups.** 继续 → only the remaining files. 评审修复 → run stage 6 on new stills, then output only the changed
255
+ files, in full.
@@ -0,0 +1,25 @@
1
+ # Design systems
2
+
3
+ Use one only when the prompt does not state its own style (SKILL.md stage 2).
4
+
5
+ Each file is a base contract: adapt the palette, the copy and the details to the idea, and keep the mechanisms. When
6
+ none fits, write a new contract in the same sections — that is often the right answer.
7
+
8
+ | File | Fits |
9
+ | --- | --- |
10
+ | `drafting-table.md` | Designers, tools, process, engineering, "how it's made" |
11
+ | `swiss-kinetic.md` | Brands, launches, statements, events, tech |
12
+ | `editorial-ink.md` | Culture, food, books, craft, heritage, Chinese themes |
13
+ | `data-instrument.md` | Explainers, finance, science, products with numbers |
14
+ | `bold-poster.md` | Music, sport, youth, fashion, campaigns |
15
+ | `riso-halftone.md` | Indie, zines, retro, nostalgia, playful brands |
16
+ | `storybook-scene.md` | Stories, characters, music videos and lyric clips, picture books |
17
+
18
+ Every seed uses the same functions, all in `../pages.md`: `prog`, `EASE`, `settle`, `beats`, `stepped`, `wobble`,
19
+ `rand`, `ring`, `polygon`, `toPath`, `morphPts`, `drawOn`, `revealInset`, `revealCircle`, `counter`, `poseAt`. Copy
20
+ `lib/motion.js` from there into the film once; do not paste helpers into a scene.
21
+
22
+ The sound lines name instruments (`kick`, `pluck`, `scratch`, …). AICUT has no synthesiser: those are descriptions
23
+ of the effects to fetch with `npx -y @autoaiai/aicut@latest get` or to bring as files under `assets/`, one `<audio>` clip per hit
24
+ on the `T` block. Write the cue list down even when the files are not there yet, so the film can be finished later
25
+ without re-deciding the rhythm.
@@ -0,0 +1,62 @@
1
+ # bold-poster
2
+
3
+ Fits: music, sport, youth brands, fashion, festivals, campaigns. Not for: finance, heritage, calm topics.
4
+
5
+ ## Palette
6
+
7
+ - Three or four saturated flat colours with roles, e.g. electric blue `#2346FF`, hot pink `#FF4FA3`, acid yellow
8
+ `#E8FF3A`, black `#0B0B0B` or white `#FFFFFF`.
9
+ - Every scene takes a different background from that set — the change of background is the scene change.
10
+
11
+ ## Type
12
+
13
+ - Ultra-heavy condensed or wide display at 900, 300–700 px, cropped by the frame: Anton, Archivo Black or Bebas Neue
14
+ for Latin; ZCOOL QingKe HuangYou or Noto Sans SC 900 for Chinese.
15
+ - Stacked lines, tight leading (0.85): one `<span>` per line, `line-height: 0.85`.
16
+
17
+ ## Marks, in a page
18
+
19
+ - Flat cut-out shapes — stars, circles, arrows — drawn as plain `<path>` with a flat fill and no stroke.
20
+ - Photo-free collage of colour blocks.
21
+ - Stickers: a shape with a 6 px white outline (`stroke="#fff" stroke-width="12"` behind it, or `paint-order: stroke`).
22
+
23
+ ## Texture
24
+
25
+ One grain rect at 0.08 with `mix-blend-mode: overlay`; flat otherwise.
26
+
27
+ ## Layout
28
+
29
+ - Edge to edge. Type bleeds off the frame. Diagonals at 8–15°.
30
+ - Elements overlap; a big shape behind a big word.
31
+
32
+ ## Composition
33
+
34
+ - Occupancy 80–100%; type and shapes bleed off edges on purpose.
35
+ - One giant element per scene; diagonals at 8–15°.
36
+
37
+ ## Motion character
38
+
39
+ - 128–140 BPM. Punchy: `settle` with `{ bounce: 0.3–0.6 }`, dur 0.2–0.35 s.
40
+ - Squash and stretch on landing: `scale(1 + 0.08 * (1 - p), 1 - 0.08 * (1 - p))` during the last 0.1 s.
41
+ - Repeated words strobe in colour on beats (swap `color` at `beats.index(t)`, not a fade).
42
+ - Shapes spin at fixed beat steps: `rotate(${stepped(t, bpm / 60 * 2) * 90}deg)`.
43
+
44
+ ## Transition grammar
45
+
46
+ - A colour block slams in from a side and becomes the next background (one full-frame rect, `left` from ±100%).
47
+ - Type scales up until it fills the frame, and its colour becomes the next scene's background.
48
+ - A shape iris-opens on the beat: `revealCircle(p)` at the shape's centre.
49
+
50
+ ## Signature details
51
+
52
+ A repeating word or chant that changes colour each beat; stickers with numbers or dates; a final lock-up that shakes
53
+ once on the last beat (scale the lock-up, never the camera).
54
+
55
+ ## Sound
56
+
57
+ - `kick` on every beat, `clap` on 2 and 4, `hat` on eighths; `boom` on the final lock-up; `whoosh` on colour slams.
58
+ - 128–140 BPM.
59
+
60
+ ## Bans
61
+
62
+ Muted palettes, thin type, long holds, crossfades, realistic shadows, generic gradients.