cozyclay 1.9.0 → 2.0.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 (286) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/bin/agent/agent-routes.mjs +74 -70
  3. package/bin/agent/agent-runner.mjs +10 -3
  4. package/bin/agent/motion-runtime.mjs +32 -260
  5. package/bin/agent/providers.mjs +46 -3
  6. package/bin/agent/session-store.mjs +41 -5
  7. package/bin/agent/studio-prompt.mjs +1 -1
  8. package/bin/agent/studio-tools.mjs +48 -11
  9. package/bin/cozyclay.mjs +26 -8
  10. package/bin/live/cli.mjs +22 -3
  11. package/bin/mcp-runtime.mjs +35 -20
  12. package/bin/telemetry-state.mjs +5 -2
  13. package/bin/update-check.mjs +15 -0
  14. package/dist/app/index.html +6 -6
  15. package/dist/assets/analytics-MVZOEW8O.js +1 -0
  16. package/dist/assets/app-C1sdVbg4.css +1 -0
  17. package/dist/assets/app-CA55tcI3.js +4876 -0
  18. package/dist/assets/{demo-B-eg1CT8.js → demo-ByeYp-dY.js} +1 -1
  19. package/dist/assets/{first-shot-handoff-CGgnvNu8.js → first-shot-handoff-DgT28ZiV.js} +1 -1
  20. package/dist/assets/{landing-IbRp3FnQ.js → landing-BaXkpFip.js} +1 -1
  21. package/dist/assets/shot-prompt-CbqWcWYi.css +1 -0
  22. package/dist/assets/shot-prompt-Yrt99wZx.js +17 -0
  23. package/dist/assets/{ticket-BgIzOBOf.js → ticket-BcmsnHn5.js} +1 -1
  24. package/dist/assets/workflow-DRdwoDBT.css +1 -0
  25. package/dist/assets/workflow-dNPGY9xz.js +179 -0
  26. package/dist/cozyclay-package.json +1 -1
  27. package/dist/fonts/IBM-Plex-Sans-OFL.txt +92 -0
  28. package/dist/fonts/JetBrains-Mono-OFL.txt +93 -0
  29. package/dist/fonts/README.md +13 -9
  30. package/dist/fonts/ibm-plex-sans-400-latin.woff2 +0 -0
  31. package/dist/fonts/ibm-plex-sans-500-latin.woff2 +0 -0
  32. package/dist/fonts/ibm-plex-sans-600-latin.woff2 +0 -0
  33. package/dist/fonts/jetbrains-mono-400-latin.woff2 +0 -0
  34. package/dist/fonts/jetbrains-mono-500-latin.woff2 +0 -0
  35. package/dist/index.html +7 -7
  36. package/dist/privacy/index.html +13 -8
  37. package/dist/sitemap.xml +6 -6
  38. package/dist/workflow/index.html +5 -5
  39. package/mcp/LIVE-PROTOCOL.md +1 -1
  40. package/mcp/live-hub.mjs +35 -93
  41. package/mcp/mesh-file.mjs +48 -0
  42. package/mcp/server.mjs +6 -77
  43. package/mcp/tool-handlers.mjs +224 -377
  44. package/package.json +2 -1
  45. package/src/App.jsx +1273 -9075
  46. package/src/analytics.js +393 -9
  47. package/src/app-context.js +211 -0
  48. package/src/app-stage.jsx +25 -24
  49. package/src/ardy/auto-fix-panel.css +108 -0
  50. package/src/ardy/collision-blockers.js +9 -3
  51. package/src/ardy/fix-collisions.js +10 -66
  52. package/src/ardy/ground.js +4 -4
  53. package/src/ardy/ik-drag.js +101 -0
  54. package/src/ardy/ik-key-json.js +43 -0
  55. package/src/ardy/ik.js +122 -76
  56. package/src/ardy/physics-panel.css +2 -0
  57. package/src/ardy/physics-panel.jsx +17 -5
  58. package/src/ardy/platform-fit-panel.css +64 -0
  59. package/src/ardy/platform-fit-panel.jsx +40 -0
  60. package/src/ardy/platform-fit.js +326 -0
  61. package/src/ardy/playback.js +166 -20
  62. package/src/ardy/range-pin.js +299 -0
  63. package/src/ardy/timeline-coordinates.js +26 -0
  64. package/src/ardy/timeline.css +1199 -0
  65. package/src/ardy/timeline.jsx +149 -41
  66. package/src/ardy/waypoints.js +2 -2
  67. package/src/asset-pane.css +462 -0
  68. package/src/asset-pane.jsx +461 -232
  69. package/src/command-bus.js +349 -0
  70. package/src/commands/ai.js +31 -0
  71. package/src/commands/cast.js +140 -0
  72. package/src/commands/elements/character.js +13 -0
  73. package/src/commands/elements/motion.js +14 -0
  74. package/src/commands/elements/object.js +22 -0
  75. package/src/commands/elements/scene.js +16 -0
  76. package/src/commands/elements/shot.js +9 -0
  77. package/src/commands/elements/stage.js +11 -0
  78. package/src/commands/elements.js +155 -0
  79. package/src/commands/export.js +20 -0
  80. package/src/commands/index.js +40 -0
  81. package/src/commands/motion.js +231 -0
  82. package/src/commands/objects.js +174 -0
  83. package/src/commands/project.js +53 -0
  84. package/src/commands/scene.js +81 -0
  85. package/src/commands/shared.js +19 -0
  86. package/src/commands/shot.js +103 -0
  87. package/src/commands/stage.js +17 -0
  88. package/src/commands/view.js +42 -0
  89. package/src/document-store.js +144 -0
  90. package/src/domains/cast.js +1007 -0
  91. package/src/domains/motion.js +3219 -0
  92. package/src/domains/objects.js +932 -0
  93. package/src/domains/scenes.js +817 -0
  94. package/src/domains/shots.js +404 -0
  95. package/src/domains/stage.js +93 -0
  96. package/src/dualview.jsx +113 -57
  97. package/src/facing-marks.js +3 -0
  98. package/src/first-success-guide.jsx +14 -14
  99. package/src/grid-view.js +18 -5
  100. package/src/hierarchy-model.js +24 -16
  101. package/src/hierarchy-panel.css +386 -0
  102. package/src/hierarchy-panel.jsx +150 -21
  103. package/src/{fal-motion-client.js → i2v-motion-client.js} +13 -13
  104. package/src/i2v-motion-studio.jsx +180 -0
  105. package/src/ik-camera.js +3 -0
  106. package/src/main.jsx +6 -0
  107. package/src/motion/generation.js +105 -0
  108. package/src/motion-readiness-ui.jsx +4 -4
  109. package/src/motion-readiness.js +11 -0
  110. package/src/motion-trail.js +366 -9
  111. package/src/object-gizmo.jsx +7 -1
  112. package/src/otio.js +2 -1
  113. package/src/panels/CameraPanel.jsx +60 -0
  114. package/src/panels/CharacterTransformPanel.jsx +48 -0
  115. package/src/panels/EnvironmentPanel.jsx +40 -0
  116. package/src/panels/Foldout.jsx +32 -0
  117. package/src/panels/LightPanel.jsx +24 -0
  118. package/src/panels/ObjectTransformPanel.jsx +554 -0
  119. package/src/panels/PosePanel.jsx +97 -0
  120. package/src/panels/ProjectPanel.jsx +33 -0
  121. package/src/panels/PromptBlocksPanel.jsx +442 -0
  122. package/src/panels/PropsPanel.jsx +70 -0
  123. package/src/panels/ReferenceImageField.jsx +91 -0
  124. package/src/panels/RigControlPanel.jsx +78 -0
  125. package/src/panels/RigPanel.jsx +37 -0
  126. package/src/panels/SubjectBox.jsx +47 -0
  127. package/src/panels/SubjectsPanel.jsx +39 -0
  128. package/src/panels/VideoCapturePanel.jsx +180 -0
  129. package/src/panels/details.css +1171 -0
  130. package/src/panels/motion.css +197 -0
  131. package/src/panels/pose.css +39 -0
  132. package/src/planview.jsx +60 -31
  133. package/src/posestudio.jsx +59 -4
  134. package/src/project-browser.css +1073 -0
  135. package/src/project-browser.jsx +284 -123
  136. package/src/range-pin-object-transform.js +19 -0
  137. package/src/range-pin-panel.css +518 -0
  138. package/src/range-pin-panel.jsx +344 -0
  139. package/src/result-modal.jsx +5 -5
  140. package/src/room.jsx +79 -51
  141. package/src/scene-objects.js +37 -1
  142. package/src/scenes.js +5 -0
  143. package/src/semantic-edit.js +2 -0
  144. package/src/settings-menu.jsx +39 -105
  145. package/src/shell/BottomDock.jsx +450 -0
  146. package/src/shell/DetailsSlot.jsx +513 -0
  147. package/src/shell/LibrarySlot.jsx +86 -0
  148. package/src/shell/MenuBar.jsx +601 -0
  149. package/src/shell/OutlinerSlot.jsx +50 -0
  150. package/src/shell/PreferencesDialog.jsx +538 -0
  151. package/src/shell/PreferencesSlot.jsx +40 -0
  152. package/src/shell/StatusBar.jsx +125 -0
  153. package/src/shell/StudioShell.jsx +92 -0
  154. package/src/shell/TopBar.jsx +129 -0
  155. package/src/shell/ViewportToolbar.jsx +656 -0
  156. package/src/shell/agent-glass.css +296 -0
  157. package/src/shell/dock.css +93 -0
  158. package/src/shell/glass-regions.css +985 -0
  159. package/src/shell/glass.css +687 -0
  160. package/src/shell/log-store.js +52 -0
  161. package/src/shell/mode.css +9 -0
  162. package/src/shell/preferences.css +651 -0
  163. package/src/shell/shell.css +282 -0
  164. package/src/shell/studio-shell-context.js +19 -0
  165. package/src/shell/topbar.css +435 -0
  166. package/src/shell/viewport.css +451 -0
  167. package/src/store/authored-intent.js +22 -0
  168. package/src/store/runtime-adapters.js +92 -0
  169. package/src/store/scene-stage.js +21 -0
  170. package/src/store/use-document-store.js +14 -0
  171. package/src/studio-actions.js +210 -0
  172. package/src/studio-agent-commands.js +41 -271
  173. package/src/studio-agent-context.js +39 -10
  174. package/src/studio-agent-motion.js +122 -373
  175. package/src/studio-agent-protocol.js +67 -31
  176. package/src/studio-app-binding.js +379 -0
  177. package/src/studio-contact-sheet.js +73 -0
  178. package/src/studio-elements.js +58 -51
  179. package/src/styles/themes.css +200 -0
  180. package/src/styles/tokens.css +69 -0
  181. package/src/styles.css +460 -1742
  182. package/src/theme.js +44 -0
  183. package/src/timeline-extent.js +16 -0
  184. package/src/trail-key-conflicts.js +39 -0
  185. package/src/trail-pick.js +59 -0
  186. package/src/ui.jsx +8 -8
  187. package/src/use-case-question.jsx +66 -0
  188. package/src/workflow/AgentPanel.jsx +82 -69
  189. package/src/workflow/agent-client.js +12 -2
  190. package/src/workflow/agent-panel.css +34 -32
  191. package/src/workflow/cozy-scene-node.css +2 -0
  192. package/src/workflow/workflow.css +2 -0
  193. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  194. package/tools/ardy/bridge.mjs +164 -146
  195. package/tools/ardy/visual-qa.mjs +5 -5
  196. package/tools/bench/EXP3.md +61 -0
  197. package/tools/bench/cclay_bench_extract_incam.py +125 -0
  198. package/tools/bench/cclay_bench_extract_obs.py +204 -0
  199. package/tools/bench/cclay_bench_runner.py +42 -0
  200. package/tools/bench/cube-contact.mjs +162 -0
  201. package/tools/bench/exp3.mjs +152 -0
  202. package/tools/bench/extract-bench-lib.mjs +216 -0
  203. package/tools/bench/extract-bench.mjs +302 -0
  204. package/tools/bench/fal-generate.mjs +88 -0
  205. package/tools/bench/fit/README.md +189 -0
  206. package/tools/bench/fit/camera.mjs +59 -0
  207. package/tools/bench/fit/contact.mjs +419 -0
  208. package/tools/bench/fit/footlock.mjs +234 -0
  209. package/tools/bench/fit/motion.mjs +85 -0
  210. package/tools/bench/fit/pin.mjs +27 -0
  211. package/tools/bench/fit/remote.mjs +105 -0
  212. package/tools/bench/fit-bench.mjs +126 -0
  213. package/tools/bench/fit-sanity.mjs +45 -0
  214. package/tools/bench/metrics.mjs +313 -0
  215. package/tools/bench/obs/depth.mjs +258 -0
  216. package/tools/bench/obs/extrinsics.mjs +175 -0
  217. package/tools/bench/obs/fit_mannequin_betas.py +340 -0
  218. package/tools/bench/obs/ground.mjs +294 -0
  219. package/tools/bench/obs/heading.mjs +151 -0
  220. package/tools/bench/obs/ladder.mjs +555 -0
  221. package/tools/bench/obs/mannequin-betas.json +124 -0
  222. package/tools/bench/obs/remote.mjs +83 -0
  223. package/tools/bench/obs/rest_joints.py +52 -0
  224. package/tools/bench/obs/ybot-targets.mjs +49 -0
  225. package/tools/bench/obs-bench.mjs +520 -0
  226. package/tools/bench/score.mjs +343 -0
  227. package/tools/bench/summarize.mjs +86 -0
  228. package/tools/dev/pages/privacy.html +13 -8
  229. package/tools/gt-render/browser.mjs +159 -0
  230. package/tools/gt-render/camera-math.mjs +276 -0
  231. package/tools/gt-render/page.mjs +267 -0
  232. package/tools/gt-render/render.mjs +514 -0
  233. package/tools/gt-render/scene-box.mjs +31 -0
  234. package/tools/gt-render/take-transform.mjs +87 -0
  235. package/tools/morphgs/assets/gen_truth.py +39 -0
  236. package/tools/morphgs/assets/mesh_ori_rig.txt +27 -0
  237. package/tools/morphgs/assets/playback-check.mjs +30 -0
  238. package/tools/morphgs/demo-gate.sh +26 -0
  239. package/tools/morphgs/fbx2morphgs.mjs +68 -0
  240. package/tools/morphgs/morphgs-to-cskel27.mjs +105 -0
  241. package/tools/morphgs/patches/preprocess_src-none-mode.patch +76 -0
  242. package/tools/morphgs/setup-on-cluster.sh +126 -0
  243. package/tools/qa/css-rule-usage.mjs +283 -0
  244. package/tools/qa/studio-control-count.mjs +70 -32
  245. package/tools/run-tests.mjs +134 -12
  246. package/tools/track/DESIGN.md +513 -0
  247. package/tools/track/backfill-provenance.mjs +116 -0
  248. package/tools/track/budget.mjs +8 -0
  249. package/tools/track/check-rig.mjs +209 -0
  250. package/tools/track/diagnostics.schema.json +60 -0
  251. package/tools/track/export-rig.mjs +256 -0
  252. package/tools/track/fallback.mjs +7 -0
  253. package/tools/track/fk-parity-fixture.mjs +161 -0
  254. package/tools/track/gate.mjs +349 -0
  255. package/tools/track/masks.mjs +318 -0
  256. package/tools/track/metrics.mjs +201 -0
  257. package/tools/track/publish-obs.mjs +108 -0
  258. package/tools/track/py/check_env.py +61 -0
  259. package/tools/track/py/eval_lr.py +229 -0
  260. package/tools/track/py/lr_viterbi.py +294 -0
  261. package/tools/track/py/masks.py +405 -0
  262. package/tools/track/py/objective.py +382 -0
  263. package/tools/track/py/rig.py +508 -0
  264. package/tools/track/py/scene.py +326 -0
  265. package/tools/track/py/test_joint_indices.py +123 -0
  266. package/tools/track/py/test_lr_viterbi.py +195 -0
  267. package/tools/track/py/test_masks.py +229 -0
  268. package/tools/track/py/test_rig.py +288 -0
  269. package/tools/track/py/test_scene.py +354 -0
  270. package/tools/track/py/test_track.py +328 -0
  271. package/tools/track/py/track.py +411 -0
  272. package/tools/track/remote.mjs +140 -0
  273. package/tools/track/rig-dump.mjs +227 -0
  274. package/tools/track/run-box-tests.mjs +14 -0
  275. package/tools/track/run-box.mjs +168 -0
  276. package/tools/track/setup-box.sh +59 -0
  277. package/tools/track/study-2d.mjs +728 -0
  278. package/dist/assets/analytics-B1hnH66c.js +0 -1
  279. package/dist/assets/app-BWusbqgO.js +0 -4861
  280. package/dist/assets/app-qKDo4PBX.css +0 -1
  281. package/dist/assets/shot-prompt-CHUtw6af.js +0 -17
  282. package/dist/assets/shot-prompt-C_g2BHVc.css +0 -1
  283. package/dist/assets/workflow-CVwzMhz2.js +0 -179
  284. package/dist/assets/workflow-DsudxKHF.css +0 -1
  285. package/src/fal-motion-studio.jsx +0 -180
  286. package/src/scene-history.js +0 -129
