stillmade-sdk 0.1.41 → 0.1.43

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 (285) hide show
  1. package/.stillmade/sdk-baseline.json +19 -21
  2. package/AGENTS.md +17 -12
  3. package/FRAME_VIEWS.md +113 -0
  4. package/INTERFACE_DESIGN.md +67 -22
  5. package/MOBILE_UI.md +4 -2
  6. package/MODULES.md +152 -6
  7. package/PASTE_TO_LLM.md +42 -32
  8. package/README.md +3 -2
  9. package/SDK.md +1028 -563
  10. package/UI_AESTHETIC.md +30 -3
  11. package/blocks/generate/package.js +1 -0
  12. package/blocks/generate/versions/1.0.0/package.js +463 -0
  13. package/docs/build/audio-to-editor.md +36 -0
  14. package/docs/build/block-builder-contract.md +150 -0
  15. package/docs/build/comfyui.md +227 -0
  16. package/docs/build/concepts.md +40 -0
  17. package/docs/build/context.md +159 -0
  18. package/docs/build/cookbook.md +57 -0
  19. package/docs/build/custom-interface.md +617 -0
  20. package/docs/build/data-types.md +83 -0
  21. package/docs/build/frame-views.md +259 -0
  22. package/docs/build/generate-media.md +59 -0
  23. package/docs/build/github-applications.md +314 -0
  24. package/docs/build/hosted-images.md +214 -0
  25. package/docs/build/hosted-music.md +39 -0
  26. package/docs/build/hosted-speech.md +157 -0
  27. package/docs/build/hosted-text.md +246 -0
  28. package/docs/build/image-description.md +49 -0
  29. package/docs/build/interface-design.md +343 -0
  30. package/docs/build/javascript.md +63 -0
  31. package/docs/build/local-preview.md +61 -0
  32. package/docs/build/media-analysis.md +27 -0
  33. package/docs/build/media.md +400 -0
  34. package/docs/build/mobile-ui.md +106 -0
  35. package/docs/build/modules.md +487 -0
  36. package/docs/build/original-blocks.md +70 -0
  37. package/docs/build/outside-apis.md +128 -0
  38. package/docs/build/production-context-templates.md +12 -0
  39. package/docs/build/project-storage.md +94 -0
  40. package/docs/build/quickstart.md +48 -0
  41. package/docs/build/recipes.md +103 -0
  42. package/docs/build/script-handoff.md +45 -0
  43. package/docs/build/script-writer.md +34 -0
  44. package/docs/build/state.md +223 -0
  45. package/docs/build/testing.md +112 -0
  46. package/docs/build/timeline-edits.md +116 -0
  47. package/docs/build/timeline-proposals.md +76 -0
  48. package/docs/build/transcription.md +59 -0
  49. package/docs/build/triggers.md +59 -0
  50. package/docs/build/tutorial.md +52 -0
  51. package/docs/build/typescript.md +34 -0
  52. package/docs/build/video-generation.md +61 -0
  53. package/docs/build/web-reading.md +37 -0
  54. package/docs/build/with-your-ai.md +27 -0
  55. package/docs/changelog.md +9 -0
  56. package/docs/creators.md +21 -0
  57. package/docs/distribute/discovery.md +43 -0
  58. package/docs/distribute/imports.md +58 -0
  59. package/docs/distribute/publishing.md +29 -0
  60. package/docs/distribute/sdk-versions.md +36 -0
  61. package/docs/distribute/selling.md +14 -0
  62. package/docs/distribute/teams.md +60 -0
  63. package/docs/distribute/versioning.md +28 -0
  64. package/docs/examples.md +23 -0
  65. package/docs/gallery.md +26 -0
  66. package/docs/index.md +50 -0
  67. package/docs/native-mcp.md +307 -0
  68. package/docs/project-types/automation.md +43 -0
  69. package/docs/project-types/batches.md +50 -0
  70. package/docs/project-types/build.md +42 -0
  71. package/docs/project-types/completion.md +15 -0
  72. package/docs/project-types/conditions.md +21 -0
  73. package/docs/project-types/hosted-review.md +115 -0
  74. package/docs/project-types/onboarding.md +75 -0
  75. package/docs/project-types/running.md +309 -0
  76. package/docs/project-types/testing.md +72 -0
  77. package/docs/reference/application-artifacts.md +87 -0
  78. package/docs/reference/authoring-guide.md +134 -0
  79. package/docs/reference/browser-applications.md +267 -0
  80. package/docs/reference/capabilities.md +45 -0
  81. package/docs/reference/cli.md +71 -0
  82. package/docs/reference/connection-api.md +59 -0
  83. package/docs/reference/cooperative-jobs.md +13 -0
  84. package/docs/reference/desktop-capabilities.md +172 -0
  85. package/docs/reference/desktop-execution.md +77 -0
  86. package/docs/reference/errors.md +233 -0
  87. package/docs/reference/execution.md +800 -0
  88. package/docs/reference/first-party-blocks.md +40 -0
  89. package/docs/reference/generation-models.md +59 -0
  90. package/docs/reference/limits.md +306 -0
  91. package/docs/reference/manifest-kinds-controls.md +36 -0
  92. package/docs/reference/manifest.md +181 -0
  93. package/docs/reference/operations.md +36 -0
  94. package/docs/reference/package-jobs.md +35 -0
  95. package/docs/reference/parity.md +55 -0
  96. package/docs/reference/permissions.md +86 -0
  97. package/docs/reference/ports.md +26 -0
  98. package/docs/reference/types.md +268 -0
  99. package/docs/reference/universal-resolver.md +303 -0
  100. package/docs/reference/view-bridge.md +60 -0
  101. package/docs/reference/view-rules.md +15 -0
  102. package/docs/reference/workspace-sync.md +25 -0
  103. package/docs/sdk.md +34 -0
  104. package/docs/tools/block-remix.md +211 -0
  105. package/docs/tools/llm.md +2213 -0
  106. package/docs/tools/repository-adaptation.md +613 -0
  107. package/examples/check-clip.stillmade.json +8 -1
  108. package/examples/clean-text.stillmade.json +4 -0
  109. package/examples/custom-interface.stillmade.json +4 -0
  110. package/examples/describe-image.stillmade.json +4 -0
  111. package/examples/foley-cue.stillmade.json +4 -0
  112. package/examples/generate-image.stillmade.json +4 -0
  113. package/examples/generate-video.stillmade.json +10 -2
  114. package/examples/module-word-stats/stillmade.block.json +4 -0
  115. package/examples/narrate-script.stillmade.json +4 -0
  116. package/examples/numbered-takes.stillmade.json +4 -0
  117. package/examples/research-topic.stillmade.json +9 -1
  118. package/examples/score-a-scene.stillmade.json +4 -0
  119. package/examples/script-draft.stillmade.json +4 -0
  120. package/examples/summarize-page.stillmade.json +4 -0
  121. package/examples/text-workflow.stillmade.json +7 -32
  122. package/examples/thicken-lines.stillmade.json +4 -0
  123. package/examples/timeline-polish.stillmade.json +15 -3
  124. package/examples/transcribe-audio.stillmade.json +15 -3
  125. package/examples/word-count.stillmade.json +4 -0
  126. package/package.json +1 -1
  127. package/packages/block-cli/cli.js +13 -6
  128. package/packages/block-cli/dev-host/assets/host.js +81 -38
  129. package/packages/block-cli/dev-host/assets/index.css +1 -1
  130. package/packages/block-cli/format.js +1 -1
  131. package/packages/block-cli/ready-gate.js +4 -0
  132. package/packages/block-cli/templates.js +37 -19
  133. package/packages/block-cli/type-packages.js +119 -0
  134. package/packages/block-platform/block-readiness.js +8 -1
  135. package/packages/block-platform/canvas.js +2 -1
  136. package/packages/block-platform/catalog.js +27 -48
  137. package/packages/block-platform/native-host-inventory.js +0 -226
  138. package/packages/block-platform/plain-descriptions.js +1 -25
  139. package/packages/block-platform/project-type-starters.js +13 -53
  140. package/packages/block-platform/script-handoff.js +2 -4
  141. package/packages/block-platform/type-workspace.js +2 -0
  142. package/packages/block-sdk/appearance.js +3 -1
  143. package/packages/block-sdk/audio-generation-example.js +2 -2
  144. package/packages/block-sdk/block-tier.js +1 -1
  145. package/packages/block-sdk/builder-contract.js +13 -11
  146. package/packages/block-sdk/capabilities.js +1 -1
  147. package/packages/block-sdk/capability-example.js +1 -1
  148. package/packages/block-sdk/contracts.js +6 -2
  149. package/packages/block-sdk/examples.js +3 -3
  150. package/packages/block-sdk/first-party-identities.js +1 -84
  151. package/packages/block-sdk/first-party-packages.js +3 -85
  152. package/packages/block-sdk/generation-catalog.js +15 -3
  153. package/packages/block-sdk/image-description-example.js +1 -1
  154. package/packages/block-sdk/image-generation-example.js +1 -1
  155. package/packages/block-sdk/index.d.ts +2 -1
  156. package/packages/block-sdk/media-analysis-example.js +2 -2
  157. package/packages/block-sdk/mock-host.js +7 -1
  158. package/packages/block-sdk/module-example.js +1 -1
  159. package/packages/block-sdk/module-host-calls.js +35 -10
  160. package/packages/block-sdk/module-hosted.js +15 -2
  161. package/packages/block-sdk/module-media-access.js +71 -0
  162. package/packages/block-sdk/module-node.js +1 -1
  163. package/packages/block-sdk/portable-media-actions.js +1 -1
  164. package/packages/block-sdk/runtime.js +1 -1
  165. package/packages/block-sdk/speech-example.js +1 -1
  166. package/packages/block-sdk/state-example.js +1 -1
  167. package/packages/block-sdk/timeline-proposal-example.js +1 -1
  168. package/packages/block-sdk/transcription-example.js +1 -1
  169. package/packages/block-sdk/trigger-examples.js +2 -2
  170. package/packages/block-sdk/video-generation-example.js +1 -1
  171. package/packages/block-sdk/view-bridge.js +4 -1
  172. package/packages/block-sdk/view-design.js +44 -15
  173. package/packages/block-sdk/web-example.js +2 -2
  174. package/packages/design-system/block-kit.css +53 -12
  175. package/packages/design-system/block-kit.html +3 -2
  176. package/blocks/mcp-motion-planner/versions/1.1.0/package.js +0 -97
  177. package/blocks/motion-designer/versions/1.0.1/package.js +0 -173318
  178. package/blocks/motion-designer/versions/1.0.2/package.js +0 -173318
  179. package/blocks/motion-frame-review/versions/1.1.1/package.js +0 -465
  180. package/blocks/motion-frame-review/versions/1.1.2/package.snapshot.js +0 -572
  181. package/blocks/narration/package.js +0 -1
  182. package/blocks/narration/versions/1.0.0/package.js +0 -221
  183. package/blocks/narration/versions/1.0.1/package.js +0 -221
  184. package/blocks/native/sm.animated-scene/versions/2.0.0/package.js +0 -475
  185. package/blocks/native/sm.animated-scene/versions/2.1.0/package.js +0 -498
  186. package/blocks/native/sm.animated-scene/versions/2.2.0/package.js +0 -524
  187. package/blocks/native/sm.animated-scene/versions/2.3.0/package.js +0 -618
  188. package/blocks/native/sm.animated-scene/versions/2.3.1/package.js +0 -618
  189. package/blocks/native/sm.animated-scene/versions/2.3.2/package.js +0 -723
  190. package/blocks/native/sm.animated-scene/versions/2.3.3/package.js +0 -723
  191. package/blocks/native/sm.animated-scene/versions/2.3.4/package.js +0 -676
  192. package/blocks/native/sm.animated-scene/versions/2.3.5/package.js +0 -693
  193. package/blocks/native/sm.animated-scene/versions/2.3.6/package.js +0 -700
  194. package/blocks/native/sm.animated-scene/versions/2.3.7/package.js +0 -747
  195. package/blocks/native/sm.animated-scene/versions/2.3.8/package.js +0 -769
  196. package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +0 -769
  197. package/blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js +0 -183
  198. package/blocks/native/sm.blueprint/versions/2.0.0/package.js +0 -358
  199. package/blocks/native/sm.blueprint/versions/2.1.0/package.js +0 -358
  200. package/blocks/native/sm.blueprint/versions/2.1.1/package.js +0 -358
  201. package/blocks/native/sm.blueprint/versions/2.1.2/package.js +0 -358
  202. package/blocks/native/sm.blueprint/versions/2.1.3/package.js +0 -381
  203. package/blocks/native/sm.blueprint/versions/2.1.4/package.js +0 -381
  204. package/blocks/native/sm.blueprint/versions/2.1.5/package.js +0 -339
  205. package/blocks/native/sm.blueprint/versions/2.1.6/package.js +0 -356
  206. package/blocks/native/sm.blueprint/versions/2.1.7/package.js +0 -363
  207. package/blocks/native/sm.blueprint/versions/2.1.8/package.js +0 -410
  208. package/blocks/native/sm.blueprint/versions/2.1.9/package.js +0 -422
  209. package/blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js +0 -172
  210. package/blocks/native/sm.chat/versions/2.0.0/package.js +0 -144
  211. package/blocks/native/sm.chat/versions/2.0.1/package.js +0 -97
  212. package/blocks/native/sm.chat/versions/2.0.2/package.js +0 -100
  213. package/blocks/native/sm.chat/versions/2.0.3/package.js +0 -100
  214. package/blocks/native/sm.continue-if/versions/1.0.0/package.js +0 -168
  215. package/blocks/native/sm.describe-media/versions/2.0.0/package.js +0 -153
  216. package/blocks/native/sm.describe-media/versions/2.0.1/package.js +0 -156
  217. package/blocks/native/sm.describe-media/versions/2.1.0/package.js +0 -140
  218. package/blocks/native/sm.image-editor/versions/2.0.0/package.js +0 -183
  219. package/blocks/native/sm.image-editor/versions/2.0.1/package.js +0 -190
  220. package/blocks/native/sm.new-items/versions/1.0.0/package.js +0 -191
  221. package/blocks/native/sm.pick-photos/versions/1.0.0/package.js +0 -334
  222. package/blocks/native/sm.quality-audit/versions/1.0.0/package.js +0 -192
  223. package/blocks/native/sm.quality-audit/versions/1.0.1/package.js +0 -192
  224. package/blocks/native/sm.quality-audit/versions/1.0.2/package.js +0 -195
  225. package/blocks/native/sm.research/versions/2.0.0/package.js +0 -175
  226. package/blocks/native/sm.research/versions/2.0.1/package.js +0 -184
  227. package/blocks/native/sm.research/versions/2.0.2/package.js +0 -187
  228. package/blocks/native/sm.script/versions/2.0.0/package.js +0 -144
  229. package/blocks/native/sm.script/versions/2.1.0/package.js +0 -144
  230. package/blocks/native/sm.script/versions/2.1.1/package.js +0 -144
  231. package/blocks/native/sm.script/versions/2.1.2/package.js +0 -105
  232. package/blocks/native/sm.script/versions/2.1.3/package.js +0 -152
  233. package/blocks/native/sm.script/versions/2.1.4/package.js +0 -156
  234. package/blocks/native/sm.script/versions/2.1.5/package.js +0 -156
  235. package/blocks/native/sm.shot-plan/versions/2.0.0/package.js +0 -301
  236. package/blocks/native/sm.shot-plan/versions/2.1.0/package.js +0 -528
  237. package/blocks/native/sm.shot-plan/versions/2.1.1/package.js +0 -528
  238. package/blocks/native/sm.shot-plan/versions/2.1.2/package.js +0 -528
  239. package/blocks/native/sm.shot-plan/versions/2.1.3/package.js +0 -536
  240. package/blocks/native/sm.shot-plan/versions/2.2.0/package.js +0 -800
  241. package/blocks/native/sm.shot-plan/versions/2.2.1/package.js +0 -920
  242. package/blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js +0 -173
  243. package/blocks/native/sm.stock-search/versions/2.0.0/package.js +0 -174
  244. package/blocks/native/sm.thumbnail/versions/2.0.0/package.js +0 -137
  245. package/blocks/native/sm.thumbnail/versions/2.0.1/package.js +0 -140
  246. package/blocks/native/sm.transcribe/versions/2.0.0/package.js +0 -163
  247. package/blocks/native/sm.transcribe/versions/2.0.1/package.js +0 -168
  248. package/blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js +0 -175
  249. package/blocks/native/sm.youtube/versions/2.0.0/package.js +0 -217
  250. package/blocks/occasion-story/package.js +0 -1
  251. package/blocks/occasion-story/versions/1.0.0/package.js +0 -1658
  252. package/blocks/occasion-story/versions/1.0.1/package.js +0 -1699
  253. package/blocks/occasion-story/versions/1.0.2/package.js +0 -1682
  254. package/blocks/photo-reel-composer/versions/1.0.0/package.js +0 -3043
  255. package/blocks/photo-reel-composer/versions/1.0.1/package.js +0 -3026
  256. package/blocks/photo-reel-composer/versions/1.0.2/package.js +0 -4149
  257. package/blocks/product-ad-variants/versions/1.0.0/package.js +0 -2911
  258. package/blocks/product-launch-director/versions/1.0.0/package.js +0 -103
  259. package/blocks/release-visuals/package.js +0 -1
  260. package/blocks/release-visuals/versions/1.0.0/package.js +0 -1492
  261. package/blocks/release-visuals/versions/1.0.1/package.js +0 -1517
  262. package/blocks/release-visuals/versions/1.0.2/package.js +0 -1500
  263. package/blocks/screen-recorder/package.js +0 -1
  264. package/blocks/screen-recorder/versions/1.0.0/package.js +0 -223
  265. package/blocks/screen-recorder/versions/1.0.1/package.js +0 -223
  266. package/blocks/short-form-finish/package.js +0 -1
  267. package/blocks/short-form-finish/versions/1.0.0/package.js +0 -1043
  268. package/blocks/short-form-finish/versions/1.0.1/package.js +0 -1043
  269. package/blocks/short-form-finish/versions/1.0.2/package.js +0 -1043
  270. package/blocks/short-form-finish/versions/1.0.3/package.js +0 -1026
  271. package/examples/saas-product-launch-reviewed-source.stillmade.json +0 -383
  272. package/examples/saas-product-launch.stillmade.json +0 -304
  273. package/packages/block-platform/dealer-inventory-video-project-type.js +0 -38
  274. package/packages/block-platform/first-revenue-project-types.js +0 -46
  275. package/packages/block-platform/fixture-starters.js +0 -13
  276. package/packages/block-platform/launch-project-source.js +0 -10
  277. package/packages/block-platform/launch-project.js +0 -30
  278. package/packages/block-platform/motion-project-types.js +0 -55
  279. package/packages/block-platform/motion-starters.js +0 -14
  280. package/packages/block-platform/product-ad-variants-project-type.js +0 -30
  281. package/packages/block-platform/product-launch-updated.js +0 -90
  282. package/packages/block-platform/revenue-review-project-types.js +0 -36
  283. package/packages/block-platform/revenue-review-starters.js +0 -13
  284. package/packages/block-platform/script-writer.js +0 -29
  285. package/packages/block-platform/website-source-block.js +0 -14
