castle-web-cli 0.4.75 → 0.4.76

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 (68) hide show
  1. package/dist/agent-prompts.d.ts +4 -0
  2. package/dist/agent-prompts.js +20 -8
  3. package/dist/agent.js +301 -28
  4. package/dist/castle-host/host.js +59 -5
  5. package/dist/commonInstructions.d.ts +1 -1
  6. package/dist/commonInstructions.js +4 -0
  7. package/dist/ide.d.ts +1 -0
  8. package/dist/ide.js +250 -1
  9. package/dist/init.js +46 -4
  10. package/dist/save-deck.js +8 -1
  11. package/dist/serve.js +27 -1
  12. package/dist/shell/assets/index-DNWEQd4R.js +141 -0
  13. package/dist/shell/assets/{index-WNbOHPBj.css → index-DuKq-Grp.css} +1 -1
  14. package/dist/shell/index.html +2 -2
  15. package/kits/basic-2d/CLAUDE.md +13 -5
  16. package/kits/basic-2d/castle.json +15 -0
  17. package/kits/basic-2d/drawings/pig.pxart +22 -55
  18. package/kits/basic-2d/editors/PxArtEditor.jsx +237 -4
  19. package/kits/basic-2d/editors/SingleEditor.jsx +6 -51
  20. package/kits/basic-2d/editors/pixelEditorChrome.jsx +17 -11
  21. package/kits/basic-2d/editors/pixelGeometry.js +95 -0
  22. package/kits/basic-2d/editors/pixelInspector.jsx +229 -51
  23. package/kits/basic-2d/editors/pxArtTools.js +109 -1
  24. package/kits/basic-2d/engine/ScenePlayer.jsx +11 -160
  25. package/kits/basic-2d/engine/ui.jsx +15 -0
  26. package/kits/basic-2d/engine/ui.module.css +44 -117
  27. package/kits/basic-2d/main.jsx +6 -10
  28. package/package.json +10 -1
  29. package/dist/shell/assets/index-Dfn29Bkt.js +0 -108
  30. package/kits/basic-2d/editors/App.jsx +0 -226
  31. package/kits/basic-2d/editors/CodeEditor.jsx +0 -79
  32. package/kits/basic-2d/editors/FileBrowser.jsx +0 -349
  33. package/kits/basic-2d/editors/codeTheme.js +0 -135
  34. package/kits/basic-2d/engine/playConsole.js +0 -66
  35. package/kits/basic-3d/.prettierrc +0 -8
  36. package/kits/basic-3d/CLAUDE.md +0 -162
  37. package/kits/basic-3d/behaviors/Camera.jsx +0 -56
  38. package/kits/basic-3d/behaviors/Collider.jsx +0 -78
  39. package/kits/basic-3d/behaviors/Mesh.jsx +0 -82
  40. package/kits/basic-3d/behaviors/Model.jsx +0 -61
  41. package/kits/basic-3d/behaviors/Transform.jsx +0 -35
  42. package/kits/basic-3d/editors/App.jsx +0 -147
  43. package/kits/basic-3d/editors/CodeEditor.jsx +0 -112
  44. package/kits/basic-3d/editors/FileBrowser.jsx +0 -143
  45. package/kits/basic-3d/editors/ModelEditor.jsx +0 -400
  46. package/kits/basic-3d/editors/PlayOnly.jsx +0 -22
  47. package/kits/basic-3d/editors/SceneEditor.jsx +0 -1081
  48. package/kits/basic-3d/editors/behaviorRegistry.js +0 -24
  49. package/kits/basic-3d/editors/editorHistory.js +0 -52
  50. package/kits/basic-3d/editors/viewportRig.js +0 -90
  51. package/kits/basic-3d/engine/ScenePlayer.jsx +0 -58
  52. package/kits/basic-3d/engine/SceneUI.jsx +0 -67
  53. package/kits/basic-3d/engine/SceneViewport.jsx +0 -102
  54. package/kits/basic-3d/engine/autoInspector.jsx +0 -51
  55. package/kits/basic-3d/engine/files.js +0 -73
  56. package/kits/basic-3d/engine/scene.js +0 -502
  57. package/kits/basic-3d/engine/threeUtil.js +0 -260
  58. package/kits/basic-3d/engine/ui.jsx +0 -352
  59. package/kits/basic-3d/engine/ui.module.css +0 -944
  60. package/kits/basic-3d/eslint.config.js +0 -51
  61. package/kits/basic-3d/index.html +0 -11
  62. package/kits/basic-3d/main.jsx +0 -10
  63. package/kits/basic-3d/models/block.model +0 -14
  64. package/kits/basic-3d/package-lock.json +0 -2713
  65. package/kits/basic-3d/package.json +0 -41
  66. package/kits/basic-3d/pnpm-lock.yaml +0 -1769
  67. package/kits/basic-3d/scenes/main.scene +0 -76
  68. package/kits/basic-3d/vite.config.js +0 -1
