castle-web-cli 0.4.1 → 0.4.2

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 (158) hide show
  1. package/dist/api.d.ts +53 -5
  2. package/dist/api.js +42 -15
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.js +25 -11
  5. package/dist/get-deck.d.ts +3 -0
  6. package/dist/get-deck.js +64 -0
  7. package/dist/ide-client.d.ts +1 -0
  8. package/dist/ide-client.js +537 -0
  9. package/dist/ide.d.ts +16 -0
  10. package/dist/ide.js +546 -0
  11. package/dist/index.js +36 -41
  12. package/dist/init.d.ts +3 -1
  13. package/dist/init.js +170 -24
  14. package/dist/localPaths.d.ts +6 -0
  15. package/dist/localPaths.js +33 -0
  16. package/dist/login.js +1 -1
  17. package/dist/preview.d.ts +3 -0
  18. package/dist/preview.js +53 -34
  19. package/dist/save-deck.d.ts +2 -0
  20. package/dist/{push.js → save-deck.js} +66 -5
  21. package/dist/serve.d.ts +2 -0
  22. package/dist/serve.js +290 -27
  23. package/kits/basic-2d/.prettierrc +8 -0
  24. package/kits/basic-2d/CLAUDE.md +131 -0
  25. package/kits/basic-2d/behaviors/Camera.jsx +43 -0
  26. package/kits/basic-2d/behaviors/Collider.jsx +71 -0
  27. package/kits/basic-2d/behaviors/Drawing.jsx +139 -0
  28. package/kits/basic-2d/behaviors/Layout.jsx +16 -0
  29. package/kits/basic-2d/drawings/floor.drawing +70 -0
  30. package/kits/basic-2d/editors/App.jsx +152 -0
  31. package/kits/basic-2d/editors/CodeEditor.jsx +112 -0
  32. package/kits/basic-2d/editors/DrawingEditor.jsx +222 -0
  33. package/kits/basic-2d/editors/FileBrowser.jsx +143 -0
  34. package/kits/basic-2d/editors/PlayOnly.jsx +21 -0
  35. package/kits/basic-2d/editors/SceneEditor.jsx +1012 -0
  36. package/kits/basic-2d/editors/behaviorRegistry.js +24 -0
  37. package/kits/basic-2d/editors/editorHistory.js +52 -0
  38. package/kits/basic-2d/engine/ScenePlayer.jsx +83 -0
  39. package/kits/basic-2d/engine/SceneUI.jsx +67 -0
  40. package/kits/basic-2d/engine/TouchControls.jsx +136 -0
  41. package/kits/basic-2d/engine/autoInspector.jsx +51 -0
  42. package/kits/basic-2d/engine/files.js +62 -0
  43. package/kits/basic-2d/engine/scene.js +420 -0
  44. package/kits/basic-2d/engine/ui.jsx +344 -0
  45. package/kits/basic-2d/engine/ui.module.css +928 -0
  46. package/kits/basic-2d/eslint.config.js +50 -0
  47. package/kits/basic-2d/index.html +11 -0
  48. package/kits/basic-2d/main.jsx +10 -0
  49. package/kits/basic-2d/package-lock.json +2706 -0
  50. package/kits/basic-2d/package.json +41 -0
  51. package/kits/basic-2d/scenes/main.scene +108 -0
  52. package/kits/basic-2d/vite.config.js +1 -0
  53. package/kits/basic-2d-frozen/.prettierrc +8 -0
  54. package/kits/basic-2d-frozen/CLAUDE.md +131 -0
  55. package/kits/basic-2d-frozen/behaviors/Camera.jsx +43 -0
  56. package/kits/basic-2d-frozen/behaviors/Collider.jsx +71 -0
  57. package/kits/basic-2d-frozen/behaviors/Drawing.jsx +139 -0
  58. package/kits/basic-2d-frozen/behaviors/Layout.jsx +16 -0
  59. package/kits/basic-2d-frozen/drawings/floor.drawing +70 -0
  60. package/kits/basic-2d-frozen/editors/App.jsx +152 -0
  61. package/kits/basic-2d-frozen/editors/CodeEditor.jsx +112 -0
  62. package/kits/basic-2d-frozen/editors/DrawingEditor.jsx +222 -0
  63. package/kits/basic-2d-frozen/editors/FileBrowser.jsx +143 -0
  64. package/kits/basic-2d-frozen/editors/PlayOnly.jsx +21 -0
  65. package/kits/basic-2d-frozen/editors/SceneEditor.jsx +1012 -0
  66. package/kits/basic-2d-frozen/editors/behaviorRegistry.js +24 -0
  67. package/kits/basic-2d-frozen/editors/editorHistory.js +52 -0
  68. package/kits/basic-2d-frozen/engine/ScenePlayer.jsx +83 -0
  69. package/kits/basic-2d-frozen/engine/SceneUI.jsx +67 -0
  70. package/kits/basic-2d-frozen/engine/TouchControls.jsx +136 -0
  71. package/kits/basic-2d-frozen/engine/autoInspector.jsx +51 -0
  72. package/kits/basic-2d-frozen/engine/files.js +62 -0
  73. package/kits/basic-2d-frozen/engine/scene.js +420 -0
  74. package/kits/basic-2d-frozen/engine/ui.jsx +344 -0
  75. package/kits/basic-2d-frozen/engine/ui.module.css +928 -0
  76. package/kits/basic-2d-frozen/eslint.config.js +50 -0
  77. package/kits/basic-2d-frozen/index.html +11 -0
  78. package/kits/basic-2d-frozen/main.jsx +10 -0
  79. package/kits/basic-2d-frozen/package-lock.json +2706 -0
  80. package/kits/basic-2d-frozen/package.json +41 -0
  81. package/kits/basic-2d-frozen/scenes/main.scene +108 -0
  82. package/kits/basic-2d-frozen/vite.config.js +1 -0
  83. package/kits/rpg-2d/.prettierrc +8 -0
  84. package/kits/rpg-2d/behaviors/Camera.tsx +52 -0
  85. package/kits/rpg-2d/behaviors/Collider.tsx +98 -0
  86. package/kits/rpg-2d/behaviors/Dialog.tsx +184 -0
  87. package/kits/rpg-2d/behaviors/Drawing.tsx +161 -0
  88. package/kits/rpg-2d/behaviors/Friend.tsx +45 -0
  89. package/kits/rpg-2d/behaviors/Layout.tsx +29 -0
  90. package/kits/rpg-2d/behaviors/PlayerController.tsx +255 -0
  91. package/kits/rpg-2d/behaviors/Portal.tsx +60 -0
  92. package/kits/rpg-2d/behaviors/QuestLog.tsx +90 -0
  93. package/kits/rpg-2d/behaviors/SaveMenu.tsx +123 -0
  94. package/kits/rpg-2d/behaviors/Tilemap.tsx +90 -0
  95. package/kits/rpg-2d/drawings/bld-home.drawing +8136 -0
  96. package/kits/rpg-2d/drawings/env-crate.drawing +509 -0
  97. package/kits/rpg-2d/drawings/env-fence.drawing +536 -0
  98. package/kits/rpg-2d/drawings/env-flower-bed.drawing +607 -0
  99. package/kits/rpg-2d/drawings/env-fountain.drawing +2622 -0
  100. package/kits/rpg-2d/drawings/env-hedge.drawing +601 -0
  101. package/kits/rpg-2d/drawings/env-house-blue.drawing +1 -0
  102. package/kits/rpg-2d/drawings/env-house-green.drawing +1 -0
  103. package/kits/rpg-2d/drawings/env-tree-oak.drawing +1540 -0
  104. package/kits/rpg-2d/drawings/env-tree-pine.drawing +1315 -0
  105. package/kits/rpg-2d/drawings/floor.drawing +70 -0
  106. package/kits/rpg-2d/drawings/fx-sparkle.drawing +926 -0
  107. package/kits/rpg-2d/drawings/npc-juno-idle-down.drawing +1099 -0
  108. package/kits/rpg-2d/drawings/npc-juno-walk-down.drawing +4177 -0
  109. package/kits/rpg-2d/drawings/npc-opal-idle-down.drawing +1099 -0
  110. package/kits/rpg-2d/drawings/npc-opal-walk-down.drawing +4177 -0
  111. package/kits/rpg-2d/drawings/player-idle-down.drawing +1070 -0
  112. package/kits/rpg-2d/drawings/player-idle-left.drawing +1070 -0
  113. package/kits/rpg-2d/drawings/player-idle-right.drawing +1070 -0
  114. package/kits/rpg-2d/drawings/player-idle-up.drawing +1070 -0
  115. package/kits/rpg-2d/drawings/player-walk-down.drawing +4148 -0
  116. package/kits/rpg-2d/drawings/player-walk-left.drawing +4148 -0
  117. package/kits/rpg-2d/drawings/player-walk-right.drawing +4148 -0
  118. package/kits/rpg-2d/drawings/player-walk-up.drawing +4148 -0
  119. package/kits/rpg-2d/editors/App.tsx +163 -0
  120. package/kits/rpg-2d/editors/CodeEditor.tsx +120 -0
  121. package/kits/rpg-2d/editors/DrawingEditor.tsx +278 -0
  122. package/kits/rpg-2d/editors/FileBrowser.tsx +191 -0
  123. package/kits/rpg-2d/editors/PlayOnly.tsx +26 -0
  124. package/kits/rpg-2d/editors/SceneEditor.tsx +1093 -0
  125. package/kits/rpg-2d/editors/behaviorRegistry.ts +33 -0
  126. package/kits/rpg-2d/editors/editorHistory.ts +75 -0
  127. package/kits/rpg-2d/editors/editorProps.ts +10 -0
  128. package/kits/rpg-2d/engine/ScenePlayer.tsx +130 -0
  129. package/kits/rpg-2d/engine/SceneUI.tsx +74 -0
  130. package/kits/rpg-2d/engine/TouchControls.tsx +157 -0
  131. package/kits/rpg-2d/engine/autoInspector.tsx +111 -0
  132. package/kits/rpg-2d/engine/drawing.ts +81 -0
  133. package/kits/rpg-2d/engine/files.ts +215 -0
  134. package/kits/rpg-2d/engine/scene.ts +484 -0
  135. package/kits/rpg-2d/engine/ui.module.css +928 -0
  136. package/kits/rpg-2d/engine/ui.tsx +483 -0
  137. package/kits/rpg-2d/eslint.config.js +46 -0
  138. package/kits/rpg-2d/index.html +11 -0
  139. package/kits/rpg-2d/main.tsx +14 -0
  140. package/kits/rpg-2d/package-lock.json +3149 -0
  141. package/kits/rpg-2d/package.json +46 -0
  142. package/kits/rpg-2d/scenes/main.scene +203 -0
  143. package/kits/rpg-2d/tsconfig.json +17 -0
  144. package/kits/rpg-2d/vite-env.d.ts +7 -0
  145. package/kits/rpg-2d/vite.config.js +1 -0
  146. package/package.json +27 -5
  147. package/AGENTS.md +0 -25
  148. package/dist/push.d.ts +0 -1
  149. package/src/api.ts +0 -160
  150. package/src/bundle.ts +0 -28
  151. package/src/config.ts +0 -36
  152. package/src/index.ts +0 -143
  153. package/src/init.ts +0 -71
  154. package/src/login.ts +0 -24
  155. package/src/preview.ts +0 -94
  156. package/src/push.ts +0 -118
  157. package/src/serve.ts +0 -134
  158. package/tsconfig.json +0 -13