@@ -6,6 +6,7 @@
6
6
 
7
7
  The shape of a Block page, top to bottom:
8
8
  .sm-block one workspace, no cards inside cards
9
+ .sm-fields what the person sets, as one group on its own surface
9
10
  .sm-stage the thing being made (preview, media, result); biggest area
10
11
  .sm-settings settings side by side; .sm-choices[data-segmented] for short ones
11
12
  .sm-list many items, one line each; an item opens in place
@@ -15,7 +16,7 @@
15
16
  .sm-actions one .sm-primary, optional .sm-quiet / .sm-icon
16
17
  .sm-status short live state beside the action
17
18
  .sm-more everything secondary, collapsed
18
- .sm-hint an info toggle for words that might help, collapsed
19
+ .sm-hint an (i) whose words show on hover or focus (a tap on touch screens)
19
20
  .sm-empty what an empty stage shows: a glyph, a few words, one action
20
21
  .sm-glyph icons drawn in CSS with currentColor (no SVG or url needed)
21
22
  .sm-media-off a picture or clip that cannot show here: a quiet tile, no words
@@ -34,8 +35,8 @@
34
35
  :where(.sm-block[data-layout="split"]) > :where(.sm-stage){grid-row:span 6}
35
36
  }
36
37
  /* Wide views (October 19, 2026): the controls keep a reading width on the left and
37
- the result fills the rest on the right. Under 860px everything stacks with the
38
- result first. data-layout="stack" opts out; "split" keeps its older layout. */
38
+ the result fills the rest on the right. Under 860px everything stacks in page order, so
39
+ the stage goes after the actions: the result's place under the button. data-layout="stack" opts out; "split" keeps its older layout. */
39
40
  @container (min-width:860px){
40
41
  :where(.sm-block:not([data-layout]):has(> .sm-stage)){grid-template-columns:minmax(300px,380px) minmax(0,1fr);align-items:start;column-gap:var(--s-5,24px);row-gap:var(--s-4,16px)}
41
42
  :where(.sm-block:not([data-layout]):has(> .sm-stage)) > :where(*){grid-column:1}
@@ -51,11 +52,13 @@
51
52
 
52
53
  /* ---------- The stage: the object being made gets the main surface ---------- */
53
54
  :where(.sm-stage){position:relative;display:grid;place-items:center;min-height:220px;padding:var(--s-3,12px);border-radius:var(--r-3,8px);background:var(--bg-inset);overflow:hidden}
54
- :where(.sm-stage[data-ratio="16:9"]){aspect-ratio:16/9;min-height:0}
55
- :where(.sm-stage[data-ratio="9:16"]){aspect-ratio:9/16;min-height:0;max-height:70vh;justify-self:center;width:auto;height:min(70vh,640px)}
56
- :where(.sm-stage[data-ratio="1:1"]){aspect-ratio:1;min-height:0}
55
+ :where(.sm-stage:is([data-ratio="16:9"],[data-ratio="16/9"])){aspect-ratio:16/9;min-height:0}
56
+ :where(.sm-stage:is([data-ratio="9:16"],[data-ratio="9/16"])){aspect-ratio:9/16;min-height:0;max-height:70vh;justify-self:center;width:auto;height:min(70vh,640px)}
57
+ :where(.sm-stage:is([data-ratio="1:1"],[data-ratio="1/1"])){aspect-ratio:1;min-height:0}
57
58
  :where(.sm-stage) > :where(img,video,canvas){display:block;max-width:100%;max-height:100%;object-fit:contain;border-radius:var(--r-2,4px)}
58
59
  :where(.sm-stage[data-fill]) > :where(img,video,canvas){width:100%;height:100%;object-fit:cover}
60
+ /* A picture the view has not filled yet draws nothing, never a broken-image icon (November 3, 2026). */
61
+ :where(.sm-stage) :where(img:not([src]),img[src=""]){display:none}
59
62
 
60
63
  /* ---------- Empty state: a picture and a few words, never a paragraph ---------- */
61
64
  :where(.sm-empty){display:grid;justify-items:center;gap:var(--s-3,12px);padding:var(--s-5,24px) var(--s-4,16px);text-align:center;color:var(--fg-muted)}
@@ -88,6 +91,10 @@
88
91
  :where(.sm-field) :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),select,textarea){width:100%;min-height:var(--touch-target,44px);padding:10px 12px;border:1px solid var(--border-tok);border-radius:var(--r-3,8px);background:var(--bg-elev-1);color:var(--fg);font:inherit}