@@ -1,944 +0,0 @@
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
- /* Full-bleed stage -- edit mode fills the workspace; play mode keeps the
281
- 5:7 card so the deck previews at its real aspect. */
282
- .stageWrapFull {
283
- padding: 0;
284
- }
285
-
286
- .stageWrapFull .stageCard {
287
- width: 100%;
288
- height: 100%;
289
- max-width: none;
290
- aspect-ratio: auto;
291
- border: 0;
292
- border-radius: 0;
293
- box-shadow: none;
294
- }
295
-
296
- /* Game-time UI overlay -- sits exactly over the canvas and clips to the card.
297
- Behavior `ui` output lands in `.sceneUiLayer`, which is sized in card units
298
- and scaled onto the canvas box. */
299
- .sceneUiRoot {
300
- position: absolute;
301
- inset: 0;
302
- overflow: hidden;
303
- pointer-events: none;
304
- }
305
-
306
- .sceneUiLayer {
307
- position: absolute;
308
- left: 0;
309
- top: 0;
310
- transform-origin: 0 0;
311
- }
312
-
313
- .inspector {
314
- grid-column: 2;
315
- grid-row: 1 / span 2;
316
- min-width: 0;
317
- border-left: 1px solid var(--castle-inspector-divider);
318
- background: var(--castle-inspector-bg);
319
- color: var(--castle-inspector-text);
320
- overflow: auto;
321
- padding: 0;
322
- }
323
-
324
- .panel {
325
- border: 0;
326
- border-bottom: 1px solid var(--castle-inspector-divider);
327
- border-radius: 0;
328
- background: var(--castle-inspector-bg);
329
- color: var(--castle-inspector-text);
330
- margin: 0;
331
- overflow: visible;
332
- box-shadow: none;
333
- }
334
-
335
- .panel:last-child {
336
- border-bottom: 0;
337
- }
338
-
339
- .panelHeader {
340
- padding: 14px 16px 6px;
341
- border-bottom: 0;
342
- color: var(--castle-inspector-text);
343
- font-size: 16px;
344
- font-weight: 650;
345
- }
346
-
347
- .panelBody {
348
- padding: 8px 16px 4px;
349
- }
350
-
351
- .fieldRow {
352
- display: grid;
353
- grid-template-columns: minmax(82px, 0.5fr) minmax(0, 1fr);
354
- align-items: center;
355
- gap: 12px;
356
- padding-bottom: 12px;
357
- margin-bottom: 0;
358
- min-height: 28px;
359
- }
360
-
361
- .fieldRow:last-child {
362
- margin-bottom: 0;
363
- }
364
-
365
- .fieldLabel {
366
- color: var(--castle-inspector-text);
367
- font-size: 16px;
368
- }
369
-
370
- .input,
371
- .select,
372
- .textarea {
373
- width: 100%;
374
- border: 1px solid var(--castle-inspector-border);
375
- border-radius: var(--castle-radius);
376
- background: var(--castle-inspector-input-bg);
377
- color: var(--castle-inspector-text);
378
- padding: 5px 8px;
379
- outline: 0;
380
- }
381
-
382
- .select {
383
- appearance: none;
384
- -webkit-appearance: none;
385
- padding-right: 26px;
386
- 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");
387
- background-repeat: no-repeat;
388
- background-position: right 8px center;
389
- text-overflow: ellipsis;
390
- }
391
-
392
- .numberField {
393
- position: relative;
394
- width: 100%;
395
- }
396
-
397
- .numberInput {
398
- padding-right: 22px;
399
- appearance: textfield;
400
- -moz-appearance: textfield;
401
- }
402
-
403
- .numberInput::-webkit-inner-spin-button,
404
- .numberInput::-webkit-outer-spin-button {
405
- -webkit-appearance: none;
406
- appearance: none;
407
- margin: 0;
408
- }
409
-
410
- .numberSteppers {
411
- position: absolute;
412
- top: 1px;
413
- right: 1px;
414
- bottom: 1px;
415
- width: 18px;
416
- display: flex;
417
- flex-direction: column;
418
- border-left: 1px solid var(--castle-inspector-divider);
419
- opacity: 0;
420
- pointer-events: none;
421
- transition: opacity 0.1s;
422
- }
423
-
424
- .numberField:hover .numberSteppers,
425
- .numberField:focus-within .numberSteppers {
426
- opacity: 1;
427
- pointer-events: auto;
428
- }
429
-
430
- .numberStepper {
431
- flex: 1;
432
- display: flex;
433
- align-items: center;
434
- justify-content: center;
435
- border: 0;
436
- padding: 0;
437
- background: transparent;
438
- color: var(--castle-inspector-muted);
439
- cursor: pointer;
440
- font-size: 8px;
441
- line-height: 1;
442
- }
443
-
444
- .numberStepper:first-child {
445
- border-bottom: 1px solid var(--castle-inspector-divider);
446
- }
447
-
448
- .numberStepper:hover {
449
- background: #eee;
450
- color: var(--castle-inspector-text);
451
- }
452
-
453
- .numberStepper:disabled {
454
- opacity: 0.3;
455
- cursor: default;
456
- background: transparent;
457
- }
458
-
459
- .colorInput {
460
- width: 100%;
461
- height: 28px;
462
- border: 1px solid var(--castle-inspector-border);
463
- border-radius: var(--castle-radius);
464
- background: var(--castle-inspector-input-bg);
465
- padding: 2px;
466
- outline: 0;
467
- cursor: pointer;
468
- }
469
-
470
- .toggle {
471
- width: 44px;
472
- height: 24px;
473
- border: 1px solid var(--castle-inspector-border);
474
- border-radius: 999px;
475
- background: #fff;
476
- padding: 2px;
477
- cursor: pointer;
478
- display: flex;
479
- align-items: center;
480
- justify-content: flex-start;
481
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
482
- }
483
-
484
- .toggleOn {
485
- background: var(--castle-black);
486
- justify-content: flex-end;
487
- }
488
-
489
- .toggleKnob {
490
- width: 18px;
491
- height: 18px;
492
- border-radius: 999px;
493
- background: var(--castle-black);
494
- }
495
-
496
- .toggleOn .toggleKnob {
497
- background: var(--castle-text);
498
- }
499
-
500
- .textarea {
501
- min-height: 0;
502
- resize: none;
503
- font-family: var(--castle-font-mono);
504
- font-size: 12px;
505
- line-height: 1.45;
506
- }
507
-
508
- .button {
509
- border: 1px solid var(--castle-inspector-border);
510
- border-radius: var(--castle-radius);
511
- background: var(--castle-inspector-button-bg);
512
- color: var(--castle-inspector-text);
513
- padding: 6px 10px;
514
- cursor: pointer;
515
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
516
- }
517
-
518
- .iconButton {
519
- width: 34px;
520
- height: 34px;
521
- padding: 0;
522
- display: inline-flex;
523
- align-items: center;
524
- justify-content: center;
525
- }
526
-
527
- .iconButton svg {
528
- width: 1em;
529
- height: 1em;
530
- }
531
-
532
- .button:hover {
533
- background: #eee;
534
- }
535
-
536
- .buttonPrimary,
537
- .buttonActive {
538
- background: var(--castle-black);
539
- border-color: var(--castle-black);
540
- color: var(--castle-text);
541
- }
542
-
543
- .buttonPrimary:hover,
544
- .buttonActive:hover {
545
- background: var(--castle-black);
546
- border-color: var(--castle-black);
547
- color: var(--castle-text);
548
- }
549
-
550
- .buttonDanger {
551
- color: var(--castle-danger);
552
- }
553
-
554
- .button:disabled {
555
- opacity: 0.35;
556
- cursor: default;
557
- }
558
-
559
- .actorList {
560
- display: grid;
561
- gap: 4px;
562
- }
563
-
564
- .actorRow {
565
- width: 100%;
566
- border: 1px solid transparent;
567
- background: transparent;
568
- color: var(--castle-inspector-text);
569
- border-radius: var(--castle-radius);
570
- padding: 7px 8px;
571
- text-align: left;
572
- cursor: pointer;
573
- }
574
-
575
- .actorRowSelected {
576
- background: var(--castle-black);
577
- border-color: var(--castle-black);
578
- color: var(--castle-text);
579
- }
580
-
581
- .drawingEditor,
582
- .codeEditor {
583
- flex: 1;
584
- min-width: 0;
585
- min-height: 0;
586
- display: grid;
587
- grid-template-columns: minmax(320px, 1fr) 280px;
588
- background: var(--castle-workspace-bg);
589
- }
590
-
591
- .drawingEditor {
592
- grid-template-rows: 48px minmax(0, 1fr);
593
- }
594
-
595
- .drawingCanvasWrap {
596
- grid-column: 1;
597
- grid-row: 2;
598
- display: flex;
599
- align-items: center;
600
- justify-content: center;
601
- padding: 24px;
602
- min-width: 0;
603
- min-height: 0;
604
- }
605
-
606
- .drawingCanvas {
607
- image-rendering: pixelated;
608
- background:
609
- linear-gradient(45deg, #ddd 25%, transparent 25%),
610
- linear-gradient(-45deg, #ddd 25%, transparent 25%),
611
- linear-gradient(45deg, transparent 75%, #ddd 75%),
612
- linear-gradient(-45deg, transparent 75%, #ddd 75%);
613
- background-size: 16px 16px;
614
- background-position:
615
- 0 0,
616
- 0 8px,
617
- 8px -8px,
618
- -8px 0;
619
- border: 1px solid var(--castle-inspector-border);
620
- max-width: min(70vh, 520px);
621
- max-height: min(70vh, 520px);
622
- }
623
-
624
- .palette {
625
- display: grid;
626
- grid-template-columns: repeat(6, 1fr);
627
- gap: 6px;
628
- padding-bottom: 12px;
629
- }
630
-
631
- .swatch {
632
- aspect-ratio: 1;
633
- border: 1px solid var(--castle-inspector-border);
634
- border-radius: var(--castle-radius);
635
- cursor: pointer;
636
- }
637
-
638
- .swatchSelected {
639
- outline: 2px solid var(--castle-black);
640
- outline-offset: 1px;
641
- }
642
-
643
- .codeEditor {
644
- grid-template-columns: 1fr;
645
- }
646
-
647
- .codeMirrorHost {
648
- min-width: 0;
649
- min-height: 0;
650
- height: 100%;
651
- }
652
-
653
- .headerFilesButton {
654
- width: 34px;
655
- height: 34px;
656
- border: 1px solid var(--castle-inspector-border);
657
- border-radius: var(--castle-radius);
658
- background: var(--castle-inspector-button-bg);
659
- color: var(--castle-inspector-text);
660
- cursor: pointer;
661
- align-items: center;
662
- justify-content: center;
663
- flex: 0 0 34px;
664
- }
665
-
666
- .headerFilesButton[aria-pressed='true'] {
667
- background: var(--castle-black);
668
- border-color: var(--castle-black);
669
- color: var(--castle-text);
670
- }
671
-
672
- /* mobileOnly comes AFTER element-specific rules so `display: none` wins on desktop. */
673
- .mobileOnly,
674
- .headerFilesButton,
675
- .sheetBackdrop,
676
- .sheetGrab,
677
- .sheetGrabBar,
678
- .sheetGrabLabelRow,
679
- .sheetGrabLabel,
680
- .sheetGrabHint {
681
- display: none;
682
- }
683
-
684
- @media (max-width: 860px) {
685
- :root {
686
- --sheet-high-height: 62vh;
687
- --sheet-low-height: 18vh;
688
- }
689
-
690
- /* `display: contents` makes wrapper spans transparent in layout so their
691
- children become direct flex items of the parent (gap applies, etc). */
692
- .mobileOnly {
693
- display: contents;
694
- }
695
-
696
- .headerFilesButton {
697
- display: inline-flex;
698
- }
699
-
700
- /* Backdrop sits below the header so the files toggle stays interactive. */
701
- .sheetBackdrop {
702
- display: block;
703
- position: fixed;
704
- top: 52px;
705
- left: 0;
706
- right: 0;
707
- bottom: 0;
708
- z-index: 30;
709
- background: transparent;
710
- }
711
-
712
- .appShell {
713
- grid-template-columns: 1fr;
714
- grid-template-rows: 1fr;
715
- position: relative;
716
- }
717
-
718
- .mainEditor {
719
- grid-column: 1;
720
- grid-row: 1;
721
- min-height: 0;
722
- }
723
-
724
- /* Header: title (left, compact) + centered icon group (right slot includes files button). */
725
- .editorHeader {
726
- height: 52px;
727
- flex: 0 0 52px;
728
- padding: 8px 10px;
729
- gap: 8px;
730
- justify-content: space-between;
731
- }
732
-
733
- .editorHeaderLeft {
734
- flex: 1;
735
- min-width: 0;
736
- }
737
-
738
- .editorHeaderRight {
739
- flex: 0 0 auto;
740
- justify-content: flex-end;
741
- gap: 14px;
742
- }
743
-
744
- .editorTitle {
745
- font-size: 15px;
746
- overflow: hidden;
747
- text-overflow: ellipsis;
748
- white-space: nowrap;
749
- }
750
-
751
- .muted {
752
- overflow: hidden;
753
- text-overflow: ellipsis;
754
- white-space: nowrap;
755
- }
756
-
757
- /* Hide the desktop tools row on mobile -- buttons live in the header instead. */
758
- .sceneTools,
759
- .drawingTools {
760
- display: none;
761
- }
762
-
763
- .sceneWorkspace {
764
- grid-template-columns: 1fr;
765
- grid-template-rows: minmax(0, 1fr);
766
- }
767
-
768
- .drawingEditor {
769
- grid-template-columns: 1fr;
770
- grid-template-rows: minmax(0, 1fr);
771
- }
772
-
773
- .stageWrap {
774
- grid-column: 1;
775
- grid-row: 1;
776
- align-items: flex-start;
777
- padding: 10px 12px 12px;
778
- background: var(--castle-stage-workspace-bg);
779
- }
780
-
781
- .stageCard {
782
- max-width: min(92vw, 480px);
783
- max-height: 100%;
784
- width: auto;
785
- }
786
-
787
- /* Drawing centers higher in the canvas region -- around the 1/3-from-top mark. */
788
- .drawingCanvasWrap {
789
- grid-column: 1;
790
- grid-row: 1;
791
- align-items: flex-start;
792
- padding: 6vh 16px 16px;
793
- }
794
-
795
- .drawingCanvas {
796
- max-width: min(82vw, 480px);
797
- max-height: min(54vh, 480px);
798
- }
799
-
800
- /* File-browser + inspector sheets share fixed-bottom positioning, height,
801
- transform/transition, and chrome. Per-sheet differences (z-index, side
802
- border, background, padding) follow in dedicated rules below. */
803
- .fileBrowser,
804
- .inspector {
805
- position: fixed;
806
- left: 0;
807
- right: 0;
808
- bottom: 0;
809
- width: 100%;
810
- height: var(--sheet-high-height);
811
- transform: translateY(100%);
812
- transition:
813
- transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),
814
- height 0.28s cubic-bezier(0.32, 0.72, 0, 1);
815
- border-top: 1px solid var(--castle-inspector-divider);
816
- box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.18);
817
- overflow: hidden;
818
- display: flex;
819
- flex-direction: column;
820
- }
821
-
822
- /* File-browser sheet: hidden off-screen by default; slides up to high snap. */
823
- .fileBrowser {
824
- z-index: 50;
825
- border-right: 0;
826
- background: var(--castle-sheet-bg);
827
- }
828
-
829
- .fileBrowser[data-sheet-snap='high'] {
830
- transform: translateY(0);
831
- }
832
-
833
- /* Hide the desktop fileBrowserHeader on mobile (the grab handle replaces it). */
834
- .fileBrowserHeader {
835
- display: none;
836
- }
837
-
838
- .fileTree {
839
- flex: 1 1 0;
840
- min-height: 0;
841
- overflow-y: auto;
842
- padding: 4px 6px 12px;
843
- }
844
-
845
- /* Inspector sheet: hidden off-screen by default; slides up to high (full) or low (partial). */
846
- .inspector {
847
- z-index: 45;
848
- border-left: 0;
849
- background: var(--castle-inspector-bg);
850
- padding: 0;
851
- }
852
-
853
- .inspector[data-sheet-snap='high'] {
854
- transform: translateY(0);
855
- height: var(--sheet-high-height);
856
- }
857
-
858
- .inspector[data-sheet-snap='low'] {
859
- transform: translateY(0);
860
- height: var(--sheet-low-height);
861
- }
862
-
863
- /* Auto-height variant -- inspector hugs its content at the high snap (drawing/code). */
864
- .inspector.inspectorAuto[data-sheet-snap='high'] {
865
- height: auto;
866
- max-height: var(--sheet-high-height);
867
- }
868
-
869
- /* Shared sheet chrome -- grab bar pill + label row. Always visible when sheet is visible. */
870
- .sheetGrab {
871
- display: flex;
872
- flex-direction: column;
873
- align-items: stretch;
874
- justify-content: center;
875
- flex: 0 0 auto;
876
- padding: 8px 14px 8px;
877
- cursor: grab;
878
- user-select: none;
879
- touch-action: none;
880
- background: var(--castle-sheet-bg);
881
- border-bottom: 1px solid var(--castle-inspector-divider);
882
- }
883
-
884
- .inspector .sheetGrab {
885
- background: var(--castle-inspector-bg);
886
- }
887
-
888
- .sheetGrabBar {
889
- display: block;
890
- width: 36px;
891
- height: 4px;
892
- border-radius: 999px;
893
- background: var(--castle-inspector-divider);
894
- margin: 0 auto 8px;
895
- flex: 0 0 4px;
896
- }
897
-
898
- .sheetGrabLabelRow {
899
- display: flex;
900
- align-items: baseline;
901
- gap: 8px;
902
- min-width: 0;
903
- }
904
-
905
- .sheetGrabLabel {
906
- display: inline;
907
- font-size: 14px;
908
- font-weight: 600;
909
- color: var(--castle-inspector-text);
910
- overflow: hidden;
911
- text-overflow: ellipsis;
912
- white-space: nowrap;
913
- }
914
-
915
- .sheetGrabHint {
916
- display: inline;
917
- font-size: 12px;
918
- color: var(--castle-inspector-muted);
919
- overflow: hidden;
920
- text-overflow: ellipsis;
921
- white-space: nowrap;
922
- flex: 1;
923
- }
924
-
925
- .sheetBody {
926
- flex: 1;
927
- min-height: 0;
928
- overflow: auto;
929
- }
930
-
931
- .inspectorBody {
932
- background: var(--castle-inspector-bg);
933
- }
934
-
935
- .codeInspectorInfo {
936
- display: grid;
937
- grid-template-columns: 80px 1fr;
938
- gap: 6px 12px;
939
- padding: 14px 16px;
940
- font-size: 13px;
941
- color: var(--castle-inspector-text);
942
- word-break: break-all;
943
- }
944
- }