frameyard 0.8.0 → 0.10.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 (327) hide show
  1. package/CHANGELOG.md +177 -14
  2. package/GLOSSARY.md +112 -2
  3. package/README.md +302 -265
  4. package/dist/assets/integrations.d.ts +8 -4
  5. package/dist/assets/integrations.d.ts.map +1 -1
  6. package/dist/assets/integrations.js +8 -4
  7. package/dist/assets/integrations.js.map +1 -1
  8. package/dist/assets/provenance.d.ts +2 -2
  9. package/dist/assets/provenance.d.ts.map +1 -1
  10. package/dist/assets/provenance.js +5 -3
  11. package/dist/assets/provenance.js.map +1 -1
  12. package/dist/assets/tts-supertonic.d.ts +28 -0
  13. package/dist/assets/tts-supertonic.d.ts.map +1 -0
  14. package/dist/assets/tts-supertonic.js +156 -0
  15. package/dist/assets/tts-supertonic.js.map +1 -0
  16. package/dist/assets/tts.d.ts +18 -6
  17. package/dist/assets/tts.d.ts.map +1 -1
  18. package/dist/assets/tts.js +219 -97
  19. package/dist/assets/tts.js.map +1 -1
  20. package/dist/cli.js +1685 -93
  21. package/dist/cli.js.map +1 -1
  22. package/dist/composition/format.d.ts +1 -1
  23. package/dist/composition/format.d.ts.map +1 -1
  24. package/dist/composition/format.js +1 -1
  25. package/dist/composition/format.js.map +1 -1
  26. package/dist/context.d.ts +82 -0
  27. package/dist/context.d.ts.map +1 -0
  28. package/dist/context.js +277 -0
  29. package/dist/context.js.map +1 -0
  30. package/dist/contracts.d.ts +25 -0
  31. package/dist/contracts.d.ts.map +1 -1
  32. package/dist/contracts.js.map +1 -1
  33. package/dist/doctor.d.ts +14 -1
  34. package/dist/doctor.d.ts.map +1 -1
  35. package/dist/doctor.js +166 -7
  36. package/dist/doctor.js.map +1 -1
  37. package/dist/errors.d.ts +1 -1
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/errors.js.map +1 -1
  40. package/dist/fonts/add.d.ts +41 -0
  41. package/dist/fonts/add.d.ts.map +1 -0
  42. package/dist/fonts/add.js +259 -0
  43. package/dist/fonts/add.js.map +1 -0
  44. package/dist/fonts/binary.d.ts +4 -0
  45. package/dist/fonts/binary.d.ts.map +1 -0
  46. package/dist/fonts/binary.js +21 -0
  47. package/dist/fonts/binary.js.map +1 -0
  48. package/dist/fonts/css.d.ts +4 -0
  49. package/dist/fonts/css.d.ts.map +1 -0
  50. package/dist/fonts/css.js +50 -0
  51. package/dist/fonts/css.js.map +1 -0
  52. package/dist/fonts/fontsource.d.ts +107 -0
  53. package/dist/fonts/fontsource.d.ts.map +1 -0
  54. package/dist/fonts/fontsource.js +565 -0
  55. package/dist/fonts/fontsource.js.map +1 -0
  56. package/dist/fonts/index.d.ts +11 -0
  57. package/dist/fonts/index.d.ts.map +1 -0
  58. package/dist/fonts/index.js +11 -0
  59. package/dist/fonts/index.js.map +1 -0
  60. package/dist/fonts/install.d.ts +24 -0
  61. package/dist/fonts/install.d.ts.map +1 -0
  62. package/dist/fonts/install.js +145 -0
  63. package/dist/fonts/install.js.map +1 -0
  64. package/dist/fonts/manifest.d.ts +21 -0
  65. package/dist/fonts/manifest.d.ts.map +1 -0
  66. package/dist/fonts/manifest.js +96 -0
  67. package/dist/fonts/manifest.js.map +1 -0
  68. package/dist/fonts/options.d.ts +9 -0
  69. package/dist/fonts/options.d.ts.map +1 -0
  70. package/dist/fonts/options.js +66 -0
  71. package/dist/fonts/options.js.map +1 -0
  72. package/dist/fonts/schema.d.ts +4 -0
  73. package/dist/fonts/schema.d.ts.map +1 -0
  74. package/dist/fonts/schema.js +316 -0
  75. package/dist/fonts/schema.js.map +1 -0
  76. package/dist/fonts/summary.d.ts +16 -0
  77. package/dist/fonts/summary.d.ts.map +1 -0
  78. package/dist/fonts/summary.js +22 -0
  79. package/dist/fonts/summary.js.map +1 -0
  80. package/dist/fonts/types.d.ts +56 -0
  81. package/dist/fonts/types.d.ts.map +1 -0
  82. package/dist/fonts/types.js +8 -0
  83. package/dist/fonts/types.js.map +1 -0
  84. package/dist/fonts/verify.d.ts +33 -0
  85. package/dist/fonts/verify.d.ts.map +1 -0
  86. package/dist/fonts/verify.js +200 -0
  87. package/dist/fonts/verify.js.map +1 -0
  88. package/dist/html/validate.d.ts.map +1 -1
  89. package/dist/html/validate.js +59 -0
  90. package/dist/html/validate.js.map +1 -1
  91. package/dist/index.d.ts +3 -3
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/inspect.d.ts +61 -0
  96. package/dist/inspect.d.ts.map +1 -0
  97. package/dist/inspect.js +325 -0
  98. package/dist/inspect.js.map +1 -0
  99. package/dist/lint.d.ts +63 -0
  100. package/dist/lint.d.ts.map +1 -0
  101. package/dist/lint.js +265 -0
  102. package/dist/lint.js.map +1 -0
  103. package/dist/policy.d.ts +69 -0
  104. package/dist/policy.d.ts.map +1 -0
  105. package/dist/policy.js +361 -0
  106. package/dist/policy.js.map +1 -0
  107. package/dist/preview/fonts/LICENSE-figtree.txt +93 -0
  108. package/dist/preview/fonts/LICENSE-space-mono.txt +93 -0
  109. package/dist/preview/fonts/README.md +23 -0
  110. package/dist/preview/fonts/figtree-latin-wght-normal.woff2 +0 -0
  111. package/dist/preview/fonts/space-mono-latin-400-normal.woff2 +0 -0
  112. package/dist/preview/fonts/space-mono-latin-700-normal.woff2 +0 -0
  113. package/dist/preview/main.js +5 -2
  114. package/dist/preview/main.js.map +1 -1
  115. package/dist/preview/timeline-data.d.ts +17 -69
  116. package/dist/preview/timeline-data.d.ts.map +1 -1
  117. package/dist/preview/timeline-host.d.ts.map +1 -1
  118. package/dist/preview/timeline-host.js +70 -45
  119. package/dist/preview/timeline-host.js.map +1 -1
  120. package/dist/preview/timeline-main.d.ts.map +1 -1
  121. package/dist/preview/timeline-main.js +88 -27
  122. package/dist/preview/timeline-main.js.map +1 -1
  123. package/dist/project.d.ts +10 -3
  124. package/dist/project.d.ts.map +1 -1
  125. package/dist/project.js +20 -17
  126. package/dist/project.js.map +1 -1
  127. package/dist/renderer/audio.d.ts +6 -0
  128. package/dist/renderer/audio.d.ts.map +1 -1
  129. package/dist/renderer/audio.js +3 -1
  130. package/dist/renderer/audio.js.map +1 -1
  131. package/dist/renderer/browser.d.ts.map +1 -1
  132. package/dist/renderer/browser.js +13 -0
  133. package/dist/renderer/browser.js.map +1 -1
  134. package/dist/renderer/concurrency.d.ts +6 -0
  135. package/dist/renderer/concurrency.d.ts.map +1 -0
  136. package/dist/renderer/concurrency.js +27 -0
  137. package/dist/renderer/concurrency.js.map +1 -0
  138. package/dist/renderer/ffmpeg.d.ts +104 -5
  139. package/dist/renderer/ffmpeg.d.ts.map +1 -1
  140. package/dist/renderer/ffmpeg.js +580 -67
  141. package/dist/renderer/ffmpeg.js.map +1 -1
  142. package/dist/renderer/index.js +1 -1
  143. package/dist/renderer/index.js.map +1 -1
  144. package/dist/renderer/keyframe-expressions.d.ts +39 -0
  145. package/dist/renderer/keyframe-expressions.d.ts.map +1 -0
  146. package/dist/renderer/keyframe-expressions.js +180 -0
  147. package/dist/renderer/keyframe-expressions.js.map +1 -0
  148. package/dist/renderer/session-pool.d.ts +28 -0
  149. package/dist/renderer/session-pool.d.ts.map +1 -0
  150. package/dist/renderer/session-pool.js +91 -0
  151. package/dist/renderer/session-pool.js.map +1 -0
  152. package/dist/renderer/timeline.d.ts +2 -0
  153. package/dist/renderer/timeline.d.ts.map +1 -1
  154. package/dist/renderer/timeline.js +600 -147
  155. package/dist/renderer/timeline.js.map +1 -1
  156. package/dist/renderer/timings.d.ts +13 -0
  157. package/dist/renderer/timings.d.ts.map +1 -0
  158. package/dist/renderer/timings.js +29 -0
  159. package/dist/renderer/timings.js.map +1 -0
  160. package/dist/runtime/host.d.ts.map +1 -1
  161. package/dist/runtime/host.js +4 -0
  162. package/dist/runtime/host.js.map +1 -1
  163. package/dist/scaffold.d.ts +3 -0
  164. package/dist/scaffold.d.ts.map +1 -1
  165. package/dist/scaffold.js +48 -320
  166. package/dist/scaffold.js.map +1 -1
  167. package/dist/server/composition-html.d.ts +2 -0
  168. package/dist/server/composition-html.d.ts.map +1 -1
  169. package/dist/server/composition-html.js +7 -0
  170. package/dist/server/composition-html.js.map +1 -1
  171. package/dist/server/preview-html.d.ts.map +1 -1
  172. package/dist/server/preview-html.js +74 -188
  173. package/dist/server/preview-html.js.map +1 -1
  174. package/dist/server/preview-style.d.ts +11 -0
  175. package/dist/server/preview-style.d.ts.map +1 -0
  176. package/dist/server/preview-style.js +298 -0
  177. package/dist/server/preview-style.js.map +1 -0
  178. package/dist/server/server.d.ts.map +1 -1
  179. package/dist/server/server.js +31 -1
  180. package/dist/server/server.js.map +1 -1
  181. package/dist/server/timeline-preview-data.d.ts.map +1 -1
  182. package/dist/server/timeline-preview-data.js +12 -34
  183. package/dist/server/timeline-preview-data.js.map +1 -1
  184. package/dist/server/timeline-preview-html.d.ts.map +1 -1
  185. package/dist/server/timeline-preview-html.js +140 -148
  186. package/dist/server/timeline-preview-html.js.map +1 -1
  187. package/dist/templates.d.ts +16 -0
  188. package/dist/templates.d.ts.map +1 -0
  189. package/dist/templates.js +186 -0
  190. package/dist/templates.js.map +1 -0
  191. package/dist/timeline/easing.d.ts +36 -0
  192. package/dist/timeline/easing.d.ts.map +1 -0
  193. package/dist/timeline/easing.js +225 -0
  194. package/dist/timeline/easing.js.map +1 -0
  195. package/dist/timeline/keyframes.d.ts +23 -0
  196. package/dist/timeline/keyframes.d.ts.map +1 -0
  197. package/dist/timeline/keyframes.js +95 -0
  198. package/dist/timeline/keyframes.js.map +1 -0
  199. package/dist/timeline/plan.d.ts +6 -12
  200. package/dist/timeline/plan.d.ts.map +1 -1
  201. package/dist/timeline/plan.js +17 -30
  202. package/dist/timeline/plan.js.map +1 -1
  203. package/dist/timeline/resolve.d.ts +12 -0
  204. package/dist/timeline/resolve.d.ts.map +1 -1
  205. package/dist/timeline/resolve.js +105 -9
  206. package/dist/timeline/resolve.js.map +1 -1
  207. package/dist/timeline/scene.d.ts +126 -0
  208. package/dist/timeline/scene.d.ts.map +1 -0
  209. package/dist/timeline/scene.js +109 -0
  210. package/dist/timeline/scene.js.map +1 -0
  211. package/dist/timeline/schema.d.ts +31 -0
  212. package/dist/timeline/schema.d.ts.map +1 -1
  213. package/dist/timeline/schema.js +240 -9
  214. package/dist/timeline/schema.js.map +1 -1
  215. package/dist/timeline/transitions.d.ts +21 -0
  216. package/dist/timeline/transitions.d.ts.map +1 -0
  217. package/dist/timeline/transitions.js +23 -0
  218. package/dist/timeline/transitions.js.map +1 -0
  219. package/dist/version.d.ts +1 -1
  220. package/dist/version.d.ts.map +1 -1
  221. package/dist/version.js +1 -1
  222. package/dist/version.js.map +1 -1
  223. package/docs/adr/0007-make-html-documents-the-composition-unit.md +1 -1
  224. package/docs/adr/0010-make-timelines-the-render-unit.md +3 -2
  225. package/docs/adr/0012-render-timelines-with-segmented-lossless-clip-intermediates.md +1 -1
  226. package/docs/adr/0014-compose-timeline-clips-with-css-blend-modes.md +2 -1
  227. package/docs/adr/0015-inherit-composition-format-from-the-project.md +2 -2
  228. package/docs/adr/0016-author-compositions-as-html-fragments.md +1 -1
  229. package/docs/adr/0018-animate-timeline-clips-with-keyframes.md +35 -0
  230. package/docs/adr/0019-make-same-track-overlap-the-transition-window.md +36 -0
  231. package/docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md +27 -0
  232. package/docs/adr/0021-project-timeline-scenes-once.md +32 -0
  233. package/docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md +35 -0
  234. package/docs/adr/0023-pin-fonts-as-project-assets.md +98 -0
  235. package/docs/adr/0024-stream-composition-captures-and-skip-trivial-composites.md +86 -0
  236. package/docs/adr/0025-capture-timeline-layers-in-parallel-with-a-global-limit.md +67 -0
  237. package/docs/adr/0026-reuse-loaded-composition-sessions-across-segments.md +70 -0
  238. package/docs/adr/0027-encode-two-full-frame-layers-through-dual-pipes.md +76 -0
  239. package/docs/adr/0028-encode-full-frame-video-segments-directly.md +65 -0
  240. package/docs/migration-0.4.md +2 -2
  241. package/docs/preview-testing.md +27 -6
  242. package/docs/{v0.1-design.md → v0.x-design.md} +57 -32
  243. package/examples/blend/README.md +3 -3
  244. package/examples/demo/README.md +2 -2
  245. package/examples/intro/README.md +71 -0
  246. package/examples/intro/assets/fonts/figtree/LICENSE.txt +93 -0
  247. package/examples/intro/assets/fonts/figtree/figtree-latin-wght-normal.woff2 +0 -0
  248. package/examples/intro/assets/fonts/instrument-serif/LICENSE.txt +93 -0
  249. package/examples/intro/assets/fonts/instrument-serif/instrument-serif-latin-400-italic.woff2 +0 -0
  250. package/examples/intro/assets/fonts/space-mono/LICENSE.txt +93 -0
  251. package/examples/intro/assets/fonts/space-mono/space-mono-latin-400-normal.woff2 +0 -0
  252. package/examples/intro/assets/fonts/space-mono/space-mono-latin-700-normal.woff2 +0 -0
  253. package/examples/intro/assets/grain.png +0 -0
  254. package/examples/intro/assets/score.ogg +0 -0
  255. package/examples/intro/compositions/brand.html +412 -0
  256. package/examples/intro/compositions/chrome.controller.js +63 -0
  257. package/examples/intro/compositions/chrome.html +256 -0
  258. package/examples/intro/compositions/lattice.controller.js +148 -0
  259. package/examples/intro/compositions/lattice.html +308 -0
  260. package/examples/intro/compositions/opening.html +504 -0
  261. package/examples/intro/compositions/studio.html +930 -0
  262. package/examples/intro/compositions/theme.css +218 -0
  263. package/examples/intro/fy.config.js +13 -0
  264. package/examples/intro/fy.fonts.json +100 -0
  265. package/examples/intro/scripts/make-grain.mjs +79 -0
  266. package/examples/intro/scripts/make-score.mjs +702 -0
  267. package/examples/intro/timelines/intro.timeline.json +60 -0
  268. package/examples/keyframes/README.md +76 -0
  269. package/examples/keyframes/compositions/backdrop.html +60 -0
  270. package/examples/keyframes/compositions/card.html +99 -0
  271. package/examples/keyframes/fy.config.js +10 -0
  272. package/examples/keyframes/timelines/keyframes.timeline.json +60 -0
  273. package/examples/nested/README.md +112 -0
  274. package/examples/nested/assets/pulse.wav +0 -0
  275. package/examples/nested/compositions/backdrop.html +84 -0
  276. package/examples/nested/compositions/card.html +275 -0
  277. package/examples/nested/compositions/overlay.html +307 -0
  278. package/examples/nested/fy.config.js +13 -0
  279. package/examples/nested/scripts/make-pulse.sh +20 -0
  280. package/examples/nested/timelines/chapter-a.timeline.json +39 -0
  281. package/examples/nested/timelines/chapter-b.timeline.json +39 -0
  282. package/examples/nested/timelines/nested-reel.timeline.json +52 -0
  283. package/examples/static/README.md +2 -2
  284. package/examples/transitions/README.md +128 -0
  285. package/examples/transitions/assets/alpha.wav +0 -0
  286. package/examples/transitions/assets/beta.wav +0 -0
  287. package/examples/transitions/assets/gamma.wav +0 -0
  288. package/examples/transitions/compositions/alpha.html +56 -0
  289. package/examples/transitions/compositions/beta.html +56 -0
  290. package/examples/transitions/compositions/gamma.html +56 -0
  291. package/examples/transitions/fy.config.js +12 -0
  292. package/examples/transitions/timelines/audio-crossfade.timeline.json +44 -0
  293. package/examples/transitions/timelines/transitions.timeline.json +31 -0
  294. package/examples/video/README.md +4 -4
  295. package/examples/webgl/README.md +1 -1
  296. package/package.json +13 -6
  297. package/scaffolds/init/AGENTS.md +131 -0
  298. package/scaffolds/init/README.md +56 -0
  299. package/scaffolds/init/compositions/hello.html +79 -0
  300. package/scaffolds/init/fy.config.js +9 -0
  301. package/scaffolds/init/gitignore.template +1 -0
  302. package/scaffolds/init/package.json +11 -0
  303. package/scaffolds/init/props/hello.json +4 -0
  304. package/scaffolds/init/props/main.json +6 -0
  305. package/scaffolds/init/timelines/main.timeline.json +20 -0
  306. package/scaffolds/local-models/LOCAL-MODELS.md +77 -0
  307. package/scaffolds/local-models/fy.policy.json +5 -0
  308. package/scaffolds/local-models/opencode/opencode.jsonc +17 -0
  309. package/scaffolds/local-models/pi/APPEND_SYSTEM.md +21 -0
  310. package/scaffolds/local-models/pi/sandbox.json +15 -0
  311. package/scaffolds/local-models/pi/settings.json +15 -0
  312. package/skills/frameyard/README.md +1 -0
  313. package/skills/frameyard/SKILL.md +59 -61
  314. package/skills/frameyard/references/audio-assets.md +32 -3
  315. package/skills/frameyard/references/common-mistakes.md +53 -2
  316. package/skills/frameyard/references/deterministic-authoring.md +10 -3
  317. package/skills/frameyard/references/diagnostics.md +31 -1
  318. package/skills/frameyard/references/failure-recovery.md +32 -6
  319. package/skills/frameyard/references/fonts.md +132 -0
  320. package/skills/frameyard/references/json-results.md +119 -6
  321. package/skills/frameyard/references/quick-reference.md +222 -0
  322. package/skills/frameyard/references/timelines.md +97 -7
  323. /package/examples/blend/{video.config.js → fy.config.js} +0 -0
  324. /package/examples/demo/{video.config.js → fy.config.js} +0 -0
  325. /package/examples/static/{video.config.js → fy.config.js} +0 -0
  326. /package/examples/video/{video.config.js → fy.config.js} +0 -0
  327. /package/examples/webgl/{video.config.js → fy.config.js} +0 -0