89
92
  :where(.sm-field) :where(textarea){min-height:96px;resize:vertical}
90
93
  :where(.sm-fields){display:grid;gap:var(--s-4,16px);grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr))}
94
+ /* Sections stand apart (owner, November 3, 2026: "make sure it's more separated"). The group of settings on a Block's
95
+ page sits on its own surface, the same card StillMade's Step page gives its settings, so what goes in, the settings
96
+ and the result read as separate parts. Only a top-level group: never a card inside a card. */
97
+ :where(.sm-block) > :where(.sm-fields,.sm-settings){padding:var(--s-3,12px) var(--s-4,16px);border:1px solid var(--border);border-radius:var(--r-3,8px);background:var(--bg-secondary)}
91
98
  /* Compact (October 19, 2026): a short field is one row at every width. On a phone or in a
92
99
  narrow cell the label takes its own width and the control the rest; when the two do not
93
100
  fit, the control wraps under its label. */
@@ -125,8 +132,8 @@
125
132
  :where(.sm-choices) > :where(label:has(input:disabled):not(:has(input:checked))){opacity:.45}
126
133
  :where(.sm-choices) :where(img,video,canvas,.sm-swatch){display:block;width:100%;aspect-ratio:var(--sm-tile-ratio,1);object-fit:cover;border-radius:var(--r-2,4px);background:var(--bg-inset)}
