@gtanczyk/diorama 0.0.0-stage → 0.2.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 (302) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +157 -2
  3. package/app/bin/diorama.mjs +13 -0
  4. package/app/src/actions/budget.ts +160 -0
  5. package/app/src/actions/build.ts +158 -0
  6. package/app/src/actions/cast.ts +267 -0
  7. package/app/src/actions/depth.ts +95 -0
  8. package/app/src/actions/extend.ts +36 -0
  9. package/app/src/actions/faces.ts +160 -0
  10. package/app/src/actions/feedback.ts +87 -0
  11. package/app/src/actions/fix.ts +382 -0
  12. package/app/src/actions/history.ts +93 -0
  13. package/app/src/actions/idea-preview.ts +65 -0
  14. package/app/src/actions/idea-review.ts +102 -0
  15. package/app/src/actions/idea-sketch.ts +172 -0
  16. package/app/src/actions/index.ts +32 -0
  17. package/app/src/actions/items.ts +94 -0
  18. package/app/src/actions/kids.ts +215 -0
  19. package/app/src/actions/language.ts +52 -0
  20. package/app/src/actions/models.ts +64 -0
  21. package/app/src/actions/motion.ts +119 -0
  22. package/app/src/actions/pictures.ts +49 -0
  23. package/app/src/actions/reactions.ts +36 -0
  24. package/app/src/actions/registry.ts +101 -0
  25. package/app/src/actions/share.ts +32 -0
  26. package/app/src/actions/sound.ts +73 -0
  27. package/app/src/actions/start.ts +154 -0
  28. package/app/src/actions/step-work.ts +150 -0
  29. package/app/src/actions/story.ts +101 -0
  30. package/app/src/actions/studio.ts +133 -0
  31. package/app/src/actions/style.ts +72 -0
  32. package/app/src/actions/video.ts +46 -0
  33. package/app/src/actions/view.ts +109 -0
  34. package/app/src/actions/weather.ts +38 -0
  35. package/app/src/actions/world.ts +290 -0
  36. package/app/src/commands/action.ts +39 -0
  37. package/app/src/commands/backdrop.ts +188 -0
  38. package/app/src/commands/browsers.ts +21 -0
  39. package/app/src/commands/build.ts +503 -0
  40. package/app/src/commands/cast.ts +161 -0
  41. package/app/src/commands/clip.ts +431 -0
  42. package/app/src/commands/derive.ts +167 -0
  43. package/app/src/commands/doctor.ts +74 -0
  44. package/app/src/commands/explore.ts +123 -0
  45. package/app/src/commands/export.ts +158 -0
  46. package/app/src/commands/extend.ts +75 -0
  47. package/app/src/commands/faces.ts +80 -0
  48. package/app/src/commands/icons.ts +69 -0
  49. package/app/src/commands/index.ts +37 -0
  50. package/app/src/commands/language.ts +87 -0
  51. package/app/src/commands/layout.ts +31 -0
  52. package/app/src/commands/masks.ts +117 -0
  53. package/app/src/commands/mcp.ts +52 -0
  54. package/app/src/commands/model.ts +284 -0
  55. package/app/src/commands/paint.ts +182 -0
  56. package/app/src/commands/plates.ts +97 -0
  57. package/app/src/commands/play.ts +195 -0
  58. package/app/src/commands/playthrough.ts +111 -0
  59. package/app/src/commands/publish.ts +78 -0
  60. package/app/src/commands/reactions.ts +40 -0
  61. package/app/src/commands/reel.ts +46 -0
  62. package/app/src/commands/setup.ts +85 -0
  63. package/app/src/commands/sound.ts +100 -0
  64. package/app/src/commands/sprites.ts +232 -0
  65. package/app/src/commands/story.ts +37 -0
  66. package/app/src/commands/studio.ts +65 -0
  67. package/app/src/commands/style.ts +87 -0
  68. package/app/src/commands/verify.ts +45 -0
  69. package/app/src/commands/voice-retry.ts +14 -0
  70. package/app/src/commands/voices.ts +145 -0
  71. package/app/src/commands/weather.ts +52 -0
  72. package/app/src/commands/world.ts +104 -0
  73. package/app/src/film/clip.ts +386 -0
  74. package/app/src/film/reel.ts +126 -0
  75. package/app/src/film/screencast.ts +123 -0
  76. package/app/src/image/mask.ts +29 -0
  77. package/app/src/image/overlay.ts +38 -0
  78. package/app/src/image/raster.ts +224 -0
  79. package/app/src/main.ts +28 -0
  80. package/app/src/meta/choice.ts +27 -0
  81. package/app/src/meta/http.ts +99 -0
  82. package/app/src/meta/memo.ts +105 -0
  83. package/app/src/meta/muse.ts +70 -0
  84. package/app/src/meta/openrouter.ts +93 -0
  85. package/app/src/meta/prices.ts +25 -0
  86. package/app/src/meta/sam.ts +83 -0
  87. package/app/src/meta/schema.ts +63 -0
  88. package/app/src/meta/spark.ts +220 -0
  89. package/app/src/meta/step.ts +14 -0
  90. package/app/src/meta/voice-file.ts +78 -0
  91. package/app/src/meta/voice.ts +103 -0
  92. package/app/src/model/animation.ts +38 -0
  93. package/app/src/model/blender/relax.py +284 -0
  94. package/app/src/model/blender.ts +115 -0
  95. package/app/src/model/build.ts +50 -0
  96. package/app/src/model/face.ts +21 -0
  97. package/app/src/model/fit.ts +181 -0
  98. package/app/src/model/glb.ts +241 -0
  99. package/app/src/model/plan.ts +151 -0
  100. package/app/src/model/quality.ts +48 -0
  101. package/app/src/model/space.ts +168 -0
  102. package/app/src/model/sprites.ts +293 -0
  103. package/app/src/model/views.ts +163 -0
  104. package/app/src/play/creature.ts +43 -0
  105. package/app/src/play/depth-occlusion.ts +150 -0
  106. package/app/src/play/exit-outline.ts +48 -0
  107. package/app/src/play/face3d.ts +34 -0
  108. package/app/src/play/focus.ts +78 -0
  109. package/app/src/play/geometry.ts +272 -0
  110. package/app/src/play/gestures.ts +23 -0
  111. package/app/src/play/glow.ts +187 -0
  112. package/app/src/play/lipsync.ts +69 -0
  113. package/app/src/play/living.ts +83 -0
  114. package/app/src/play/outline-path.ts +130 -0
  115. package/app/src/play/parallax.ts +200 -0
  116. package/app/src/play/path.ts +262 -0
  117. package/app/src/play/preview.ts +71 -0
  118. package/app/src/play/reactions.ts +92 -0
  119. package/app/src/play/rig.ts +172 -0
  120. package/app/src/play/shadow.ts +253 -0
  121. package/app/src/play/sound.ts +51 -0
  122. package/app/src/play/weather.ts +58 -0
  123. package/app/src/qa/explore.ts +136 -0
  124. package/app/src/qa/probe.ts +139 -0
  125. package/app/src/qa/route.ts +118 -0
  126. package/app/src/registry.ts +23 -0
  127. package/app/src/scene/animation-source.ts +36 -0
  128. package/app/src/scene/assets.ts +37 -0
  129. package/app/src/scene/autofix.ts +133 -0
  130. package/app/src/scene/backdrop.ts +326 -0
  131. package/app/src/scene/blockin.ts +189 -0
  132. package/app/src/scene/brief.ts +74 -0
  133. package/app/src/scene/carry.ts +177 -0
  134. package/app/src/scene/cast-fixes.ts +33 -0
  135. package/app/src/scene/cast.ts +199 -0
  136. package/app/src/scene/corrections.ts +164 -0
  137. package/app/src/scene/critic.ts +169 -0
  138. package/app/src/scene/depthmap.ts +149 -0
  139. package/app/src/scene/derive.ts +475 -0
  140. package/app/src/scene/diagnose.ts +132 -0
  141. package/app/src/scene/face-calibration.ts +65 -0
  142. package/app/src/scene/face-registration.ts +21 -0
  143. package/app/src/scene/face-work.ts +71 -0
  144. package/app/src/scene/faces-data.ts +48 -0
  145. package/app/src/scene/faces-settings.ts +20 -0
  146. package/app/src/scene/faces.ts +435 -0
  147. package/app/src/scene/glows.ts +153 -0
  148. package/app/src/scene/held.ts +109 -0
  149. package/app/src/scene/icons.ts +185 -0
  150. package/app/src/scene/layers.ts +822 -0
  151. package/app/src/scene/layout.ts +216 -0
  152. package/app/src/scene/locate.ts +118 -0
  153. package/app/src/scene/maskcheck.ts +43 -0
  154. package/app/src/scene/masks.ts +392 -0
  155. package/app/src/scene/occluders.ts +123 -0
  156. package/app/src/scene/occlusion-check.ts +138 -0
  157. package/app/src/scene/paint-layout.ts +135 -0
  158. package/app/src/scene/paint.ts +81 -0
  159. package/app/src/scene/photo.ts +123 -0
  160. package/app/src/scene/plates.ts +256 -0
  161. package/app/src/scene/playbook.ts +121 -0
  162. package/app/src/scene/preview.ts +23 -0
  163. package/app/src/scene/reactions.ts +118 -0
  164. package/app/src/scene/restyle.ts +53 -0
  165. package/app/src/scene/rig-check.ts +68 -0
  166. package/app/src/scene/rig.ts +379 -0
  167. package/app/src/scene/scale.ts +148 -0
  168. package/app/src/scene/shadows.ts +215 -0
  169. package/app/src/scene/stairs.ts +183 -0
  170. package/app/src/scene/status.ts +32 -0
  171. package/app/src/scene/verify.ts +156 -0
  172. package/app/src/scene/walk.ts +326 -0
  173. package/app/src/scene/warp.ts +419 -0
  174. package/app/src/scene/weather.ts +118 -0
  175. package/app/src/scene/words.ts +65 -0
  176. package/app/src/secrets.ts +219 -0
  177. package/app/src/setup/checks.ts +110 -0
  178. package/app/src/sound/cost.ts +74 -0
  179. package/app/src/sound/data.ts +89 -0
  180. package/app/src/sound/fixes.ts +23 -0
  181. package/app/src/sound/issues.ts +21 -0
  182. package/app/src/sound/language.ts +11 -0
  183. package/app/src/sound/lipsync-make.ts +98 -0
  184. package/app/src/sound/lipsync.ts +24 -0
  185. package/app/src/sound/make.ts +229 -0
  186. package/app/src/sound/musicgen.py +20 -0
  187. package/app/src/sound/pcm.ts +280 -0
  188. package/app/src/sound/plan.ts +154 -0
  189. package/app/src/sound/retry.ts +43 -0
  190. package/app/src/sound/settings.ts +28 -0
  191. package/app/src/sound/sources.ts +81 -0
  192. package/app/src/sound/spoken.ts +70 -0
  193. package/app/src/sound/voices.ts +579 -0
  194. package/app/src/speech/transcribe.ts +38 -0
  195. package/app/src/speech/types.ts +18 -0
  196. package/app/src/story/check.ts +230 -0
  197. package/app/src/story/design.ts +108 -0
  198. package/app/src/story/engine.ts +233 -0
  199. package/app/src/story/fixes.ts +54 -0
  200. package/app/src/story/npc-guidance.ts +7 -0
  201. package/app/src/story/phrases.ts +4 -0
  202. package/app/src/story/schema.ts +92 -0
  203. package/app/src/studio/agent.ts +555 -0
  204. package/app/src/studio/discovery.ts +28 -0
  205. package/app/src/studio/events.ts +48 -0
  206. package/app/src/studio/history.ts +124 -0
  207. package/app/src/studio/jobs.ts +291 -0
  208. package/app/src/studio/locks.ts +33 -0
  209. package/app/src/studio/mcp.ts +86 -0
  210. package/app/src/studio/operation.ts +18 -0
  211. package/app/src/studio/repair.ts +31 -0
  212. package/app/src/studio/server.ts +423 -0
  213. package/app/src/studio/trouble.ts +48 -0
  214. package/app/src/world/design.ts +72 -0
  215. package/app/src/world/drawings.ts +198 -0
  216. package/app/src/world/extend-stage.ts +109 -0
  217. package/app/src/world/extend.ts +123 -0
  218. package/app/src/world/extension-progress.ts +10 -0
  219. package/app/src/world/files.ts +62 -0
  220. package/app/src/world/idea-review.ts +32 -0
  221. package/app/src/world/language.ts +116 -0
  222. package/app/src/world/photo-limits.ts +2 -0
  223. package/app/src/world/pool.ts +41 -0
  224. package/app/src/world/schedule.ts +64 -0
  225. package/app/src/world/schema.ts +74 -0
  226. package/app/src/world/sketch.ts +81 -0
  227. package/app/src/world/style-plan.ts +90 -0
  228. package/app/src/world/style-reference.ts +16 -0
  229. package/app/src/world/styled.ts +51 -0
  230. package/app/src/world/told.ts +105 -0
  231. package/app/src/world/video-limits.ts +3 -0
  232. package/app/src/world/video.ts +98 -0
  233. package/app/studio/activity.tsx +124 -0
  234. package/app/studio/agent.tsx +384 -0
  235. package/app/studio/api.ts +111 -0
  236. package/app/studio/atelier.tsx +234 -0
  237. package/app/studio/audio-missing.tsx +25 -0
  238. package/app/studio/audio-setup.tsx +33 -0
  239. package/app/studio/blender-setup.tsx +30 -0
  240. package/app/studio/build.tsx +679 -0
  241. package/app/studio/camera.tsx +59 -0
  242. package/app/studio/cast-work.tsx +207 -0
  243. package/app/studio/cast.tsx +178 -0
  244. package/app/studio/concept-edit.tsx +47 -0
  245. package/app/studio/creator-idea.tsx +46 -0
  246. package/app/studio/custom-look.tsx +36 -0
  247. package/app/studio/faces-setup.tsx +28 -0
  248. package/app/studio/favicon.svg +11 -0
  249. package/app/studio/figure.tsx +314 -0
  250. package/app/studio/fonts/OFL.txt +93 -0
  251. package/app/studio/fonts/fonts.css +7 -0
  252. package/app/studio/fonts/fraunces-italic-latin-ext.woff2 +0 -0
  253. package/app/studio/fonts/fraunces-italic-latin.woff2 +0 -0
  254. package/app/studio/fonts/fraunces-normal-latin-ext.woff2 +0 -0
  255. package/app/studio/fonts/fraunces-normal-latin.woff2 +0 -0
  256. package/app/studio/fonts/instrument-sans-normal-latin-ext.woff2 +0 -0
  257. package/app/studio/fonts/instrument-sans-normal-latin.woff2 +0 -0
  258. package/app/studio/icons.tsx +42 -0
  259. package/app/studio/idea-card.tsx +42 -0
  260. package/app/studio/idea-review.tsx +181 -0
  261. package/app/studio/idea-storyboard.tsx +134 -0
  262. package/app/studio/index.html +15 -0
  263. package/app/studio/job-words.ts +33 -0
  264. package/app/studio/lightbox.tsx +49 -0
  265. package/app/studio/main.tsx +1329 -0
  266. package/app/studio/nav.ts +14 -0
  267. package/app/studio/place.tsx +264 -0
  268. package/app/studio/review-sketch.tsx +47 -0
  269. package/app/studio/say-it.tsx +49 -0
  270. package/app/studio/step-work.tsx +134 -0
  271. package/app/studio/story.tsx +394 -0
  272. package/app/studio/style-menu.tsx +81 -0
  273. package/app/studio/style.css +1390 -0
  274. package/app/studio/sure.tsx +54 -0
  275. package/app/studio/tip.tsx +74 -0
  276. package/app/studio/tsconfig.json +5 -0
  277. package/app/studio/video.tsx +73 -0
  278. package/app/studio/world.tsx +188 -0
  279. package/app/tsconfig.json +13 -0
  280. package/app/web/audio.ts +315 -0
  281. package/app/web/face.ts +131 -0
  282. package/app/web/face3d.ts +35 -0
  283. package/app/web/glows.ts +387 -0
  284. package/app/web/hero3d.ts +728 -0
  285. package/app/web/index.html +118 -0
  286. package/app/web/living.ts +404 -0
  287. package/app/web/main.ts +3769 -0
  288. package/app/web/pad.ts +174 -0
  289. package/app/web/reactions.ts +79 -0
  290. package/app/web/sheet.ts +36 -0
  291. package/app/web/synth.ts +140 -0
  292. package/app/web/tsconfig.json +5 -0
  293. package/app/web/ui.ts +263 -0
  294. package/app/web/weather.ts +306 -0
  295. package/app/web/words.ts +12 -0
  296. package/docs/characters.md +58 -0
  297. package/docs/npc-motion.md +69 -0
  298. package/docs/scenes.md +75 -0
  299. package/docs/setup.md +60 -0
  300. package/docs/sound.md +23 -0
  301. package/docs/studio.md +62 -0
  302. package/package.json +70 -4