@@ -0,0 +1,412 @@
1
+ <link rel="stylesheet" href="./theme.css" />
2
+ <script type="application/json" data-fy="props">
3
+ {
4
+ "eyebrow": "FRAMEYARD / 04",
5
+ "tagline": "Deterministic video,",
6
+ "taglineTwo": "authored with the web platform.",
7
+ "meta": "Local-first · Frame-exact · HTML + JSON",
8
+ "accent": "#b8f36b"
9
+ }
10
+ </script>
11
+ <style>
12
+ @keyframes mark-in {
13
+ from {
14
+ opacity: 0;
15
+ transform: scale(0.28) rotate(-9deg);
16
+ }
17
+ to {
18
+ opacity: 1;
19
+ transform: scale(1) rotate(0deg);
20
+ }
21
+ }
22
+ @keyframes sheen {
23
+ from {
24
+ transform: translateX(-140%);
25
+ }
26
+ to {
27
+ transform: translateX(140%);
28
+ }
29
+ }
30
+ @keyframes spin {
31
+ to {
32
+ transform: rotate(360deg);
33
+ }
34
+ }
35
+ @keyframes spin-reverse {
36
+ to {
37
+ transform: rotate(-360deg);
38
+ }
39
+ }
40
+ .scene {
41
+ background: radial-gradient(circle at 50% 38%, rgba(184, 243, 107, 0.075), transparent 33%), #06080b;
42
+ }
43
+ .cross {
44
+ position: absolute;
45
+ inset: 0;
46
+ opacity: 0.55;
47
+ }
48
+ .cross::before,
49
+ .cross::after {
50
+ content: "";
51
+ position: absolute;
52
+ background: rgba(242, 245, 238, 0.07);
53
+ }
54
+ .cross::before {
55
+ left: 50%;
56
+ top: 110px;
57
+ bottom: 150px;
58
+ width: 1px;
59
+ background: linear-gradient(
60
+ 180deg,
61
+ transparent,
62
+ rgba(242, 245, 238, 0.08) 18%,
63
+ rgba(242, 245, 238, 0.08) 82%,
64
+ transparent
65
+ );
66
+ }
67
+ .cross::after {
68
+ left: 220px;
69
+ right: 220px;
70
+ top: 50%;
71
+ height: 1px;
72
+ background: linear-gradient(
73
+ 90deg,
74
+ transparent,
75
+ rgba(242, 245, 238, 0.07) 22%,
76
+ rgba(242, 245, 238, 0.07) 78%,
77
+ transparent
78
+ );
79
+ }
80
+ .ring {
81
+ position: absolute;
82
+ left: 50%;
83
+ top: 160px;
84
+ width: 600px;
85
+ height: 600px;
86
+ margin-left: -300px;
87
+ border: 1px solid rgba(242, 245, 238, 0.055);
88
+ border-radius: 50%;
89
+ }
90
+ .ring.dashed {
91
+ width: 744px;
92
+ height: 744px;
93
+ margin-left: -372px;
94
+ margin-top: -72px;
95
+ border: 1px dashed rgba(184, 243, 107, 0.12);
96
+ animation: spin 96s linear infinite;
97
+ }
98
+ .ring.outer {
99
+ width: 980px;
100
+ height: 980px;
101
+ margin-left: -490px;
102
+ margin-top: -190px;
103
+ border-color: rgba(242, 245, 238, 0.035);
104
+ animation: spin-reverse 140s linear infinite;
105
+ }
106
+ .glow {
107
+ position: absolute;
108
+ left: 50%;
109
+ top: 106px;
110
+ width: 1100px;
111
+ height: 760px;
112
+ margin-left: -550px;
113
+ background: radial-gradient(ellipse, rgba(184, 243, 107, 0.1), transparent 64%);
114
+ filter: blur(22px);
115
+ animation: glow-pulse 6.5s ease-in-out infinite;
116
+ }
117
+ .eyebrow {
118
+ position: absolute;
119
+ left: 0;
120
+ right: 0;
121
+ top: 138px;
122
+ display: flex;
123
+ align-items: center;
124
+ justify-content: center;
125
+ gap: 18px;
126
+ color: var(--accent);
127
+ font-size: 18px;
128
+ font-weight: 600;
129
+ letter-spacing: 0.26em;
130
+ text-transform: uppercase;
131
+ animation: rise-small 1s ease-out both;
132
+ }
133
+ .eyebrow::before,
134
+ .eyebrow::after {
135
+ content: "";
136
+ width: 30px;
137
+ height: 1px;
138
+ background: rgba(184, 243, 107, 0.55);
139
+ }
140
+ .mark {
141
+ position: absolute;
142
+ left: 50%;
143
+ top: 188px;
144
+ display: grid;
145
+ grid-template-columns: repeat(2, 108px);
146
+ grid-template-rows: repeat(2, 108px);
147
+ gap: 12px;
148
+ transform: translateX(-50%);
149
+ }
150
+ .cell {
151
+ border: 1px solid rgba(242, 245, 238, 0.42);
152
+ border-radius: 2px;
153
+ background: rgba(242, 245, 238, 0.015);
154
+ animation: mark-in 1s cubic-bezier(0.16, 1, 0.3, 1) both;
155
+ }
156
+ .cell.fill {
157
+ border-color: var(--accent);
158
+ background: radial-gradient(circle at 38% 32%, #e6ffc7, var(--accent) 46%, #7cb633 100%);
159
+ box-shadow:
160
+ 0 0 44px rgba(184, 243, 107, 0.32),
161
+ 0 0 110px rgba(184, 243, 107, 0.14);
162
+ }
163
+ .wordmark-block {
164
+ position: absolute;
165
+ left: 0;
166
+ right: 0;
167
+ top: 438px;
168
+ text-align: center;
169
+ }
170
+ .wordmark-mask {
171
+ position: relative;
172
+ display: inline-flex;
173
+ overflow: hidden;
174
+ padding: 0 0.04em 0.1em;
175
+ }
176
+ .wordmark {
177
+ display: flex;
178
+ color: var(--paper);
179
+ font-size: 144px;
180
+ font-weight: 650;
181
+ line-height: 0.86;
182
+ letter-spacing: 0.045em;
183
+ }
184
+ .glyph {
185
+ display: inline-block;
186
+ animation: line-up 1s cubic-bezier(0.16, 1, 0.3, 1) both;
187
+ }
188
+ .sheen {
189
+ position: absolute;
190
+ inset: 0;
191
+ background: linear-gradient(104deg, transparent 40%, rgba(184, 243, 107, 0.34) 50%, transparent 60%);
192
+ animation: sheen 1s ease-in-out both;
193
+ pointer-events: none;
194
+ }
195
+ .rule {
196
+ width: 520px;
197
+ height: 1px;
198
+ margin: 26px auto 0;
199
+ background: linear-gradient(
200
+ 90deg,
201
+ transparent,
202
+ rgba(184, 243, 107, 0.7) 18%,
203
+ rgba(184, 243, 107, 0.7) 82%,
204
+ transparent
205
+ );
206
+ box-shadow: 0 0 14px rgba(184, 243, 107, 0.34);
207
+ transform-origin: center;
208
+ animation: draw-x 1s cubic-bezier(0.16, 1, 0.3, 1) both;
209
+ }
210
+ .tagline {
211
+ position: absolute;
212
+ left: 0;
213
+ right: 0;
214
+ top: 630px;
215
+ text-align: center;
216
+ color: #c2ccc6;
217
+ font-family: "Instrument Serif", Georgia, serif;
218
+ font-style: italic;
219
+ font-size: 54px;
220
+ line-height: 1.16;
221
+ letter-spacing: -0.005em;
222
+ animation: rise-in 1s ease-out both;
223
+ }
224
+ .tagline b {
225
+ color: var(--paper);
226
+ font-weight: 400;
227
+ }
228
+ .chip {
229
+ position: absolute;
230
+ left: 50%;
231
+ top: 780px;
232
+ display: flex;
233
+ align-items: center;
234
+ gap: 18px;
235
+ height: 58px;
236
+ padding: 0 28px;
237
+ border: 1px solid rgba(242, 245, 238, 0.22);
238
+ border-radius: 3px;
239
+ background: rgba(242, 245, 238, 0.035);
240
+ color: var(--paper);
241
+ font-size: 21px;
242
+ letter-spacing: 0.01em;
243
+ translate: -50% 0;
244
+ box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
245
+ animation: rise-in 1s cubic-bezier(0.16, 1, 0.3, 1) both;
246
+ }
247
+ .chip .prompt {
248
+ color: var(--accent);
249
+ font-weight: 500;
250
+ }
251
+ .chip .slash {
252
+ width: 1px;
253
+ height: 24px;
254
+ background: rgba(242, 245, 238, 0.18);
255
+ }
256
+ .chip .hint {
257
+ color: var(--muted);
258
+ font-size: 13px;
259
+ letter-spacing: 0.12em;
260
+ text-transform: uppercase;
261
+ }
262
+ .chip-note {
263
+ position: absolute;
264
+ left: 0;
265
+ right: 0;
266
+ top: 852px;
267
+ text-align: center;
268
+ color: rgba(139, 152, 146, 0.78);
269
+ font-size: 13px;
270
+ letter-spacing: 0.18em;
271
+ text-transform: uppercase;
272
+ animation: fade-in 1s ease-out both;
273
+ }
274
+ </style>
275
+ <fy-composition duration-in-frames="330">
276
+ <div class="scene">
277
+ <div class="cross"></div>
278
+ <div class="glow"></div>
279
+ <div class="ring outer"></div>
280
+ <div class="ring"></div>
281
+ <div class="ring dashed"></div>
282
+
283
+ <div class="eyebrow mono" data-fy-anim-start="20" data-fy-anim-duration="40" data-fy-anim-easing="ease-out">
284
+ <span data-fy-text="eyebrow"></span>
285
+ </div>
286
+
287
+ <div class="mark">
288
+ <span
289
+ class="cell"
290
+ data-fy-anim-start="16"
291
+ data-fy-anim-duration="48"
292
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
293
+ ></span>
294
+ <span
295
+ class="cell fill"
296
+ data-fy-anim-start="24"
297
+ data-fy-anim-duration="48"
298
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
299
+ ></span>
300
+ <span
301
+ class="cell"
302
+ data-fy-anim-start="32"
303
+ data-fy-anim-duration="48"
304
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
305
+ ></span>
306
+ <span
307
+ class="cell"
308
+ data-fy-anim-start="40"
309
+ data-fy-anim-duration="48"
310
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
311
+ ></span>
312
+ </div>
313
+
314
+ <div class="wordmark-block">
315
+ <div class="wordmark-mask">
316
+ <div class="wordmark" aria-label="Frameyard">
317
+ <span
318
+ class="glyph"
319
+ data-fy-anim-start="48"
320
+ data-fy-anim-duration="68"
321
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
322
+ >F</span
323
+ >
324
+ <span
325
+ class="glyph"
326
+ data-fy-anim-start="54"
327
+ data-fy-anim-duration="68"
328
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
329
+ >R</span
330
+ >
331
+ <span
332
+ class="glyph"
333
+ data-fy-anim-start="60"
334
+ data-fy-anim-duration="68"
335
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
336
+ >A</span
337
+ >
338
+ <span
339
+ class="glyph"
340
+ data-fy-anim-start="66"
341
+ data-fy-anim-duration="68"
342
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
343
+ >M</span
344
+ >
345
+ <span
346
+ class="glyph"
347
+ data-fy-anim-start="72"
348
+ data-fy-anim-duration="68"
349
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
350
+ >E</span
351
+ >
352
+ <span
353
+ class="glyph"
354
+ data-fy-anim-start="78"
355
+ data-fy-anim-duration="68"
356
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
357
+ >Y</span
358
+ >
359
+ <span
360
+ class="glyph"
361
+ data-fy-anim-start="84"
362
+ data-fy-anim-duration="68"
363
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
364
+ >A</span
365
+ >
366
+ <span
367
+ class="glyph"
368
+ data-fy-anim-start="90"
369
+ data-fy-anim-duration="68"
370
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
371
+ >R</span
372
+ >
373
+ <span
374
+ class="glyph"
375
+ data-fy-anim-start="96"
376
+ data-fy-anim-duration="68"
377
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
378
+ >D</span
379
+ >
380
+ </div>
381
+ <div class="sheen" data-fy-anim-start="168" data-fy-anim-duration="60" data-fy-anim-easing="ease-in-out"></div>
382
+ </div>
383
+ <div
384
+ class="rule"
385
+ data-fy-anim-start="152"
386
+ data-fy-anim-duration="52"
387
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
388
+ ></div>
389
+ </div>
390
+
391
+ <div class="tagline" data-fy-anim-start="164" data-fy-anim-duration="56" data-fy-anim-easing="ease-out">
392
+ <span data-fy-text="tagline"></span><br />
393
+ <b data-fy-text="taglineTwo"></b>
394
+ </div>
395
+
396
+ <div
397
+ class="chip mono"
398
+ data-fy-anim-start="212"
399
+ data-fy-anim-duration="48"
400
+ data-fy-anim-easing="cubic-bezier(0.16, 1, 0.3, 1)"
401
+ >
402
+ <span class="prompt">$</span>
403
+ <span>npx frameyard init my-video</span>
404
+ <span class="slash"></span>
405
+ <span class="hint">start here</span>
406
+ </div>
407
+
408
+ <div class="chip-note mono" data-fy-anim-start="236" data-fy-anim-duration="36" data-fy-anim-easing="ease-out">
409
+ one command · ready to render
410
+ </div>
411
+ </div>
412
+ </fy-composition>
@@ -0,0 +1,63 @@
1
+ const CHAPTERS = [
2
+ { start: 0, label: "01 / author" },
3
+ { start: 270, label: "02 / compose" },
4
+ { start: 570, label: "03 / render" },
5
+ { start: 870, label: "04 / frameyard" },
6
+ ];
7
+ const CHAPTER_FADE = 12;
8
+
9
+ let frameLabel;
10
+ let timeLabel;
11
+ let totalLabel;
12
+ let chapterLabel;
13
+ let fps = 60;
14
+ let duration = 1200;
15
+
16
+ function chapterAt(frame) {
17
+ let index = 0;
18
+ for (let i = 0; i < CHAPTERS.length; i += 1) {
19
+ if (frame >= CHAPTERS[i].start) {
20
+ index = i;
21
+ }
22
+ }
23
+ const entry = CHAPTERS[index];
24
+ const end = index + 1 < CHAPTERS.length ? CHAPTERS[index + 1].start : duration;
25
+ let alpha = 1;
26
+ if (frame < entry.start + CHAPTER_FADE) {
27
+ alpha = (frame - entry.start) / CHAPTER_FADE;
28
+ } else if (frame > end - CHAPTER_FADE) {
29
+ alpha = (end - frame) / CHAPTER_FADE;
30
+ }
31
+ return { label: entry.label, alpha: Math.min(1, Math.max(0, alpha)) };
32
+ }
33
+
34
+ export default {
35
+ mount({ root }) {
36
+ frameLabel = root.querySelector("#frame");
37
+ timeLabel = root.querySelector("#time");
38
+ totalLabel = root.querySelector("#total");
39
+ chapterLabel = root.querySelector("#chapter");
40
+ fps = Number(root.getAttribute("fps") ?? 60);
41
+ duration = Number(root.getAttribute("duration-in-frames") ?? 1200);
42
+ totalLabel.textContent = String(Math.max(0, duration - 1)).padStart(4, "0");
43
+ },
44
+
45
+ update({ frame }) {
46
+ frameLabel.textContent = String(frame).padStart(4, "0");
47
+ timeLabel.textContent = (frame / fps).toFixed(2) + " S";
48
+
49
+ const chapter = chapterAt(frame);
50
+ chapterLabel.textContent = chapter.label;
51
+ chapterLabel.style.opacity = chapter.alpha.toFixed(3);
52
+ chapterLabel.style.transform = `translateY(${((1 - chapter.alpha) * 4).toFixed(2)}px)`;
53
+ },
54
+
55
+ dispose() {
56
+ frameLabel = undefined;
57
+ timeLabel = undefined;
58
+ totalLabel = undefined;
59
+ chapterLabel = undefined;
60
+ fps = 60;
61
+ duration = 1200;
62
+ },
63
+ };