127
134
  :where(.sm-choices) :where(.sm-glyph){--sm-glyph-size:28px;margin:10px 0 4px}
128
- :where(.sm-choices[data-ratio="16:9"]){--sm-tile-ratio:16/9}
129
- :where(.sm-choices[data-ratio="9:16"]){--sm-tile-ratio:9/16}
135
+ :where(.sm-choices:is([data-ratio="16:9"],[data-ratio="16/9"])){--sm-tile-ratio:16/9}
136
+ :where(.sm-choices:is([data-ratio="9:16"],[data-ratio="9/16"])){--sm-tile-ratio:9/16}
130
137
  :where(.sm-choices[data-compact]) > :where(label){grid-auto-flow:column;justify-content:center;align-content:center;align-items:center;min-height:var(--touch-target,44px);padding:6px 12px}
131
138
  :where(.sm-choices[data-compact]) :where(.sm-glyph){--sm-glyph-size:18px;margin:0}
132
139
  :where(.sm-choices) :where(audio){width:100%;height:32px;position:relative;z-index:1}
@@ -194,6 +201,36 @@
194
201
  Its edge separates it from a stage or gallery tile of the same colour; in a gallery it takes the tile's shape. */
195
202
  :where(.sm-media-off){display:inline-grid;place-items:center;box-sizing:border-box;width:min(100%,320px);aspect-ratio:var(--sm-photo-ratio,4/3);border:1px solid var(--border-tok);border-radius:var(--r-2,4px);background:var(--bg-inset);color:var(--fg-subtle,var(--fg-muted));vertical-align:top}
196
203
  :where(.sm-gallery) :where(.sm-media-off){display:grid;width:100%;aspect-ratio:var(--sm-tile-ratio,1);border-radius:inherit}
204
+ /* The add tile (November 3, 2026): a dashed + after an input's files, as on StillMade's Step page. With
205
+ data-stillmade-add naming the input, StillMade opens its own picker and saves the files as its own tiles do; they
206
+ arrive through onInput. Never an <input type="file"> of the Block's own.
207
+ <button type="button" class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos" title="Add photos"></button>
208
+ Alone it is a small square; in an .sm-gallery it takes the tile's shape. Words inside show under the +. A viewer and
209
+ an input an earlier Step fills see no tile. */
210
+ :where(.sm-add){display:inline-grid;place-items:center;align-content:center;gap:2px;box-sizing:border-box;min-width:52px;min-height:52px;margin:0;padding:6px;border:1px dashed var(--border-strong);border-radius:var(--r-2,4px);background:transparent;color:var(--fg-muted);font:inherit;font-size:max(12px,var(--fs-caption,.8125rem));line-height:1.2;cursor:pointer}
211
+ :where(.sm-add)::before{content:"+";font-size:20px;line-height:1}
212
+ :where(.sm-add):hover{color:var(--fg);border-style:solid}
213
+ :where(.sm-add):focus-visible{outline:2px solid var(--signal);outline-offset:3px}
214
+ :where(.sm-add):disabled,:where(.sm-add[aria-busy="true"]){opacity:.45;cursor:default}
215
+ :where(.sm-gallery) :where(.sm-add){display:grid;width:100%;aspect-ratio:var(--sm-tile-ratio,1);border-radius:var(--r-3,8px);background:transparent}
216
+ /* A scrim (November 3, 2026): words over a photo or video read in every theme (a listing Block could not write one:
217
+ a Block's CSS takes only theme tokens, and color-mix() over them is refused). --scrim is the page's background, partly
218
+ see-through, for a Block's own rules (background:var(--scrim)); .sm-scrim lays it over the bottom of a positioned box
219
+ (an sm-stage, a gallery tile) under the words inside it.
220
+ <figure class="sm-stage" data-fill><img src="..." alt=""><figcaption class="sm-scrim">12 Elm Street</figcaption></figure> */
221
+ :where(:root,[data-mode]){--scrim:color-mix(in srgb,var(--bg) 72%,transparent)}
222
+ :where(.sm-scrim){position:absolute;inset:auto 0 0 0;margin:0;padding:var(--s-5,24px) var(--s-3,12px) var(--s-3,12px);background:linear-gradient(to top,var(--scrim) 55%,transparent);color:var(--fg)}
223
+ /* A tile's own tools (the same day): move and remove buttons in an .sm-tile-tools inside a gallery tile, wired by
224
+ data-stillmade-move and data-stillmade-remove (FRAME_VIEWS.md, "Removing and reordering files"). They sit in the
225
+ tile's top corner on a solid chip, show on hover or focus where there is a pointer and always on touch, and are hidden
226
+ with the + tile from viewers and for an input an earlier Step fills. */
227
+ :where(.sm-gallery) :where(.sm-tile-tools){position:absolute;top:4px;right:4px;display:flex;gap:2px}
228
+ :where(.sm-gallery) :where(.sm-tile-tools) > :where(button){--sm-glyph-size:14px;display:grid;place-items:center;box-sizing:border-box;min-width:24px;height:24px;margin:0;padding:0 4px;border:0;border-radius:var(--r-2,4px);background:var(--bg);color:var(--fg);font:inherit;font-size:16px;line-height:1;cursor:pointer}
229
+ :where(.sm-gallery) :where(.sm-tile-tools) > :where(button):focus-visible{outline:2px solid var(--signal);outline-offset:1px}
230
+ :where(.sm-gallery) :where(.sm-tile-tools) > :where(button:disabled,button[aria-busy="true"]){opacity:.45;cursor:default}
231
+ /* Three tools fit a 92px small tile on touch: 3 x 28 + gaps. */
232
+ @media (pointer:coarse){:where(.sm-gallery) :where(.sm-tile-tools) > :where(button){min-width:28px;height:28px}}
233
+ @media (hover:hover){:where(.sm-gallery) > :where(:not(:hover,:focus-within)) :where(.sm-tile-tools){opacity:0}}
197
234
 