@@ -1 +1 @@
1
- import{g as e,u as t}from"./analytics-B1hnH66c.js";import{t as n}from"./config-Bx7pYsD9.js";t();var r=3e4,i=`Usually a few minutes while the generator is online.`,a=null,o=null,s=!1,c=null,l=!1;function u(e){return typeof document>`u`?null:document.getElementById(e)}function d(e){if(typeof e!=`string`)return null;let t=e.trim();return/^[A-Za-z0-9][A-Za-z0-9._~-]{0,199}$/u.test(t)?t:null}function f(e){if(typeof e!=`string`)return null;let t=e.startsWith(`#`)?e.slice(1):e;try{return d(new URLSearchParams(t).get(`t`))}catch{return null}}function p(){try{return new URL(globalThis.location.href)}catch{return null}}function m(){let e=p();if(!e)return null;if(e.searchParams.has(`t`)){let t=d(e.searchParams.get(`t`));e.searchParams.delete(`t`);let n=e.searchParams.toString(),r=`${e.pathname}${n?`?${n}`:``}${t?`#t=${encodeURIComponent(t)}`:``}`;try{globalThis.history?.replaceState(null,``,r)}catch{}return t}return f(e.hash)}function h(e,t){let n=u(e);return n&&(n.textContent=t==null?``:String(t)),n}function g(e,t){let n=u(e);return n&&n.classList.toggle(`is-hidden`,!t),n}function _(e){h(`ticket-message`,e)}function v(e){let t=u(`ticket-prompt`);t&&(t.textContent=typeof e==`string`?e:``,t.hidden=!t.textContent)}function y(){g(`open-result`,!1),g(`copy-link`,!1),g(`ticket-result`,!1)}function b(e){h(`ticket-state-title`,`Queued`);let t=Number(e?.position);h(`ticket-position`,Number.isInteger(t)&&t>0?`You are #${t} in line`:`You are in line`);let n=Number(e?.etaMinutes),r=e?.etaMinutes!==null&&e?.etaMinutes!==void 0&&Number.isFinite(n)&&n>=0,a=typeof e?.etaText==`string`?e.etaText.trim():``;r?h(`ticket-eta`,a||`About ${n} minute${n===1?``:`s`}`):h(`ticket-eta`,/\b\d+\s+minutes?\b/iu.test(a)||/^Usually within a few hours\s+(?:—|-)\s+at most 48 hours\.$/iu.test(a)?i:a||i),y(),g(`copy-link`,!0),_(``)}function x(e=null){h(`ticket-state-title`,`Running`),h(`ticket-position`,`Your motion is being prepared.`),h(`ticket-eta`,`The generator is working on it now.`),y(),g(`copy-link`,!0),_(``)}function S(t){l||(l=!0,e(`hosted:result_opened`)),h(`ticket-state-title`,`Ready`),h(`ticket-position`,`Your motion is ready.`),h(`ticket-eta`,`Open it in CozyClay to play it back.`),y(),v(t?.promptText);let n=typeof t?.resultUrl==`string`?t.resultUrl:``,r=u(`open-result`);r&&n&&(r.href=`/app/?motion=${encodeURIComponent(n)}`,g(`open-result`,!0)),g(`copy-link`,!0),g(`ticket-result`,!0),_(``)}function C(e=null){h(`ticket-state-title`,`Could not complete`),h(`ticket-position`,`This motion failed.`),h(`ticket-eta`,`No charge was made. You can create another motion.`),y(),_(``)}function w(e=null){h(`ticket-state-title`,`Ticket unavailable`),h(`ticket-position`,`This ticket has been revoked.`),h(`ticket-eta`,`The result link is no longer active.`),y(),_(``)}function T(e=null){h(`ticket-state-title`,`Ticket expired`),h(`ticket-position`,`This link has expired.`),h(`ticket-eta`,`Results are kept for 30 days.`),y(),_(``)}function E(){h(`ticket-state-title`,`Ticket not found`),h(`ticket-position`,`We could not find that ticket.`),h(`ticket-eta`,`Check the link and try again.`),v(``),y(),_(``)}function D(e){switch(v(e?.promptText),e?.status){case`queued`:b(e);break;case`running`:x(e);break;case`done`:S(e);break;case`failed`:C(e);break;case`revoked`:case`canceled`:w(e);break;default:h(`ticket-state-title`,`Ticket unavailable`),h(`ticket-position`,`We could not read this ticket.`),h(`ticket-eta`,`Please return to the composer and try again.`),y(),_(``)}}function O(e){return e===`done`||e===`failed`||e===`revoked`||e===`canceled`}function k(){o!==null&&(globalThis.clearInterval?.(o),o=null)}function A(){o===null&&(o=globalThis.setInterval(N,r))}async function j(e){try{return await e.json()}catch{return{}}}async function M(e){return fetch(`${n}/jobs/${encodeURIComponent(e)}`,{method:`GET`,credentials:`omit`,cache:`no-store`,headers:{Accept:`application/json`}})}async function N(){if(!a||s)return null;s=!0;try{let e=await M(a),t=await j(e);if(e.status===404||t.error===`not_found`)return E(),k(),t;if(e.status===410)return t.error===`expired`?T():w(),k(),t;if(!e.ok)throw Error(t.error||`poll_failed`);return c=t,D(t),O(t.status)?k():A(),t}catch{return c||(h(`ticket-state-title`,`Connection problem`),h(`ticket-position`,`We could not reach the queue.`),h(`ticket-eta`,`We will keep trying.`)),_(`The latest update did not arrive. We will try again shortly.`),A(),null}finally{s=!1}}async function P(){let e=globalThis.location?.href??``;if(e)try{if(globalThis.navigator?.clipboard?.writeText)await globalThis.navigator.clipboard.writeText(e);else{let t=document.createElement(`input`);t.value=e,t.setAttribute(`readonly`,``),t.style.position=`fixed`,t.style.opacity=`0`,document.body.append(t),t.select(),document.execCommand(`copy`),t.remove()}_(`Share link copied.`)}catch{_(`Copy was not available. Copy the link from your address bar.`)}}function F(){typeof document<`u`&&document.visibilityState===`visible`&&N()}function I(){if(u(`copy-link`)?.addEventListener(`click`,P),u(`open-result`)?.addEventListener(`click`,()=>e(`hosted:opened_in_studio`)),a){let e=u(`report-link`);e&&(e.href=`mailto:hello@cozyclay.org?subject=${encodeURIComponent(`CozyClay ticket ${a}`)}`)}document.addEventListener(`visibilitychange`,F)}function L(){if(a=m(),I(),!a){E();return}N(),A()}typeof document<`u`&&(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,L,{once:!0}):L());
1
+ import{b as e,d as t}from"./analytics-MVZOEW8O.js";import{t as n}from"./config-Bx7pYsD9.js";t();var r=3e4,i=`Usually a few minutes while the generator is online.`,a=null,o=null,s=!1,c=null,l=!1;function u(e){return typeof document>`u`?null:document.getElementById(e)}function d(e){if(typeof e!=`string`)return null;let t=e.trim();return/^[A-Za-z0-9][A-Za-z0-9._~-]{0,199}$/u.test(t)?t:null}function f(e){if(typeof e!=`string`)return null;let t=e.startsWith(`#`)?e.slice(1):e;try{return d(new URLSearchParams(t).get(`t`))}catch{return null}}function p(){try{return new URL(globalThis.location.href)}catch{return null}}function m(){let e=p();if(!e)return null;if(e.searchParams.has(`t`)){let t=d(e.searchParams.get(`t`));e.searchParams.delete(`t`);let n=e.searchParams.toString(),r=`${e.pathname}${n?`?${n}`:``}${t?`#t=${encodeURIComponent(t)}`:``}`;try{globalThis.history?.replaceState(null,``,r)}catch{}return t}return f(e.hash)}function h(e,t){let n=u(e);return n&&(n.textContent=t==null?``:String(t)),n}function g(e,t){let n=u(e);return n&&n.classList.toggle(`is-hidden`,!t),n}function _(e){h(`ticket-message`,e)}function v(e){let t=u(`ticket-prompt`);t&&(t.textContent=typeof e==`string`?e:``,t.hidden=!t.textContent)}function y(){g(`open-result`,!1),g(`copy-link`,!1),g(`ticket-result`,!1)}function b(e){h(`ticket-state-title`,`Queued`);let t=Number(e?.position);h(`ticket-position`,Number.isInteger(t)&&t>0?`You are #${t} in line`:`You are in line`);let n=Number(e?.etaMinutes),r=e?.etaMinutes!==null&&e?.etaMinutes!==void 0&&Number.isFinite(n)&&n>=0,a=typeof e?.etaText==`string`?e.etaText.trim():``;r?h(`ticket-eta`,a||`About ${n} minute${n===1?``:`s`}`):h(`ticket-eta`,/\b\d+\s+minutes?\b/iu.test(a)||/^Usually within a few hours\s+(?:—|-)\s+at most 48 hours\.$/iu.test(a)?i:a||i),y(),g(`copy-link`,!0),_(``)}function x(e=null){h(`ticket-state-title`,`Running`),h(`ticket-position`,`Your motion is being prepared.`),h(`ticket-eta`,`The generator is working on it now.`),y(),g(`copy-link`,!0),_(``)}function S(t){l||(l=!0,e(`hosted:result_opened`)),h(`ticket-state-title`,`Ready`),h(`ticket-position`,`Your motion is ready.`),h(`ticket-eta`,`Open it in CozyClay to play it back.`),y(),v(t?.promptText);let n=typeof t?.resultUrl==`string`?t.resultUrl:``,r=u(`open-result`);r&&n&&(r.href=`/app/?motion=${encodeURIComponent(n)}`,g(`open-result`,!0)),g(`copy-link`,!0),g(`ticket-result`,!0),_(``)}function C(e=null){h(`ticket-state-title`,`Could not complete`),h(`ticket-position`,`This motion failed.`),h(`ticket-eta`,`No charge was made. You can create another motion.`),y(),_(``)}function w(e=null){h(`ticket-state-title`,`Ticket unavailable`),h(`ticket-position`,`This ticket has been revoked.`),h(`ticket-eta`,`The result link is no longer active.`),y(),_(``)}function T(e=null){h(`ticket-state-title`,`Ticket expired`),h(`ticket-position`,`This link has expired.`),h(`ticket-eta`,`Results are kept for 30 days.`),y(),_(``)}function E(){h(`ticket-state-title`,`Ticket not found`),h(`ticket-position`,`We could not find that ticket.`),h(`ticket-eta`,`Check the link and try again.`),v(``),y(),_(``)}function D(e){switch(v(e?.promptText),e?.status){case`queued`:b(e);break;case`running`:x(e);break;case`done`:S(e);break;case`failed`:C(e);break;case`revoked`:case`canceled`:w(e);break;default:h(`ticket-state-title`,`Ticket unavailable`),h(`ticket-position`,`We could not read this ticket.`),h(`ticket-eta`,`Please return to the composer and try again.`),y(),_(``)}}function O(e){return e===`done`||e===`failed`||e===`revoked`||e===`canceled`}function k(){o!==null&&(globalThis.clearInterval?.(o),o=null)}function A(){o===null&&(o=globalThis.setInterval(N,r))}async function j(e){try{return await e.json()}catch{return{}}}async function M(e){return fetch(`${n}/jobs/${encodeURIComponent(e)}`,{method:`GET`,credentials:`omit`,cache:`no-store`,headers:{Accept:`application/json`}})}async function N(){if(!a||s)return null;s=!0;try{let e=await M(a),t=await j(e);if(e.status===404||t.error===`not_found`)return E(),k(),t;if(e.status===410)return t.error===`expired`?T():w(),k(),t;if(!e.ok)throw Error(t.error||`poll_failed`);return c=t,D(t),O(t.status)?k():A(),t}catch{return c||(h(`ticket-state-title`,`Connection problem`),h(`ticket-position`,`We could not reach the queue.`),h(`ticket-eta`,`We will keep trying.`)),_(`The latest update did not arrive. We will try again shortly.`),A(),null}finally{s=!1}}async function P(){let e=globalThis.location?.href??``;if(e)try{if(globalThis.navigator?.clipboard?.writeText)await globalThis.navigator.clipboard.writeText(e);else{let t=document.createElement(`input`);t.value=e,t.setAttribute(`readonly`,``),t.style.position=`fixed`,t.style.opacity=`0`,document.body.append(t),t.select(),document.execCommand(`copy`),t.remove()}_(`Share link copied.`)}catch{_(`Copy was not available. Copy the link from your address bar.`)}}function F(){typeof document<`u`&&document.visibilityState===`visible`&&N()}function I(){if(u(`copy-link`)?.addEventListener(`click`,P),u(`open-result`)?.addEventListener(`click`,()=>e(`hosted:opened_in_studio`)),a){let e=u(`report-link`);e&&(e.href=`mailto:hello@cozyclay.org?subject=${encodeURIComponent(`CozyClay ticket ${a}`)}`)}document.addEventListener(`visibilitychange`,F)}function L(){if(a=m(),I(),!a){E();return}N(),A()}typeof document<`u`&&(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,L,{once:!0}):L());
@@ -0,0 +1 @@
1
+ .react-flow{direction:ltr}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1;cursor:-webkit-grab;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1px;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:-webkit-grab;cursor:grab;position:absolute}.react-flow__node.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:-webkit-grab;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background:#1a192b;border:1px solid #fff;border-radius:100%;width:6px;min-width:5px;height:6px;min-height:5px;position:absolute}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:-4px;left:50%;transform:translate(-50%)}.react-flow__handle-top{top:-4px;left:50%;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{top:50%;right:-4px;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{background:#ffffff80;margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{color:#222;text-align:center;background-color:#fff;border:1px solid #1a192b;border-radius:3px;width:150px;padding:10px;font-size:12px}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted #0059dccc}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{box-sizing:content-box;cursor:pointer;-webkit-user-select:none;user-select:none;background:#fefefe;border:none;border-bottom:1px solid #eee;justify-content:center;align-items:center;width:16px;height:16px;padding:5px;display:flex}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:#3367d9;border:1px solid #fff;border-radius:1px;width:4px;height:4px;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border:0 solid #3367d9}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}@layer legacy{:root{color:#edf0fb;font-synthesis:none;background:#101116;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif}*{box-sizing:border-box}body{background:#101116;min-width:900px;margin:0}#workflow-root{height:100vh}.workflow-app{color:#edf0fb;background:#101116;flex-direction:column;height:100vh;display:flex}.workflow-topbar{background:#171921;border-bottom:1px solid #292d38;justify-content:space-between;align-items:center;height:58px;padding:0 22px;display:flex}.workflow-brand{color:#afb4c6;align-items:center;gap:9px;font-size:14px;display:flex}.workflow-brand strong{color:#f5f7ff;font-size:14px}.workflow-brand-mark{color:#fff;background:linear-gradient(135deg,#ef759d,#6c7cff);border-radius:7px;place-items:center;width:23px;height:23px;font-size:12px;font-weight:800;display:grid}.workflow-divider{color:#555b70;margin-left:3px}.workflow-top-actions{align-items:center;gap:9px;display:flex}.workflow-top-actions button,.workflow-sidebar-bottom button,.workflow-sidebar-bottom a{color:#c8ccdb;font:inherit;cursor:pointer;background:#20232d;border:1px solid #353a4a;border-radius:6px;padding:7px 12px;font-size:12px;text-decoration:none}.workflow-top-actions button:hover,.workflow-sidebar-bottom button:hover,.workflow-sidebar-bottom a:hover{background:#2b3040;border-color:#606b9a}.workflow-status{color:#7f879e;align-items:center;gap:7px;margin-right:8px;font-size:11px;display:flex}.workflow-status i{background:#4dcda4;border-radius:50%;width:6px;height:6px;box-shadow:0 0 8px #4dcda4}.workflow-main{flex:1;min-height:0;display:flex}.workflow-sidebar{background:#171921;border-right:1px solid #292d38;flex-direction:column;flex:none;width:232px;padding:22px 14px;display:flex}.workflow-sidebar-title{letter-spacing:.08em;text-transform:uppercase;color:#f3f5fd;font-size:12px;font-weight:700}.workflow-sidebar-copy{color:#737b92;margin:8px 6px 18px 0;font-size:11px;line-height:1.5}.workflow-node-menu{flex-direction:column;gap:5px;display:flex}.workflow-add-node{color:#bcc2d4;width:100%;font:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:10px;padding:9px 10px;font-size:12px;display:flex}.workflow-add-node:hover{color:#f5f7ff;background:#222631;border-color:#373d50}.workflow-add-node span:nth-child(2){flex:1}.workflow-sidebar-bottom{flex-direction:column;gap:8px;margin-top:auto;display:flex}.workflow-sidebar-bottom button,.workflow-sidebar-bottom a{text-align:center;font-size:11px}.workflow-canvas{flex:1;min-width:0;position:relative}.workflow-canvas .react-flow{background:#11141c}.workflow-canvas .react-flow__controls{bottom:22px;left:20px;box-shadow:0 5px 18px #0005}.workflow-canvas .react-flow__controls-button{fill:#aeb5c9;color:#aeb5c9;background:#20242e;border-bottom:1px solid #323744;width:28px;height:28px}.workflow-canvas .react-flow__minimap{border:1px solid #353a49;border-radius:7px;bottom:20px;right:20px;overflow:hidden}.workflow-canvas-panel{margin:14px}.workflow-canvas-panel button{color:#e7eaff;font:inherit;cursor:pointer;background:#27304a;border:1px solid #454d70;border-radius:6px;align-items:center;gap:6px;padding:8px 11px;font-size:11px;display:flex}.workflow-node{color:#e5e8f5;background:#20232d;border:1px solid #3c4152;border-radius:9px;width:230px;position:relative;overflow:visible;box-shadow:0 10px 30px #0004}.workflow-node:hover{border-color:#6877bd}.workflow-node-header{background:#252935;border-bottom:1px solid #343946;border-radius:9px 9px 0 0;align-items:center;gap:8px;padding:10px 11px;font-size:12px;display:flex}.workflow-node-icon{color:#aeb8ff;background:#303648;border-radius:6px;place-items:center;width:23px;height:23px;display:grid}.workflow-node-image .workflow-node-icon{color:#67d8b6}.workflow-node-video .workflow-node-icon{color:#eca56e}.workflow-node-upload .workflow-node-icon{color:#c4a8ef}.workflow-node-concat .workflow-node-icon{color:#e3c969}.workflow-node-scene .workflow-node-icon{color:#ef82a7}.workflow-node-id{color:#6c7389;margin-left:auto;font:10px ui-monospace,monospace}.workflow-node-body{flex-direction:column;gap:7px;padding:11px;display:flex}.workflow-node label{color:#8d95ab;font-size:10px}.workflow-node input,.workflow-node textarea,.workflow-node select{color:#e5e8f5;width:100%;font:inherit;resize:vertical;background:#171a21;border:1px solid #3a3f4e;border-radius:5px;outline:0;padding:7px 8px;font-size:11px}.workflow-node input:focus,.workflow-node textarea:focus,.workflow-node select:focus{border-color:#707dce}.workflow-textarea{height:65px}.workflow-node-foot{color:#737b92;justify-content:space-between;align-items:center;margin-top:3px;font-size:10px;display:flex}.workflow-mini-button,.workflow-run-button{color:#e6e9ff;font:inherit;cursor:pointer;background:#303b71;border:1px solid #4c5aab;border-radius:5px;align-items:center;gap:4px;padding:5px 8px;font-size:10px;display:flex}.workflow-dropzone{color:#78819c;text-align:center;border:1px dashed #49516a;border-radius:6px;justify-content:center;align-items:center;gap:7px;height:74px;font-size:10px;display:flex}.workflow-upload{color:#a89ce4;cursor:pointer;border:1px dashed #525b79;border-radius:6px;flex-direction:column;justify-content:center;align-items:center;gap:5px;height:90px;display:flex;position:relative}.workflow-upload input{opacity:0;cursor:pointer;position:absolute;inset:0}.workflow-schema-fields{border-top:1px solid #323746;flex-direction:column;gap:6px;padding-top:4px;display:flex}.workflow-schema-title{color:#8d95ab;text-transform:uppercase;letter-spacing:.08em;font-size:9px}.workflow-schema-fields label{flex-direction:column;gap:4px;display:flex}.workflow-schema-check{align-items:center;flex-direction:row!important;gap:6px!important;display:flex!important}.workflow-schema-check input{width:auto}.workflow-node-cost{color:#78d9b0;margin-left:4px}.workflow-hint{color:#666e83;margin:0;font-size:9px;line-height:1.35}.workflow-scene-preview{color:#7b849e;background:#171a23;border:1px solid #3d4357;border-radius:6px;justify-content:center;align-items:center;height:80px;font-size:10px;display:flex;position:relative;overflow:hidden}.workflow-scene-grid{opacity:.32;background-color:#0000;background-image:linear-gradient(135deg,#0000 46%,#687090 47%,#0000 49%),linear-gradient(45deg,#0000 46%,#687090 47%,#0000 49%);background-position:0 0,0 0;background-repeat:repeat,repeat;background-size:22px 22px;background-attachment:scroll,scroll;background-origin:padding-box,padding-box;background-clip:border-box,border-box;position:absolute;inset:0}.workflow-scene-preview span{position:relative}.workflow-scene-controls{gap:4px;display:flex}.workflow-scene-controls button{color:#9da5ba;font:inherit;cursor:pointer;background:#292d39;border:1px solid #3b4050;border-radius:4px;flex:1;padding:5px 2px;font-size:9px}.workflow-handle{background:#8994ff;border:2px solid #20232d;width:9px;height:9px}.workflow-handle.target{background:#4c566f}.workflow-node-image .workflow-handle{background:#44c2a4}.workflow-node-video .workflow-handle{background:#d9955b}.workflow-node-scene .workflow-handle{background:#ef759d}.workflow-node-upload .workflow-handle{background:#a88cdb}.workflow-video-preview{background:#11141c;border:1px solid #3d4357;border-radius:6px;width:100%;max-height:150px;display:block}.workflow-provider-hint{color:#737b92;margin-top:-3px;font-size:9px}.workflow-node-search{color:#e5e8f5;width:100%;font:inherit;background:#11141b;border:1px solid #353a4a;border-radius:6px;outline:0;margin:0 0 8px;padding:8px 9px;font-size:11px}.workflow-node-search:focus{border-color:#707dce}.workflow-model-results{background:#12151d;border:1px solid #303545;border-radius:6px;flex-direction:column;gap:2px;margin:0 0 7px;padding:4px;display:flex}.workflow-model-results .workflow-hint{padding:6px}.workflow-node-motion-input .workflow-node-icon{color:#79b5ed}.workflow-motion-upload{height:70px}.workflow-node-motion-input .workflow-handle{background:#79b5ed}.workflow-agent-toggle{position:relative}.workflow-main{position:relative;overflow:hidden}.workflow-image-preview{object-fit:contain;background:#11141c;border:1px solid #3d4357;border-radius:6px;width:100%;max-height:150px;display:block}.workflow-error{color:#ef759d;font-size:9px;line-height:1.35}.workflow-preservation-ok{color:#78d9b0}.workflow-preservation-failed{background:#3a202c;border:1px solid #8b405d;border-radius:5px;padding:6px 7px}.workflow-versions{flex-direction:column;gap:5px;display:flex}.workflow-ab-toggle{cursor:pointer;border-color:#67d8b6;box-shadow:0 0 0 1px #67d8b64d}.workflow-version-bar{align-items:center;gap:4px;display:flex}.workflow-version-bar button{color:#9da5ba;font:inherit;cursor:pointer;background:#292d39;border:1px solid #3b4050;border-radius:4px;padding:4px 7px;font-size:9px;line-height:1}.workflow-version-bar button:hover:not(:disabled){color:#e5e8f5;border-color:#606b9a}.workflow-version-bar button:disabled{opacity:.4;cursor:default}.workflow-version-count{text-align:center;color:#78d9b0;flex:1;font:10px ui-monospace,monospace}.workflow-version-ab.active{color:#78d9b0;background:#25443c;border-color:#4c8f7c}.workflow-version-compare{color:#8d95ab;align-items:center;gap:6px;font-size:9px;flex-direction:row!important;display:flex!important}.workflow-version-compare select{flex:1;width:auto}.workflow-version-pin{color:#8d95ab;font-size:9px}.workflow-version-reuse{color:#e6e9ff;font:inherit;cursor:pointer;background:#303b71;border:1px solid #4c5aab;border-radius:5px;padding:5px 8px;font-size:10px}.workflow-version-reuse:hover{background:#3a468a;border-color:#7180d6}.workflow-node-shot-prompt .workflow-node-icon{color:#8fd4b0}.workflow-node-shot-prompt .workflow-handle{background:#8fd4b0}.workflow-shot-prompt-text{color:#cfe6da;height:92px;font:11px ui-monospace,monospace}.workflow-shot-prompt-copy{color:#a9e6c8;font:inherit;cursor:pointer;background:#25443c;border:1px solid #4c8f7c;border-radius:5px;justify-content:center;align-items:center;gap:5px;padding:5px 8px;font-size:10px;display:flex}.workflow-shot-prompt-copy:hover{background:#2e564b;border-color:#6fc0a2}.workflow-warning{color:#e8c78c;background:#2b2419;border:1px solid #8d6b3d;border-radius:5px;margin:0;padding:6px 7px;font-size:9px;line-height:1.35}.cozy-scene-node{color:#e4e9ef;background:#202631;border:1px solid #3b4756;border-radius:10px;width:318px;font:12px/1.35 Inter,system-ui,sans-serif;position:relative;overflow:visible;box-shadow:0 12px 28px #00000052}.cozy-scene-node.is-selected{border-color:#79b7e8;box-shadow:0 0 0 2px #79b7e842,0 12px 28px #00000052}.cozy-scene-node-header,.cozy-scene-node-footer{justify-content:space-between;align-items:center;gap:10px;padding:11px 13px;display:flex}.cozy-scene-node-kicker{color:#78a9d3;letter-spacing:.14em;font-size:9px;font-weight:800}.cozy-scene-node h3{margin:2px 0 0;font-size:14px;font-weight:700}.cozy-scene-node-status{color:#aebccc;text-align:right;max-width:112px;font-size:10px}.cozy-scene-node-status.has-pack{word-break:break-word;max-width:178px}.status-running{color:#f0c979}.status-complete{color:#8dd5b1}.status-error{color:#f08d8d}.cozy-scene-preview{background:linear-gradient(145deg,#32475d,#121820 70%);border:1px solid #3c4b5d;border-radius:6px;height:134px;margin:0 10px;position:relative;overflow:hidden}.cozy-scene-canvas{position:absolute;inset:0}.cozy-scene-live-frame{transform-origin:0 0;background:#111722;border:0;width:200%;height:200%;position:absolute;top:0;left:0;transform:scale(.5)}.cozy-scene-world-image{filter:saturate(.78)brightness(.82);background-image:url(/media/cozyclay-demo-poster.jpg);background-position:0;background-repeat:no-repeat;background-size:auto 250%;position:absolute;inset:0}.cozy-scene-world-tint{pointer-events:none;background:linear-gradient(#090f160a,#090f169e);position:absolute;inset:0}.cozy-scene-render-thumb{background:#111722;border:1px solid #3c4b5d;border-radius:5px;width:76px;margin:0;position:absolute;bottom:8px;left:8px;overflow:hidden;box-shadow:0 4px 10px #00000057}.cozy-scene-render-thumb img{aspect-ratio:16/9;object-fit:cover;width:100%;display:block}.cozy-scene-render-thumb figcaption{color:#9eb0c2;letter-spacing:.08em;text-transform:uppercase;background:#121722db;padding:2px 5px;font-size:9px;font-weight:800}.cozy-scene-grid{background:repeating-linear-gradient(90deg,#0000 0 19px,#85b4da2e 20px 21px),repeating-linear-gradient(0deg,#0000 0 17px,#85b4da24 18px 19px);position:absolute;inset:45% -25% -55%;transform:perspective(80px)rotateX(58deg)}.cozy-scene-stage-mark{background:#79b7e82e;border:2px solid #b4d7f1b8;border-radius:8px;width:78px;height:78px;position:absolute;top:25px;left:50%;transform:translate(-50%)rotate(45deg)}.cozy-scene-stage-mark span{background:#527c9d;border:1px solid #c3e5ff;border-radius:50%;width:8px;height:8px;position:absolute}.cozy-scene-stage-mark span:first-child{top:-5px;left:-5px}.cozy-scene-stage-mark span:nth-child(2){top:-5px;right:-5px}.cozy-scene-stage-mark span:nth-child(3){bottom:-5px;right:-5px}.cozy-scene-preview-copy{color:#d7e4ef;text-align:right;background:#121722c7;border-radius:5px;gap:1px;padding:4px 7px;display:grid;position:absolute;bottom:8px;right:8px}.cozy-scene-preview-copy strong{font-size:11px}.cozy-scene-preview-copy span{color:#9eb0c2;font-size:10px}.cozy-scene-controls{gap:8px;padding:11px 13px 9px;display:grid}.cozy-scene-control-row{gap:6px;display:flex}.cozy-scene-button,.cozy-scene-send,.cozy-scene-video,.cozy-scene-run,.cozy-scene-camera-row button{color:#d8e5f0;font:inherit;cursor:pointer;background:#2c3846;border:1px solid #465668;border-radius:5px;padding:5px 8px}.cozy-scene-button:hover,.cozy-scene-camera-row button:hover{background:#344658}.cozy-scene-run{background:#35658c;border-color:#5f96c3;margin-left:auto}.cozy-scene-run:disabled,.cozy-scene-send:disabled{cursor:wait;opacity:.7}.cozy-scene-send{color:#cfe6f8;background:#2a4256;border-color:#4d6c88}.cozy-scene-send:hover:not(:disabled){background:#33506a}.cozy-scene-handoff{align-items:center;gap:8px;display:flex}.cozy-scene-video{color:#cfe6f8;background:#2a4256;border-color:#4d6c88;flex:none}.cozy-scene-video:hover{background:#33506a}.cozy-scene-hint{color:#8799aa;margin:0;font-size:10px;line-height:1.3}.cozy-scene-frame-control{color:#acbbc9;grid-template-columns:auto 1fr auto;align-items:center;gap:7px;font-size:10px;display:grid}.cozy-scene-frame-control input{accent-color:#79b7e8;width:100%}.cozy-scene-frame-control output{color:#dce7f1;text-align:right;min-width:40px;font-family:ui-monospace,monospace}.cozy-scene-camera-row{color:#9eafbf;justify-content:center;align-items:center;gap:8px;font-size:10px;display:flex}.cozy-scene-camera-row button{padding:2px 7px}.cozy-scene-node-footer{color:#8799aa;border-top:1px solid #33404e;font-size:10px}.cozy-scene-node-footer span+span{margin-left:auto}.cozy-scene-node-inputs,.cozy-scene-node-outputs{pointer-events:none;width:12px;position:absolute;top:0;bottom:0}.cozy-scene-node-inputs{left:-7px}.cozy-scene-node-outputs{right:-7px}.cozy-scene-handle{pointer-events:auto;background:#243443;border:2px solid #a9d1f0;border-radius:50%;width:10px;height:10px;display:block;position:absolute}.cozy-scene-handle-target{left:0}.cozy-scene-handle-source{right:0}.cozy-scene-handle-asset{top:85px}.cozy-scene-handle-motion{top:115px}.cozy-scene-handle-render{top:108px}.cozy-scene-handle-scene{top:140px}.cozy-scene-reactflow-handle{z-index:5}.cozy-scene-reactflow-handle-asset{top:85px!important}.cozy-scene-reactflow-handle-motion{top:115px!important}.cozy-scene-reactflow-handle-render{top:108px!important}.cozy-scene-reactflow-handle-scene{top:140px!important}}