@@ -0,0 +1,1390 @@
1
+ :root {
2
+ /* The atelier: paper, ink and lamplight. Paintings carry the colour; the Studio around them stays quiet. */
3
+ --bg: #f2ece1; --panel: #faf6ee; --raised: #ebe3d5; --line: #e2d9ca; --line-strong: #cfc3ae;
4
+ --text: #2b2723; --muted: #6f675d; --faint: #998f82;
5
+ --accent: #b86f22; --amber: #c27a2c; --ok: #4f8a6e; --bad: #b5523f; --indigo: #3d4b7c; --ink: #2b2723;
6
+ --display: "Fraunces", Georgia, "Iowan Old Style", serif; --body: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
7
+ color-scheme: light;
8
+ }
9
+ * { box-sizing: border-box; }
10
+ html, body { margin: 0; background: var(--bg); color: var(--text); font: 15px/1.45 var(--body); }
11
+ /* The page itself never scrolls: the app is exactly the window, top bar then content, and long content scrolls inside its own panel. */
12
+ html, body { height: 100%; overflow: hidden; }
13
+ #app { height: 100dvh; display: flex; flex-direction: column; }
14
+ #app > .top { flex: none; }
15
+ #app > main { flex: 1 1 0; min-height: 0; overflow: auto; overscroll-behavior: contain; }
16
+ h1, h2 { font-family: var(--display); font-weight: 500; margin: 0; letter-spacing: -0.01em; }
17
+ h1 { font-size: 30px; }
18
+ h2 { font-size: 18px; }
19
+ a { color: var(--accent); }
20
+ code, pre { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 13px; }
21
+ pre { margin: 0; padding: 10px 12px; border-radius: 8px; background: var(--panel); white-space: pre-wrap; }
22
+ button, input, select, textarea { font: inherit; color: inherit; }
23
+ button { min-height: 40px; padding: 0 18px; border-radius: 20px; cursor: pointer; border: 1px solid var(--line-strong); background: transparent; }
24
+ button.primary { background: var(--ink); color: var(--panel); border: 0; font-weight: 600; }
25
+ button.amber { background: var(--amber); color: #fff; border: 0; font-weight: 600; }
26
+ button.small { min-height: 32px; padding: 0 12px; font-size: 13px; }
27
+ button:disabled { opacity: 0.5; cursor: default; }
28
+ input, select, textarea { background: var(--panel); border: 1px solid var(--line-strong); border-radius: 10px; padding: 8px 10px; }
29
+ /* One drawn chevron, inset like the text, instead of each browser's own arrow hugging the edge. */
30
+ select { appearance: none; padding-right: 30px; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: right 15px center, right 10px center; background-size: 5px 5px; background-repeat: no-repeat; cursor: pointer; }
31
+ select:disabled { cursor: default; opacity: 0.7; }
32
+ textarea { width: 100%; resize: vertical; font-size: 17px; line-height: 1.4; }
33
+ .row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
34
+ .grow { flex: 1; }
35
+ .lead { color: var(--muted); font-size: 16px; margin: 6px 0 0; }
36
+ .note, .detail { color: var(--faint); font-size: 13px; }
37
+ .error { color: var(--bad); }
38
+ .flag { color: var(--accent); font-size: 13px; margin: 4px 0; }
39
+
40
+ .top { display: flex; align-items: center; gap: 12px; padding: 10px 20px; border-bottom: 1px solid var(--raised); flex-wrap: wrap; }
41
+ .brand { display: flex; align-items: center; gap: 8px; color: var(--text); text-decoration: none; font-family: Georgia, serif; font-size: 18px; }
42
+ .brand svg { color: var(--accent); }
43
+ .sep { color: var(--line-strong); }
44
+ .navlink { color: var(--muted); text-decoration: none; padding: 6px 12px; border-radius: 16px; }
45
+ .navlink:hover { background: var(--raised); }
46
+ .live { font-size: 12px; color: var(--faint); }
47
+ .live.on { color: var(--ok); }
48
+ .follow { font-size: 13px; color: var(--muted); display: flex; gap: 6px; align-items: center; }
49
+
50
+ /* Full width so their scrollbar sits at the window's edge; the column stays centred by its padding. */
51
+ main.narrow { width: 100%; padding: 36px max(20px, calc((100% - 820px) / 2)); display: flex; flex-direction: column; gap: 18px; }
52
+ main.setup { width: 100%; display: grid; grid-template-columns: minmax(300px, 420px) minmax(0, 1fr); gap: 28px; padding: 28px max(20px, calc((100% - 1240px) / 2)); overflow: hidden; }
53
+ main.setup > .side { display: flex; flex-direction: column; gap: 16px; min-height: 0; overflow: auto; }
54
+ .setup-heading { display: flex; align-items: center; gap: 12px; }
55
+ .setup-back { width: 40px; height: 40px; flex: none; display: grid; place-items: center; border: 1px solid var(--line-strong); border-radius: 50%; color: var(--text); text-decoration: none; font-size: 21px; }
56
+ .setup-back:hover { background: var(--raised); }
57
+ main.setup > .checks { min-height: 0; overflow: auto; overscroll-behavior: contain; padding-right: 4px; }
58
+ @media (max-width: 860px) { main.setup { display: flex; flex-direction: column; overflow: auto; } main.setup > .side, main.setup > .checks { overflow: visible; } }
59
+ main.wide { width: 100%; padding: 28px max(20px, calc((100% - 1160px) / 2)); display: flex; flex-direction: column; gap: 28px; }
60
+
61
+ .mark { width: 24px; height: 24px; flex: none; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; border: 1.5px solid var(--line-strong); }
62
+ .mark.ok { background: rgba(108, 195, 181, 0.18); color: var(--ok); border-color: transparent; }
63
+ .mark.missing, .mark.run { background: rgba(232, 168, 92, 0.2); color: var(--accent); border-color: transparent; }
64
+ .mark.fail { background: rgba(229, 154, 154, 0.18); color: var(--bad); border-color: transparent; }
65
+ .mark.run { animation: pulse 1.2s ease-in-out infinite; }
66
+ @keyframes pulse { 50% { opacity: 0.4; } }
67
+
68
+ .checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
69
+ .checks li { display: flex; gap: 14px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; }
70
+ .checks li.missing, .checks li.fail { border-color: var(--accent); background: rgba(232, 168, 92, 0.06); }
71
+ .checks .body { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
72
+ .checks .detail { color: var(--muted); }
73
+ .fix { display: flex; gap: 8px; align-items: flex-start; margin-top: 6px; }
74
+ .fix pre { flex: 1; }
75
+
76
+ .banner { display: block; padding: 12px 16px; border-radius: 12px; border: 1px solid var(--accent); background: rgba(232, 168, 92, 0.08); text-decoration: none; }
77
+ .idea { display: flex; flex-direction: column; gap: 12px; }
78
+ .idea label { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 14px; }
79
+ .worlds { list-style: none; margin: 14px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
80
+ .worlds a { display: flex; flex-direction: column; gap: 4px; color: var(--text); text-decoration: none; }
81
+ .worlds img, .worlds .noimg { width: 100%; aspect-ratio: 1200 / 896; object-fit: cover; border-radius: 10px; background: var(--raised); }
82
+
83
+ main.workshop { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; padding: 20px; }
84
+ @media (max-width: 960px) { main.workshop { grid-template-columns: 1fr; } }
85
+ .left { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
86
+ .steps { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
87
+ .steps li { display: flex; gap: 6px; align-items: center; padding: 4px 10px 4px 4px; border-radius: 16px; background: var(--panel); font-size: 13px; color: var(--muted); }
88
+ .steps li.ok { color: var(--text); }
89
+ .steps .mark { width: 20px; height: 20px; font-size: 11px; }
90
+ .places { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
91
+ .places .card { all: unset; cursor: pointer; display: flex; flex-direction: column; gap: 6px; width: 100%; }
92
+ .places img, .places .noimg { width: 100%; aspect-ratio: 1200 / 896; object-fit: cover; border-radius: 10px; background: var(--raised); display: flex; align-items: center; justify-content: center; color: var(--faint); font-size: 13px; }
93
+ .places li.focus img { outline: 2px solid var(--accent); }
94
+ .places .name { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
95
+ .badge { font-size: 12px; padding: 2px 8px; border-radius: 10px; background: var(--raised); color: var(--muted); }
96
+ .badge.ok { color: var(--ok); }
97
+ .badge.fail { color: var(--bad); }
98
+ .badge.run { color: var(--accent); }
99
+ .inspect { padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; }
100
+ .inspect p { margin: 6px 0; }
101
+
102
+ .right { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
103
+ .right section, .right details.log { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); padding: 14px; }
104
+ .log summary { display: flex; align-items: baseline; gap: 10px; cursor: pointer; list-style: none; min-width: 0; }
105
+ .log summary::-webkit-details-marker { display: none; }
106
+ .log summary h2 { font-size: 15px; flex: none; }
107
+ .log summary h2::before { content: "▸ "; color: var(--faint); font-size: 12px; }
108
+ .log[open] summary h2::before { content: "▾ "; }
109
+ .log summary .latest { flex: 1; min-width: 0; font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
110
+ .log[open] summary .latest { display: none; }
111
+ .log > .row { margin-top: 6px; }
112
+ .log ol { list-style: none; margin: 10px 0 0; padding: 0; max-height: 60vh; overflow: auto; font-family: ui-monospace, Menlo, monospace; font-size: 12px; display: flex; flex-direction: column-reverse; }
113
+ .log li { padding: 1px 0; color: var(--muted); white-space: pre-wrap; word-break: break-word; }
114
+ .log li.step, .log li.job { color: var(--text); }
115
+ .log li.err { color: var(--bad); }
116
+ .log li.agent { color: var(--accent); }
117
+
118
+ .agent { display: flex; flex-direction: column; gap: 10px; }
119
+ .chat { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 42vh; overflow: auto; }
120
+ .chat li { font-size: 14px; line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
121
+ .chat li.user { align-self: flex-end; max-width: 85%; padding: 6px 10px; border-radius: 12px 12px 2px 12px; background: var(--raised); }
122
+ .chat li.agent { max-width: 92%; }
123
+ .chat li.streaming { color: var(--muted); }
124
+ .chat li.tool { display: flex; gap: 6px; align-items: center; font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--accent); }
125
+ .chat li.tool .mark { width: 18px; height: 18px; font-size: 10px; }
126
+ .chat li.error { color: var(--bad); }
127
+ .ask { display: flex; flex-direction: column; gap: 8px; padding: 10px; border: 1px solid var(--accent); border-radius: 10px; background: rgba(232, 168, 92, 0.06); font-size: 13px; }
128
+ .say { display: flex; flex-direction: column; gap: 6px; }
129
+ .say textarea { font-size: 14px; }
130
+
131
+ .seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 18px; overflow: hidden; }
132
+ .seg button { border: 0; border-radius: 0; min-height: 32px; padding: 0 12px; font-size: 13px; color: var(--muted); }
133
+ .seg button + button { border-left: 1px solid var(--line-strong); }
134
+ .seg button.on { background: var(--raised); color: var(--text); }
135
+ .seg.tools { flex-wrap: wrap; }
136
+ .editor { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
137
+ .editor label { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 13px; }
138
+ .stage { position: relative; width: 100%; aspect-ratio: 1200 / 896; border-radius: 10px; overflow: hidden; background: var(--raised); user-select: none; }
139
+ .stage img, .stage .noimg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; }
140
+ .stage svg { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; }
141
+ .stage:not(.tool-look) svg { cursor: crosshair; }
142
+ .stage .sel { fill: rgba(232, 168, 92, 0.15); stroke: var(--accent); stroke-width: 3; stroke-dasharray: 10 6; }
143
+ .stage .sel.repaint { fill: rgba(108, 195, 181, 0.15); stroke: var(--ok); }
144
+ .stage .sel.npc { fill: none; stroke: var(--muted); stroke-width: 2; }
145
+ .stage .sel.npc.on { stroke: var(--accent); stroke-width: 3; }
146
+ .stage .stroke { fill: none; stroke-linecap: round; stroke-linejoin: round; opacity: 0.55; }
147
+ .stage .stroke.add { stroke: #3ddc84; }
148
+ .stage .stroke.erase { stroke: #ff5a5a; }
149
+ .stage .stand { fill: #fff; stroke: #000; stroke-width: 2; }
150
+ .stage .pin { fill: var(--accent); stroke: #000; stroke-width: 3; }
151
+ table.things { width: 100%; border-collapse: collapse; font-size: 13px; }
152
+ table.things th { text-align: left; color: var(--faint); font-weight: 500; padding: 4px 6px; }
153
+ table.things td { padding: 4px 6px; border-top: 1px solid var(--line); vertical-align: middle; }
154
+ table.things input { width: 100%; min-width: 120px; padding: 4px 8px; }
155
+ table.things form { flex-wrap: nowrap; }
156
+ table.things select { padding: 4px 6px; }
157
+ .fixes ul, .notes ul { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
158
+ .fixes li, .notes li { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
159
+ .notes { padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; display: flex; flex-direction: column; gap: 6px; }
160
+ .notes li.done { color: var(--faint); }
161
+ .notes input { flex: 1; min-width: 200px; }
162
+ .failed { padding: 12px 14px; border: 1px solid var(--bad); border-radius: 12px; background: rgba(229, 154, 154, 0.07); display: flex; flex-direction: column; gap: 8px; }
163
+ .failed p { margin: 0; }
164
+ .ask code { word-break: break-word; }
165
+ .ask pre { max-height: 200px; overflow: auto; font-size: 12px; }
166
+ .budget { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; }
167
+ .budget .prices { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
168
+ .budget label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
169
+ .chat { scroll-behavior: smooth; }
170
+ .chat li.thinking { color: var(--faint); font-size: 13px; animation: pulse 1.6s ease-in-out infinite; }
171
+ .chat li.steps-card { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border-left: 2px solid var(--line-strong); }
172
+ .chat li.steps-card ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
173
+ .chat .step summary { display: flex; align-items: baseline; gap: 8px; cursor: pointer; list-style: none; font-size: 13px; padding: 2px 0; }
174
+ .chat .step summary::-webkit-details-marker { display: none; }
175
+ .chat .step summary.plain { cursor: default; }
176
+ .chat .step .mark { width: 18px; height: 18px; font-size: 10px; align-self: center; }
177
+ .chat .step .what { color: var(--text); }
178
+ .chat .step.fail .what { color: var(--bad); }
179
+ .chat .step .args { color: var(--faint); font-family: ui-monospace, Menlo, monospace; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
180
+ .chat .step .io { display: flex; flex-direction: column; gap: 4px; margin: 4px 0 8px 26px; }
181
+ .chat .step .io pre { max-height: 220px; overflow: auto; font-size: 11.5px; padding: 8px 10px; }
182
+ button.link { all: unset; cursor: pointer; color: var(--accent); font-size: 12px; }
183
+ button.link:focus-visible { outline: 2px solid var(--accent); }
184
+
185
+ /* genaicode's chat in the Studio's colours. */
186
+ section.agent { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
187
+ section.agent > .gc-chat { --gc-bg: var(--panel); --gc-panel: var(--raised); --gc-border: var(--line); --gc-text: var(--text); --gc-muted: var(--muted);
188
+ --gc-accent: var(--ink); --gc-accent-text: var(--panel); --gc-ok: var(--ok); --gc-error: var(--bad); --gc-font-size: 14px; flex: 1; min-height: 360px; }
189
+ section.agent .row { padding: 12px 14px 0; }
190
+ .agent-pick { font-family: Georgia, "Iowan Old Style", serif; font-size: 17px; padding: 4px 8px; }
191
+ .play { display: flex; flex-direction: column; gap: 8px; }
192
+ .play iframe { width: 100%; aspect-ratio: 1200 / 896; max-width: 100%; border: 0; border-radius: 10px; background: #0b0b0e; }
193
+ .log li.play { color: var(--ok); }
194
+ .replays { padding: 0 14px 12px; font-size: 13px; color: var(--muted); }
195
+ .replays summary { cursor: pointer; padding: 6px 0; }
196
+ .replays ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
197
+ .cast { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
198
+ .cast .who { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 16px; padding: 14px; border: 1px solid var(--line); border-radius: 12px; }
199
+ .cast .who.narrator { grid-template-columns: minmax(0, 1fr); }
200
+ .cast img, .cast .noimg { width: 140px; height: 210px; object-fit: contain; border-radius: 10px; background: var(--raised); display: flex; align-items: center; justify-content: center; color: var(--faint); font-size: 13px; text-align: center; }
201
+ .cast .body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
202
+ .cast textarea { font-size: 14px; }
203
+ .cast .voice label { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 13px; }
204
+ .cast .voice select { max-width: 320px; }
205
+ .cast .sample { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
206
+ .cast audio { height: 32px; max-width: 100%; }
207
+ .items { margin-top: 22px; }
208
+ .items h3 { margin: 0 0 10px; font-size: 15px; }
209
+ .items ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; }
210
+ .items li { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 12px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; }
211
+ .items li.focus { border-color: var(--amber); box-shadow: 0 0 0 3px rgba(194, 122, 44, 0.15); }
212
+ .items img, .items .noimg { width: 88px; height: 88px; object-fit: contain; border-radius: 10px; background: var(--raised); display: flex; align-items: center; justify-content: center; color: var(--faint); font-size: 12px; text-align: center; }
213
+ .items .body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
214
+ .items .row { display: flex; flex-wrap: wrap; gap: 6px; }
215
+ .items input { flex: 1 1 140px; min-width: 0; }
216
+ /* A character moving as the game moves them: 3D model, 2D rig, painted sheets. */
217
+ :is(.cast, .cw-focus) .figure-preview { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 10px; padding-top: 12px; border-top: 1px solid var(--line); }
218
+ :is(.cast, .cw-focus) .figure-preview .moves { display: flex; flex-direction: column; gap: 10px; }
219
+ :is(.cast, .cw-focus) .figure-preview .turntable { min-height: 340px; display: flex; align-items: center; justify-content: center; border-radius: 10px; background: var(--raised); cursor: grab; touch-action: none; user-select: none; }
220
+ :is(.cast, .cw-focus) .figure-preview .turntable:active { cursor: grabbing; }
221
+ :is(.cast, .cw-focus) .figure-preview canvas.rig { height: 300px; width: auto; align-self: flex-start; border-radius: 10px; background: var(--raised); }
222
+ :is(.cast, .cw-focus) .figure-preview .sheets { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
223
+ :is(.cast, .cw-focus) .figure-preview .sheets li { display: flex; flex-direction: column; align-items: center; gap: 4px; }
224
+ :is(.cast, .cw-focus) .figure-preview .sheets canvas { height: 220px; width: auto; border-radius: 10px; background: var(--raised); }
225
+ @media (max-width: 600px) { .cast .who { grid-template-columns: 1fr; } }
226
+
227
+ .story { display: flex; flex-direction: column; gap: 14px; }
228
+ .story-writing { display: flex; flex-direction: column; gap: 6px; padding: 10px 14px; border-radius: 10px; border: 1px solid var(--accent); background: var(--panel); }
229
+ .story-log { margin: 0; padding-left: 20px; max-height: 22vh; overflow: auto; font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 2px; }
230
+ .story-log li.check { color: var(--text); }
231
+ .story .plan-places { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; overflow: auto; min-height: 0; }
232
+ .story .plan-places li { display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
233
+ .story .verdict { display: flex; flex-direction: column; gap: 8px; }
234
+ .story .issues { margin: 0; padding-left: 18px; color: var(--muted); font-size: 13px; display: flex; flex-direction: column; gap: 2px; }
235
+ .story-map { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
236
+ .story .map { overflow: auto; max-height: 48vh; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); overscroll-behavior: contain; }
237
+ .story .map-tools label { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }
238
+ .story .map-tools select { max-width: min(280px, 100%); min-width: 0; }
239
+ .story .map-help { margin: 0; }
240
+ .story .map svg { display: block; max-width: none; }
241
+ .story .join path { fill: none; stroke: var(--line-strong); stroke-width: 2; }
242
+ .story .join.locked path { stroke: var(--accent); stroke-dasharray: 6 5; }
243
+ .story .join text { fill: var(--accent); font-size: 11px; }
244
+ .story .lock-label rect { fill: var(--panel); stroke: var(--accent); }
245
+ .story .to-end path { stroke: var(--faint); stroke-width: 1.5; stroke-dasharray: 2 4; }
246
+ .story .node { cursor: pointer; }
247
+ .story .dim { opacity: 0.3; }
248
+ .story .dim:hover, .story .dim:focus-visible { opacity: 1; }
249
+ .story .node rect { fill: var(--raised); stroke: var(--line-strong); }
250
+ .story .node.start rect { stroke: var(--ok); }
251
+ .story .node.ending rect { fill: var(--panel); stroke: var(--accent); }
252
+ .story .node.on rect { stroke: var(--text); stroke-width: 2; }
253
+ .story .node:focus-visible { outline: none; }
254
+ .story .node:focus-visible rect { stroke: var(--text); stroke-width: 2; }
255
+ .story .map-name { color: var(--text); font-size: 13px; font-weight: 600; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
256
+ .story .map-sub { color: var(--muted); font-size: 11px; margin-top: 7px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
257
+ .story-place { display: flex; flex-direction: column; gap: 12px; }
258
+ .story-place h2 { margin: 0; }
259
+ .story .beat { display: flex; flex-direction: column; gap: 6px; padding-top: 10px; border-top: 1px solid var(--line); }
260
+ .story .act { display: flex; flex-direction: column; gap: 4px; padding-left: 12px; }
261
+ .story .verb { font: 12px ui-monospace, Menlo, monospace; color: var(--accent); }
262
+ .story .facts, .story .effects { font-size: 12px; color: var(--muted); }
263
+ .story .line { display: flex; flex-direction: column; gap: 2px; }
264
+ .story .line textarea { font-size: 14px; resize: vertical; }
265
+ .story .over { font-size: 12px; color: var(--warn, var(--accent)); }
266
+ .story .choices, .story .items { list-style: none; margin: 0; padding-left: 16px; display: flex; flex-direction: column; gap: 6px; }
267
+ .story .route { margin: 0; padding-left: 22px; color: var(--muted); font-size: 13px; }
268
+
269
+ .progress { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-radius: 10px; background: var(--panel); border: 1px solid var(--line); }
270
+ .progress .steps li { background: var(--raised); }
271
+ .progress .tail { font-family: ui-monospace, Menlo, monospace; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; }
272
+ /* A turn that ended well: a step that failed on the way was retried, so its summary says no "errors" (the step itself still shows it). */
273
+ /* A refused or failed step mid-turn is the agent finding its way; "errors" in the fold is for a turn that ended badly. */
274
+ section.agent .gc-turn:not(:has(.gc-turn-footer.gc-bad)) .gc-fold summary .gc-err { display: none; }
275
+ section.agent .gc-fold > summary { display: block; cursor: pointer; }
276
+ /* A workshop with children: drawings, recordings, their story. */
277
+ .tabs { display: flex; gap: 6px; }
278
+ .tabs button.on { border-color: var(--accent); color: var(--text); }
279
+ .kids { display: flex; flex-direction: column; gap: 16px; }
280
+ .kids section { display: flex; flex-direction: column; gap: 12px; }
281
+ .kids .card { padding: 20px 22px; border: 1px solid var(--line); border-radius: 16px; opacity: 0.72; transition: opacity .3s; }
282
+ .kids .card.now, .kids .card:focus-within, .kids .card:hover { opacity: 1; }
283
+ .kids .card.now { border-color: var(--accent); }
284
+ .kids h2 { margin: 0; font-size: 22px; display: flex; align-items: center; gap: 12px; }
285
+ .kids h2 .n { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--raised); font-size: 17px; flex: none; }
286
+ .kids .card.now h2 .n { background: var(--accent); color: #121417; }
287
+ .kids .row.big button, .kids .row.big .button { min-height: 52px; padding: 0 26px; font-size: 18px; border-radius: 26px; }
288
+ .kids label.button { display: inline-flex; align-items: center; cursor: pointer; border: 1px solid var(--line-strong); }
289
+ .kids label.button input { display: none; }
290
+ .kids .busy { position: sticky; top: 8px; z-index: 3; align-self: center; margin: 0; padding: 8px 18px; border-radius: 999px; background: var(--raised); border: 1px solid var(--accent); }
291
+ .kids .story { font-size: 18px; line-height: 1.5; margin: 0; cursor: text; white-space: pre-wrap; }
292
+ .kids .empty { grid-column: 1 / -1; margin: 0; }
293
+ .kids .more { padding: 0 4px; display: flex; flex-direction: column; gap: 10px; }
294
+ .kids .more[open] { gap: 12px; }
295
+ .kids .more summary { cursor: pointer; color: var(--muted); }
296
+ .kids .told ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
297
+ .drawings { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
298
+ .drawings figure { position: relative; margin: 0; display: flex; flex-direction: column; gap: 4px; }
299
+ .drawings img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 10px; background: var(--raised); }
300
+ .drawings figure button { position: absolute; top: 4px; right: 4px; }
301
+ .drawings figcaption { font-size: 13px; color: var(--muted); }
302
+ .drawings .add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; aspect-ratio: 3 / 4; border: 2px dashed var(--line); border-radius: 10px; cursor: pointer; color: var(--muted); text-align: center; padding: 8px; }
303
+ .drawings .add input { display: none; }
304
+ .camera { display: flex; flex-direction: column; gap: 8px; }
305
+ .camera video { width: 100%; max-width: 720px; border-radius: 10px; background: #000; }
306
+ .record { font-size: 20px; min-height: 60px; padding: 0 30px; border-radius: 999px; }
307
+ .record.on { background: var(--bad); border-color: var(--bad); color: #fff; }
308
+ .told li { display: flex; gap: 10px; align-items: center; }
309
+ .told audio { height: 32px; flex: none; width: 220px; }
310
+ .drawings figcaption select { width: 100%; min-height: 32px; padding: 2px 6px; font-size: 14px; border-radius: 8px; }
311
+ .drawings figure > button.small { background: var(--bg); width: 32px; padding: 0; opacity: 0.85; }
312
+ .play-hint { margin: 2px 0 8px; } .play-hint summary { cursor: pointer; color: var(--accent); font-size: 13px; } .play-hint p { margin: 4px 0; }
313
+ .drawings .pic { position: relative; padding: 0; border: 0; min-height: 0; border-radius: 10px; background: none; display: block; width: 100%; }
314
+ .drawings .pic img.alive { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: rgba(255, 255, 255, 0.92); border-radius: 10px; animation: alive 0.9s ease-out; }
315
+ .drawings .pic img.alive.place { object-fit: cover; }
316
+ .drawings .pic:hover img.alive { opacity: 0; transition: opacity 0.2s; }
317
+ .drawings .spark { position: absolute; inset: auto 0 8px; text-align: center; font-size: 13px; color: #121417; background: var(--accent); border-radius: 999px; margin: 0 12px; padding: 2px 8px; animation: pulse 1.2s ease-in-out infinite; }
318
+ @keyframes alive { from { opacity: 0; transform: scale(0.9) rotate(-2deg); } to { opacity: 1; transform: none; } }
319
+ @keyframes pulse { 50% { opacity: 0.55; } }
320
+ .show { position: fixed; inset: 0; z-index: 50; background: var(--bg); display: grid; grid-template-columns: 1fr auto 1.4fr; align-items: center; gap: 24px; padding: 4vh 4vw; cursor: zoom-out; }
321
+ .show img { max-width: 100%; max-height: 82vh; margin: auto; border-radius: 14px; }
322
+ .show img.alive { animation: alive 1.1s ease-out; background: #fff; }
323
+ .show .arrow { font-size: 64px; color: var(--accent); }
324
+ .show p { grid-column: 1 / -1; text-align: center; font-size: 22px; margin: 0; color: var(--text); }
325
+ @media (prefers-reduced-motion: reduce) { .drawings .pic img.alive, .show img.alive, .drawings .spark { animation: none; } }
326
+ .share { position: relative; }
327
+ .share-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 5; width: 300px; display: flex; flex-direction: column; gap: 6px; padding: 12px; border-radius: 10px; background: var(--raised); border: 1px solid var(--line); }
328
+ .share-menu p { margin: 0 0 6px; }
329
+ .share-menu.history { width: 380px; max-height: 70vh; overflow: auto; }
330
+ .share-menu.style-menu { width: 380px; max-height: 70vh; overflow: auto; gap: 8px; }
331
+ .style-menu p { margin: 0; }
332
+ .style-menu .row.wrap { flex-wrap: wrap; gap: 6px; }
333
+ .style-menu textarea, .style-menu select { width: 100%; box-sizing: border-box; }
334
+ .history ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
335
+ .history li { display: flex; flex-direction: column; gap: 4px; padding: 10px 2px; border-top: 1px solid var(--line); }
336
+ .history li:first-child { border-top: 0; }
337
+ .history li p { margin: 0; }
338
+ .history li > button { align-self: flex-start; }
339
+
340
+ /* A note from the Studio to the agent, not a bubble from the person. */
341
+ .gc-prompt:has(> .studio-note) { background: none; border: 0; box-shadow: none; padding: 0; max-width: none; color: var(--muted); }
342
+ .gc-steer:has(> .studio-note) > small { display: none; }
343
+ .studio-note { font-size: 12px; color: var(--muted); }
344
+ .studio-note summary { cursor: pointer; list-style: none; }
345
+ .studio-note summary::before { content: 'ⓘ '; }
346
+ .studio-note[open] { white-space: pre-wrap; }
347
+ .studio-note[open] summary { margin-bottom: 4px; }
348
+
349
+ /* Pictures for the agent: the tray under the composer and the thumbnails in a sent prompt. */
350
+ .agent .pics { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
351
+ .agent .pic { position: relative; display: inline-flex; }
352
+ .agent .pics img { height: 48px; max-width: 80px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
353
+ .agent .pic button { position: absolute; top: -6px; right: -6px; padding: 0 6px; min-height: 0; line-height: 18px; background: var(--panel); }
354
+ .agent .pics.sent { margin-bottom: 6px; }
355
+ .agent .pics.sent img { height: 72px; max-width: 120px; }
356
+ .agent .camera video { width: 100%; border-radius: 8px; }
357
+
358
+ /* The wait while a workshop world builds: a show for the children, the hero walking the road to the end. */
359
+ .wait { position: fixed; inset: 0; z-index: 40; background: var(--bg); display: flex; flex-direction: column; gap: 2vh; padding: 3vh 4vw; }
360
+ .wait h1 { font-size: clamp(24px, 4vw, 48px); margin: 0; }
361
+ .wait .screen { flex: 1; min-height: 0; display: grid; place-items: center; }
362
+ .wait figure { margin: 0; display: grid; grid-template-columns: 1fr auto 1.5fr; align-items: center; gap: 2vh 3vw; width: 100%; animation: arrive 1.2s ease-out; }
363
+ .wait figure.place, .wait figure.telling { grid-template-columns: 1fr; }
364
+ .wait .telling-text { margin: 0 auto; max-width: 40ch; font-size: clamp(22px, 2.6vw, 34px); line-height: 1.45; text-align: center; text-wrap: pretty; }
365
+ .wait figure img { max-width: 100%; max-height: 54vh; margin: auto; border-radius: 16px; object-fit: contain; }
366
+ .wait figure img.to { background: #fff; }
367
+ .wait figure.place img.to { background: none; }
368
+ .wait figure .arrow { font-size: 72px; color: var(--accent); }
369
+ .wait figcaption { grid-column: 1 / -1; text-align: center; font-size: clamp(22px, 3vw, 40px); font-weight: 600; min-height: 1.2em; }
370
+ .wait figcaption::first-letter { text-transform: uppercase; }
371
+ .wait .road { position: relative; flex: none; height: 18px; margin: 12vh 6vw 4vh; border-radius: 9px; background: var(--raised); border: 1px solid var(--line); }
372
+ .wait .road .done { height: 100%; border-radius: 9px; background: var(--accent); transition: width 2s ease; }
373
+ .wait .road .walker { position: absolute; bottom: 4px; height: 11vh; transform: translateX(-50%); transition: left 2s ease; animation: hop .7s ease-in-out infinite alternate; }
374
+ .wait .road .flag { position: absolute; right: -10px; bottom: 6px; font-size: 6vh; line-height: 1; }
375
+ .wait .road .detail { position: absolute; top: 26px; left: 0; right: 0; text-align: center; font-size: 20px; }
376
+ .wait .go { align-self: center; flex: none; margin: 2vh 0; font-size: clamp(28px, 4vw, 52px); padding: 2vh 6vw; border-radius: 999px; animation: beckon 1.2s ease-in-out infinite alternate; }
377
+ .wait .oops { text-align: center; font-size: 22px; }
378
+ @keyframes arrive { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
379
+ @keyframes hop { from { transform: translateX(-50%) translateY(0); } to { transform: translateX(-50%) translateY(-8px); } }
380
+ @keyframes beckon { from { transform: scale(1); } to { transform: scale(1.06); } }
381
+ @media (prefers-reduced-motion: reduce) { .wait figure, .wait .road .walker, .wait .go { animation: none; } }
382
+
383
+ /* The build stage (studio/build.tsx): one progress line, the place being built, the story beside it. */
384
+ :root { --spark: #7fb2ff; --image: #e8a85c; --sam: #6cc3b5; }
385
+ .model { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; letter-spacing: 0.02em; padding: 1px 7px 1px 6px; border-radius: 9px; background: var(--raised); color: var(--muted); white-space: nowrap; }
386
+ .model::before { content: ""; width: 6px; height: 6px; border-radius: 3px; background: var(--faint); }
387
+ .model.spark { color: var(--spark); } .model.spark::before { background: var(--spark); }
388
+ .model.image { color: var(--image); } .model.image::before { background: var(--image); }
389
+ .model.sam { color: var(--sam); } .model.sam::before { background: var(--sam); }
390
+
391
+ .pipeline { container-type: inline-size; display: flex; flex-direction: column; gap: 8px; padding: 10px 14px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); }
392
+ .pipeline .phases { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
393
+ /* Narrow (a wide agent panel, a small window): the phases wrap to two lines, their model tags cut short. */
394
+ @container (max-width: 760px) { .pipeline .phases li { min-width: 88px; } }
395
+ .pipeline .phases li { flex-basis: 0; min-width: 124px; display: flex; flex-direction: column; gap: 5px; }
396
+ .pipeline .bar { position: relative; height: 8px; border-radius: 4px; background: var(--raised); overflow: hidden; }
397
+ .pipeline .fill { position: absolute; inset: 0 auto 0 0; background: var(--ok); border-radius: 4px; transition: width 1s linear; }
398
+ .pipeline .fill.existing { opacity: 0.55; }
399
+ .pipeline .tick { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--panel); }
400
+ .pipeline .fill.run, .extension-pipeline li.run .fill { background: linear-gradient(90deg, var(--accent), #ffd59a, var(--accent)); background-size: 200% 100%; animation: flow 1.6s linear infinite; }
401
+ .stage-live .wanted { max-width: 70%; padding: 6px 10px; border-radius: 8px; background: rgba(20, 16, 10, 0.72); color: #fff; font-size: 13px; }
402
+ .stage-live .wanted.trouble { background: rgba(120, 40, 20, 0.85); }
403
+ .pipeline .fill.warn { background: repeating-linear-gradient(135deg, var(--ok) 0 6px, var(--accent) 6px 12px); }
404
+ .pipeline li.warn .name { color: var(--accent); }
405
+ .pipeline .fill.fail, .extension-pipeline li.fail .fill { background: var(--bad); }
406
+ .pipeline li.skip { opacity: 0.45; }
407
+ .pipeline li.todo .name, .pipeline li.skip .name { color: var(--faint); }
408
+ .pipeline li.run .name { color: var(--accent); }
409
+ .pipeline .label { display: flex; align-items: center; gap: 4px; overflow: hidden; white-space: nowrap; mask-image: linear-gradient(90deg, #000 85%, transparent); }
410
+ .pipeline .name { font-size: 13px; font-weight: 600; margin-right: 2px; }
411
+ .pipeline .head { flex-wrap: nowrap; gap: 8px; font-size: 13px; }
412
+ .pipeline .head strong { white-space: nowrap; margin-right: 6px; }
413
+ .pipeline .head .when { white-space: nowrap; }
414
+ .pipeline .head .tail { flex: 1; min-width: 0; text-align: right; }
415
+ .pipeline li.todo .model, .pipeline li.skip .model { opacity: 0.6; }
416
+ .pipeline .phases li .model { font-size: 10px; padding: 0 6px 0 5px; }
417
+ .pipeline .count { display: inline-flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; color: var(--muted); transition: transform 0.2s; }
418
+ .pipeline .count.hot { transform: scale(1.08); color: var(--text); }
419
+ .pipeline .tail { font-family: ui-monospace, Menlo, monospace; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
420
+ @keyframes flow { to { background-position: -200% 0; } }
421
+
422
+ .build-grid { display: grid; grid-template-columns: minmax(0, 2.1fr) minmax(220px, 1fr); grid-template-rows: auto auto; grid-template-areas: "stage tale" "strip tale"; gap: 12px 16px; align-items: stretch; }
423
+ .build-grid > .stage-live { grid-area: stage; }
424
+ .build-grid > .tale { grid-area: tale; }
425
+ .build-grid > .strip { grid-area: strip; }
426
+ .stage-live { margin: 0; display: flex; flex-direction: column; gap: 8px; }
427
+ .stage-live .frame { position: relative; width: min(100%, calc(64vh * 1200 / 896)); margin: 0 auto; aspect-ratio: 1200 / 896; border-radius: 14px; overflow: hidden; background: radial-gradient(ellipse at 50% 40%, #232831, #15181c); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45); }
428
+ .stage-live .layer { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; }
429
+ .stage-live .layer.depth { opacity: 0.78; }
430
+ .stage-live .empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 40px; text-align: center; font-family: Georgia, serif; font-size: 20px; color: var(--muted); }
431
+ .stage-live .empty span { animation: pulse 2.4s ease-in-out infinite; max-width: 32em; }
432
+ .stage-live .empty.waiting { flex-direction: column; gap: 10px; background: repeating-linear-gradient(135deg, transparent 0 18px, rgba(255, 255, 255, 0.02) 18px 36px); }
433
+ .stage-live .empty.waiting strong { font-size: 30px; font-weight: 400; color: var(--text); }
434
+ .stage-live .empty.waiting span { display: inline-flex; align-items: center; gap: 8px; font-family: inherit; font-size: 14px; }
435
+ .stage-live figcaption { position: absolute; left: 14px; bottom: 14px; display: flex; align-items: center; gap: 8px; padding: 6px 12px 6px 8px; border-radius: 16px; background: rgba(12, 14, 17, 0.72); backdrop-filter: blur(6px); font-size: 14px; }
436
+ .stage-live figcaption .model { font-size: 12px; background: rgba(255, 255, 255, 0.08); }
437
+ .stage-live .where { position: absolute; right: 14px; bottom: 14px; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px 10px; border-radius: 12px; background: rgba(12, 14, 17, 0.6); font-size: 12px; color: var(--muted); }
438
+ .stage-live .over { position: absolute; left: 12px; top: 10px; right: 12px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; pointer-events: none; }
439
+ .stage-live .over > * { pointer-events: auto; }
440
+ .stage-live .layers { display: flex; flex-wrap: wrap; gap: 4px; }
441
+ .stage-live .layers button { min-height: 26px; padding: 0 10px; font-size: 12px; border: 0; background: rgba(12, 14, 17, 0.6); color: var(--muted); backdrop-filter: blur(6px); }
442
+ .stage-live .layers .on { background: rgba(12, 14, 17, 0.85); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent); }
443
+ .enter-fade { animation: enter-fade 0.9s ease-out both; }
444
+ .enter-wipe { animation: enter-wipe 1.8s cubic-bezier(0.6, 0, 0.3, 1) both; }
445
+ .enter-iris { animation: enter-iris 1.4s ease-out both; }
446
+ .enter-sweep { animation: enter-sweep 1.6s ease-in-out both; }
447
+ @keyframes enter-fade { from { opacity: 0; } }
448
+ @keyframes enter-wipe { from { clip-path: inset(0 100% 0 0); filter: saturate(0.4) brightness(1.3); } }
449
+ @keyframes enter-iris { from { clip-path: circle(0% at 50% 62%); } to { clip-path: circle(80% at 50% 62%); } }
450
+ @keyframes enter-sweep { from { clip-path: inset(0 0 100% 0); } }
451
+ .scan { position: absolute; inset: 0; pointer-events: none; border-radius: inherit; box-shadow: inset 0 0 0 2px rgba(232, 168, 92, 0.7); animation: pulse 1.8s ease-in-out infinite; }
452
+ .scan.masks { box-shadow: inset 0 0 0 2px rgba(108, 195, 181, 0.7); }
453
+ .scan.layout { box-shadow: inset 0 0 0 2px rgba(127, 178, 255, 0.7); }
454
+ .stage-live .finds { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
455
+ .finds g { animation: enter-fade 0.5s ease-out both; }
456
+ .finds rect { fill: none; stroke: rgba(160, 196, 255, 0.85); stroke-width: 3; stroke-dasharray: 12 8; vector-effect: non-scaling-stroke; }
457
+ .finds .cut rect { fill: rgba(108, 195, 181, 0.22); stroke: rgb(108, 195, 181); stroke-dasharray: none; transition: fill 0.4s, stroke 0.4s; }
458
+ .finds text { font: 600 22px system-ui, sans-serif; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.7); stroke-width: 5px; }
459
+
460
+ .tale { display: flex; flex-direction: column; gap: 12px; padding: 14px 16px; border-radius: 14px; background: var(--panel); border: 1px solid var(--line); overflow: auto; contain: size; }
461
+ .tale > * { animation: rise 0.6s ease-out both; }
462
+ .tale .kicker { margin: 0; display: flex; gap: 6px; align-items: center; font-size: 12px; color: var(--faint); }
463
+ .tale .pitch { margin: 0; font-family: Georgia, serif; font-size: 17px; line-height: 1.4; }
464
+ .tale blockquote { margin: 0; padding-left: 12px; border-left: 2px solid var(--accent); font-family: Georgia, serif; font-style: italic; color: var(--muted); }
465
+ .tale ul, .tale ol { list-style: none; margin: 0; padding: 0; }
466
+ .tale li { animation: rise 0.5s ease-out both; }
467
+ .tale .people { display: flex; flex-wrap: wrap; gap: 10px; }
468
+ .tale .people li { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 11px; color: var(--muted); max-width: 64px; text-align: center; overflow-wrap: anywhere; }
469
+ .tale .people img, .tale .noface { width: 48px; height: 64px; object-fit: contain; border-radius: 8px; background: var(--raised); }
470
+ .tale .noface { display: flex; align-items: center; justify-content: center; font-family: Georgia, serif; font-size: 20px; color: var(--faint); text-transform: uppercase; }
471
+ .tale .where-list { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
472
+ .tale .where-list strong { color: var(--text); font-weight: 600; margin-right: 4px; }
473
+ .tale .finds { display: flex; flex-wrap: wrap; gap: 8px; }
474
+ .tale .finds li { display: flex; align-items: center; gap: 6px; padding: 3px 10px 3px 3px; border-radius: 16px; background: var(--raised); font-size: 12px; }
475
+ .tale .finds img, .tale .noicon { width: 26px; height: 26px; object-fit: contain; border-radius: 13px; background: rgba(255, 255, 255, 0.05); }
476
+ .tale .endings { margin: 0; font-size: 13px; color: var(--muted); }
477
+ @keyframes rise { from { opacity: 0; transform: translateY(6px); } }
478
+
479
+ .strip { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
480
+ .strip .card { all: unset; cursor: pointer; display: flex; flex-direction: column; gap: 5px; width: 100%; }
481
+ .strip .thumb { position: relative; display: block; aspect-ratio: 1200 / 896; border-radius: 10px; overflow: hidden; background: var(--raised); }
482
+ .strip .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; animation: enter-fade 0.8s ease-out both; }
483
+ .strip .noimg { position: absolute; inset: 0; overflow: hidden; padding: 10px; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 12px; font-style: italic; color: var(--faint); background: repeating-linear-gradient(135deg, transparent 0 10px, rgba(255, 255, 255, 0.025) 10px 20px); }
484
+ .strip li.focus .thumb { outline: 2px solid var(--accent); outline-offset: 2px; }
485
+ .strip .name { display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; gap: 6px; font-size: 13px; min-width: 0; }
486
+ .strip .name strong { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
487
+ .strip .name .badge { flex: none; white-space: nowrap; max-width: 60%; overflow: hidden; text-overflow: ellipsis; }
488
+ .strip .dots { display: flex; gap: 3px; }
489
+ .strip li { position: relative; }
490
+ /* Fix it sits over the bottom of the thumbnail, so a failed card is no taller than the others. */
491
+ .strip .fixit { position: absolute; left: 0; right: 0; top: 0; aspect-ratio: 1200 / 896; display: flex; align-items: flex-end; overflow: hidden; border-radius: 10px; pointer-events: none; }
492
+ .strip .fixit .panel { pointer-events: auto; flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: stretch; gap: 4px; margin: 4px; padding: 5px 6px; border-radius: 8px; background: rgba(18, 20, 23, 0.88); border: 1px solid var(--bad); }
493
+ .strip .fixit .why { font-size: 11px; line-height: 1.25; color: var(--bad); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
494
+ .strip .fixit button { padding: 2px 8px; }
495
+ .strip .dots i { width: 6px; height: 6px; border-radius: 3px; background: var(--line-strong); }
496
+ .strip .dots i.on { background: var(--ok); }
497
+ @media (max-width: 1100px) { .build-grid { grid-template-columns: 1fr; grid-template-areas: "stage" "strip" "tale"; } .tale { contain: none; } }
498
+
499
+ /* The Workshop fits the window (main.workshop.fit): the stage takes the height that is left; the tale and the Story, Cast and Notes tabs scroll inside. */
500
+ @media (min-width: 961px) and (min-height: 560px) {
501
+ main.workshop.fit { height: calc(100dvh - var(--top-h, 55px)); padding-block: 14px; overflow: hidden; }
502
+ main.workshop.fit > .left { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
503
+ main.workshop.fit > .left > * { flex: none; margin: 0; }
504
+ main.workshop.fit > .left > .row h1 { font-size: 26px; }
505
+ main.workshop.fit .lead { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 15px; }
506
+ main.workshop.fit .seg { align-self: flex-start; }
507
+ /* The stage column is as wide as the picture the height allows; the story takes the rest. */
508
+ main.workshop.fit > .left > .build-stage { flex: 1 1 0; min-height: 0; container-type: size; }
509
+ /* Also on a narrow window: the picture shrinks before the story drops under it, so nothing goes below the fold. */
510
+ main.workshop.fit .build-grid { height: 100%; grid-template-rows: minmax(0, 1fr) 132px; grid-template-areas: "stage tale" "strip tale";
511
+ grid-template-columns: min(calc(100cqw - clamp(220px, 34cqw, 316px)), calc((100cqh - 144px) * 1200 / 896)) minmax(0, 1fr); }
512
+ main.workshop.fit .tale { contain: size; }
513
+ main.workshop.fit .build-grid > .inspect { grid-area: tale; min-height: 0; overflow: auto; overscroll-behavior: contain; margin: 0; }
514
+ main.workshop.fit .stage-live { min-height: 0; }
515
+ main.workshop.fit .stage-live .frame { width: 100%; margin: 0; }
516
+ main.workshop.fit .strip { display: flex; gap: 10px; overflow-x: auto; }
517
+ main.workshop.fit .strip li { flex: 0 0 132px; }
518
+ main.workshop.fit .strip .name { font-size: 12px; }
519
+ main.workshop.fit .tale { min-height: 0; }
520
+ main.workshop.fit > .right { min-height: 0; }
521
+ main.workshop.fit > .left > .play { flex: 1 1 0; min-height: 0; }
522
+ main.workshop.fit > .left > .tab-body { flex: 1 1 0; min-height: 0; overflow: auto; overscroll-behavior: contain; padding-right: 4px; }
523
+ main.workshop.fit .play .screen { flex: 1 1 0; min-height: 0; container-type: size; display: grid; place-items: center; }
524
+ main.workshop.fit .play iframe { width: min(100cqw, calc(100cqh * 1200 / 896)); }
525
+ main.workshop.fit > .right .dock-body { flex: 1 1 0; min-height: 0; overflow: hidden; }
526
+ }
527
+
528
+ /* The agent's dock (studio/dock.tsx): right or left at a dragged width, floating, or folded to a bar. */
529
+ main.workshop.dock-right { grid-template-columns: minmax(0, 1fr) var(--dock-w, 380px); }
530
+ main.workshop.dock-left { grid-template-columns: var(--dock-w, 380px) minmax(0, 1fr); }
531
+ main.workshop.dock-left > .dock { order: -1; }
532
+ main.workshop.dock-right-folded { grid-template-columns: minmax(0, 1fr) 44px; }
533
+ main.workshop.dock-left-folded { grid-template-columns: 44px minmax(0, 1fr); }
534
+ main.workshop.dock-left-folded > .dock { order: -1; }
535
+ main.workshop.dock-float { grid-template-columns: minmax(0, 1fr); }
536
+ .dock { position: relative; }
537
+ /* Docked, the agent keeps the window's height whatever the tab and however long the page: it stays put while the page scrolls. */
538
+ main.workshop:not(.fit) > .dock:not(.float) { position: sticky; top: 20px; align-self: start; height: calc(100dvh - var(--top-h, 55px) - 40px); min-height: 0; }
539
+ main.workshop:not(.fit) > .dock:not(.float):not(.folded) .dock-body { flex: 1 1 0; min-height: 0; overflow: hidden; }
540
+ .dock-body { display: flex; flex-direction: column; gap: 14px; min-height: 0; }
541
+ .dock-body[hidden] { display: none; }
542
+ .dock-body > section.agent { flex: 1 1 0; min-height: 200px; max-height: none; }
543
+ .dock-body > .log { flex: none; }
544
+ .dock-body > .log[open] { flex: 0 1 40%; min-height: 140px; display: flex; flex-direction: column; overflow: hidden; }
545
+ .dock-body > .log[open] ol { flex: 1; min-height: 0; max-height: none; }
546
+ .dockbar { display: flex; align-items: center; gap: 2px; min-height: 28px; padding: 0 2px; color: var(--faint); font-size: 12px; user-select: none; }
547
+ .dock-title { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }
548
+ button.tiny { min-height: 26px; min-width: 28px; padding: 0 6px; border: 0; border-radius: 8px; font-size: 14px; color: var(--faint); }
549
+ button.tiny:hover, button.tiny.on { color: var(--text); background: var(--raised); }
550
+ .dock-edge { position: absolute; top: 0; bottom: 0; width: 10px; cursor: col-resize; z-index: 2; }
551
+ .dock.right .dock-edge { left: -12px; }
552
+ .dock.left .dock-edge { right: -12px; }
553
+ .dock-edge:hover, body.dragging .dock-edge { background: linear-gradient(90deg, transparent 4px, var(--accent) 4px, var(--accent) 6px, transparent 6px); }
554
+ body.dragging { cursor: grabbing; user-select: none; }
555
+ body.dragging iframe { pointer-events: none; }
556
+ .dock.folded { flex-direction: column; align-items: center; }
557
+ .dock.folded .dockbar { flex-direction: column; gap: 8px; padding-top: 4px; }
558
+ .dock.folded .dock-title { writing-mode: vertical-rl; transform: rotate(180deg); }
559
+ .dock.float { position: fixed; z-index: 30; padding: 8px 10px 10px; border-radius: 14px; background: var(--bg); border: 1px solid var(--line-strong); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55); overflow: visible; display: flex; flex-direction: column; }
560
+ .dock.float .dockbar { cursor: grab; }
561
+ .dock.float .dock-body { flex: 1 1 0; min-height: 0; overflow: hidden; }
562
+ /* Inside the dock the chat takes whatever height there is, its input pinned at the bottom. */
563
+ .dock-body section.agent > .gc-chat { min-height: 0; }
564
+ .grip { position: absolute; z-index: 3; }
565
+ .grip.n, .grip.s { left: 10px; right: 10px; height: 8px; cursor: ns-resize; }
566
+ .grip.e, .grip.w { top: 10px; bottom: 10px; width: 8px; cursor: ew-resize; }
567
+ .grip.n { top: -4px; } .grip.s { bottom: -4px; } .grip.e { right: -4px; } .grip.w { left: -4px; }
568
+ .grip.ne, .grip.nw, .grip.se, .grip.sw { width: 16px; height: 16px; }
569
+ .grip.ne { top: -5px; right: -5px; cursor: nesw-resize; } .grip.sw { bottom: -5px; left: -5px; cursor: nesw-resize; }
570
+ .grip.nw { top: -5px; left: -5px; cursor: nwse-resize; } .grip.se { bottom: -5px; right: -5px; cursor: nwse-resize; }
571
+ .dock.float.folded { width: auto; height: auto; flex-direction: row; }
572
+ .dock.float.folded .dockbar { flex-direction: row; }
573
+ .dock.float.folded .dock-title { writing-mode: horizontal-tb; transform: none; }
574
+ @media (max-width: 960px) { main.workshop[class*="dock-"] { grid-template-columns: 1fr; } .dock-edge { display: none; } }
575
+
576
+ /* Top bar: a live dot, Activity, and the seldom-used options behind ☰. */
577
+ .live-dot { width: 8px; height: 8px; border-radius: 4px; background: var(--faint); }
578
+ .live-dot.on { background: var(--ok); box-shadow: 0 0 0 3px rgba(108, 195, 181, 0.18); }
579
+ .menu-button { font-size: 16px; }
580
+ .share-menu.top-menu { width: 220px; gap: 4px; }
581
+ .top-menu .navlink { padding: 6px 4px; border-radius: 8px; }
582
+ .top-menu .follow { padding: 6px 4px; }
583
+ /* Activity as a drawer from the right, scrolling inside. */
584
+ .drawer-back { position: fixed; inset: 0; z-index: 50; background: rgba(8, 9, 11, 0.5); display: flex; justify-content: flex-end; }
585
+ .drawer { width: min(560px, 92vw); height: 100%; display: flex; flex-direction: column; gap: 8px; padding: 16px 18px; background: var(--panel); border-left: 1px solid var(--line-strong); box-shadow: -20px 0 50px rgba(0, 0, 0, 0.45); animation: drawer-in 0.18s ease-out; }
586
+ .drawer.log ol { flex: 1; min-height: 0; max-height: none; overflow: auto; }
587
+ @keyframes drawer-in { from { transform: translateX(24px); opacity: 0; } }
588
+ .share-menu.top-menu:has(.menu-group) { width: 300px; }
589
+ .menu-group { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; padding-top: 10px; border-top: 1px solid var(--line); }
590
+ .menu-group p { margin: 0; }
591
+ .menu-head { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--faint); }
592
+ /* One tooltip for the whole Studio (tip.tsx): what a control does and what it costs. */
593
+ .tip { position: fixed; left: 0; top: 0; z-index: 1000; max-width: 300px; padding: 7px 10px; border-radius: 8px; background: var(--raised); color: var(--text); border: 1px solid var(--line-strong); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45); font-size: 13px; line-height: 1.4; white-space: pre-line; pointer-events: none; opacity: 0; transition: opacity 0.12s; }
594
+ .tip.on { opacity: 1; }
595
+
596
+ /* The agent's side during a build: what the models do now; after it, ideas to ask. */
597
+ .crew { flex: none; display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; padding: 12px 14px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); }
598
+ .crew.live { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
599
+ .crew .row strong { font-size: 13px; }
600
+ .crew.live .row strong::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 7px; border-radius: 4px; background: var(--accent); animation: pulse 1.6s ease-in-out infinite; }
601
+ .crew .feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; max-height: 40vh; overflow: hidden; }
602
+ .crew .feed li { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); animation: rise 0.4s ease-out both; white-space: nowrap; overflow: hidden; }
603
+ .crew .feed li span:last-child { overflow: hidden; text-overflow: ellipsis; }
604
+ .crew .feed li:nth-child(n + 5) { opacity: 0.6; }
605
+ .crew .feed li.step { color: var(--ok); }
606
+ .crew .detail { margin: 0; }
607
+ .crew .ideas { display: flex; flex-wrap: wrap; gap: 6px; }
608
+ .crew .ideas button { font-size: 12px; }
609
+ .things td.remove { width: 1%; text-align: right; }
610
+ .things tr.confirm td { padding-top: 0; }
611
+ .things tr.confirm .row { flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
612
+ .things .add-thing input { width: 100%; }
613
+ button.danger { color: var(--bad); }
614
+ /* Start: one idea box up top, the worlds below scroll inside, the page itself never scrolls. */
615
+ main.start { max-width: 1100px; margin: 0 auto; padding: 32px 20px 0; height: calc(100dvh - var(--top-h, 55px)); display: flex; flex-direction: column; gap: 22px; overflow: hidden; }
616
+ main.start .hero { display: flex; flex-direction: column; gap: 14px; flex: none; }
617
+ main.start .hero h1 { font-size: clamp(30px, 4vw, 44px); letter-spacing: -0.01em; text-wrap: balance; }
618
+ main.start .hero h1 em { color: var(--accent); }
619
+ main.start .lead { margin: 0; }
620
+ .prompt { display: flex; flex-direction: column; gap: 10px; padding: 18px 18px 12px; border: 1px solid var(--line-strong); border-radius: 22px; background: var(--panel); transition: border-color .2s, box-shadow .2s; }
621
+ .prompt:focus-within, .prompt.drop { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(232, 168, 92, 0.13), 0 20px 60px rgba(232, 168, 92, 0.06); }
622
+ .prompt textarea { border: 0; background: transparent; padding: 0; resize: none; font: 21px/1.45 Georgia, "Iowan Old Style", serif; min-height: 96px; }
623
+ .prompt textarea:focus { outline: none; }
624
+ .prompt .attached { display: flex; gap: 8px; flex-wrap: wrap; }
625
+ .prompt .att { display: inline-flex; align-items: center; gap: 8px; padding: 4px 4px 4px 4px; border-radius: 12px; background: var(--raised); font-size: 13px; color: var(--muted); }
626
+ .prompt .att img { width: 36px; height: 36px; object-fit: cover; border-radius: 8px; }
627
+ .prompt .row > .primary { min-height: 44px; padding: 0 24px; border-radius: 22px; }
628
+ .prompt label.button { display: inline-flex; align-items: center; cursor: pointer; }
629
+ .prompt label.button input { display: none; }
630
+ button.bare, label.bare { border-color: transparent; color: var(--muted); min-height: 36px; padding: 0 12px; border-radius: 18px; }
631
+ button.bare:hover, label.bare:hover { background: var(--raised); color: var(--text); }
632
+ button.bare.rec { color: var(--bad); }
633
+ .ideas { gap: 8px; }
634
+ .chip { min-height: 32px; padding: 0 14px; border-radius: 999px; font-size: 13px; color: var(--muted); border-color: var(--line); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
635
+ .chip:hover { color: var(--text); border-color: var(--accent); }
636
+ main.start .more summary { cursor: pointer; color: var(--faint); font-size: 14px; }
637
+ main.start .more .row { margin-top: 10px; }
638
+ main.start .more label, .workshop-start label { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 14px; }
639
+ .start-worlds { flex: 1; min-height: 0; overflow: auto; padding-bottom: 24px; }
640
+ .start-worlds .worlds { margin-top: 10px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
641
+ main.workshop-start { overflow: auto; }
642
+ main.workshop-start > * { flex: none; }
643
+ main.workshop-start .start-worlds { flex: none; overflow: visible; }
644
+ /* In a narrow column the things table drops the mask column; narrower still, each thing is a small card: its key over its controls. */
645
+ .editor { container-type: inline-size; }
646
+ @container (max-width: 640px) {
647
+ .things th:nth-child(4), .things td:nth-child(4):not([colspan]) { display: none; }
648
+ .things select { max-width: 110px; }
649
+ }
650
+ @container (max-width: 520px) {
651
+ table.things thead { display: none; }
652
+ table.things tr { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 4px 6px; padding: 6px 0; border-top: 1px solid var(--line); }
653
+ table.things td { border: 0; padding: 0; }
654
+ table.things td:first-child, table.things tr.confirm td, table.things tr.add-thing td:nth-child(2) { grid-column: 1 / -1; }
655
+ table.things tr.add-thing td:last-child { display: none; }
656
+ table.things tr.confirm { border-top: 0; padding-top: 0; }
657
+ table.things input { min-width: 0; }
658
+ }
659
+
660
+ /* ── The atelier ───────────────────────────────────────────────────────────────────────────────────────────
661
+ The worlds rail on the left, then the page. A world is the conversation beside its stage. Paper is the
662
+ ground and the mat around paintings; type and controls stay plain. Nothing scrolls as a page. */
663
+ body { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .4 0 0 0 0 .33 0 0 0 0 .22 0 0 0 .06 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E"); }
664
+ button:focus-visible, a:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
665
+ .atelier { flex: 1; min-height: 0; display: grid; grid-template-columns: 88px minmax(0, 1fr); }
666
+ .atelier-page { min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
667
+ .atelier-page > main { flex: 1 1 0; min-height: 0; }
668
+ .logo { color: var(--ink); flex: none; }
669
+
670
+ .rail { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 14px 0 10px; border-right: 1px solid var(--line); min-height: 0; }
671
+ .rail .mark-link { display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--ink); text-decoration: none; font-family: var(--display); font-size: 13px; }
672
+ .rail .new { width: 40px; height: 40px; min-height: 0; padding: 0; border-radius: 50%; font-size: 20px; background: var(--panel); border-color: var(--line); }
673
+ .rail .new:hover { border-color: var(--amber); }
674
+ .rail-worlds { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 6px 0 12px; width: 100%; scrollbar-width: none; }
675
+ .rail-world { position: relative; width: 62px; display: flex; flex-direction: column; align-items: center; gap: 6px; text-decoration: none; color: var(--muted); font-size: 11px; line-height: 1.2; text-align: center; }
676
+ .rail-world .th { width: 62px; height: 46px; border-radius: 5px; background: var(--raised) center / cover; box-shadow: 0 0 0 3px var(--panel), 0 2px 6px rgba(60, 40, 20, 0.22); transition: box-shadow .15s; }
677
+ .rail-world:hover .th { box-shadow: 0 0 0 3px var(--panel), 0 0 0 4px var(--line-strong), 0 4px 10px rgba(60, 40, 20, 0.25); }
678
+ .rail-world.on .th { box-shadow: 0 0 0 3px var(--amber), 0 2px 6px rgba(60, 40, 20, 0.22); }
679
+ .rail-world.on { color: var(--text); }
680
+ .rail-world .lb { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 76px; }
681
+ .rail-world .ring { position: absolute; top: -8px; right: -10px; }
682
+ .ring .track { fill: var(--panel); stroke: var(--line); stroke-width: 3; }
683
+ .ring .done { fill: none; stroke: var(--amber); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray 1s; }
684
+ .rail-world .dot-needs { position: absolute; top: -6px; right: -6px; width: 17px; height: 17px; border-radius: 50%; background: var(--bad); color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center; box-shadow: 0 0 0 2px var(--panel); }
685
+
686
+ .corner { position: absolute; top: 14px; right: 18px; display: flex; gap: 8px; z-index: 6; }
687
+ .bell-wrap { position: relative; }
688
+ .bell { width: 38px; min-height: 38px; padding: 0; border-radius: 50%; background: var(--panel); border-color: var(--line); color: var(--muted); display: grid; place-items: center; position: relative; }
689
+ .bell.loud { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); }
690
+ .bell b { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--bad); color: #fff; font-size: 10.5px; line-height: 18px; }
691
+ .bell:not(.loud) b { background: var(--amber); }
692
+ .bell-pop { position: absolute; right: 0; top: calc(100% + 8px); width: 360px; max-height: 70vh; overflow: auto; z-index: 20; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 18px 44px rgba(60, 40, 20, 0.18); padding: 6px; }
693
+ .bell-pop .detail { padding: 10px; margin: 0; }
694
+ .bell-row { display: flex; align-items: center; gap: 2px; }
695
+ .bell-row .bell-item { flex: 1; min-width: 0; }
696
+ .bell-x { flex: none; align-self: flex-start; margin-top: 8px; }
697
+ .bell-clear { display: block; margin: 4px 6px 4px auto; }
698
+ .bell-item { display: flex; gap: 10px; align-items: center; padding: 9px; border-radius: 8px; color: var(--text); text-decoration: none; font-size: 13.5px; }
699
+ .bell-item:hover { background: var(--bg); }
700
+ .bell-item .th { width: 48px; height: 36px; border-radius: 4px; flex: none; background: var(--raised) center / cover; }
701
+ .bell-pop .bell-item small { display: block; color: var(--muted); font-size: 12px; white-space: normal; overflow: visible; }
702
+ .bell-item > span:last-child { flex: 1; min-width: 0; white-space: normal; overflow-wrap: anywhere; }
703
+ .bell-item.needs strong { color: var(--bad); }
704
+ .menu-wrap > .menu-button, .share-wrap > button { min-height: 38px; border-color: var(--line); background: var(--panel); }
705
+ .top-menu { width: 280px; }
706
+ .top-menu .share { width: 100%; }
707
+ .top-menu .share > button, .top-menu > button { width: 100%; justify-content: flex-start; text-align: left; }
708
+
709
+ /* The front door. */
710
+ main.start { max-width: none; width: 100%; height: auto; padding: 24px max(24px, calc((100% - 780px) / 2)); justify-content: center; gap: 18px; overflow: auto; }
711
+ main.start .hero { align-items: center; text-align: center; gap: 16px; }
712
+ main.start .hero h1 { font-size: clamp(36px, 4.6vw, 60px); font-weight: 400; }
713
+ main.start .hero h1 em { color: var(--amber); font-style: italic; }
714
+ main.start .lead { max-width: 60ch; }
715
+ main.start .prompt { width: 100%; text-align: left; background: var(--panel); border-color: var(--line); border-radius: 18px; box-shadow: 0 1px 0 #fff inset, 0 18px 50px rgba(80, 55, 25, 0.12); }
716
+ main.start .prompt:focus-within, main.start .prompt.drop { border-color: var(--amber); box-shadow: 0 0 0 4px rgba(194, 122, 44, 0.12), 0 18px 50px rgba(80, 55, 25, 0.14); }
717
+ main.start .prompt textarea { font-family: var(--display); }
718
+ main.start .prompt .row > .primary { background: var(--amber); color: #fff; }
719
+ main.start .ideas { justify-content: center; }
720
+ main.start .chip { background: transparent; }
721
+ main.start .more { align-self: center; }
722
+ main.start .banner { align-self: stretch; }
723
+
724
+ main.start .hero[hidden] { display: none; }
725
+ main.start.reviewing { justify-content: flex-start; scroll-padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
726
+ .video-picker { display: none; }
727
+ .video-status { flex: 0 0 100%; order: 1; min-width: 0; padding-top: 14px; border-top: 1px solid var(--line); }
728
+ .video-status video { display: block; border-radius: 12px; }
729
+ .video-filename { display: flex; align-items: center; gap: 8px; overflow-wrap: anywhere; color: var(--muted); }
730
+ .video-status details { margin-top: 12px; }
731
+ /* Review feels like a drawing table: a note, loose studies, then the chosen world. */
732
+ .idea-review { width: 100%; max-width: 780px; margin: 0 auto; padding-bottom: calc(150px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; outline: none; animation: review-in .4s ease-out; }
733
+ .idea-review:focus-visible { outline: none; }
734
+ .review-header { display: flex; align-items: center; gap: 10px; padding: 8px 0 18px; margin-bottom: 28px; color: var(--muted); border-bottom: 1px solid var(--line); }
735
+ .review-header button { margin-right: auto; border: 0; padding-left: 0; background: transparent; }
736
+ .review-header span { font: 18px var(--display); }
737
+ .review-header .logo { width: 23px; }
738
+ .idea-review-body { min-width: 0; }
739
+ .review-style-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 12px; }
740
+ .review-style-actions .amber { background: var(--amber); color: #fffdf7; border-color: var(--amber); }
741
+ .review-style-cancel { border-color: transparent; background: transparent; color: var(--muted); }
742
+ .review-style-cancel:hover:not(:disabled) { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
743
+ .review-question-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 20px; margin-top: 16px; }
744
+ .review-question-actions:empty { display: none; }
745
+ .review-question-actions .review-explore-looks { display: inline-flex; align-items: center; gap: 8px; border-color: transparent; background: transparent; color: #996022; }
746
+ .review-question-actions .review-explore-looks:hover:not(:disabled) { background: #c47b2510; border-color: transparent; text-decoration: underline; text-underline-offset: 4px; }
747
+ .review-text-options { display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0; }
748
+ .review-text-option { display: inline-flex; align-items: baseline; gap: 9px; max-width: 100%; padding: 13px 18px; border-radius: 7px; background: var(--panel); text-align: left; font: 19px/1.4 var(--display); box-shadow: 0 3px 10px #59442808; white-space: normal; overflow-wrap: anywhere; }
749
+ .review-text-option:hover:not(:disabled), .review-text-option.selected { border-color: var(--amber); background: #f7eddd; }
750
+ .review-text-option.selected > span:first-child { color: var(--amber); font: 14px var(--body); }
751
+ .review-text-option[hidden] { display: none; }
752
+ .review-origin { position: relative; margin: 8px 8px 38px; padding: 22px 28px 24px; background: var(--panel); border: 1px solid #e2d8c7; border-radius: 3px 7px 5px 2px; box-shadow: 0 2px 3px #59442806, 0 14px 28px -20px #59442850; transform: rotate(-.45deg); }
753
+ .review-origin::before { content: ''; position: absolute; top: -9px; left: calc(50% - 24px); width: 48px; height: 18px; background: #d9cbaa70; transform: rotate(3deg); border-inline: 1px solid #f5efdf80; }
754
+ .review-kicker { display: block; font: 10px/1.4 var(--body); text-transform: uppercase; letter-spacing: .18em; color: #94734c; }
755
+ .review-origin > .review-reply { padding: 0; margin: 9px 0 0; width: auto; max-width: none; background: transparent; color: var(--ink); font: italic 24px/1.45 var(--display); border-radius: 0; }
756
+ .review-attachments { display: flex; gap: 9px; max-width: 100%; margin: 18px 0 0; width: fit-content; overflow-x: auto; padding: 4px; }
757
+ .review-attachments img { flex: none; width: 64px; height: 60px; object-fit: contain; padding: 4px 4px 9px; border-radius: 2px; background: #fffcf4; box-shadow: 0 2px 5px #59442820; }
758
+ .review-attachments img:nth-child(even) { transform: rotate(3deg); }
759
+ .review-expand { display: block; color: var(--muted); margin-top: 8px; font: 12px var(--body); }
760
+ .review-exchange { margin: 0 8px 24px; padding-left: 18px; border-left: 1px solid var(--line-strong); }
761
+ .review-exchange .review-says { font-size: 18px; color: var(--muted); margin: 0 0 4px; }
762
+ .review-says { font: 400 32px/1.2 var(--display); letter-spacing: -.02em; margin: 12px 0 24px; text-wrap: pretty; }
763
+ .review-says em { color: var(--amber); font-weight: 400; }
764
+ .review-reply { margin: 0; font: italic 21px/1.4 var(--display); color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
765
+ .review-thinking { display: grid; grid-template-columns: 1.15fr 1fr; align-items: center; gap: 22px; min-height: 292px; margin: -6px 0 16px; }
766
+ .review-thinking-copy { padding: 12px 18px 24px 0; }
767
+ .review-thinking .review-says { font-size: clamp(27px, 3vw, 37px); margin: 14px 0; }
768
+ .review-aside { font: italic 16px/1.5 var(--display); color: var(--muted); margin: 0; }
769
+ .review-ink-trail { display: block; width: 62px; height: 9px; margin-top: 22px; border-top: 2px solid var(--amber); border-radius: 50%; transform: rotate(-4deg); transform-origin: left; animation: review-ink-breathe 3s ease-in-out infinite; }
770
+ .review-sketch { display: block; width: 100%; max-width: 440px; margin: 0 auto; }
771
+ .review-sketch svg { display: block; width: 100%; height: auto; overflow: visible; }
772
+ .sketch-leaf { transform-box: fill-box; transform-origin: center; animation: review-paper-drift 6s ease-in-out infinite; }
773
+ .sketch-leaf-right { animation-delay: -3s; }
774
+ .sketch-theatre { animation: review-theatre-in .8s ease-out both; }
775
+ .sketch-sun { animation: review-sun 5s ease-in-out infinite; }
776
+ .sketch-ink { stroke-dasharray: 1; stroke-dashoffset: 0; animation: review-pencil-line 5s ease-in-out infinite; }
777
+ .sketch-ink-late { animation-delay: -.8s; }
778
+ .review-sketch.compact { max-width: 180px; }
779
+ .review-sketch.compact .sketch-leaf, .review-sketch.compact .sketch-pencil { display: none; }
780
+ .review-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 16px; padding: 10px 10px 22px; margin-bottom: 10px; counter-reset: study; }
781
+ .idea-card { --paper-angle: -1.3deg; position: relative; min-width: 0; padding: 9px 9px 18px; display: flex; flex-direction: column; gap: 8px; align-items: center; border: 1px solid #ded3bf; border-radius: 3px; background: #fffcf4; box-shadow: 0 2px 4px #5944280a, 0 14px 25px -14px #59442845; transform: rotate(var(--paper-angle)); transition: transform .25s, box-shadow .25s, border-color .2s; animation: review-study-in .5s ease-out both; }
782
+ .idea-card:nth-child(2n) { --paper-angle: 1.2deg; animation-delay: .08s; }
783
+ .idea-card:nth-child(3n) { --paper-angle: -.6deg; animation-delay: .16s; }
784
+ .idea-card:hover:not(:disabled), .idea-card:focus-visible { transform: translateY(-6px) rotate(0); border-color: var(--amber); box-shadow: 0 5px 8px #5944280c, 0 18px 30px -12px #59442845; }
785
+ .idea-card:active:not(:disabled) { transform: translateY(-2px) rotate(0); }
786
+ .idea-card-picture { position: relative; display: grid; place-items: center; width: 100%; aspect-ratio: 4 / 3; background: #eee8dc; overflow: hidden; margin-bottom: 6px; border-radius: 1px; }
787
+ .idea-card-picture img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; animation: review-image-in .6s ease-out both; }
788
+ .idea-card strong { padding: 0 10px; font: 400 21px/1.2 var(--display); color: var(--ink); }
789
+ .idea-card small { font-size: 9px; letter-spacing: .08em; color: var(--muted); }
790
+ .idea-card-placeholder { display: grid; justify-items: center; gap: 0; color: var(--faint); width: 100%; }
791
+ .idea-card-placeholder > small { position: absolute; bottom: 8px; }
792
+ .review-compose { display: flex; align-items: center; gap: 6px; border: 0; border-bottom: 1px solid var(--line-strong); padding: 3px; margin: 8px 0 18px; }
793
+ .review-compose input { min-width: 0; flex: 1; border: 0; background: transparent; }
794
+ .review-compose button { flex: none; }
795
+ .review-reference { max-width: 150px; max-height: 110px; object-fit: contain; border-radius: 3px; margin-bottom: 12px; }
796
+ .review-chosen { display: flex; gap: 6px; align-items: center; }
797
+ .idea-review footer { display: flex; justify-content: center; align-items: center; padding: 9px; position: fixed; bottom: calc(16px + env(safe-area-inset-bottom)); left: 50%; right: auto; transform: translateX(-50%); width: max-content; max-width: calc(100% - 24px); background: #e7ddcbcc; backdrop-filter: blur(18px); border: 1px solid #bca88740; border-radius: 32px; box-shadow: 0 8px 28px #59442816; margin: 0; z-index: 20; gap: 10px; flex-wrap: wrap; }
798
+ .idea-review footer button { display: inline-flex; align-items: center; justify-content: center; gap: 9px; }
799
+ .review-spinner { width: 15px; height: 15px; flex: 0 0 15px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: review-spin .85s linear infinite; }
800
+ @keyframes review-spin { to { transform: rotate(360deg); } }
801
+ .idea-review footer button[aria-busy=true]:disabled { opacity: .85; cursor: progress; }
802
+ .idea-review footer .ghost { border-color: transparent; color: var(--muted); font-size: 13px; }
803
+ .idea-review footer .ghost:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
804
+ .idea-review footer .primary { background: var(--amber); color: #fffdf7; border-color: var(--amber); padding: 13px 24px; box-shadow: 0 4px 10px #bc7a2420; }
805
+ .idea-review footer .primary:hover:not(:disabled) { background: #ac6925; transform: translateY(-1px); }
806
+ /* Keep the viewport dock outside a transformed containing block, including on entry. */
807
+ @keyframes review-in { from { opacity: 0; } to { opacity: 1; } }
808
+ @keyframes review-study-in { from { opacity: 0; transform: translateY(12px) rotate(0); } to { opacity: 1; transform: rotate(var(--paper-angle)); } }
809
+ @keyframes review-image-in { from { opacity: 0; } to { opacity: 1; } }
810
+ @keyframes review-paper-drift { 0%, 100% { transform: translateY(0) rotate(-1deg); } 50% { transform: translateY(-4px) rotate(1deg); } }
811
+ @keyframes review-theatre-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
812
+ @keyframes review-pencil-line { 0%, 12% { stroke-dashoffset: 1; } 58%, 92% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 1; } }
813
+ @keyframes review-sun { 0%, 100% { opacity: .8; } 50% { opacity: .55; } }
814
+ @keyframes review-ink-breathe { 0%, 100% { transform: rotate(-4deg) scaleX(.7); opacity: .5; } 50% { transform: rotate(-4deg) scaleX(1); opacity: 1; } }
815
+ @media (max-width: 520px) {
816
+ .review-header { margin-bottom: 18px; padding-top: 2px; }
817
+ .review-header span { font-size: 14px; max-width: 130px; }
818
+ .review-header .logo { display: none; }
819
+ .review-says { font-size: 27px; }
820
+ .review-origin { margin: 8px 4px 24px; padding: 20px; }
821
+ .review-origin > .review-reply { font-size: 21px; }
822
+ .review-thinking { grid-template-columns: minmax(0, 1fr); gap: 0; margin-top: -10px; }
823
+ .review-thinking > .review-sketch { max-width: 260px; }
824
+ .review-thinking-copy { padding: 0 8px 16px; text-align: center; }
825
+ .review-thinking .review-says { font-size: 28px; margin: 10px 0; }
826
+ .review-ink-trail { margin: 16px auto 0; }
827
+ .review-cards { gap: 12px; padding: 8px 6px 20px; }
828
+ .idea-card { padding: 6px 6px 14px; }
829
+ .idea-card strong { font-size: 19px; }
830
+ }
831
+ @media (prefers-reduced-motion: reduce) {
832
+ .idea-review, .idea-review *, .idea-review *::before, .idea-review *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
833
+ }
834
+
835
+ /* A world: the conversation, then the stage. */
836
+ main.world { display: grid; grid-template-columns: minmax(340px, 30%) minmax(0, 1fr); overflow: hidden; }
837
+ @media (min-width: 1500px) { main.world { grid-template-columns: 440px minmax(0, 1fr); } }
838
+ .convo { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--line); background: color-mix(in srgb, var(--panel) 55%, transparent); }
839
+ .convo > header { flex: none; padding: 16px 18px 10px; border-bottom: 1px solid var(--line); }
840
+ .convo > header h1 { font-size: 22px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
841
+ .convo > header small { color: var(--muted); font-size: 12.5px; }
842
+ .convo section.agent { flex: 1; min-height: 0; border: 0; border-radius: 0; background: none; }
843
+ .convo section.agent > .gc-chat { --gc-bg: transparent; --gc-panel: var(--panel); --gc-border: var(--line); --gc-text: var(--text); --gc-muted: var(--muted); --gc-ok: var(--ok); --gc-error: var(--bad); --gc-font-size: 14.5px; min-height: 0; font-family: var(--body); background: none; }
844
+ .convo section.agent .row { padding: 10px 14px 0; }
845
+ .convo .gc-prompt { background: var(--ink); color: var(--panel); border: 0; border-radius: 16px 16px 4px 16px; }
846
+ .convo .gc-prompt a { color: var(--panel); }
847
+ .convo .replays { display: none; }
848
+ .convo .agent-pick { font-family: var(--body); font-size: 13px; border: 0; background: transparent; color: var(--muted); padding: 2px 0; }
849
+ .idea-bubble { margin: 4px 0 2px auto; max-width: 88%; width: fit-content; background: var(--ink); color: var(--panel); padding: 9px 13px; border-radius: 16px 16px 4px 16px; font-size: 14.5px; }
850
+ .creator-idea .idea-bubble { white-space: pre-wrap; overflow-wrap: anywhere; }
851
+ .creator-choices { max-width: 88%; margin: 8px 0 12px auto; color: var(--muted); font-size: 12px; }
852
+ .creator-choices summary { cursor: pointer; padding: 6px 0; }
853
+ .creator-choices summary:hover { color: var(--ink); }
854
+ .creator-choices dl { margin: 8px 0 0; padding: 4px 0 4px 14px; border-left: 2px solid var(--line-strong); }
855
+ .creator-choices dl > div + div { margin-top: 14px; }
856
+ .creator-choices dt { font-size: 12px; color: var(--muted); }
857
+ .creator-choices dd { margin: 3px 0 0; color: var(--ink); font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
858
+
859
+ .wcard { display: block; margin: 6px 0; padding: 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; color: var(--text); transition: border-color .15s; }
860
+ .wcard.click { cursor: pointer; }
861
+ .wcard.click:hover, .wcard.on { border-color: var(--amber); }
862
+ .wcard .k { display: flex; gap: 6px; align-items: center; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); margin-bottom: 6px; }
863
+ .wcard .k .by { margin-left: auto; text-transform: none; letter-spacing: 0; color: var(--indigo); }
864
+ .wcard h3 { font-family: var(--display); font-weight: 500; font-size: 17px; margin: 0 0 4px; }
865
+ .wcard p { margin: 0 0 6px; font-size: 13.5px; color: var(--muted); }
866
+ .wcard.ask { border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); }
867
+ .wcard.ask .k { color: var(--bad); }
868
+ .wcard.ask section.failed { border: 0; padding: 0; background: none; }
869
+ .wcard .btns { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
870
+ .wcard .bar { height: 5px; border-radius: 3px; background: var(--raised); overflow: hidden; margin: 6px 0; }
871
+ .wcard .bar i { display: block; height: 100%; background: var(--amber); transition: width 1s linear; }
872
+ .wcard .thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 6px; }
873
+ .wcard .thumb { aspect-ratio: 1200 / 896; min-height: 0; padding: 0; border-radius: 4px; border: 2px solid transparent; background: var(--raised) center / cover; display: grid; place-items: center; font-size: 11px; color: var(--muted); }
874
+ .wcard .thumb.on { border-color: var(--amber); }
875
+ /* A place verify let through: playable, even while the build still makes the others. */
876
+ .wcard .thumb.ready { position: relative; }
877
+ .wcard .thumb.ready::after { content: '▶'; position: absolute; right: 4px; bottom: 3px; font-size: 10px; line-height: 1; padding: 3px 4px; border-radius: 6px; background: var(--ok); color: #fff; }
878
+ .wcard .thumb.trouble { box-shadow: inset 0 0 0 2px var(--bad); }
879
+ /* Any number of figures fits the card: each shrinks in width (drawn whole, feet on one line), none spills over. */
880
+ .wcard .lineup-mini { display: flex; align-items: flex-end; gap: 4px; height: 84px; overflow: hidden; }
881
+ .wcard .lineup-mini img { flex: 0 1 auto; min-width: 0; height: 100%; width: auto; object-fit: contain; object-position: bottom; }
882
+ .wcard.play { padding: 0; overflow: hidden; border: 0; background: var(--ink) center / cover; color: #fff; }
883
+ .wcard.play .in { display: flex; align-items: flex-end; gap: 10px; padding: 68px 14px 12px; background: linear-gradient(transparent, rgba(0, 0, 0, 0.75)); }
884
+ .wcard.play .k { color: #e9dcc6; }
885
+ .wcard.play h3 { color: #fff; margin: 0; }
886
+ .world-footer { display: flex; flex-direction: column; gap: 2px; }
887
+ .world-note { font-size: 12.5px; color: var(--muted); margin: 4px 0; }
888
+
889
+ .theatre { position: relative; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 10px; padding: 14px 18px 16px; }
890
+ .stage-top { flex: none; display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; min-width: 0; }
891
+ .stage-top h2 { font-size: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
892
+ .stage-top small { color: var(--muted); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
893
+ .stage-top > button { min-height: 38px; padding: 0 14px; white-space: nowrap; flex: none; }
894
+ .stage-top > button.ghost { background: var(--panel); border-color: var(--line); }
895
+ @media (max-width: 1250px) { .stage-top small { display: none; } }
896
+ .stage-body { flex: 1; min-height: 0; display: flex; flex-direction: column; container-type: size; }
897
+ .stage-body:fullscreen { background: #000; padding: 0; }
898
+ .stage-body:fullscreen .mat .frame { padding: 0; box-shadow: none; }
899
+ .mat { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; position: relative; }
900
+ .mat .frame { position: relative; width: min(100cqw, 100cqh * 1200 / 896); aspect-ratio: 1200 / 896; padding: 14px; background: var(--panel); border-radius: 3px; box-shadow: 0 1px 2px rgba(60, 40, 20, 0.15), 0 22px 50px rgba(60, 40, 20, 0.22); }
901
+ .mat .pic { position: relative; width: 100%; height: 100%; overflow: hidden; background: var(--raised); }
902
+ .mat .pic > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; display: block; }
903
+ .mat .pic .empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; color: var(--muted); font-family: var(--display); }
904
+ .mat .pic .empty strong { font-size: 28px; font-weight: 400; color: var(--text); }
905
+ .mat .glow { position: absolute; inset: 0; background: rgba(255, 214, 150, 0.42); mask-size: 100% 100%; -webkit-mask-size: 100% 100%; mask-mode: luminance; pointer-events: none; mix-blend-mode: screen; }
906
+ .mat .spot { position: absolute; min-height: 0; padding: 0; border: 0; border-radius: 6px; background: transparent; cursor: pointer; }
907
+ .mat .spot:hover, .mat .spot:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.85); outline-offset: 0; box-shadow: 0 0 0 4px var(--amber); }
908
+ .mat .spot .name { position: absolute; left: 0; top: -26px; background: var(--panel); color: var(--text); font-size: 12px; padding: 2px 8px; border-radius: 6px; white-space: nowrap; pointer-events: none; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); }
909
+ .mat.lineup { gap: clamp(16px, 4cqw, 48px); align-items: flex-end; padding-bottom: 6cqh; }
910
+ .mat.lineup .who { display: flex; flex-direction: column; align-items: center; gap: 8px; min-height: 0; padding: 10px; border: 2px solid transparent; border-radius: 14px; background: none; color: var(--muted); font-size: 13.5px; }
911
+ .mat.lineup .who:hover, .mat.lineup .who:focus-visible { border-color: var(--amber); color: var(--text); }
912
+ .mat.lineup .who img { height: 52cqh; max-width: 26cqw; object-fit: contain; filter: drop-shadow(0 12px 14px rgba(60, 40, 20, 0.25)); }
913
+ .paper-panel { flex: 1; min-height: 0; overflow: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
914
+ .build-on-stage { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
915
+ .build-on-stage > .stage-live { flex: 1; min-height: 0; container-type: size; }
916
+ .build-places { display: flex; flex-direction: column; gap: 4px; flex: none; min-width: 0; }
917
+ .build-places-head { display: flex; align-items: center; gap: 10px; min-height: 0; }
918
+ .build-places-head .sums { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12.5px; color: var(--muted); }
919
+ .build-places-head .sum { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
920
+ .build-places-head .sum i, .place-chip .state { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--line); }
921
+ .sum.sum-working i, .place-chip.st-working .state, .place-chip.st-repairing .state { background: var(--amber); box-shadow: 0 0 0 0 rgba(194, 122, 44, 0.6); animation: chip-live 1.4s ease-out infinite; }
922
+ .sum.sum-waiting i, .place-chip.st-waiting .state { background: #e2bf8e; }
923
+ .sum.sum-queued i, .place-chip.st-queued .state { background: transparent; border: 1.5px dashed var(--muted); }
924
+ .sum.sum-done i, .place-chip.st-done .state { background: var(--ok); }
925
+ .sum.sum-failed i, .place-chip.st-failed .state { background: var(--bad); }
926
+ @keyframes chip-live { 70% { box-shadow: 0 0 0 7px rgba(194, 122, 44, 0); } 100% { box-shadow: 0 0 0 0 rgba(194, 122, 44, 0); } }
927
+ .build-follow { flex: none; }
928
+ .build-place-row { position: relative; min-width: 0; }
929
+ .build-place-list { display: flex; align-items: stretch; gap: 7px; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scroll-padding-inline: 40px; padding: 3px; scrollbar-width: thin; }
930
+ .build-place-row.more-left .build-place-list { mask-image: linear-gradient(to right, transparent 0, #000 56px); -webkit-mask-image: linear-gradient(to right, transparent 0, #000 56px); }
931
+ .build-place-row.more-right .build-place-list { mask-image: linear-gradient(to left, transparent 0, #000 56px); -webkit-mask-image: linear-gradient(to left, transparent 0, #000 56px); }
932
+ .build-place-row.more-left.more-right .build-place-list { mask-image: linear-gradient(to right, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%); -webkit-mask-image: linear-gradient(to right, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%); }
933
+ .scroll-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 32px; min-height: 32px; padding: 0; border-radius: 50%; background: var(--panel); font-size: 20px; line-height: 1; box-shadow: 0 2px 8px rgba(60, 40, 20, 0.2); }
934
+ .scroll-arrow.left { left: 0; } .scroll-arrow.right { right: 0; }
935
+ .place-chip { display: inline-flex; align-items: center; gap: 8px; flex: none; min-height: 0; padding: 4px 12px 4px 4px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--text); text-align: left; scroll-snap-align: start; }
936
+ .place-chip .thumb { position: relative; flex: none; }
937
+ .place-chip img, .place-chip .none { display: block; width: 38px; height: 28px; object-fit: cover; border-radius: 999px 6px 6px 999px; background: var(--line); }
938
+ .place-chip .state { position: absolute; right: -3px; bottom: -2px; border: 2px solid var(--panel); width: 11px; height: 11px; box-sizing: border-box; }
939
+ .place-chip.st-queued .state { border: 1.5px dashed var(--muted); background: var(--panel); }
940
+ .place-chip .words { display: flex; flex-direction: column; line-height: 1.15; white-space: nowrap; }
941
+ .place-chip .words b { font-weight: 500; font-size: 13.5px; }
942
+ .place-chip .words small { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--muted); }
943
+ .place-chip .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--amber); animation: pulse 1s ease-in-out infinite; }
944
+ .place-chip.st-queued { opacity: 0.62; }
945
+ .place-chip.st-queued img { filter: grayscale(0.7); }
946
+ .place-chip.st-working { border-color: var(--amber); background: linear-gradient(90deg, #fbf1e2, var(--panel) 60%, #fbf1e2) 0 0 / 200% 100%; animation: flow 2.4s linear infinite; }
947
+ .place-chip.st-working .words small, .place-chip.st-repairing .words small { color: var(--accent); font-weight: 500; }
948
+ .place-chip.st-done .words small { color: var(--ok); }
949
+ .place-chip.st-failed { border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); }
950
+ .place-chip.st-failed .words small { color: var(--bad); }
951
+ .place-chip[aria-pressed=true] { outline: 2px solid var(--amber); outline-offset: 1px; background-color: #f3e5cf; }
952
+ @media (prefers-reduced-motion: reduce) { .place-chip.st-working, .place-chip .dot, .place-chip .state, .sum i { animation: none !important; } }
953
+ @media (max-width: 540px) { .build-follow { padding-inline: 8px; font-size: 12px; } .place-chip .words b { font-size: 12.5px; } }
954
+ .build-on-stage > .stage-live .frame { width: min(100cqw, (100cqh - 8px) * 1200 / 896); border-radius: 3px; box-shadow: 0 1px 2px rgba(60, 40, 20, 0.15), 0 22px 50px rgba(60, 40, 20, 0.22); outline: 14px solid var(--panel); margin-top: 14px; }
955
+ .stage-body.play > .play { flex: 1; min-height: 0; }
956
+ .stage-body.play > .play .screen { flex: 1 1 0; min-height: 0; container-type: size; display: grid; place-items: center; }
957
+ .stage-body.play > .play iframe { width: min(100cqw, calc(100cqh * 1200 / 896)); }
958
+ .stage-body.play > .play > .row { flex-wrap: wrap; }
959
+ .drawer.by-hand { width: min(1100px, 92vw); }
960
+ .drawer > .notes, .drawer.by-hand > .editor { flex: 1; min-height: 0; overflow: auto; }
961
+
962
+ /* Opening cards and turn cards ride in genaicode notices: no dashed box, the chat's own font. */
963
+ .convo .gc-notice:has(> .wcard, > .idea-bubble, > .creator-idea, > div > .wcard) { align-self: stretch; background: none; border: 0; padding: 0; color: inherit; font-size: inherit; white-space: normal; font-family: var(--body); }
964
+ .convo .gc-notice .wcard, .convo .gc-notice .wcard * { font-family: var(--body); }
965
+ .convo .gc-notice .wcard h3 { font-family: var(--display); }
966
+ .wcard .thumb { height: auto; width: 100%; align-self: start; overflow: hidden; }
967
+ .stage-top h2 { flex: 1 1 auto; }
968
+ .stage-top > :not(h2) { flex: none; }
969
+ @media (max-width: 1100px) { .stage-top > button.ghost.wide { display: none; } }
970
+
971
+ /* The Studio's own words to the agent: a quiet line in the conversation, never the person's ink bubble. */
972
+ .convo .gc-prompt:has(> .studio-note) { align-self: stretch; background: none; color: var(--muted); border: 0; border-radius: 0; box-shadow: none; padding: 0; max-width: none; }
973
+ .convo .studio-note { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
974
+ .convo .studio-note summary { display: flex; gap: 6px; align-items: baseline; padding: 2px 0; }
975
+ .convo .studio-note summary::before { content: 'ⓘ'; color: var(--faint); }
976
+ .convo .studio-note summary::after { content: 'show'; margin-left: auto; color: var(--faint); text-decoration: underline; text-underline-offset: 2px; }
977
+ .convo .studio-note[open] summary::after { content: 'hide'; }
978
+ .convo .studio-note[open] { padding: 8px 12px 10px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; color: var(--text); }
979
+
980
+ /* ☰: whole-diorama and studio operations as a quiet list; one row each, a hover on every row. */
981
+ .share-menu.top-menu { width: 260px; gap: 0; padding: 6px; background: var(--panel); border-color: var(--line-strong); box-shadow: 0 12px 34px rgba(60, 40, 20, 0.18); max-height: calc(100vh - 90px); overflow: auto; }
982
+ .top-menu .menu-head { margin: 6px 10px 2px; font-size: 11px; }
983
+ .top-menu hr { border: 0; border-top: 1px solid var(--line); margin: 6px 4px; }
984
+ .top-menu .mi, .top-menu .share > button { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 34px; padding: 0 10px; border: 0; border-radius: 8px; background: none; color: var(--text); font-size: 14px; font-weight: 400; text-align: left; justify-content: flex-start; text-decoration: none; cursor: pointer; }
985
+ .top-menu .mi:hover, .top-menu .share > button:hover, .top-menu .share > button[aria-expanded="true"] { background: var(--raised); }
986
+ .top-menu .mi.danger { color: var(--bad); }
987
+ .top-menu .share-menu { position: static; width: auto; margin: 2px 0 6px; box-shadow: none; background: var(--bg); max-height: 50vh; }
988
+ .mi-confirm { margin: 2px 0; padding: 10px; border-radius: 8px; background: color-mix(in srgb, var(--bad) 8%, var(--panel)); border: 1px solid color-mix(in srgb, var(--bad) 30%, var(--line)); }
989
+ .mi-confirm p { margin: 0 0 8px; font-size: 12.5px; color: var(--muted); }
990
+ .mi-confirm .row { gap: 6px; }
991
+ button.danger-fill { background: var(--bad); color: #fff; border: 0; font-weight: 600; }
992
+ .top-menu .mi-confirm .mi.go { width: auto; display: inline-flex; padding: 0 12px; color: #fff; }
993
+ /* A switch, not a raw checkbox. */
994
+ .mi.switch { justify-content: space-between; }
995
+ .budget .switch-row { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; font-size: 14px; color: var(--text); cursor: pointer; }
996
+ .budget.blender { gap: 8px; }
997
+ .budget.blender p { margin: 0; }
998
+ .mi.switch input, .switch-row input { appearance: none; -webkit-appearance: none; flex: none; position: relative; width: 32px; height: 18px; margin: 0; border-radius: 9px; background: var(--line-strong); cursor: pointer; transition: background .15s; }
999
+ .mi.switch input::after, .switch-row input::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .15s; }
1000
+ .mi.switch input:checked, .switch-row input:checked { background: var(--ok); }
1001
+ .mi.switch input:checked::after, .switch-row input:checked::after { transform: translateX(14px); }
1002
+ .switch-row input:disabled { opacity: .5; cursor: default; }
1003
+ /* Hand tools sit on the stage they work on, not in ☰. */
1004
+ .stage-body { position: relative; }
1005
+ .stage-tool { position: absolute; right: 8px; bottom: 6px; z-index: 2; min-height: 32px; padding: 0 12px; font-size: 13px; border-color: var(--line); background: color-mix(in srgb, var(--panel) 88%, transparent); color: var(--muted); backdrop-filter: blur(4px); }
1006
+ .stage-tool:hover { color: var(--text); background: var(--panel); border-color: var(--line-strong); }
1007
+
1008
+ /* Every button answers the pointer. Class rules for special buttons (spots, thumbs, the cast) still win. */
1009
+ button:where(:hover:not(:disabled)) { background-color: var(--raised); border-color: var(--line-strong); }
1010
+ button.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 82%, var(--panel)); }
1011
+ button.amber:hover:not(:disabled) { background: color-mix(in srgb, var(--amber) 86%, #000); }
1012
+ button.danger-fill:hover:not(:disabled) { background: color-mix(in srgb, var(--bad) 86%, #000); }
1013
+ .stage-top > button.ghost:hover:not(:disabled), .menu-wrap > .menu-button:hover, .share-wrap > button:hover, .bell:hover { background: var(--raised); border-color: var(--line-strong); }
1014
+ button:not(.spot, .thumb, .who):active:not(:disabled) { transform: translateY(1px); }
1015
+ .convo .studio-note summary::after { flex: none; white-space: nowrap; }
1016
+ .top-menu .mi-confirm .mi.go { background: var(--bad); border-radius: 16px; min-height: 30px; font-weight: 600; }
1017
+ .top-menu .mi-confirm .mi.go:hover { background: color-mix(in srgb, var(--bad) 86%, #000); }
1018
+ .convo .agent-says { margin: -2px 0 4px 46px; font-size: 14.5px; color: var(--text); }
1019
+
1020
+ /* Pictures in the conversation open over the Studio. */
1021
+ .agent .pic-open { min-height: 0; padding: 0; border: 0; border-radius: 6px; background: none; cursor: zoom-in; }
1022
+ .agent .gc-tool summary .tool-pic { flex: none; margin-left: auto; min-height: 0; padding: 0; border: 1px solid var(--line); border-radius: 5px; background: none; overflow: hidden; cursor: zoom-in; }
1023
+ .agent .gc-tool summary .tool-pic img { display: block; height: 34px; width: auto; max-width: 64px; object-fit: cover; }
1024
+ .lightbox { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 32px; background: rgba(28, 24, 20, 0.78); animation: enter-fade .15s ease-out; cursor: zoom-out; }
1025
+ .lightbox img { max-width: calc(100vw - 64px); max-height: calc(100vh - 64px); object-fit: contain; border-radius: 6px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5); cursor: default; }
1026
+ .lightbox .close { position: absolute; top: 16px; right: 16px; width: 40px; padding: 0; border-radius: 50%; background: var(--panel); border-color: var(--line); }
1027
+
1028
+ /* Handing the conversation to another agent: a quiet control in the header, and a line where it changed hands. */
1029
+ .convo .agent-hand { font-family: var(--body); font-size: 12px; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--muted); padding: 2px 8px; margin-left: 8px; cursor: pointer; }
1030
+ .convo .agent-hand:hover:not(:disabled) { color: var(--ink); border-color: var(--muted); }
1031
+ .convo .handover { display: flex; align-items: center; gap: 10px; margin: 14px 0; font-size: 12px; color: var(--muted); }
1032
+ .convo .handover::before, .convo .handover::after { content: ""; flex: 1; border-top: 1px dashed var(--line); }
1033
+
1034
+ /* Start: many photos (a class's drawings), the camera that keeps taking them, and the quiet options under More. */
1035
+ main.start .prompt .attached { max-height: 96px; overflow: auto; }
1036
+ main.start .prompt .att { padding: 3px 3px 3px 3px; gap: 2px; }
1037
+ main.start .prompt .att > button.bare { min-height: 0; padding: 0; border: 0; background: none; line-height: 0; }
1038
+ main.start .prompt .att > button.remove-photo { min-width: 20px; min-height: 24px; line-height: 1; }
1039
+ main.start .shoot { position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; background: rgba(43, 39, 35, 0.72); backdrop-filter: blur(6px); }
1040
+ main.start .shoot .camera { width: min(960px, 100%); padding: 14px; border-radius: 18px; background: var(--panel); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35); }
1041
+ main.start .shoot .camera video { max-width: none; max-height: calc(100dvh - 260px); object-fit: contain; }
1042
+ main.start .shoot .camera .row { align-items: center; gap: 10px; }
1043
+ main.start .shoot .camera .primary { background: var(--amber); color: #fff; border-color: var(--amber); }
1044
+ main.start .shoot .taken { display: flex; gap: 6px; max-width: min(960px, 100%); overflow-x: auto; padding: 2px; }
1045
+ main.start .shoot .taken img { width: 64px; height: 64px; object-fit: cover; border-radius: 10px; border: 2px solid #fff; flex: none; }
1046
+ main.start .more { display: flex; flex-direction: column; align-items: center; gap: 12px; }
1047
+ main.start .more summary { list-style: none; padding: 6px 14px; border-radius: 999px; color: var(--muted); font-size: 13px; user-select: none; }
1048
+ main.start .more summary::-webkit-details-marker { display: none; }
1049
+ main.start .more summary::after { content: " ▾"; color: var(--faint); }
1050
+ main.start .more[open] summary::after { content: " ▴"; }
1051
+ main.start .more summary:hover { background: var(--raised); color: var(--text); }
1052
+ main.start .more .fields { display: grid; grid-template-columns: 1.4fr 0.8fr 1.2fr; gap: 12px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 16px; background: var(--panel); box-shadow: 0 8px 24px rgba(80, 55, 25, 0.06); }
1053
+ main.start .more .fields label { text-align: left; display: flex; flex-direction: column; align-items: stretch; gap: 5px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }
1054
+ main.start .more .fields input, main.start .more .fields select { min-width: 0; height: 38px; padding: 0 12px; font-size: 14px; letter-spacing: normal; text-transform: none; color: var(--text); background: var(--bg); border: 1px solid var(--line); border-radius: 10px; }
1055
+ main.start .more .fields select { appearance: none; padding-right: 30px; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: right 15px top 17px, right 10px top 17px; background-size: 5px 5px; background-repeat: no-repeat; cursor: pointer; }
1056
+ main.start .more .fields input:focus, main.start .more .fields select:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px rgba(194, 122, 44, 0.15); }
1057
+ @media (max-width: 640px) { main.start .more .fields { grid-template-columns: 1fr; } }
1058
+
1059
+ /* The build bar is clickable: a phase's name puts what it made on the stage, a segment what that step made. */
1060
+ .pipeline .phases li .label { min-height: 0; padding: 0; border: 0; border-radius: 6px; background: none; font: inherit; color: inherit; text-align: left; }
1061
+ .pipeline .phases li.open .label { cursor: pointer; }
1062
+ .pipeline .phases li.open .label:hover .name { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
1063
+ .pipeline .phases li.open .bar { transition: height 0.15s, margin 0.15s; }
1064
+ .pipeline .phases li.open:hover .bar { height: 12px; margin: -2px 0; }
1065
+ .pipeline .seg { position: absolute; top: -6px; bottom: -6px; min-height: 0; padding: 0; border: 0; border-radius: 0; background: transparent; cursor: pointer; }
1066
+ .pipeline .seg.later { cursor: help; }
1067
+ .pipeline .seg.later:hover { background: rgba(255, 255, 255, 0.25); box-shadow: inset 0 0 0 1px var(--line-strong); }
1068
+ .pipeline .seg:hover, .pipeline .seg:focus-visible { background: rgba(255, 255, 255, 0.35); box-shadow: inset 0 0 0 1.5px var(--ink); outline: none; }
1069
+
1070
+ /* A button's ask in the chat: its gist in the bubble, the whole wording under it on a click. */
1071
+ .ask-note summary { cursor: pointer; list-style: none; }
1072
+ .ask-note summary::-webkit-details-marker { display: none; }
1073
+ .ask-note summary::after { content: ' ▸'; opacity: 0.55; font-size: 0.85em; }
1074
+ .ask-note[open] summary::after { content: ' ▾'; }
1075
+ .ask-note p { margin: 8px 0 0; font-size: 12.5px; line-height: 1.45; opacity: 0.72; white-space: pre-wrap; word-break: break-word; }
1076
+
1077
+ /* By hand: whatever the drawer holds (a place's editor, the cast) scrolls inside it, under its title row. */
1078
+ .drawer.by-hand > :not(.row) { flex: 1; min-height: 0; overflow: auto; }
1079
+ .mat.lineup .who-at { position: relative; display: flex; flex-direction: column; align-items: center; }
1080
+ .drawer.by-hand .cast-view { display: flex; flex-direction: column; gap: 14px; }
1081
+ .drawer.by-hand .cast { scroll-margin-top: 0; }
1082
+
1083
+ /* The cast stage: figures on a row, the story's items on a shelf under them. */
1084
+ .mat.lineup { flex-direction: column; align-items: center; justify-content: center; gap: 4cqh; padding-bottom: 3cqh; }
1085
+ .mat.lineup .figures { --gap: clamp(8px, calc(16cqw / var(--per-row, 1)), 48px); display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: center; gap: 2cqh var(--gap); max-width: 96cqw; }
1086
+ .mat.lineup .who-at { min-width: 0; max-width: calc((96cqw - var(--gap) * (var(--per-row, 1) - 1)) / var(--per-row, 1)); }
1087
+ .mat.lineup .who { max-width: 100%; }
1088
+ .mat.lineup .who span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1089
+ .mat.lineup .who img { height: calc(44cqh / var(--rows, 1) + 6cqh * (var(--rows, 1) - 1) / var(--rows, 1)); max-width: 100%; }
1090
+ .mat.lineup .shelf { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; max-width: 92cqw; padding-top: 16px; border-top: 1px solid var(--line); }
1091
+ .mat.lineup .item { display: flex; flex-direction: column; align-items: center; gap: 4px; min-height: 0; width: 92px; padding: 6px 4px; border: 2px solid transparent; border-radius: 12px; background: none; color: var(--muted); font-size: 12px; line-height: 1.25; text-align: center; }
1092
+ .mat.lineup .item:hover, .mat.lineup .item:focus-visible { border-color: var(--amber); color: var(--text); }
1093
+ .mat.lineup .item img { width: 52px; height: 52px; object-fit: contain; filter: drop-shadow(0 4px 6px rgba(60, 40, 20, 0.2)); }
1094
+ .mat.lineup .item .noicon { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 12px; background: var(--raised); color: var(--faint); font-size: 18px; }
1095
+ /* Cast details: signs for what a character has, a round play button, and the one opened from the stage. */
1096
+ .cast .who .has { display: inline-flex; gap: 4px; }
1097
+ .cast .who .sign { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; background: var(--raised); font-size: 14px; cursor: help; }
1098
+ .cast .who button.round { width: 34px; min-width: 34px; height: 34px; min-height: 34px; padding: 0; border-radius: 50%; font-size: 12px; }
1099
+ .cast .who.focus { border-color: var(--amber); box-shadow: 0 0 0 3px rgba(194, 122, 44, 0.15); scroll-margin-top: 8px; }
1100
+
1101
+ /* A long conversation: the world pinned under the agent's header once its opening cards scrolled away. */
1102
+ .world-strip { display: flex; align-items: center; gap: 10px; margin-top: 8px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: 0 6px 16px rgba(80, 55, 25, 0.08); animation: drawer-in 0.15s ease-out; }
1103
+ .world-strip button { min-height: 0; padding: 0; border: 2px solid transparent; background: none; }
1104
+ .world-strip .ws-story { flex: 1; min-width: 0; padding: 4px 6px; border-radius: 8px; font-family: var(--display); font-size: 14px; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1105
+ .world-strip .ws-places { display: flex; align-items: center; gap: 5px; flex: none; padding: 3px 5px; border-radius: 8px; }
1106
+ .world-strip .ws-stack { position: relative; display: block; width: 55px; height: 38px; }
1107
+ .world-strip .ws-sheet { position: absolute; top: 3px; left: 0; width: 40px; height: 30px; border: 2px solid var(--panel); border-radius: 5px; background: var(--raised) center / cover; box-shadow: 0 1px 3px rgba(60, 40, 20, 0.25); transform: rotate(-7deg); }
1108
+ .world-strip .ws-sheet:nth-child(2) { left: 7px; top: 2px; transform: rotate(4deg); }
1109
+ .world-strip .ws-sheet:nth-child(3) { left: 14px; top: 4px; transform: rotate(10deg); }
1110
+ .world-strip .ws-count, .world-strip .ws-building { color: var(--muted); font-size: 12px; white-space: nowrap; }
1111
+ .world-strip .ws-building { color: var(--accent); }
1112
+ .wcard .thumb.pending-place { border: 1px dashed var(--amber); color: var(--accent); }
1113
+ .world-strip .ws-cast { display: flex; align-items: flex-end; height: 42px; padding: 0 4px; border-radius: 8px; flex: none; }
1114
+ .world-strip .ws-cast img { height: 100%; max-width: 26px; object-fit: contain; }
1115
+ .world-strip .ws-cast img + img { margin-left: -6px; }
1116
+ .world-strip .ws-cast img:nth-child(even) { transform: translateY(-3px); }
1117
+ .world-strip button:hover, .world-strip button.on { border-color: var(--amber); background: var(--raised); }
1118
+
1119
+ /* Layer chips over the picture: dark glass, so their words are light whatever the page's theme. */
1120
+ .stage-live .layers button { color: rgba(255, 255, 255, 0.78); background: rgba(20, 18, 16, 0.55); }
1121
+ .stage-live .layers button:hover:not(:disabled) { color: #fff; background: rgba(20, 18, 16, 0.75); }
1122
+ .stage-live .layers .on, .stage-live .layers .on:hover:not(:disabled) { color: #fff; background: rgba(20, 18, 16, 0.85); box-shadow: inset 0 0 0 1.5px var(--amber); }
1123
+ /* The same for the caption and the place's name at the bottom, and the model tag inside the caption. */
1124
+ .stage-live figcaption { color: #fff; background: rgba(20, 18, 16, 0.72); }
1125
+ .stage-live figcaption .model { color: rgba(255, 255, 255, 0.85); background: rgba(255, 255, 255, 0.14); }
1126
+ .stage-live .where { color: rgba(255, 255, 255, 0.85); background: rgba(20, 18, 16, 0.6); }
1127
+
1128
+ /* Activity: one row per job with its steps folded under it, the agent's and your clicks folded per run. */
1129
+ .drawer.log .mi.switch { display: flex; align-items: center; gap: 10px; justify-content: flex-start; font-size: 13px; color: var(--muted); }
1130
+ .drawer.log .activity { flex: 1; min-height: 0; overflow: auto; list-style: none; margin: 6px 0 0; padding: 0 2px 0 0; display: flex; flex-direction: column; gap: 6px; font-family: var(--body); font-size: 13px; }
1131
+ .activity > li { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border-radius: 10px; color: var(--text); white-space: normal; }
1132
+ .activity .a-sign { flex: none; width: 24px; text-align: center; font-size: 15px; line-height: 20px; }
1133
+ .activity .a-what { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
1134
+ .activity .a-what small { font-size: 11.5px; color: var(--faint); }
1135
+ .activity .a-job { display: block; padding: 0; border: 1px solid var(--line); background: var(--panel); }
1136
+ .activity .a-job summary { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; cursor: pointer; list-style: none; }
1137
+ .activity .a-job summary::-webkit-details-marker { display: none; }
1138
+ .activity .a-job strong { font-weight: 600; }
1139
+ .activity .a-state { flex: none; font-size: 12px; padding: 1px 8px; border-radius: 999px; background: var(--raised); color: var(--muted); white-space: nowrap; }
1140
+ .activity .a-state.done { color: var(--ok); }
1141
+ .activity .a-state.running { color: var(--amber); }
1142
+ .activity .a-state.failed { color: #fff; background: var(--bad); }
1143
+ .activity .a-job.failed { border-color: var(--bad); }
1144
+ .activity .a-error { margin: 0 12px 8px 44px; color: var(--bad); font-size: 12.5px; word-break: break-word; }
1145
+ .activity .a-steps { list-style: none; margin: 0; padding: 0 12px 10px 44px; display: flex; flex-direction: column; gap: 2px; font-family: ui-monospace, Menlo, monospace; font-size: 11.5px; color: var(--muted); }
1146
+ .activity .a-steps li { white-space: pre-wrap; word-break: break-word; }
1147
+ .activity .a-steps li.err { color: var(--bad); }
1148
+ .activity .a-steps li.step { color: var(--text); }
1149
+ .activity .a-acts .a-what span { color: var(--muted); }
1150
+ .activity .a-line.err { color: var(--bad); }
1151
+ .activity .a-line.play .a-what span { color: var(--ok); font-style: italic; }
1152
+ .activity .a-more { flex: none; width: 16px; text-align: center; color: var(--faint); line-height: 20px; }
1153
+ .activity .a-more::before { content: '▸'; }
1154
+ .activity details[open] .a-more::before { content: '▾'; }
1155
+
1156
+ /* A cast step at work: the character being made, each picture as it lands, then the result moving. */
1157
+ .cast-work { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
1158
+ .cw-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
1159
+ .cw-head strong { font-family: var(--display); font-size: 18px; font-weight: 400; }
1160
+ .cw-wait { flex: 1; display: grid; place-items: center; color: var(--muted); font-family: var(--display); font-size: 18px; text-align: center; padding: 30px; }
1161
+ .cw-wait span { animation: pulse 2.4s ease-in-out infinite; }
1162
+ .cw-focus { display: flex; flex-direction: column; gap: 12px; padding: 14px; border-radius: 12px; background: var(--panel); box-shadow: 0 1px 2px rgba(60, 40, 20, 0.12); }
1163
+ .cw-who { display: flex; gap: 14px; align-items: flex-start; }
1164
+ .cw-who > img, .cw-who > .noimg { width: 84px; height: 110px; object-fit: contain; flex: none; border-radius: 8px; background: var(--raised); }
1165
+ .cw-text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
1166
+ .cw-text h3 { margin: 0; font-family: var(--display); font-weight: 400; font-size: 22px; }
1167
+ .cw-stages { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 0; padding: 0; list-style: none; }
1168
+ .cw-stages li { padding: 3px 10px; border-radius: 999px; background: var(--raised); color: var(--muted); font-size: 12.5px; }
1169
+ .cw-stages li small { opacity: 0.7; margin-left: 2px; }
1170
+ .cw-stages li.on { background: var(--amber); color: #2a1d0a; animation: pulse 2.4s ease-in-out infinite; }
1171
+ .cw-stages li.ok { color: var(--text); }
1172
+ .cw-slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(140px, 40%), 1fr)); gap: 10px; }
1173
+ .cw-slots figure { margin: 0; display: flex; flex-direction: column; gap: 4px; }
1174
+ .cw-slots img, .cw-slots .to-come { width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: 8px; background: var(--raised); }
1175
+ .cw-slots img { animation: land 0.5s ease-out; }
1176
+ .cw-slots .to-come { background: repeating-linear-gradient(135deg, var(--raised) 0 14px, transparent 14px 28px); animation: pulse 2.4s ease-in-out infinite; }
1177
+ .cw-slots figcaption { font-size: 12px; color: var(--muted); text-align: center; }
1178
+ .cw-others { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
1179
+ .cw-others button { display: flex; align-items: center; gap: 8px; padding: 4px 10px 4px 4px; }
1180
+ .cw-others img, .cw-others .noimg { width: 30px; height: 38px; object-fit: contain; border-radius: 4px; background: var(--raised); }
1181
+ .cw-others small { color: var(--muted); }
1182
+ @keyframes land { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
1183
+ .cw-stages li.stop { background: #f3d9d2; color: #8a2b17; }
1184
+ .cw-slots .to-come.still { animation: none; opacity: 0.5; }
1185
+ .stage-top .back { flex: none; width: 36px; height: 36px; min-height: 0; padding: 0; border-radius: 50%; font-size: 18px; line-height: 1; }
1186
+ table.things tr.focus td { background: color-mix(in srgb, var(--amber) 16%, transparent); }
1187
+ /* The editor scrolls as a whole: none of its rows (the tool tabs above all) is squeezed to fit. */
1188
+ .editor > * { flex-shrink: 0; }
1189
+ /* Every select keeps room for its chevron, whatever padding a panel gives it. */
1190
+ select:not([multiple]) { padding-right: 28px !important; }
1191
+ .lightbox .prev, .lightbox .next { position: absolute; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; padding: 0; border-radius: 50%; font-size: 26px; line-height: 1; background: var(--panel); border-color: var(--line); }
1192
+ .lightbox .prev { left: 16px; } .lightbox .next { right: 16px; }
1193
+ .lightbox .count { position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%); color: #fff; font-size: 13px; }
1194
+ .cast-work img[data-lightbox], .figure-preview canvas[data-lightbox] { cursor: zoom-in; }
1195
+ .step-work .sw-cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 10px; }
1196
+ .step-work .sw-cards li { display: flex; flex-direction: column; gap: 8px; padding: 10px; border-radius: 12px; background: var(--panel); box-shadow: 0 1px 2px rgba(60, 40, 20, 0.12); min-width: 0; }
1197
+ .step-work .pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; align-items: start; }
1198
+ .step-work .pair figure { margin: 0; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
1199
+ .step-work .pair figcaption { font-size: 12px; color: var(--muted); text-align: center; }
1200
+ .step-work .sw-crop { position: relative; width: 100%; overflow: hidden; border-radius: 8px; background: var(--raised); cursor: zoom-in; }
1201
+ .step-work .sw-crop img { position: absolute; max-width: none; height: auto; display: block; }
1202
+ .step-work .sw-crop img.dim { filter: brightness(0.42) saturate(0.6); }
1203
+ .step-work .sw-crop img.cut { mask-mode: luminance; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; filter: drop-shadow(0 0 3px rgba(255, 230, 170, 0.9)); }
1204
+ .step-work .sw-icon, .step-work .pair .to-come, .step-work .sw-none { width: 100%; aspect-ratio: 1; max-height: 180px; object-fit: contain; border-radius: 8px; background: var(--raised); }
1205
+ .step-work .sw-icon { animation: land 0.5s ease-out; cursor: zoom-in; }
1206
+ .step-work .pair .to-come { background: repeating-linear-gradient(135deg, var(--raised) 0 14px, transparent 14px 28px); animation: pulse 2.4s ease-in-out infinite; }
1207
+ .step-work .pair .to-come.still { animation: none; opacity: 0.6; }
1208
+ .step-work .sw-none { display: grid; place-items: center; color: var(--muted); font-size: 13px; text-align: center; padding: 8px; box-sizing: border-box; }
1209
+ .step-work .words { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
1210
+ .step-work .words strong { font-family: var(--display); font-weight: 400; font-size: 17px; }
1211
+ .step-work .words .detail { font-size: 12.5px; overflow-wrap: anywhere; }
1212
+ .step-work .sw-sounds { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
1213
+ .step-work .sw-sounds li { display: grid; grid-template-columns: 54px minmax(0, 1fr) minmax(0, 240px); gap: 10px; align-items: center; padding: 6px 10px; border-radius: 10px; background: var(--panel); }
1214
+ .step-work .sw-sounds .kind { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
1215
+ .step-work .sw-sounds .what { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
1216
+ .step-work .sw-sounds audio { width: 100%; height: 30px; }
1217
+ .step-work .sw-sounds li.fail .detail:last-child { color: var(--red, #b0412e); }
1218
+ /* History in its own drawer: one card per job, the newest on top. */
1219
+ .drawer.history { display: flex; flex-direction: column; }
1220
+ .drawer.history > .history-list, .drawer.history > .note { flex: 1; min-height: 0; overflow: auto; }
1221
+ .history-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
1222
+ .history-list li { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
1223
+ .convo header small.to-build { cursor: pointer; }
1224
+ .convo header small.to-build:hover { color: var(--text); text-decoration: underline; }
1225
+ /* The Studio's own "are you sure": a card over a dimmed page; typing the slug wakes a delete. */
1226
+ .sure-back { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 16px; background: rgba(28, 24, 20, 0.45); animation: enter-fade .12s ease-out; }
1227
+ .sure { width: min(460px, 100%); display: flex; flex-direction: column; gap: 12px; padding: 22px 22px 18px; border-radius: 16px; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 24px 60px rgba(40, 25, 10, 0.3); }
1228
+ .sure h2 { margin: 0; font-size: 20px; }
1229
+ .sure p { margin: 0; color: var(--muted); }
1230
+ .sure label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
1231
+ .sure code { color: var(--text); font-weight: 600; }
1232
+ .sure input { font-size: 15px; }
1233
+ /* Style in its own drawer: now beside a picture of it, presets as cards, wide words. */
1234
+ .drawer.style { width: min(760px, 94vw); display: flex; flex-direction: column; }
1235
+ .style-view { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; }
1236
+ .sv-now { display: flex; gap: 14px; align-items: flex-start; }
1237
+ .sv-now img { width: 220px; aspect-ratio: 1200 / 896; object-fit: cover; border-radius: 10px; cursor: zoom-in; flex: none; }
1238
+ .sv-now p { margin: 4px 0; }
1239
+ .sv-presets { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); gap: 10px; }
1240
+ .sv-card { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-height: 0; padding: 12px; text-align: left; border-radius: 12px; border: 1px solid var(--line); background: var(--raised); color: var(--text); white-space: normal; }
1241
+ .sv-card span { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
1242
+ .sv-card.on { border-color: var(--amber); box-shadow: inset 0 0 0 1px var(--amber); background: var(--panel); }
1243
+ .sv-words { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
1244
+ .sv-words textarea { width: 100%; font-size: 15px; color: var(--text); }
1245
+ .sv-est { margin: 0; padding: 10px 12px; border-radius: 10px; background: color-mix(in srgb, var(--amber) 14%, transparent); }
1246
+ @media (max-width: 600px) { .sv-now { flex-direction: column; } .sv-now img { width: 100%; } }
1247
+
1248
+ /* Line icons (icons.tsx) sit on the text's baseline and take its colour. */
1249
+ .icon { vertical-align: -3px; flex: none; }
1250
+ button > .icon, .detail > .icon { margin-right: 2px; }
1251
+ .a-sign .icon { vertical-align: middle; }
1252
+ .cast .who .sign .icon { vertical-align: 0; }
1253
+
1254
+ /* The 4 painted sides under a 3D model preview. */
1255
+ .fig-sides { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
1256
+ .fig-sides .row { gap: 8px; flex-wrap: wrap; }
1257
+ .fig-sides figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 2px; }
1258
+ .fig-sides img { width: 96px; height: 128px; object-fit: contain; background: var(--raised); border-radius: 8px; cursor: zoom-in; }
1259
+ .fig-sides figcaption { font-size: 12px; color: var(--muted, inherit); }
1260
+
1261
+ /* A contact sheet before production, kept inside the start conversation. */
1262
+ .idea-storyboard { margin-top: 28px; }
1263
+ .storyboard-pitch { margin: 0 0 8px; color: var(--muted); line-height: 1.5; }
1264
+ .concept-group { margin: 30px 0; }
1265
+ .concept-group h3 { font: italic 21px var(--display); color: var(--muted); margin: 0 0 14px; }
1266
+ .concept-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 18px; align-items: start; }
1267
+ .concept-grid.place { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1268
+ .concept-card { min-width: 0; padding: 9px 9px 14px; border-radius: 3px; background: #fffcf4; border: 1px solid #ded3bf; box-shadow: 0 2px 4px #59442808, 0 12px 24px -16px #59442840; overflow: hidden; animation: review-image-in .5s ease-out both; }
1269
+ .concept-picture { position: relative; aspect-ratio: 4 / 3; background: #eee5d6; display: grid; place-items: center; overflow: hidden; isolation: isolate; }
1270
+ .concept-picture > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
1271
+ .concept-placeholder { display: grid; justify-items: center; color: #81786c; font-size: 12px; }
1272
+ .concept-watermark { position: absolute; bottom: 10px; right: 10px; font-size: 10px; letter-spacing: .16em; padding: 4px 7px; border: 1px solid #fff9; border-radius: 2px; color: #66543b; background: #fff9e9cf; pointer-events: none; transform: rotate(-5deg); }
1273
+ .concept-loading { position: absolute; left: 8px; right: 8px; bottom: 9px; display: grid; justify-items: center; gap: 6px; padding: 10px; border-radius: 3px; background: #faf6eef2; font-size: 12px; box-shadow: 0 2px 8px #59442815; }
1274
+ .concept-caption { padding: 14px 14px 8px; display: grid; gap: 4px; }
1275
+ .concept-caption strong { font: 400 23px var(--display); line-height: 1.25; overflow-wrap: anywhere; }
1276
+ .concept-caption > span { color: #81786c; font-size: 12px; }
1277
+ .concept-card > button, .concept-error { margin: 4px 12px 0; }
1278
+ .concept-error details { padding: 8px 0; overflow-wrap: anywhere; }
1279
+ .concept-versions { display: flex; gap: 6px; padding: 4px 12px; overflow-x: auto; }
1280
+ .concept-versions button { padding: 0; width: 44px; height: 34px; flex: 0 0 44px; overflow: hidden; border-radius: 7px; border: 2px solid transparent; }
1281
+ .concept-versions button[aria-pressed=true] { border-color: #c47b25; }
1282
+ .concept-versions img { width: 100%; height: 100%; object-fit: contain; }
1283
+ .idea-review footer { gap: 10px; flex-wrap: wrap; }
1284
+ @media (max-width: 540px) {
1285
+ .concept-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
1286
+ .concept-grid.place { grid-template-columns: minmax(0, 1fr); }
1287
+ .concept-caption { padding: 10px; }
1288
+ .concept-caption strong { font-size: 19px; }
1289
+ .concept-card > button { font-size: 12px; padding: 8px 10px; margin-left: 8px; }
1290
+ .idea-review footer { justify-content: center; border-radius: 24px; gap: 4px; }
1291
+ .idea-review footer button { font-size: 14px; padding: 12px 16px; }
1292
+ }
1293
+
1294
+ /* A decision keeps its picture on the table; opening it reveals the original alternatives. */
1295
+ .idea-card[hidden] { display: none; }
1296
+ .idea-card-caption { display: grid; gap: 7px; }
1297
+ .idea-card.selected { border-color: var(--amber); }
1298
+ .idea-card-zoom { position: absolute; right: 8px; bottom: 8px; z-index: 1; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; background: #fff9e9e6; color: #66543b; box-shadow: 0 1px 4px #59442830; cursor: zoom-in; opacity: .82; transition: opacity .15s, transform .15s, background .15s; }
1299
+ .idea-card:hover .idea-card-zoom, .idea-card-zoom:focus-visible { opacity: 1; }
1300
+ .idea-card-zoom:hover { background: #fff; color: var(--ink); transform: scale(1.1); }
1301
+ .idea-card-zoom:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }
1302
+ .review-exchange.is-collapsed .idea-card-zoom { right: 4px; bottom: 4px; width: 24px; height: 24px; }
1303
+ .review-exchange.is-collapsed .idea-card-zoom .icon { width: 14px; height: 14px; }
1304
+ .idea-card-mark { position: absolute; right: 8px; top: 8px; width: 23px; height: 23px; display: grid; place-items: center; border-radius: 50%; background: var(--amber); color: #fff; font: 14px var(--body); box-shadow: 0 1px 4px #59442825; }
1305
+ .review-decision-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
1306
+ .review-decision-heading .review-says { margin: 0; }
1307
+ .review-decision-heading > button { flex: none; border-color: transparent; color: var(--muted); text-decoration: underline; text-underline-offset: 4px; }
1308
+ .review-exchange.is-collapsed .review-cards { display: block; padding: 10px 6px 8px; margin: 0; }
1309
+ .review-exchange.is-collapsed .idea-card { flex-direction: row; align-items: center; width: min(100%, 420px); padding: 7px; gap: 14px; text-align: left; animation: none; }
1310
+ .review-exchange.is-collapsed .idea-card-picture { width: 116px; flex: none; margin: 0; }
1311
+ .review-exchange.is-collapsed .idea-card-caption { min-width: 0; padding: 6px 8px 6px 0; }
1312
+ .review-exchange.is-collapsed .idea-card strong { font-size: 21px; padding: 0; }
1313
+ .review-exchange.is-editing { border-left-color: var(--amber); }
1314
+ .review-written-choice { border: 0; border-bottom: 1px dashed var(--line-strong); border-radius: 0; padding: 8px 0; font: italic 21px/1.4 var(--display); text-align: left; white-space: pre-wrap; overflow-wrap: anywhere; }
1315
+ @media (max-width: 520px) {
1316
+ .review-exchange.is-collapsed .idea-card-picture { width: 88px; }
1317
+ .review-exchange.is-collapsed .idea-card strong { font-size: 18px; }
1318
+ .review-decision-heading { align-items: center; }
1319
+ .review-decision-heading > button { padding-inline: 8px; }
1320
+ }
1321
+
1322
+
1323
+ /* The sketch table stays alive while two brushes work through the queue. */
1324
+ .concept-art { animation: concept-art-reveal .85s cubic-bezier(.2,.65,.25,1) both; }
1325
+ .concept-previous { pointer-events: none; }
1326
+ .concept-placeholder { width: 100%; height: 100%; box-sizing: border-box; padding: 8px; gap: 5px; grid-template-rows: minmax(0, 1fr) auto auto; align-items: center; text-align: center; }
1327
+ .concept-placeholder .review-sketch.compact { width: auto; height: 100%; max-width: 70%; max-height: 120px; }
1328
+ .concept-placeholder .review-sketch.compact svg { width: 100%; height: 100%; }
1329
+ .concept-brush-trail { position: relative; display: block; width: 64px; height: 3px; border-radius: 50%; background: #c18a3e24; overflow: hidden; }
1330
+ .concept-brush-trail::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: var(--amber); transform-origin: left; animation: concept-brush-stroke 2s ease-in-out infinite; }
1331
+ .is-queued .concept-brush-trail { opacity: .45; }
1332
+ .is-queued .concept-brush-trail::after { animation-duration: 3.5s; }
1333
+ .concept-paper-stack { position: relative; display: block; width: 80px; height: min(82px, 100%); margin: 0; }
1334
+ .concept-paper-stack i { position: absolute; inset: 8px 12px; border: 1px solid #d0c2a9; border-radius: 2px; background: #faf6ed; box-shadow: 0 5px 8px #5944280b; transform: rotate(-8deg); }
1335
+ .concept-paper-stack i:nth-child(2) { transform: translate(5px, -3px) rotate(8deg); }
1336
+ .concept-paper-stack i:last-child { transform: translate(0, -6px) rotate(-2deg); animation: concept-paper-breathe 3.5s ease-in-out infinite; }
1337
+ .concept-paper-stack i:last-child::after { content: ''; position: absolute; inset: 12px 10px; border-bottom: 1px solid #d7c8ae; border-top: 1px solid #d7c8ae; opacity: .5; }
1338
+ .concept-card { transition: box-shadow .25s ease, border-color .25s ease; }
1339
+ .concept-card:hover { border-color: #cdb488; box-shadow: 0 3px 8px #5944280b, 0 16px 28px -16px #59442850; }
1340
+ @keyframes concept-art-reveal { from { opacity: 0; clip-path: inset(0 0 100% 0); } to { opacity: 1; clip-path: inset(0); } }
1341
+ @keyframes concept-brush-stroke { 0% { transform: translateX(-100%) scaleX(.3); opacity: .25; } 45% { transform: translateX(0) scaleX(.85); opacity: .85; } 100% { transform: translateX(100%) scaleX(.4); opacity: .25; } }
1342
+ @keyframes concept-paper-breathe { 0%, 100% { transform: translate(0, -6px) rotate(-2deg); } 50% { transform: translate(0, -10px) rotate(1deg); } }
1343
+ .concept-zoom { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; cursor: zoom-in; }
1344
+ .concept-zoom:hover { background: transparent; }
1345
+ .concept-zoom > span { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%; background: #fff9e9df; color: #66543b; font-size: 21px; }
1346
+ .concept-zoom:focus-visible { outline: 2px solid var(--amber); outline-offset: -3px; }
1347
+ .concept-card > .concept-change { margin-left: 4px; }
1348
+ .concept-edit { margin: 14px 3px 0; padding: 14px 7px 0; border-top: 1px solid var(--line-strong); }
1349
+ .concept-edit label { display: grid; gap: 8px; font: italic 19px var(--display); }
1350
+ .concept-edit textarea { width: 100%; min-width: 0; resize: vertical; box-sizing: border-box; padding: 10px; border: 1px solid var(--line-strong); border-radius: 8px; background: #faf6ee; color: var(--ink); font: 14px/1.5 var(--body); }
1351
+ .concept-edit textarea:focus { outline: 2px solid #c47b2540; border-color: var(--amber); }
1352
+ .concept-edit > p { margin: 8px 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
1353
+ .concept-edit-tools { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
1354
+ .concept-edit-tools button { padding: 8px 10px; font-size: 12px; }
1355
+ .concept-reference { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
1356
+ .concept-reference img { display: block; width: 60px; height: 60px; object-fit: contain; }
1357
+ .concept-direction { margin: 2px 14px 10px; font: italic 14px/1.4 var(--display); color: var(--muted); overflow-wrap: anywhere; max-height: 6em; overflow: auto; }
1358
+ .concept-grid.character .concept-card.is-editing { grid-column: span 2; }
1359
+ .concept-card.is-editing .concept-picture { max-height: 300px; }
1360
+ @media (max-width: 540px) {
1361
+ .concept-placeholder { gap: 4px; font-size: 11px; }
1362
+ .concept-placeholder .review-sketch.compact { max-width: 100px; }
1363
+ .concept-paper-stack { width: 60px; height: 48px; margin: 4px 0; }
1364
+ }
1365
+
1366
+ .custom-look { margin: 20px 0; }
1367
+ .custom-look .concept-edit { margin: 0; }
1368
+ .custom-look > [role=status] { display: flex; align-items: center; gap: 10px; color: var(--muted); }
1369
+ .custom-look-preview { max-width: 480px; margin: 20px auto; text-align: center; }
1370
+ .custom-look-preview img { width: 100%; display: block; border-radius: 5px; }
1371
+ .custom-look-preview p { color: var(--muted); font-size: 14px; line-height: 1.5; }
1372
+
1373
+ .storyboard-expand { margin: 24px 0; }
1374
+ .storyboard-expand form { max-width: 600px; padding: 16px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
1375
+ .storyboard-expand label { display: grid; gap: 8px; font: italic 20px var(--display); }
1376
+ .storyboard-expand textarea { width: 100%; min-height: 76px; box-sizing: border-box; padding: 10px; border: 1px solid var(--line-strong); border-radius: 6px; background: #faf6ee; color: var(--ink); font: 14px/1.5 var(--body); }
1377
+
1378
+ /* The places strip above a place on stage and atop the Places drawer: the same chips as the build room. */
1379
+ .theatre > .build-places { margin-bottom: -2px; }
1380
+ .drawer.by-hand > .build-places { flex: none; overflow: visible; margin-bottom: 4px; }
1381
+ .cw-faces { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; overflow: auto; min-height: 0; }
1382
+ .cw-faces > li { display: flex; gap: 12px; align-items: flex-start; padding: 8px; border-radius: 10px; background: var(--raised); }
1383
+ .cw-faces > li > img { width: 72px; height: 96px; object-fit: contain; flex: none; }
1384
+ .cw-faces > li.fail .detail { color: var(--warn, #b5651d); }
1385
+ .mouths .sheets { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; padding: 0; margin: 4px 0 0; }
1386
+ .mouths .sheets li { display: flex; flex-direction: column; align-items: center; gap: 2px; }
1387
+ .mouths canvas { border-radius: 6px; background: var(--paper, #fff); max-width: 120px; }
1388
+
1389
+ .pipeline .head .calls-kicker { font-size: 12px; cursor: help; }
1390
+ .pipeline .head .count .of { color: var(--faint, var(--muted)); font-size: 0.85em; }