198
235
  /* ---------- Status: a glyph and a few words, next to the action ---------- */
199
236
  :where(.sm-status){display:inline-flex;align-items:center;gap:var(--s-2,8px);min-height:24px;font-size:var(--fs-body-s,.875rem);color:var(--fg-muted)}
@@ -228,11 +265,12 @@
228
265
  :where(.sm-hint) > :where(summary){display:inline-grid;place-items:center;width:var(--touch-target,44px);height:var(--touch-target,44px);margin:-8px;min-height:0;padding:0;border:0;list-style:none;color:var(--fg-subtle);cursor:pointer}
229
266
  :where(.sm-hint) > :where(summary)::-webkit-details-marker{display:none}
230
267
  :where(.sm-hint) > :where(summary)::before{content:"i";display:grid;place-items:center;width:15px;height:15px;border:1.5px solid currentColor;border-radius:50%;font:600 10px/1 var(--font-body);font-style:normal}
231
- :where(.sm-hint) > :where(summary):hover,:where(.sm-hint[open]) > :where(summary){color:var(--fg)}
268
+ :where(.sm-hint:hover,.sm-hint:focus-within,.sm-hint[open]) > :where(summary){color:var(--fg)}
269
+ /* The words float over the page and never push it around (owner, November 3, 2026: "it makes me click and makes the ui weird"). */
232
270
  :where(.sm-hint) > :where(:not(summary)){position:absolute;z-index:5;inset-inline-start:0;top:100%;width:max-content;max-width:min(280px,calc(100cqi - 32px));margin:4px 0 0;padding:10px 12px;border:1px solid var(--border-tok);border-radius:var(--r-3,8px);background:var(--bg-elev-2);color:var(--fg);font-size:var(--fs-body-s,.875rem);line-height:1.45;box-shadow:var(--shadow-1)}
233
- /* Outside a label row there is no safe anchor, so the explanation opens in the flow instead. */
234
- :where(:not(.sm-label)) > :where(.sm-hint[open]){display:block}
235
- :where(:not(.sm-label)) > :where(.sm-hint) > :where(:not(summary)){position:static;width:auto;max-width:60ch}
271
+ :where(.sm-hint:hover,.sm-hint:focus-within)::details-content{content-visibility:visible}
272
+ /* With a mouse, hovering shows the words and a click does nothing: the click lands on the closed <details>, not its summary. Touch screens keep the tap. */
273
+ @media (hover:hover){:where(.sm-hint) > :where(summary){pointer-events:none}}
236
274
 
237
275
  /* ---------- Glyphs: small icons drawn with currentColor ----------
238
276
  <span class="sm-glyph" data-glyph="upload" aria-hidden="true"></span>
@@ -245,6 +283,9 @@
245
283
  :where(.sm-glyph[data-glyph="close"])::before{transform:rotate(45deg)}
246
284
  :where(.sm-glyph[data-glyph="check"])::before{left:36%;top:12%;width:30%;height:58%;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg)}
247
285
  :where(.sm-glyph[data-glyph="chevron"])::before{left:30%;top:22%;width:40%;height:40%;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg)}
286
+ /* Earlier and later (a tile's move tools, November 3, 2026). */
287
+ :where(.sm-glyph[data-glyph="chevron-left"])::before{left:36%;top:30%;width:40%;height:40%;border:solid currentColor;border-width:0 0 2px 2px;transform:rotate(45deg)}
288
+ :where(.sm-glyph[data-glyph="chevron-right"])::before{left:24%;top:30%;width:40%;height:40%;border:solid currentColor;border-width:2px 2px 0 0;transform:rotate(45deg)}
248
289
  :where(.sm-glyph[data-glyph="upload"])::before{left:10%;right:10%;bottom:10%;height:35%;border:2px solid currentColor;border-top:0;border-radius:0 0 3px 3px}
249
290
  :where(.sm-glyph[data-glyph="upload"])::after{left:25%;right:25%;top:4%;height:62%;background:currentColor;clip-path:polygon(50% 0,100% 45%,60% 45%,60% 100%,40% 100%,40% 45%,0 45%)}
250
291
  :where(.sm-glyph[data-glyph="image"])::before{inset:12%;border:2px solid currentColor;border-radius:3px}
@@ -21,7 +21,7 @@
21
21
  Drop it if nobody needs it to finish the task (intros, "how it works",
22
22
  restating the Block name, describing what is already visible).
23
23
  Picture it if a glyph, thumbnail, swatch or sample says the same thing.
24
- Collapse it if it might help some people: .sm-hint (info toggle) for an
24
+ Collapse it if it might help some people: .sm-hint (an (i) that shows on hover) for an
25
25
  explanation, .sm-more for secondary settings.
26
26
  Keep it for errors, spending or credit approvals, stale inputs and
27
27
  anything destructive. Keep those visible, in few words.
@@ -111,7 +111,8 @@
111
111
  <li><span class="sm-swatch swatch-a" style="display:block;aspect-ratio:3/2"></span></li>
112
112
  <li><span class="sm-swatch swatch-b" style="display:block;aspect-ratio:3/2"></span></li>
113
113
  <li><span class="sm-swatch swatch-c" style="display:block;aspect-ratio:3/2"></span></li>
114
- <li><label class="sm-empty" style="padding:8px;aspect-ratio:3/2" aria-label="Add photos" title="Add photos"><span class="sm-glyph" data-glyph="plus" aria-hidden="true"></span><input type="file" hidden multiple></label></li>
114
+ <!-- The add tile: StillMade opens its own picker for the named input and saves the files; they arrive through onInput. -->
115
+ <li><button type="button" class="sm-add" data-stillmade-add="listingPhotos" aria-label="Add photos" title="Add photos"></button></li>
115
116
  </ul>
116
117
  </div>