@@ -0,0 +1,928 @@
1
+ @font-face {
2
+ font-family: 'Basteleur';
3
+ src:
4
+ url('/Basteleur-Bold.woff2') format('woff2'),
5
+ url('/Basteleur-Bold.woff') format('woff');
6
+ }
7
+
8
+ :global(:root) {
9
+ --castle-font-body:
10
+ baltomobile, Balto, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
11
+ sans-serif;
12
+ --castle-font-display: var(--castle-font-body);
13
+ --castle-font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
14
+ --castle-black: #000;
15
+ --castle-tap-highlight: #111;
16
+ --castle-panel: #080808;
17
+ --castle-panel-raised: #101010;
18
+ --castle-panel-sunken: #050505;
19
+ --castle-border: #444;
20
+ --castle-border-soft: #252525;
21
+ --castle-text: #fff;
22
+ --castle-text-dim: #777;
23
+ --castle-text-muted: #aaa;
24
+ --castle-inspector-bg: #fff;
25
+ --castle-inspector-text: #222;
26
+ --castle-inspector-muted: #888;
27
+ --castle-inspector-border: #000;
28
+ --castle-inspector-divider: #ccc;
29
+ --castle-inspector-input-bg: #fff;
30
+ --castle-inspector-button-bg: #fff;
31
+ --castle-workspace-bg: #f0f0f0;
32
+ --castle-stage-workspace-bg: #ddd;
33
+ --castle-sheet-bg: #fff;
34
+ --castle-card: #121213;
35
+ --castle-selected: #e3e6ff;
36
+ --castle-selected-ink: #242234;
37
+ --castle-danger: #ff5d5d;
38
+ --castle-ok: #81e69b;
39
+ --castle-blue: #8db7ff;
40
+ --castle-radius: 4px;
41
+ }
42
+
43
+ :global(*) {
44
+ box-sizing: border-box;
45
+ }
46
+
47
+ :global(html),
48
+ :global(body),
49
+ :global(#root) {
50
+ width: 100%;
51
+ height: 100%;
52
+ margin: 0;
53
+ }
54
+
55
+ :global(body) {
56
+ overflow: hidden;
57
+ background: var(--castle-workspace-bg);
58
+ color: var(--castle-inspector-text);
59
+ font-family: var(--castle-font-body);
60
+ -webkit-font-smoothing: antialiased;
61
+ }
62
+
63
+ :global(button),
64
+ :global(input),
65
+ :global(select),
66
+ :global(textarea) {
67
+ font: inherit;
68
+ }
69
+
70
+ :global(button),
71
+ :global(input),
72
+ :global(select),
73
+ :global(textarea),
74
+ :global([tabindex]) {
75
+ outline: none;
76
+ }
77
+
78
+ :global(*:focus),
79
+ :global(*:focus-visible) {
80
+ outline: none;
81
+ }
82
+
83
+ .appShell {
84
+ width: 100vw;
85
+ height: 100vh;
86
+ display: grid;
87
+ grid-template-columns: 236px 1fr;
88
+ background: var(--castle-workspace-bg);
89
+ color: var(--castle-inspector-text);
90
+ }
91
+
92
+ .fileBrowser {
93
+ min-width: 0;
94
+ border-right: 1px solid var(--castle-inspector-divider);
95
+ background: var(--castle-workspace-bg);
96
+ display: flex;
97
+ flex-direction: column;
98
+ }
99
+
100
+ .fileBrowserHeader,
101
+ .editorHeader {
102
+ height: 48px;
103
+ flex: 0 0 48px;
104
+ display: flex;
105
+ align-items: center;
106
+ gap: 8px;
107
+ padding: 10px 12px;
108
+ border-bottom: 1px solid var(--castle-inspector-divider);
109
+ background: var(--castle-sheet-bg);
110
+ }
111
+
112
+ .fileBrowserTitle,
113
+ .editorTitle {
114
+ font-family: var(--castle-font-display);
115
+ letter-spacing: 0.01em;
116
+ font-size: 16px;
117
+ line-height: 1;
118
+ }
119
+
120
+ .fileBrowserSubtitle,
121
+ .muted {
122
+ color: var(--castle-inspector-muted);
123
+ font-size: 12px;
124
+ }
125
+
126
+ .fileTree {
127
+ flex: 1 1 0;
128
+ min-height: 0;
129
+ padding: 8px 6px;
130
+ overflow-y: auto;
131
+ }
132
+
133
+ .fileBranch {
134
+ min-width: 0;
135
+ }
136
+
137
+ .fileRow,
138
+ .fileDirRow {
139
+ width: 100%;
140
+ border: 0;
141
+ border-radius: var(--castle-radius);
142
+ background: transparent;
143
+ color: var(--castle-inspector-text);
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: flex-start;
147
+ gap: 6px;
148
+ padding: 8px 9px 8px calc(9px + var(--file-depth, 0) * 16px);
149
+ text-align: left;
150
+ cursor: pointer;
151
+ }
152
+
153
+ .fileDirRow {
154
+ color: var(--castle-inspector-muted);
155
+ }
156
+
157
+ .fileRow:hover,
158
+ .fileDirRow:hover {
159
+ background: var(--castle-sheet-bg);
160
+ color: var(--castle-inspector-text);
161
+ }
162
+
163
+ .fileRowSelected {
164
+ background: var(--castle-sheet-bg);
165
+ color: var(--castle-inspector-text);
166
+ }
167
+
168
+ .fileRowSelected:hover {
169
+ background: var(--castle-sheet-bg);
170
+ color: var(--castle-inspector-text);
171
+ }
172
+
173
+ .fileDisclosure {
174
+ width: 12px;
175
+ flex: 0 0 12px;
176
+ display: inline-flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+ color: var(--castle-inspector-muted);
180
+ font-size: 10px;
181
+ }
182
+
183
+ .mainEditor {
184
+ min-width: 0;
185
+ min-height: 0;
186
+ display: flex;
187
+ flex-direction: column;
188
+ background: var(--castle-sheet-bg);
189
+ }
190
+
191
+ .editorHeader {
192
+ justify-content: space-between;
193
+ }
194
+
195
+ .editorHeaderLeft,
196
+ .editorHeaderRight,
197
+ .toolbar {
198
+ display: flex;
199
+ align-items: center;
200
+ gap: 8px;
201
+ min-width: 0;
202
+ }
203
+
204
+ .editorBody {
205
+ min-height: 0;
206
+ flex: 1;
207
+ display: flex;
208
+ overflow: hidden;
209
+ }
210
+
211
+ .sceneWorkspace {
212
+ flex: 1;
213
+ min-width: 0;
214
+ min-height: 0;
215
+ display: grid;
216
+ grid-template-columns: minmax(360px, 1fr) 320px;
217
+ grid-template-rows: 48px minmax(0, 1fr);
218
+ }
219
+
220
+ .sceneTools,
221
+ .drawingTools {
222
+ grid-column: 1;
223
+ grid-row: 1;
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: center;
227
+ gap: 8px;
228
+ padding: 8px 12px;
229
+ border-bottom: 1px solid var(--castle-inspector-divider);
230
+ background: var(--castle-sheet-bg);
231
+ }
232
+
233
+ .sceneTools {
234
+ display: grid;
235
+ grid-template-columns: 1fr auto 1fr;
236
+ gap: 8px;
237
+ }
238
+
239
+ .sceneToolsGroup {
240
+ display: flex;
241
+ align-items: center;
242
+ gap: 8px;
243
+ }
244
+
245
+ .sceneToolsGroup:last-child {
246
+ justify-self: end;
247
+ }
248
+
249
+ .stageWrap {
250
+ grid-column: 1;
251
+ grid-row: 2;
252
+ min-width: 0;
253
+ min-height: 0;
254
+ display: flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ padding: 20px;
258
+ background: var(--castle-stage-workspace-bg);
259
+ }
260
+
261
+ .stageCard {
262
+ position: relative;
263
+ width: min(52vh, 440px);
264
+ aspect-ratio: 5 / 7;
265
+ max-width: calc(100vw - 620px);
266
+ background: var(--castle-card);
267
+ border: 1px solid var(--castle-inspector-border);
268
+ border-radius: 12px;
269
+ overflow: hidden;
270
+ box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
271
+ }
272
+
273
+ .stageCanvas {
274
+ width: 100%;
275
+ height: 100%;
276
+ display: block;
277
+ touch-action: none;
278
+ }
279
+
280
+ /* Game-time UI overlay -- sits exactly over the canvas and clips to the card.
281
+ Behavior `ui` output lands in `.sceneUiLayer`, which is sized in card units
282
+ and scaled onto the canvas box. */
283
+ .sceneUiRoot {
284
+ position: absolute;
285
+ inset: 0;
286
+ overflow: hidden;
287
+ pointer-events: none;
288
+ }
289
+
290
+ .sceneUiLayer {
291
+ position: absolute;
292
+ left: 0;
293
+ top: 0;
294
+ transform-origin: 0 0;
295
+ }
296
+
297
+ .inspector {
298
+ grid-column: 2;
299
+ grid-row: 1 / span 2;
300
+ min-width: 0;
301
+ border-left: 1px solid var(--castle-inspector-divider);
302
+ background: var(--castle-inspector-bg);
303
+ color: var(--castle-inspector-text);
304
+ overflow: auto;
305
+ padding: 0;
306
+ }
307
+
308
+ .panel {
309
+ border: 0;
310
+ border-bottom: 1px solid var(--castle-inspector-divider);
311
+ border-radius: 0;
312
+ background: var(--castle-inspector-bg);
313
+ color: var(--castle-inspector-text);
314
+ margin: 0;
315
+ overflow: visible;
316
+ box-shadow: none;
317
+ }
318
+
319
+ .panel:last-child {
320
+ border-bottom: 0;
321
+ }
322
+
323
+ .panelHeader {
324
+ padding: 14px 16px 6px;
325
+ border-bottom: 0;
326
+ color: var(--castle-inspector-text);
327
+ font-size: 16px;
328
+ font-weight: 650;
329
+ }
330
+
331
+ .panelBody {
332
+ padding: 8px 16px 4px;
333
+ }
334
+
335
+ .fieldRow {
336
+ display: grid;
337
+ grid-template-columns: minmax(82px, 0.5fr) minmax(0, 1fr);
338
+ align-items: center;
339
+ gap: 12px;
340
+ padding-bottom: 12px;
341
+ margin-bottom: 0;
342
+ min-height: 28px;
343
+ }
344
+
345
+ .fieldRow:last-child {
346
+ margin-bottom: 0;
347
+ }
348
+
349
+ .fieldLabel {
350
+ color: var(--castle-inspector-text);
351
+ font-size: 16px;
352
+ }
353
+
354
+ .input,
355
+ .select,
356
+ .textarea {
357
+ width: 100%;
358
+ border: 1px solid var(--castle-inspector-border);
359
+ border-radius: var(--castle-radius);
360
+ background: var(--castle-inspector-input-bg);
361
+ color: var(--castle-inspector-text);
362
+ padding: 5px 8px;
363
+ outline: 0;
364
+ }
365
+
366
+ .select {
367
+ appearance: none;
368
+ -webkit-appearance: none;
369
+ padding-right: 26px;
370
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%23222' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
371
+ background-repeat: no-repeat;
372
+ background-position: right 8px center;
373
+ text-overflow: ellipsis;
374
+ }
375
+
376
+ .numberField {
377
+ position: relative;
378
+ width: 100%;
379
+ }
380
+
381
+ .numberInput {
382
+ padding-right: 22px;
383
+ appearance: textfield;
384
+ -moz-appearance: textfield;
385
+ }
386
+
387
+ .numberInput::-webkit-inner-spin-button,
388
+ .numberInput::-webkit-outer-spin-button {
389
+ -webkit-appearance: none;
390
+ appearance: none;
391
+ margin: 0;
392
+ }
393
+
394
+ .numberSteppers {
395
+ position: absolute;
396
+ top: 1px;
397
+ right: 1px;
398
+ bottom: 1px;
399
+ width: 18px;
400
+ display: flex;
401
+ flex-direction: column;
402
+ border-left: 1px solid var(--castle-inspector-divider);
403
+ opacity: 0;
404
+ pointer-events: none;
405
+ transition: opacity 0.1s;
406
+ }
407
+
408
+ .numberField:hover .numberSteppers,
409
+ .numberField:focus-within .numberSteppers {
410
+ opacity: 1;
411
+ pointer-events: auto;
412
+ }
413
+
414
+ .numberStepper {
415
+ flex: 1;
416
+ display: flex;
417
+ align-items: center;
418
+ justify-content: center;
419
+ border: 0;
420
+ padding: 0;
421
+ background: transparent;
422
+ color: var(--castle-inspector-muted);
423
+ cursor: pointer;
424
+ font-size: 8px;
425
+ line-height: 1;
426
+ }
427
+
428
+ .numberStepper:first-child {
429
+ border-bottom: 1px solid var(--castle-inspector-divider);
430
+ }
431
+
432
+ .numberStepper:hover {
433
+ background: #eee;
434
+ color: var(--castle-inspector-text);
435
+ }
436
+
437
+ .numberStepper:disabled {
438
+ opacity: 0.3;
439
+ cursor: default;
440
+ background: transparent;
441
+ }
442
+
443
+ .colorInput {
444
+ width: 100%;
445
+ height: 28px;
446
+ border: 1px solid var(--castle-inspector-border);
447
+ border-radius: var(--castle-radius);
448
+ background: var(--castle-inspector-input-bg);
449
+ padding: 2px;
450
+ outline: 0;
451
+ cursor: pointer;
452
+ }
453
+
454
+ .toggle {
455
+ width: 44px;
456
+ height: 24px;
457
+ border: 1px solid var(--castle-inspector-border);
458
+ border-radius: 999px;
459
+ background: #fff;
460
+ padding: 2px;
461
+ cursor: pointer;
462
+ display: flex;
463
+ align-items: center;
464
+ justify-content: flex-start;
465
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
466
+ }
467
+
468
+ .toggleOn {
469
+ background: var(--castle-black);
470
+ justify-content: flex-end;
471
+ }
472
+
473
+ .toggleKnob {
474
+ width: 18px;
475
+ height: 18px;
476
+ border-radius: 999px;
477
+ background: var(--castle-black);
478
+ }
479
+
480
+ .toggleOn .toggleKnob {
481
+ background: var(--castle-text);
482
+ }
483
+
484
+ .textarea {
485
+ min-height: 0;
486
+ resize: none;
487
+ font-family: var(--castle-font-mono);
488
+ font-size: 12px;
489
+ line-height: 1.45;
490
+ }
491
+
492
+ .button {
493
+ border: 1px solid var(--castle-inspector-border);
494
+ border-radius: var(--castle-radius);
495
+ background: var(--castle-inspector-button-bg);
496
+ color: var(--castle-inspector-text);
497
+ padding: 6px 10px;
498
+ cursor: pointer;
499
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
500
+ }
501
+
502
+ .iconButton {
503
+ width: 34px;
504
+ height: 34px;
505
+ padding: 0;
506
+ display: inline-flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ }
510
+
511
+ .iconButton svg {
512
+ width: 1em;
513
+ height: 1em;
514
+ }
515
+
516
+ .button:hover {
517
+ background: #eee;
518
+ }
519
+
520
+ .buttonPrimary,
521
+ .buttonActive {
522
+ background: var(--castle-black);
523
+ border-color: var(--castle-black);
524
+ color: var(--castle-text);
525
+ }
526
+
527
+ .buttonPrimary:hover,
528
+ .buttonActive:hover {
529
+ background: var(--castle-black);
530
+ border-color: var(--castle-black);
531
+ color: var(--castle-text);
532
+ }
533
+
534
+ .buttonDanger {
535
+ color: var(--castle-danger);
536
+ }
537
+
538
+ .button:disabled {
539
+ opacity: 0.35;
540
+ cursor: default;
541
+ }
542
+
543
+ .actorList {
544
+ display: grid;
545
+ gap: 4px;
546
+ }
547
+
548
+ .actorRow {
549
+ width: 100%;
550
+ border: 1px solid transparent;
551
+ background: transparent;
552
+ color: var(--castle-inspector-text);
553
+ border-radius: var(--castle-radius);
554
+ padding: 7px 8px;
555
+ text-align: left;
556
+ cursor: pointer;
557
+ }
558
+
559
+ .actorRowSelected {
560
+ background: var(--castle-black);
561
+ border-color: var(--castle-black);
562
+ color: var(--castle-text);
563
+ }
564
+
565
+ .drawingEditor,
566
+ .codeEditor {
567
+ flex: 1;
568
+ min-width: 0;
569
+ min-height: 0;
570
+ display: grid;
571
+ grid-template-columns: minmax(320px, 1fr) 280px;
572
+ background: var(--castle-workspace-bg);
573
+ }
574
+
575
+ .drawingEditor {
576
+ grid-template-rows: 48px minmax(0, 1fr);
577
+ }
578
+
579
+ .drawingCanvasWrap {
580
+ grid-column: 1;
581
+ grid-row: 2;
582
+ display: flex;
583
+ align-items: center;
584
+ justify-content: center;
585
+ padding: 24px;
586
+ min-width: 0;
587
+ min-height: 0;
588
+ }
589
+
590
+ .drawingCanvas {
591
+ image-rendering: pixelated;
592
+ background:
593
+ linear-gradient(45deg, #ddd 25%, transparent 25%),
594
+ linear-gradient(-45deg, #ddd 25%, transparent 25%),
595
+ linear-gradient(45deg, transparent 75%, #ddd 75%),
596
+ linear-gradient(-45deg, transparent 75%, #ddd 75%);
597
+ background-size: 16px 16px;
598
+ background-position:
599
+ 0 0,
600
+ 0 8px,
601
+ 8px -8px,
602
+ -8px 0;
603
+ border: 1px solid var(--castle-inspector-border);
604
+ max-width: min(70vh, 520px);
605
+ max-height: min(70vh, 520px);
606
+ }
607
+
608
+ .palette {
609
+ display: grid;
610
+ grid-template-columns: repeat(6, 1fr);
611
+ gap: 6px;
612
+ padding-bottom: 12px;
613
+ }
614
+
615
+ .swatch {
616
+ aspect-ratio: 1;
617
+ border: 1px solid var(--castle-inspector-border);
618
+ border-radius: var(--castle-radius);
619
+ cursor: pointer;
620
+ }
621
+
622
+ .swatchSelected {
623
+ outline: 2px solid var(--castle-black);
624
+ outline-offset: 1px;
625
+ }
626
+
627
+ .codeEditor {
628
+ grid-template-columns: 1fr;
629
+ }
630
+
631
+ .codeMirrorHost {
632
+ min-width: 0;
633
+ min-height: 0;
634
+ height: 100%;
635
+ }
636
+
637
+ .headerFilesButton {
638
+ width: 34px;
639
+ height: 34px;
640
+ border: 1px solid var(--castle-inspector-border);
641
+ border-radius: var(--castle-radius);
642
+ background: var(--castle-inspector-button-bg);
643
+ color: var(--castle-inspector-text);
644
+ cursor: pointer;
645
+ align-items: center;
646
+ justify-content: center;
647
+ flex: 0 0 34px;
648
+ }
649
+
650
+ .headerFilesButton[aria-pressed='true'] {
651
+ background: var(--castle-black);
652
+ border-color: var(--castle-black);
653
+ color: var(--castle-text);
654
+ }
655
+
656
+ /* mobileOnly comes AFTER element-specific rules so `display: none` wins on desktop. */
657
+ .mobileOnly,
658
+ .headerFilesButton,
659
+ .sheetBackdrop,
660
+ .sheetGrab,
661
+ .sheetGrabBar,
662
+ .sheetGrabLabelRow,
663
+ .sheetGrabLabel,
664
+ .sheetGrabHint {
665
+ display: none;
666
+ }
667
+
668
+ @media (max-width: 860px) {
669
+ :root {
670
+ --sheet-high-height: 62vh;
671
+ --sheet-low-height: 18vh;
672
+ }
673
+
674
+ /* `display: contents` makes wrapper spans transparent in layout so their
675
+ children become direct flex items of the parent (gap applies, etc). */
676
+ .mobileOnly {
677
+ display: contents;
678
+ }
679
+
680
+ .headerFilesButton {
681
+ display: inline-flex;
682
+ }
683
+
684
+ /* Backdrop sits below the header so the files toggle stays interactive. */
685
+ .sheetBackdrop {
686
+ display: block;
687
+ position: fixed;
688
+ top: 52px;
689
+ left: 0;
690
+ right: 0;
691
+ bottom: 0;
692
+ z-index: 30;
693
+ background: transparent;
694
+ }
695
+
696
+ .appShell {
697
+ grid-template-columns: 1fr;
698
+ grid-template-rows: 1fr;
699
+ position: relative;
700
+ }
701
+
702
+ .mainEditor {
703
+ grid-column: 1;
704
+ grid-row: 1;
705
+ min-height: 0;
706
+ }
707
+
708
+ /* Header: title (left, compact) + centered icon group (right slot includes files button). */
709
+ .editorHeader {
710
+ height: 52px;
711
+ flex: 0 0 52px;
712
+ padding: 8px 10px;
713
+ gap: 8px;
714
+ justify-content: space-between;
715
+ }
716
+
717
+ .editorHeaderLeft {
718
+ flex: 1;
719
+ min-width: 0;
720
+ }
721
+
722
+ .editorHeaderRight {
723
+ flex: 0 0 auto;
724
+ justify-content: flex-end;
725
+ gap: 14px;
726
+ }
727
+
728
+ .editorTitle {
729
+ font-size: 15px;
730
+ overflow: hidden;
731
+ text-overflow: ellipsis;
732
+ white-space: nowrap;
733
+ }
734
+
735
+ .muted {
736
+ overflow: hidden;
737
+ text-overflow: ellipsis;
738
+ white-space: nowrap;
739
+ }
740
+
741
+ /* Hide the desktop tools row on mobile -- buttons live in the header instead. */
742
+ .sceneTools,
743
+ .drawingTools {
744
+ display: none;
745
+ }
746
+
747
+ .sceneWorkspace {
748
+ grid-template-columns: 1fr;
749
+ grid-template-rows: minmax(0, 1fr);
750
+ }
751
+
752
+ .drawingEditor {
753
+ grid-template-columns: 1fr;
754
+ grid-template-rows: minmax(0, 1fr);
755
+ }
756
+
757
+ .stageWrap {
758
+ grid-column: 1;
759
+ grid-row: 1;
760
+ align-items: flex-start;
761
+ padding: 10px 12px 12px;
762
+ background: var(--castle-stage-workspace-bg);
763
+ }
764
+
765
+ .stageCard {
766
+ max-width: min(92vw, 480px);
767
+ max-height: 100%;
768
+ width: auto;
769
+ }
770
+
771
+ /* Drawing centers higher in the canvas region -- around the 1/3-from-top mark. */
772
+ .drawingCanvasWrap {
773
+ grid-column: 1;
774
+ grid-row: 1;
775
+ align-items: flex-start;
776
+ padding: 6vh 16px 16px;
777
+ }
778
+
779
+ .drawingCanvas {
780
+ max-width: min(82vw, 480px);
781
+ max-height: min(54vh, 480px);
782
+ }
783
+
784
+ /* File-browser + inspector sheets share fixed-bottom positioning, height,
785
+ transform/transition, and chrome. Per-sheet differences (z-index, side
786
+ border, background, padding) follow in dedicated rules below. */
787
+ .fileBrowser,
788
+ .inspector {
789
+ position: fixed;
790
+ left: 0;
791
+ right: 0;
792
+ bottom: 0;
793
+ width: 100%;
794
+ height: var(--sheet-high-height);
795
+ transform: translateY(100%);
796
+ transition:
797
+ transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),
798
+ height 0.28s cubic-bezier(0.32, 0.72, 0, 1);
799
+ border-top: 1px solid var(--castle-inspector-divider);
800
+ box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.18);
801
+ overflow: hidden;
802
+ display: flex;
803
+ flex-direction: column;
804
+ }
805
+
806
+ /* File-browser sheet: hidden off-screen by default; slides up to high snap. */
807
+ .fileBrowser {
808
+ z-index: 50;
809
+ border-right: 0;
810
+ background: var(--castle-sheet-bg);
811
+ }
812
+
813
+ .fileBrowser[data-sheet-snap='high'] {
814
+ transform: translateY(0);
815
+ }
816
+
817
+ /* Hide the desktop fileBrowserHeader on mobile (the grab handle replaces it). */
818
+ .fileBrowserHeader {
819
+ display: none;
820
+ }
821
+
822
+ .fileTree {
823
+ flex: 1 1 0;
824
+ min-height: 0;
825
+ overflow-y: auto;
826
+ padding: 4px 6px 12px;
827
+ }
828
+
829
+ /* Inspector sheet: hidden off-screen by default; slides up to high (full) or low (partial). */
830
+ .inspector {
831
+ z-index: 45;
832
+ border-left: 0;
833
+ background: var(--castle-inspector-bg);
834
+ padding: 0;
835
+ }
836
+
837
+ .inspector[data-sheet-snap='high'] {
838
+ transform: translateY(0);
839
+ height: var(--sheet-high-height);
840
+ }
841
+
842
+ .inspector[data-sheet-snap='low'] {
843
+ transform: translateY(0);
844
+ height: var(--sheet-low-height);
845
+ }
846
+
847
+ /* Auto-height variant -- inspector hugs its content at the high snap (drawing/code). */
848
+ .inspector.inspectorAuto[data-sheet-snap='high'] {
849
+ height: auto;
850
+ max-height: var(--sheet-high-height);
851
+ }
852
+
853
+ /* Shared sheet chrome -- grab bar pill + label row. Always visible when sheet is visible. */
854
+ .sheetGrab {
855
+ display: flex;
856
+ flex-direction: column;
857
+ align-items: stretch;
858
+ justify-content: center;
859
+ flex: 0 0 auto;
860
+ padding: 8px 14px 8px;
861
+ cursor: grab;
862
+ user-select: none;
863
+ touch-action: none;
864
+ background: var(--castle-sheet-bg);
865
+ border-bottom: 1px solid var(--castle-inspector-divider);
866
+ }
867
+
868
+ .inspector .sheetGrab {
869
+ background: var(--castle-inspector-bg);
870
+ }
871
+
872
+ .sheetGrabBar {
873
+ display: block;
874
+ width: 36px;
875
+ height: 4px;
876
+ border-radius: 999px;
877
+ background: var(--castle-inspector-divider);
878
+ margin: 0 auto 8px;
879
+ flex: 0 0 4px;
880
+ }
881
+
882
+ .sheetGrabLabelRow {
883
+ display: flex;
884
+ align-items: baseline;
885
+ gap: 8px;
886
+ min-width: 0;
887
+ }
888
+
889
+ .sheetGrabLabel {
890
+ display: inline;
891
+ font-size: 14px;
892
+ font-weight: 600;
893
+ color: var(--castle-inspector-text);
894
+ overflow: hidden;
895
+ text-overflow: ellipsis;
896
+ white-space: nowrap;
897
+ }
898
+
899
+ .sheetGrabHint {
900
+ display: inline;
901
+ font-size: 12px;
902
+ color: var(--castle-inspector-muted);
903
+ overflow: hidden;
904
+ text-overflow: ellipsis;
905
+ white-space: nowrap;
906
+ flex: 1;
907
+ }
908
+
909
+ .sheetBody {
910
+ flex: 1;
911
+ min-height: 0;
912
+ overflow: auto;
913
+ }
914
+
915
+ .inspectorBody {
916
+ background: var(--castle-inspector-bg);
917
+ }
918
+
919
+ .codeInspectorInfo {
920
+ display: grid;
921
+ grid-template-columns: 80px 1fr;
922
+ gap: 6px 12px;
923
+ padding: 14px 16px;
924
+ font-size: 13px;
925
+ color: var(--castle-inspector-text);
926
+ word-break: break-all;
927
+ }
928
+ }