117
118
  <ol class="sm-list" data-peek>
@@ -1,97 +0,0 @@
1
- // Generated immutable package data.
2
- export default {
3
- "manifest": {
4
- "schemaVersion": 1,
5
- "sdkVersion": "0.1.0",
6
- "id": "stillmade.mcp-motion-planner",
7
- "name": "Motion Plan",
8
- "version": "1.1.0",
9
- "kind": "workspace",
10
- "runtime": "javascript",
11
- "entry": "src/run.js",
12
- "description": "Review a visual scene plan authored through StillMade MCP, adjust its source only when needed, and hand the approved structure to Frame Review locally.",
13
- "inputs": {
14
- "plan": {
15
- "type": "text",
16
- "primary": true,
17
- "required": false,
18
- "semantic": "project_brief",
19
- "sources": [
20
- "project",
21
- "user"
22
- ],
23
- "description": "A complete motion-design-package between BEGIN_MOTION_PLAN and END_MOTION_PLAN, or a concise fallback brief."
24
- },
25
- "brief": {
26
- "type": "text",
27
- "required": false,
28
- "description": "Optional plain-language fallback when an MCP-authored plan has not been supplied."
29
- }
30
- },
31
- "outputs": {
32
- "designPackage": {
33
- "type": "text",
34
- "primary": true,
35
- "role": "motion_design_package",
36
- "description": "Validated version 1 motion design package for Frame Review and Motion Designer."
37
- },
38
- "report": {
39
- "type": "metadata",
40
- "description": "Local scene-count, duration, source, and zero-credit validation report."
41
- }
42
- },
43
- "permissions": {
44
- "project": [],
45
- "actions": [],
46
- "network": [],
47
- "filesystem": [],
48
- "secrets": []
49
- },
50
- "ui": [
51
- {
52
- "control": "text",
53
- "port": "plan"
54
- }
55
- ],
56
- "platforms": {
57
- "phone": {
58
- "supported": true
59
- },
60
- "browser": {
61
- "supported": true
62
- },
63
- "desktop": {
64
- "supported": true
65
- }
66
- },
67
- "license": "MIT",
68
- "provenance": {
69
- "notice": "MIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and \nassociated documentation files (the \"Software\"), to deal in the Software without restriction, including \nwithout limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the \nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO \nEVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER \nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE \nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n"
70
- }
71
- },
72
- "code": "\n const text=value=>value==null?'':String(value),clone=value=>JSON.parse(JSON.stringify(value));\n const source=text(input.plan||input.brief).trim();\n const begin='BEGIN_MOTION_PLAN',end='END_MOTION_PLAN';\n let candidate=null;\n const start=source.indexOf(begin),finish=source.indexOf(end,start+begin.length);\n const encoded=start>=0&&finish>start?source.slice(start+begin.length,finish).trim():source;\n if(encoded.startsWith('{')){try{candidate=JSON.parse(encoded)}catch{throw new Error('The MCP motion plan is not valid JSON. Ask the connected assistant to repair the exact plan before continuing.')}}\n if(!candidate){\n const brief=source||'Create a concise product motion graphic.';\n candidate={schemaVersion:1,revision:'local-'+brief.length,kind:'motion-design-package',brief,audience:'Product-minded creative teams',creativeIntent:{idea:'Show the product as a living creative system',tone:'confident, precise, cinematic',visualLanguage:'editorial product UI, oversized type, clean vector geometry',motionCharacter:'restrained acceleration with decisive cuts',density:'open',avoid:['generic slideshow','floating mockup carousel','invented product claims']},constraints:{required:['Use only supplied product evidence and exact saved assets','Keep the composition editable'],preferences:['Prefer coded SVG, kinetic type, masks, camera moves, and real UI'],locks:[]},references:[],intendedOutputs:[{aspect:'16:9',durationSec:30,channel:'product launch'}],style:{background:'#0A0A0A',foreground:'#F7F0DB',accent:'#F2A93B',fontDirection:'editorial grotesk with monospace details'},product:{name:'StillMade',url:'',targetBuyer:'creative teams',promise:'Build complete visual productions from connected modular Blocks',availability:'',cta:{label:'Build with StillMade',destination:''},benefits:[]},scenes:[\n {id:'scene-1',goal:'Open with a singular promise',copy:{eyebrow:'STILLMADE',headline:'Make the whole thing.',support:'One connected creative system.'},durationSec:4,visualApproach:'Oversized masked typography and a precise vector aperture',layout:'centered poster',motionIntent:'restrained reveal, then sharp exit',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-2',goal:'Establish the modular workflow',copy:{eyebrow:'BLOCKS THAT WORK TOGETHER',headline:'From idea to final cut.',support:'Plan, review, design, and edit in one flow.'},durationSec:5,visualApproach:'Editable node path with semantic icons and cropped UI evidence when supplied',layout:'offset editorial',motionIntent:'measured camera push with sequential connections',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-3',goal:'Show visual review before animation',copy:{eyebrow:'APPROVE THE LOOK FIRST',headline:'See the frames. Then make them move.',support:'Choose a 3, 5, or 10 second review cadence.'},durationSec:5,visualApproach:'A grid of exact approved styleframes with one selected frame expanding full bleed',layout:'modular proof grid',motionIntent:'staggered tiles, magnetic selection, mask expansion',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-4',goal:'Reveal coded construction',copy:{eyebrow:'EDITABLE BY DESIGN',headline:'Real layers. Real timing. Real control.',support:'SVG, kinetic type, camera, transitions, and exact assets.'},durationSec:6,visualApproach:'Split view between coded vector layers and the live composition',layout:'copy on the left with product UI on the right',motionIntent:'typewriter detail, controlled parallax, precise callouts',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-5',goal:'Show the final editor handoff',copy:{eyebrow:'FINISH IN YOUR EDITOR',headline:'Polish without starting over.',support:'Every scene arrives as an editable timeline.'},durationSec:5,visualApproach:'Full-width timeline with layered motion scene clips and a final export target',layout:'full-bleed product UI',motionIntent:'timeline scrub, clip focus, restrained zoom',assetIds:[],evidenceRefs:[],locks:[]},\n {id:'scene-6',goal:'Close on the product promise',copy:{eyebrow:'STILLMADE',headline:'Make more than a clip.',support:'Build the system behind it.'},durationSec:5,visualApproach:'Return to the opening aperture as the product mark resolves',layout:'centered hero statement',motionIntent:'confident lockup and clean hold',assetIds:[],evidenceRefs:[],locks:[]}\n ],audio:{mode:'silent',assetIds:[],captions:[],notes:'Designed to work silently; optional sound design can accent transitions.'},unresolved:['Add exact StillMade UI screenshots or recordings as content assets before claiming visible product behavior.'],branch:{intent:'create',parentRevision:null}};\n }\n if(!candidate||Array.isArray(candidate)||candidate.schemaVersion!==1||candidate.kind!=='motion-design-package')throw new Error('Connect a version 1 motion-design-package authored by the StillMade MCP assistant.');\n if(!Array.isArray(candidate.scenes)||candidate.scenes.length<1||candidate.scenes.length>12)throw new Error('The MCP motion plan needs 1 to 12 scenes.');\n const ids=new Set();let duration=0;\n for(const scene of candidate.scenes){\n if(!scene||typeof scene!=='object'||Array.isArray(scene)||!text(scene.id).trim()||ids.has(scene.id))throw new Error('Every planned scene needs a distinct stable ID.');\n ids.add(scene.id);const seconds=Number(scene.durationSec);if(!Number.isFinite(seconds)||seconds<1||seconds>20)throw new Error('Every planned scene needs a duration from 1 to 20 seconds.');duration+=seconds;\n if(!scene.copy||typeof scene.copy!=='object'||!text(scene.copy.headline||scene.goal).trim())throw new Error('Every planned scene needs a communication goal or approved headline.');\n }\n if(duration>180)throw new Error('The complete MCP motion plan cannot exceed 180 seconds.');\n const plan=clone(candidate);plan.revision=text(plan.revision).trim()||'mcp-authored-1';plan.branch=plan.branch&&typeof plan.branch==='object'?plan.branch:{intent:'create',parentRevision:null};\n return {designPackage:JSON.stringify(plan),report:{schemaVersion:1,source:start>=0?'mcp-authored':'local-fallback',sceneCount:plan.scenes.length,durationSec:duration,creditCost:0,ready:true}};\n",
73
- "view": {
74
- "html": "<main class=\"planner\"><section class=\"overview\"><div class=\"ready\"><i class=\"plan-icon\" aria-hidden=\"true\"></i><div><small>CONNECTED PLAN</small><h2 id=\"planTitle\">Motion plan</h2></div></div><div class=\"metrics\" aria-label=\"Plan summary\"><span><i class=\"scene-icon\" aria-hidden=\"true\"></i><strong id=\"sceneCount\">—</strong> scenes</span><span><i class=\"time-icon\" aria-hidden=\"true\"></i><strong id=\"duration\">—</strong></span><span><i class=\"local-icon\" aria-hidden=\"true\"></i>Local · 0 credits</span></div><p id=\"idea\">Connect a brief or an assistant-authored plan to begin.</p><button id=\"use\" type=\"button\">Use this plan</button><output id=\"status\" role=\"status\">Waiting for a motion plan.</output></section><section class=\"storyboard\"><header><div><small>STORYBOARD</small><h2>Scenes and motion</h2></div><span id=\"format\">16:9</span></header><div id=\"scenes\" class=\"scenes\"></div></section><details><summary>Plan source</summary><p>Edit the structured source only when you need exact copy, timing, or scene IDs.</p><textarea id=\"source\" rows=\"14\" aria-label=\"Motion plan source\"></textarea></details></main>",
75
- "css": ".planner{container:motion-plan/inline-size;max-width:1160px;margin:0 auto;padding:12px;color:var(--fg);font-family:var(--font-body)}section,details{border:1px solid var(--border-tok);border-radius:var(--r-3);background:var(--bg-elev-1)}.overview{padding:20px}.ready,section header,.metrics,.metrics span,.scene-head,.scene-meta{display:flex;align-items:center}.ready{gap:12px}.ready h2,section header h2{margin:2px 0 0;font-family:var(--font-display);font-size:26px;font-style:italic;font-weight:200}.ready small,section header small,.scene small{font:600 11px/1.2 var(--font-mono);letter-spacing:.09em;color:var(--fg-muted)}.plan-icon{position:relative;width:30px;height:30px;border:1px solid var(--border-strong);border-radius:var(--r-2)}.plan-icon:before,.plan-icon:after{content:\"\";position:absolute;left:7px;right:7px;height:1px;background:var(--fg)}.plan-icon:before{top:10px;box-shadow:0 5px 0 var(--fg)}.plan-icon:after{top:20px;width:9px}.metrics{gap:8px;flex-wrap:wrap;margin:18px 0 12px}.metrics span,.scene-meta span{gap:7px;padding:7px 10px;border:1px solid var(--border-tok);border-radius:999px;color:var(--fg-muted);font-size:12px}.metrics strong{color:var(--fg)}.scene-icon,.local-icon{position:relative;width:14px;height:12px;border:1px solid currentColor}.scene-icon:after{content:\"\";position:absolute;inset:2px;border-top:1px solid currentColor;border-bottom:1px solid currentColor}.time-icon{position:relative;width:13px;height:13px;border:1px solid currentColor;border-radius:50%}.time-icon:before{content:\"\";position:absolute;left:6px;top:2px;width:1px;height:5px;background:currentColor;transform-origin:bottom;transform:rotate(-35deg)}.local-icon{border-radius:50%;width:12px;height:12px}.local-icon:after{content:\"\";position:absolute;left:3px;top:3px;width:4px;height:2px;border-left:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(-45deg)}#idea{max-width:720px;margin:0 0 16px;color:var(--fg-muted);line-height:1.5}button{min-height:44px;padding:10px 18px;border:0;border-radius:999px;background:var(--fg);color:var(--bg);font:600 14px var(--font-body)}button:disabled{opacity:.5}output{display:inline-block;margin-left:12px;color:var(--fg-muted);font-size:13px}.storyboard{margin-top:12px;padding:20px}.storyboard>header{justify-content:space-between;gap:16px}.storyboard>header>span{font:600 12px var(--font-mono);color:var(--fg-muted)}.scenes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:16px}.scene{min-width:0;padding:14px;border:1px solid var(--border-tok);border-radius:var(--r-2);background:var(--bg)}.scene-head{justify-content:space-between;gap:10px}.scene-index{font:600 11px var(--font-mono);color:var(--fg-muted)}.scene-duration{font:600 11px var(--font-mono);color:var(--fg)}.scene h3{margin:14px 0 6px;font-size:16px;line-height:1.15}.scene p{margin:0;color:var(--fg-muted);font-size:13px;line-height:1.4}.scene-meta{gap:6px;flex-wrap:wrap;margin-top:14px}.scene-meta span{padding:5px 8px;font-size:11px}.empty{grid-column:1/-1;padding:28px;text-align:center;color:var(--fg-muted)}details{margin-top:12px;padding:14px 16px}summary{cursor:pointer;font-weight:600}details p{color:var(--fg-muted);font-size:13px}textarea{box-sizing:border-box;width:100%;min-height:240px;padding:12px;border:1px solid var(--border-tok);border-radius:var(--r-2);background:var(--bg);color:var(--fg);font:12px/1.5 var(--font-mono);resize:vertical}@container motion-plan (max-width:760px){.scenes{grid-template-columns:repeat(2,minmax(0,1fr))}}@container motion-plan (max-width:500px){.planner{padding:4px}.overview,.storyboard{padding:14px}.scenes{grid-template-columns:1fr}output{display:block;margin:10px 0 0}}",
76
- "javascript": "const e=id=>document.getElementById(id),source=e('source'),button=e('use');let current=null;const text=value=>value==null?'':String(value);const read=value=>{const raw=text(value).trim(),begin='BEGIN_MOTION_PLAN',end='END_MOTION_PLAN',start=raw.indexOf(begin),finish=raw.indexOf(end,start+begin.length),encoded=start>=0&&finish>start?raw.slice(start+begin.length,finish).trim():raw;if(!encoded.startsWith('{'))return null;try{return JSON.parse(encoded)}catch{return null}};const card=(scene,index)=>({tag:'article',className:'scene',children:[{tag:'div',className:'scene-head',children:[{tag:'span',className:'scene-index',text:String(index+1).padStart(2,'0')},{tag:'span',className:'scene-duration',text:String(scene.durationSec||0)+'s'}]},{tag:'small',text:text(scene.copy&&scene.copy.eyebrow||scene.goal||'SCENE')},{tag:'h3',text:text(scene.copy&&scene.copy.headline||scene.goal||'Untitled scene')},{tag:'p',text:text(scene.visualApproach||scene.copy&&scene.copy.support||'Visual direction will be resolved in Frame Review.')},{tag:'div',className:'scene-meta',children:[{tag:'span',text:text(scene.layout||'Layout')},{tag:'span',text:text(scene.motionIntent||'Motion')}]}]});const show=plan=>{current=plan;const scenes=Array.isArray(plan&&plan.scenes)?plan.scenes:[],duration=scenes.reduce((sum,scene)=>sum+(Number(scene.durationSec)||0),0);e('sceneCount').textContent=scenes.length?String(scenes.length):'—';e('duration').textContent=scenes.length?String(duration)+' sec':'—';e('idea').textContent=text(plan&&plan.creativeIntent&&plan.creativeIntent.idea||plan&&plan.brief||'Connect a brief or an assistant-authored plan to begin.');e('format').textContent=text(plan&&plan.intendedOutputs&&plan.intendedOutputs[0]&&plan.intendedOutputs[0].aspect||'16:9');e('planTitle').textContent=text(plan&&plan.product&&plan.product.name?plan.product.name+' motion plan':'Motion plan');StillMade.render('scenes',scenes.length?scenes.map(card):[{tag:'p',className:'empty',text:'Your scene cards will appear here. The structured source stays out of the way.'}]);button.textContent=scenes.length?'Use this plan':'Create plan from brief'};StillMade.onInput(values=>{const incoming=values.plan||values.brief||'';source.value=incoming;show(read(incoming))});source.addEventListener('input',()=>show(read(source.value)));button.addEventListener('click',async()=>{button.disabled=true;e('status').textContent='Checking copy, timing, and scene IDs…';try{const result=await StillMade.run({plan:source.value});const plan=read(result.designPackage);show(plan);e('status').textContent=String(result.report.sceneCount)+' scenes · '+String(result.report.durationSec)+' seconds · ready for Frame Review.'}catch(error){e('status').textContent=error.message||'The plan could not be prepared.'}finally{button.disabled=false}});show(null);"
77
- },
78
- "tests": [
79
- {
80
- "name": "Build a zero-credit fallback motion plan",
81
- "input": {
82
- "brief": "Create a StillMade product-launch motion graphic."
83
- },
84
- "expected": {
85
- "designPackage": "{\"schemaVersion\":1,\"revision\":\"local-49\",\"kind\":\"motion-design-package\",\"brief\":\"Create a StillMade product-launch motion graphic.\",\"audience\":\"Product-minded creative teams\",\"creativeIntent\":{\"idea\":\"Show the product as a living creative system\",\"tone\":\"confident, precise, cinematic\",\"visualLanguage\":\"editorial product UI, oversized type, clean vector geometry\",\"motionCharacter\":\"restrained acceleration with decisive cuts\",\"density\":\"open\",\"avoid\":[\"generic slideshow\",\"floating mockup carousel\",\"invented product claims\"]},\"constraints\":{\"required\":[\"Use only supplied product evidence and exact saved assets\",\"Keep the composition editable\"],\"preferences\":[\"Prefer coded SVG, kinetic type, masks, camera moves, and real UI\"],\"locks\":[]},\"references\":[],\"intendedOutputs\":[{\"aspect\":\"16:9\",\"durationSec\":30,\"channel\":\"product launch\"}],\"style\":{\"background\":\"#0A0A0A\",\"foreground\":\"#F7F0DB\",\"accent\":\"#F2A93B\",\"fontDirection\":\"editorial grotesk with monospace details\"},\"product\":{\"name\":\"StillMade\",\"url\":\"\",\"targetBuyer\":\"creative teams\",\"promise\":\"Build complete visual productions from connected modular Blocks\",\"availability\":\"\",\"cta\":{\"label\":\"Build with StillMade\",\"destination\":\"\"},\"benefits\":[]},\"scenes\":[{\"id\":\"scene-1\",\"goal\":\"Open with a singular promise\",\"copy\":{\"eyebrow\":\"STILLMADE\",\"headline\":\"Make the whole thing.\",\"support\":\"One connected creative system.\"},\"durationSec\":4,\"visualApproach\":\"Oversized masked typography and a precise vector aperture\",\"layout\":\"centered poster\",\"motionIntent\":\"restrained reveal, then sharp exit\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-2\",\"goal\":\"Establish the modular workflow\",\"copy\":{\"eyebrow\":\"BLOCKS THAT WORK TOGETHER\",\"headline\":\"From idea to final cut.\",\"support\":\"Plan, review, design, and edit in one flow.\"},\"durationSec\":5,\"visualApproach\":\"Editable node path with semantic icons and cropped UI evidence when supplied\",\"layout\":\"offset editorial\",\"motionIntent\":\"measured camera push with sequential connections\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-3\",\"goal\":\"Show visual review before animation\",\"copy\":{\"eyebrow\":\"APPROVE THE LOOK FIRST\",\"headline\":\"See the frames. Then make them move.\",\"support\":\"Choose a 3, 5, or 10 second review cadence.\"},\"durationSec\":5,\"visualApproach\":\"A grid of exact approved styleframes with one selected frame expanding full bleed\",\"layout\":\"modular proof grid\",\"motionIntent\":\"staggered tiles, magnetic selection, mask expansion\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-4\",\"goal\":\"Reveal coded construction\",\"copy\":{\"eyebrow\":\"EDITABLE BY DESIGN\",\"headline\":\"Real layers. Real timing. Real control.\",\"support\":\"SVG, kinetic type, camera, transitions, and exact assets.\"},\"durationSec\":6,\"visualApproach\":\"Split view between coded vector layers and the live composition\",\"layout\":\"copy on the left with product UI on the right\",\"motionIntent\":\"typewriter detail, controlled parallax, precise callouts\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-5\",\"goal\":\"Show the final editor handoff\",\"copy\":{\"eyebrow\":\"FINISH IN YOUR EDITOR\",\"headline\":\"Polish without starting over.\",\"support\":\"Every scene arrives as an editable timeline.\"},\"durationSec\":5,\"visualApproach\":\"Full-width timeline with layered motion scene clips and a final export target\",\"layout\":\"full-bleed product UI\",\"motionIntent\":\"timeline scrub, clip focus, restrained zoom\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]},{\"id\":\"scene-6\",\"goal\":\"Close on the product promise\",\"copy\":{\"eyebrow\":\"STILLMADE\",\"headline\":\"Make more than a clip.\",\"support\":\"Build the system behind it.\"},\"durationSec\":5,\"visualApproach\":\"Return to the opening aperture as the product mark resolves\",\"layout\":\"centered hero statement\",\"motionIntent\":\"confident lockup and clean hold\",\"assetIds\":[],\"evidenceRefs\":[],\"locks\":[]}],\"audio\":{\"mode\":\"silent\",\"assetIds\":[],\"captions\":[],\"notes\":\"Designed to work silently; optional sound design can accent transitions.\"},\"unresolved\":[\"Add exact StillMade UI screenshots or recordings as content assets before claiming visible product behavior.\"],\"branch\":{\"intent\":\"create\",\"parentRevision\":null}}",
86
- "report": {
87
- "schemaVersion": 1,
88
- "source": "local-fallback",
89
- "sceneCount": 6,
90
- "durationSec": 30,
91
- "creditCost": 0,
92
- "ready": true
93
- }
94
- }
95
- }
96
- ]
97
- };