castle-web-cli 0.4.72 → 0.4.73
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.
- package/dist/agent-prompts.js +22 -3
- package/dist/agent.js +731 -313
- package/dist/init.js +1 -1
- package/dist/shell/assets/index-Dfn29Bkt.js +108 -0
- package/dist/shell/assets/{index-CVEnWuGV.css → index-WNbOHPBj.css} +1 -1
- package/dist/shell/index.html +2 -2
- package/dist/vitePlugins.js +3 -2
- package/kits/basic-2d/CLAUDE.md +29 -8
- package/kits/basic-2d/behaviors/Collider.jsx +6 -4
- package/kits/basic-2d/behaviors/Layout.jsx +2 -2
- package/kits/basic-2d/behaviors/Sprite.jsx +210 -0
- package/kits/basic-2d/behaviors/tint.js +47 -0
- package/kits/basic-2d/docs/pxart-format.md +298 -0
- package/kits/basic-2d/drawings/pig.pxart +59 -0
- package/kits/basic-2d/editors/App.jsx +125 -76
- package/kits/basic-2d/editors/CodeEditor.jsx +9 -45
- package/kits/basic-2d/editors/FileBrowser.jsx +234 -47
- package/kits/basic-2d/editors/PlayOnly.jsx +9 -7
- package/kits/basic-2d/editors/PxArtEditor.jsx +662 -0
- package/kits/basic-2d/editors/SceneEditor.jsx +587 -221
- package/kits/basic-2d/editors/SelectionOverlay.jsx +808 -0
- package/kits/basic-2d/editors/SingleEditor.jsx +38 -20
- package/kits/basic-2d/editors/codeTheme.js +135 -0
- package/kits/basic-2d/editors/editorHistory.js +44 -17
- package/kits/basic-2d/editors/inspectorSheet.js +23 -0
- package/kits/basic-2d/editors/pixelCanvas.js +11 -0
- package/kits/basic-2d/editors/pixelEditorChrome.jsx +55 -0
- package/kits/basic-2d/editors/pixelGeometry.js +45 -0
- package/kits/basic-2d/editors/pixelInspector.jsx +416 -0
- package/kits/basic-2d/editors/pxArtEditorModel.js +718 -0
- package/kits/basic-2d/editors/pxArtPlayback.js +92 -0
- package/kits/basic-2d/editors/pxArtTimeline.jsx +752 -0
- package/kits/basic-2d/editors/pxArtTimeline.module.css +506 -0
- package/kits/basic-2d/editors/pxArtTools.js +124 -0
- package/kits/basic-2d/editors/useArtboardFit.js +102 -0
- package/kits/basic-2d/engine/ScenePlayer.jsx +10 -4
- package/kits/basic-2d/engine/SceneUI.jsx +3 -11
- package/kits/basic-2d/engine/assets.js +15 -0
- package/kits/basic-2d/engine/files.js +57 -2
- package/kits/basic-2d/engine/pxart.js +985 -0
- package/kits/basic-2d/engine/scene.js +222 -41
- package/kits/basic-2d/engine/ui.jsx +155 -26
- package/kits/basic-2d/engine/ui.module.css +1280 -344
- package/kits/basic-2d/eslint.config.js +21 -0
- package/kits/basic-2d/index.html +13 -0
- package/kits/basic-2d/package.json +1 -0
- package/kits/basic-2d/pnpm-lock.yaml +5 -5
- package/kits/basic-2d/scenes/main.scene +19 -26
- package/kits/basic-2d/scripts/draw.mjs +121 -0
- package/kits/basic-3d/editors/PlayOnly.jsx +9 -1
- package/kits/basic-3d/engine/ScenePlayer.jsx +7 -1
- package/package.json +1 -1
- package/dist/shell/assets/index-vmdKwUE1.js +0 -106
- package/kits/basic-2d/behaviors/Drawing.jsx +0 -142
- package/kits/basic-2d/drawings/block.drawing +0 -70
- package/kits/basic-2d/drawings/default.drawing +0 -70
- package/kits/basic-2d/editors/DrawingEditor.jsx +0 -224
|
@@ -11,33 +11,47 @@
|
|
|
11
11
|
sans-serif;
|
|
12
12
|
--castle-font-display: var(--castle-font-body);
|
|
13
13
|
--castle-font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
|
|
14
|
-
--castle-black: #
|
|
14
|
+
--castle-black: #111;
|
|
15
15
|
--castle-tap-highlight: #111;
|
|
16
16
|
--castle-panel: #080808;
|
|
17
17
|
--castle-panel-raised: #101010;
|
|
18
18
|
--castle-panel-sunken: #050505;
|
|
19
19
|
--castle-border: #444;
|
|
20
|
-
--castle-border-soft: #
|
|
20
|
+
--castle-border-soft: #2a2a2a;
|
|
21
21
|
--castle-text: #fff;
|
|
22
|
-
--castle-text-dim: #
|
|
23
|
-
--castle-text-muted: #
|
|
24
|
-
--castle-inspector-bg: #
|
|
25
|
-
--castle-inspector-text: #
|
|
22
|
+
--castle-text-dim: #888;
|
|
23
|
+
--castle-text-muted: #888;
|
|
24
|
+
--castle-inspector-bg: #0d0d0d;
|
|
25
|
+
--castle-inspector-text: #e6e6e6;
|
|
26
26
|
--castle-inspector-muted: #888;
|
|
27
|
-
--castle-inspector-border: #
|
|
28
|
-
--castle-inspector-divider: #
|
|
29
|
-
--castle-inspector-input-bg: #
|
|
30
|
-
--castle-inspector-button-bg: #
|
|
31
|
-
--castle-workspace-bg: #
|
|
32
|
-
--castle-stage-workspace-bg: #
|
|
33
|
-
--castle-sheet-bg: #
|
|
27
|
+
--castle-inspector-border: #2a2a2a;
|
|
28
|
+
--castle-inspector-divider: #2a2a2a;
|
|
29
|
+
--castle-inspector-input-bg: #161616;
|
|
30
|
+
--castle-inspector-button-bg: #0d0d0d;
|
|
31
|
+
--castle-workspace-bg: #0a0a0a;
|
|
32
|
+
--castle-stage-workspace-bg: #161616;
|
|
33
|
+
--castle-sheet-bg: #0d0d0d;
|
|
34
34
|
--castle-card: #121213;
|
|
35
|
-
--castle-selected: #
|
|
36
|
-
--castle-selected-ink: #
|
|
35
|
+
--castle-selected: #e6e6e6;
|
|
36
|
+
--castle-selected-ink: #111;
|
|
37
37
|
--castle-danger: #ff5d5d;
|
|
38
38
|
--castle-ok: #81e69b;
|
|
39
39
|
--castle-blue: #8db7ff;
|
|
40
40
|
--castle-radius: 4px;
|
|
41
|
+
/* Tools/hotbar strip height -- aligned to the inspector "+ Add behavior" row
|
|
42
|
+
(top+bottom pad + 1px borders + select padding + text line). The text line
|
|
43
|
+
uses `rem` (root-relative), NOT `em`: the hotbar inherits the 16px body font
|
|
44
|
+
while the inspector sets font-size:14px, so an `em` here resolved to 20px on
|
|
45
|
+
the hotbar but only 17.5px inside the inspector -- leaving the Add-behavior
|
|
46
|
+
row ~2.5px short of the hotbar. `rem` resolves to the same value in both. */
|
|
47
|
+
--castle-hotbar-row-pad-y: 12px;
|
|
48
|
+
--castle-hotbar-row-h: calc(var(--castle-hotbar-row-pad-y) * 2 + 2px + 10px + 1.25rem);
|
|
49
|
+
/* Full row height shared by the scene hotbar (.sceneTools + its grid track)
|
|
50
|
+
and the inspector "+ Add behavior" row, so both bottom borders land on the
|
|
51
|
+
same y. The +2px matches the Add-behavior row's outer box; it also gives the
|
|
52
|
+
46px hotbar buttons room to sit fully inside the bar (no bottom clipping). */
|
|
53
|
+
--castle-hotbar-row-full: calc(var(--castle-hotbar-row-h) + 2px);
|
|
54
|
+
color-scheme: dark;
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
:global(*) {
|
|
@@ -89,15 +103,42 @@
|
|
|
89
103
|
outline: none;
|
|
90
104
|
}
|
|
91
105
|
|
|
106
|
+
/* Editor-root is a vertical stack: full-width header row, then the
|
|
107
|
+
`[file list | workspace]` grid row. */
|
|
108
|
+
.editorRoot {
|
|
109
|
+
width: 100%;
|
|
110
|
+
height: 100%;
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
background: var(--castle-workspace-bg);
|
|
114
|
+
color: var(--castle-inspector-text);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Portal target for the active editor's header. `display: contents` lets the
|
|
118
|
+
portaled `.editorHeader` be a direct flex child of `.editorRoot`. */
|
|
119
|
+
.editorHeaderHost {
|
|
120
|
+
display: contents;
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
.appShell {
|
|
93
|
-
|
|
94
|
-
height:
|
|
124
|
+
flex: 1 1 0;
|
|
125
|
+
min-height: 0;
|
|
95
126
|
display: grid;
|
|
96
|
-
grid-template-columns:
|
|
127
|
+
grid-template-columns: 200px 1fr;
|
|
97
128
|
background: var(--castle-workspace-bg);
|
|
98
129
|
color: var(--castle-inspector-text);
|
|
99
130
|
}
|
|
100
131
|
|
|
132
|
+
/* Desktop: the files toggle collapses the file-list column. (Never set in
|
|
133
|
+
compact mode, where the file list is a bottom sheet instead.) */
|
|
134
|
+
.editorRoot.filesHidden .appShell {
|
|
135
|
+
grid-template-columns: 1fr;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.editorRoot.filesHidden .fileBrowser {
|
|
139
|
+
display: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
101
142
|
.fileBrowser {
|
|
102
143
|
min-width: 0;
|
|
103
144
|
border-right: 1px solid var(--castle-inspector-divider);
|
|
@@ -106,7 +147,16 @@
|
|
|
106
147
|
flex-direction: column;
|
|
107
148
|
}
|
|
108
149
|
|
|
109
|
-
|
|
150
|
+
/* Bare file browser for the dockview "Files" panel: no sidebar border or
|
|
151
|
+
mobile-sheet chrome, just a full-height column so the tree fills the panel
|
|
152
|
+
and the empty area below the rows still catches the blank-area menu. */
|
|
153
|
+
.fileBrowserBare {
|
|
154
|
+
min-width: 0;
|
|
155
|
+
height: 100%;
|
|
156
|
+
display: flex;
|
|
157
|
+
flex-direction: column;
|
|
158
|
+
}
|
|
159
|
+
|
|
110
160
|
.editorHeader {
|
|
111
161
|
height: 48px;
|
|
112
162
|
flex: 0 0 48px;
|
|
@@ -115,18 +165,16 @@
|
|
|
115
165
|
gap: 8px;
|
|
116
166
|
padding: 10px 12px;
|
|
117
167
|
border-bottom: 1px solid var(--castle-inspector-divider);
|
|
118
|
-
background: var(--castle-
|
|
168
|
+
background: var(--castle-workspace-bg);
|
|
119
169
|
}
|
|
120
170
|
|
|
121
|
-
.fileBrowserTitle,
|
|
122
171
|
.editorTitle {
|
|
123
172
|
font-family: var(--castle-font-display);
|
|
124
173
|
letter-spacing: 0.01em;
|
|
125
|
-
font-size:
|
|
174
|
+
font-size: 14px;
|
|
126
175
|
line-height: 1;
|
|
127
176
|
}
|
|
128
177
|
|
|
129
|
-
.fileBrowserSubtitle,
|
|
130
178
|
.muted {
|
|
131
179
|
color: var(--castle-inspector-muted);
|
|
132
180
|
font-size: 12px;
|
|
@@ -135,7 +183,7 @@
|
|
|
135
183
|
.fileTree {
|
|
136
184
|
flex: 1 1 0;
|
|
137
185
|
min-height: 0;
|
|
138
|
-
padding:
|
|
186
|
+
padding-top: 5px;
|
|
139
187
|
overflow-y: auto;
|
|
140
188
|
}
|
|
141
189
|
|
|
@@ -143,24 +191,39 @@
|
|
|
143
191
|
min-width: 0;
|
|
144
192
|
}
|
|
145
193
|
|
|
194
|
+
/* File-list rows ride the workspace "notch" ladder: default sits on the
|
|
195
|
+
workspace bg (#0a0a0a, transparent), hover lifts one notch to the sheet bg
|
|
196
|
+
(#0d0d0d), and the selected row lifts one notch further to panel-raised
|
|
197
|
+
(#101010). Text follows the same idea: unselected rows are the SAME light
|
|
198
|
+
text token as the selected/hover row, just faded (reduced opacity) so they
|
|
199
|
+
stay clearly legible on the dark panel; the selected row is the full
|
|
200
|
+
standard light text. */
|
|
146
201
|
.fileRow,
|
|
147
202
|
.fileDirRow {
|
|
148
203
|
width: 100%;
|
|
149
204
|
border: 0;
|
|
150
205
|
border-radius: var(--castle-radius);
|
|
151
206
|
background: transparent;
|
|
152
|
-
color:
|
|
207
|
+
/* Plain opaque gray, NOT color-mix(...transparent): Safari fails to paint a
|
|
208
|
+
semi-transparent color-mix result until a repaint is forced (opening
|
|
209
|
+
devtools makes it appear), leaving rows invisible at rest. This solid value
|
|
210
|
+
approximates the light text token faded over the dark panel. */
|
|
211
|
+
color: #a8a8a8;
|
|
153
212
|
display: flex;
|
|
154
213
|
align-items: center;
|
|
155
214
|
justify-content: flex-start;
|
|
156
215
|
gap: 6px;
|
|
157
|
-
padding:
|
|
216
|
+
padding: 5px 9px 5px calc(9px + var(--file-depth, 0) * 20px);
|
|
158
217
|
text-align: left;
|
|
159
218
|
cursor: pointer;
|
|
219
|
+
font-size: 14px;
|
|
160
220
|
}
|
|
161
221
|
|
|
222
|
+
/* Folders read darker than files at rest so the tree's structure (containers
|
|
223
|
+
vs. leaves) is legible at a glance. Hover/selected still lift both to the full
|
|
224
|
+
light text via the higher-specificity rules below. */
|
|
162
225
|
.fileDirRow {
|
|
163
|
-
color:
|
|
226
|
+
color: #777;
|
|
164
227
|
}
|
|
165
228
|
|
|
166
229
|
.fileRow:hover,
|
|
@@ -169,29 +232,82 @@
|
|
|
169
232
|
color: var(--castle-inspector-text);
|
|
170
233
|
}
|
|
171
234
|
|
|
172
|
-
.fileRowSelected
|
|
173
|
-
|
|
235
|
+
/* Compound `.fileRow.fileRowSelected` so the selected look (full text +
|
|
236
|
+
one-notch-lighter bg) outranks `.fileRow:hover` on specificity, not source
|
|
237
|
+
order -- the selected row stays put even while hovered. */
|
|
238
|
+
.fileRow.fileRowSelected,
|
|
239
|
+
.fileRow.fileRowSelected:hover {
|
|
240
|
+
background: var(--castle-panel-raised);
|
|
174
241
|
color: var(--castle-inspector-text);
|
|
175
242
|
}
|
|
176
243
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
244
|
+
/* The disclosure caret only appears on folder rows; keep it a shade darker than
|
|
245
|
+
the folder name (#666 vs #777) at rest, then lift it to the full light text on
|
|
246
|
+
hover alongside the name. Compound `.fileIcon.fileDisclosure` (0,2,0) is
|
|
247
|
+
required to beat the later `.fileIcon` muted-color rule (0,1,0); a bare
|
|
248
|
+
`.fileDisclosure` ties on specificity and loses on source order. */
|
|
249
|
+
.fileIcon.fileDisclosure {
|
|
250
|
+
color: #666;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.fileDirRow:hover .fileIcon.fileDisclosure {
|
|
254
|
+
color: inherit;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.fileDisclosure svg {
|
|
258
|
+
width: 10px;
|
|
259
|
+
height: 10px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Icon + name group: its own gap controls icon<->name spacing, independent of
|
|
263
|
+
the row's disclosure<->label gap. */
|
|
264
|
+
.fileLabel {
|
|
265
|
+
display: inline-flex;
|
|
266
|
+
align-items: center;
|
|
267
|
+
gap: 6px;
|
|
268
|
+
min-width: 0;
|
|
269
|
+
flex: 1 1 auto;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* Inline rename field. Constrained to the row width (flex:1 + min-width:0 +
|
|
273
|
+
border-box) so a long name never pushes the file browser into horizontal
|
|
274
|
+
overflow. */
|
|
275
|
+
.fileRenameInput {
|
|
276
|
+
flex: 1 1 auto;
|
|
277
|
+
min-width: 0;
|
|
278
|
+
width: 100%;
|
|
279
|
+
max-width: 100%;
|
|
280
|
+
box-sizing: border-box;
|
|
281
|
+
padding: 1px 4px;
|
|
282
|
+
border: 1px solid var(--castle-border);
|
|
283
|
+
border-radius: 5px;
|
|
284
|
+
background: var(--castle-panel-raised);
|
|
285
|
+
color: var(--castle-text);
|
|
286
|
+
font: inherit;
|
|
287
|
+
font-size: 13px;
|
|
180
288
|
}
|
|
181
289
|
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
290
|
+
.fileRenameInput:focus {
|
|
291
|
+
outline: none;
|
|
292
|
+
border-color: var(--castle-text-dim);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* Type-based file icon: muted so the file name stays the visual emphasis. */
|
|
296
|
+
.fileIcon {
|
|
297
|
+
width: 14px;
|
|
298
|
+
flex: 0 0 14px;
|
|
185
299
|
display: inline-flex;
|
|
186
300
|
align-items: center;
|
|
187
301
|
justify-content: center;
|
|
188
302
|
color: var(--castle-inspector-muted);
|
|
189
|
-
font-size:
|
|
303
|
+
font-size: 14px;
|
|
190
304
|
}
|
|
191
305
|
|
|
192
306
|
.mainEditor {
|
|
193
307
|
min-width: 0;
|
|
194
308
|
min-height: 0;
|
|
309
|
+
width: 100%;
|
|
310
|
+
height: 100%;
|
|
195
311
|
display: flex;
|
|
196
312
|
flex-direction: column;
|
|
197
313
|
background: var(--castle-sheet-bg);
|
|
@@ -215,6 +331,8 @@
|
|
|
215
331
|
flex: 1;
|
|
216
332
|
display: flex;
|
|
217
333
|
overflow: hidden;
|
|
334
|
+
container-type: inline-size;
|
|
335
|
+
container-name: editor;
|
|
218
336
|
}
|
|
219
337
|
|
|
220
338
|
.sceneWorkspace {
|
|
@@ -222,37 +340,112 @@
|
|
|
222
340
|
min-width: 0;
|
|
223
341
|
min-height: 0;
|
|
224
342
|
display: grid;
|
|
225
|
-
grid-template-columns: minmax(
|
|
226
|
-
grid-template-rows:
|
|
343
|
+
grid-template-columns: minmax(0, 1fr) 280px;
|
|
344
|
+
grid-template-rows: var(--castle-hotbar-row-full) minmax(0, 1fr);
|
|
227
345
|
}
|
|
228
346
|
|
|
229
|
-
.sceneTools
|
|
230
|
-
.drawingTools {
|
|
347
|
+
.sceneTools {
|
|
231
348
|
grid-column: 1;
|
|
232
349
|
grid-row: 1;
|
|
350
|
+
height: var(--castle-hotbar-row-full);
|
|
351
|
+
min-width: 0;
|
|
233
352
|
display: flex;
|
|
234
353
|
align-items: center;
|
|
235
|
-
|
|
236
|
-
gap: 8px;
|
|
237
|
-
padding: 8px 12px;
|
|
354
|
+
padding: 0;
|
|
238
355
|
border-bottom: 1px solid var(--castle-inspector-divider);
|
|
239
|
-
background: var(--castle-
|
|
356
|
+
background: var(--castle-workspace-bg);
|
|
240
357
|
}
|
|
241
358
|
|
|
242
|
-
.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
359
|
+
/* Blueprint hotbar -- left-aligned djinn-style stamp palette. Today it holds a
|
|
360
|
+
single "+" Add-actor control; drag-and-drop blueprint slots land here later. */
|
|
361
|
+
.bpHotbar {
|
|
362
|
+
display: flex;
|
|
363
|
+
flex-direction: row;
|
|
364
|
+
align-items: center;
|
|
365
|
+
gap: 6px;
|
|
366
|
+
width: 100%;
|
|
367
|
+
height: 100%;
|
|
368
|
+
padding: 0 6px;
|
|
369
|
+
overflow-x: auto;
|
|
370
|
+
overflow-y: hidden;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.bpSlot,
|
|
374
|
+
.bpActionSlot {
|
|
375
|
+
width: 46px;
|
|
376
|
+
height: 46px;
|
|
377
|
+
display: inline-flex;
|
|
378
|
+
align-items: center;
|
|
379
|
+
justify-content: center;
|
|
380
|
+
padding: 0;
|
|
381
|
+
border: 1px solid var(--castle-inspector-border);
|
|
382
|
+
border-radius: var(--castle-radius);
|
|
383
|
+
background: var(--castle-inspector-button-bg);
|
|
384
|
+
color: var(--castle-inspector-text);
|
|
385
|
+
cursor: pointer;
|
|
386
|
+
font-size: 14px;
|
|
387
|
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.bpSlot:hover,
|
|
391
|
+
.bpActionSlot:hover {
|
|
392
|
+
background: var(--castle-inspector-input-bg);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.bpSlot:disabled,
|
|
396
|
+
.bpActionSlot:disabled {
|
|
397
|
+
cursor: default;
|
|
398
|
+
opacity: 0.35;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.bpSlot svg,
|
|
402
|
+
.bpActionSlot svg {
|
|
403
|
+
width: 14px;
|
|
404
|
+
height: 14px;
|
|
405
|
+
flex: 0 0 auto;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.bpSlotThumb,
|
|
409
|
+
.bpSlotFallback {
|
|
410
|
+
width: 36px;
|
|
411
|
+
height: 36px;
|
|
412
|
+
flex: 0 0 36px;
|
|
413
|
+
border-radius: 3px;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.bpSlotThumb {
|
|
417
|
+
image-rendering: pixelated;
|
|
418
|
+
background: var(--castle-card);
|
|
419
|
+
object-fit: contain;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.bpSlotFallback {
|
|
423
|
+
display: inline-flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
justify-content: center;
|
|
426
|
+
color: var(--castle-inspector-muted);
|
|
246
427
|
}
|
|
247
428
|
|
|
248
|
-
.
|
|
429
|
+
.bpDragPreview {
|
|
430
|
+
position: fixed;
|
|
431
|
+
z-index: 1000;
|
|
432
|
+
pointer-events: none;
|
|
249
433
|
display: flex;
|
|
250
434
|
align-items: center;
|
|
251
|
-
|
|
435
|
+
justify-content: center;
|
|
436
|
+
border: 1px dashed var(--castle-text);
|
|
437
|
+
background: rgb(230 230 230 / 0.08);
|
|
438
|
+
opacity: 0.7;
|
|
252
439
|
}
|
|
253
440
|
|
|
254
|
-
.
|
|
255
|
-
|
|
441
|
+
.bpDragPreviewOverStage {
|
|
442
|
+
opacity: 0.9;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.bpPreviewThumb {
|
|
446
|
+
width: 100%;
|
|
447
|
+
height: 100%;
|
|
448
|
+
flex: 1 1 auto;
|
|
256
449
|
}
|
|
257
450
|
|
|
258
451
|
.stageWrap {
|
|
@@ -265,20 +458,30 @@
|
|
|
265
458
|
justify-content: center;
|
|
266
459
|
padding: 20px;
|
|
267
460
|
background: var(--castle-stage-workspace-bg);
|
|
461
|
+
overflow: hidden;
|
|
268
462
|
}
|
|
269
463
|
|
|
270
464
|
.stageCard {
|
|
271
465
|
position: relative;
|
|
272
466
|
width: min(52vh, 440px);
|
|
273
467
|
aspect-ratio: 5 / 7;
|
|
274
|
-
max-width:
|
|
468
|
+
max-width: 100%;
|
|
469
|
+
overflow: visible;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.stageCardClip {
|
|
473
|
+
position: absolute;
|
|
474
|
+
inset: 0;
|
|
275
475
|
background: var(--castle-card);
|
|
276
|
-
border: 1px solid var(--castle-inspector-border);
|
|
277
476
|
border-radius: 12px;
|
|
278
477
|
overflow: hidden;
|
|
279
478
|
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
|
|
280
479
|
}
|
|
281
480
|
|
|
481
|
+
.stageCardEditSurface {
|
|
482
|
+
overflow: visible;
|
|
483
|
+
}
|
|
484
|
+
|
|
282
485
|
.stageCanvas {
|
|
283
486
|
width: 100%;
|
|
284
487
|
height: 100%;
|
|
@@ -286,6 +489,14 @@
|
|
|
286
489
|
touch-action: none;
|
|
287
490
|
}
|
|
288
491
|
|
|
492
|
+
.stageCanvasEdit {
|
|
493
|
+
position: absolute;
|
|
494
|
+
left: -100%;
|
|
495
|
+
top: -100%;
|
|
496
|
+
width: 300%;
|
|
497
|
+
height: 300%;
|
|
498
|
+
}
|
|
499
|
+
|
|
289
500
|
/* Game-time UI overlay -- sits exactly over the canvas and clips to the card.
|
|
290
501
|
Behavior `ui` output lands in `.sceneUiLayer`, which is sized in card units
|
|
291
502
|
and scaled onto the canvas box. */
|
|
@@ -303,334 +514,1064 @@
|
|
|
303
514
|
transform-origin: 0 0;
|
|
304
515
|
}
|
|
305
516
|
|
|
306
|
-
.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
517
|
+
/* On-canvas selection toolbar ("selection handles"). Two stacked layers cover
|
|
518
|
+
the canvas box (sized by a ResizeObserver, like .sceneUiRoot):
|
|
519
|
+
- .selChromeLayer is the card-unit (500x700) layer, scaled onto the canvas
|
|
520
|
+
and translated by -camera so the dashed box / dots / pivot track the edit
|
|
521
|
+
camera exactly like the canvas draw path. Chrome lives in card units, so it
|
|
522
|
+
scales gently with the responsive card.
|
|
523
|
+
- .selButtonLayer is an un-scaled px layer; the floating buttons are placed
|
|
524
|
+
in projected px (world -> screen) so they stay crisp and fixed-size with
|
|
525
|
+
fixed px gaps regardless of card scale. */
|
|
526
|
+
.selOverlayRoot {
|
|
527
|
+
position: absolute;
|
|
528
|
+
inset: 0;
|
|
529
|
+
overflow: visible;
|
|
530
|
+
pointer-events: none;
|
|
531
|
+
animation: selOverlayIn 150ms ease;
|
|
315
532
|
}
|
|
316
533
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
534
|
+
@keyframes selOverlayIn {
|
|
535
|
+
from {
|
|
536
|
+
opacity: 0;
|
|
537
|
+
transform: scale(0.92);
|
|
538
|
+
}
|
|
539
|
+
to {
|
|
540
|
+
opacity: 1;
|
|
541
|
+
transform: scale(1);
|
|
542
|
+
}
|
|
326
543
|
}
|
|
327
544
|
|
|
328
|
-
.
|
|
329
|
-
|
|
545
|
+
.selChromeLayer {
|
|
546
|
+
position: absolute;
|
|
547
|
+
left: 0;
|
|
548
|
+
top: 0;
|
|
549
|
+
transform-origin: 0 0;
|
|
550
|
+
pointer-events: none;
|
|
330
551
|
}
|
|
331
552
|
|
|
332
|
-
.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
font-size: 16px;
|
|
337
|
-
font-weight: 650;
|
|
553
|
+
.selChromeWorld {
|
|
554
|
+
position: absolute;
|
|
555
|
+
left: 0;
|
|
556
|
+
top: 0;
|
|
338
557
|
}
|
|
339
558
|
|
|
340
|
-
.
|
|
341
|
-
|
|
559
|
+
.selChromeRotate {
|
|
560
|
+
position: absolute;
|
|
561
|
+
left: 0;
|
|
562
|
+
top: 0;
|
|
342
563
|
}
|
|
343
564
|
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
min-height: 28px;
|
|
565
|
+
.selColliderBox {
|
|
566
|
+
position: absolute;
|
|
567
|
+
box-sizing: border-box;
|
|
568
|
+
border: 2px solid rgb(141 183 255 / 0.9);
|
|
569
|
+
background: rgb(141 183 255 / 0.14);
|
|
570
|
+
border-radius: 2px;
|
|
571
|
+
pointer-events: none;
|
|
352
572
|
}
|
|
353
573
|
|
|
354
|
-
.
|
|
355
|
-
|
|
574
|
+
.selColliderPickup {
|
|
575
|
+
border-color: rgb(255 225 122 / 0.9);
|
|
576
|
+
background: rgb(255 225 122 / 0.14);
|
|
356
577
|
}
|
|
357
578
|
|
|
358
|
-
.
|
|
359
|
-
|
|
360
|
-
|
|
579
|
+
.selBox {
|
|
580
|
+
position: absolute;
|
|
581
|
+
border: 2px dashed var(--castle-text);
|
|
582
|
+
border-radius: 3px;
|
|
583
|
+
opacity: 0.85;
|
|
361
584
|
}
|
|
362
585
|
|
|
363
|
-
.
|
|
364
|
-
.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
color: var(--castle-inspector-text);
|
|
371
|
-
padding: 5px 8px;
|
|
372
|
-
outline: 0;
|
|
586
|
+
/* Connector stem from the box's right-center edge to the rotate handle. */
|
|
587
|
+
.selStem {
|
|
588
|
+
position: absolute;
|
|
589
|
+
height: 2px;
|
|
590
|
+
background: var(--castle-text);
|
|
591
|
+
opacity: 0.7;
|
|
592
|
+
transform: translateY(-50%);
|
|
373
593
|
}
|
|
374
594
|
|
|
375
|
-
.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
padding
|
|
379
|
-
background
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
595
|
+
.selScaleHandle {
|
|
596
|
+
position: absolute;
|
|
597
|
+
border: 0;
|
|
598
|
+
padding: 0;
|
|
599
|
+
background: var(--castle-text);
|
|
600
|
+
border: 2px solid var(--castle-selected-ink);
|
|
601
|
+
transform: translate(-50%, -50%);
|
|
602
|
+
pointer-events: auto;
|
|
603
|
+
touch-action: none;
|
|
604
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
|
383
605
|
}
|
|
384
606
|
|
|
385
|
-
.
|
|
386
|
-
|
|
387
|
-
|
|
607
|
+
.selScaleCorner {
|
|
608
|
+
width: 11px;
|
|
609
|
+
height: 11px;
|
|
610
|
+
border-radius: 999px;
|
|
388
611
|
}
|
|
389
612
|
|
|
390
|
-
.
|
|
391
|
-
|
|
392
|
-
appearance: textfield;
|
|
393
|
-
-moz-appearance: textfield;
|
|
613
|
+
.selScaleEdge {
|
|
614
|
+
border-radius: 999px;
|
|
394
615
|
}
|
|
395
616
|
|
|
396
|
-
.
|
|
397
|
-
.
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
margin: 0;
|
|
617
|
+
.selScaleEdge[data-handle='n'],
|
|
618
|
+
.selScaleEdge[data-handle='s'] {
|
|
619
|
+
width: 28px;
|
|
620
|
+
height: 9px;
|
|
401
621
|
}
|
|
402
622
|
|
|
403
|
-
.
|
|
623
|
+
.selScaleEdge[data-handle='e'],
|
|
624
|
+
.selScaleEdge[data-handle='w'] {
|
|
625
|
+
width: 9px;
|
|
626
|
+
height: 28px;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.selPivot {
|
|
404
630
|
position: absolute;
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
631
|
+
width: 13px;
|
|
632
|
+
height: 13px;
|
|
633
|
+
border-radius: 999px;
|
|
634
|
+
border: 2px solid var(--castle-text);
|
|
635
|
+
background: transparent;
|
|
636
|
+
opacity: 0.85;
|
|
637
|
+
transform: translate(-50%, -50%);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.selButtonLayer {
|
|
641
|
+
position: absolute;
|
|
642
|
+
inset: 0;
|
|
413
643
|
pointer-events: none;
|
|
414
|
-
transition: opacity 0.1s;
|
|
415
644
|
}
|
|
416
645
|
|
|
417
|
-
.
|
|
418
|
-
|
|
419
|
-
|
|
646
|
+
.selBtnWrap {
|
|
647
|
+
position: absolute;
|
|
648
|
+
transform: translate(-50%, -50%);
|
|
420
649
|
pointer-events: auto;
|
|
421
650
|
}
|
|
422
651
|
|
|
423
|
-
.
|
|
424
|
-
|
|
652
|
+
.selBtnGroup {
|
|
653
|
+
display: flex;
|
|
654
|
+
gap: 8px;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.selArrangeWrap {
|
|
658
|
+
position: relative;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.selArrangeMenu {
|
|
662
|
+
position: absolute;
|
|
663
|
+
left: 50%;
|
|
664
|
+
top: calc(100% + 8px);
|
|
665
|
+
min-width: 150px;
|
|
666
|
+
padding: 5px;
|
|
667
|
+
border: 1px solid var(--castle-border);
|
|
668
|
+
border-radius: 10px;
|
|
669
|
+
background: var(--castle-panel-raised);
|
|
670
|
+
color: var(--castle-text);
|
|
671
|
+
box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
|
|
672
|
+
transform: translateX(-50%);
|
|
673
|
+
z-index: 2;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
.selArrangeItem {
|
|
677
|
+
width: 100%;
|
|
678
|
+
border: 0;
|
|
679
|
+
border-radius: 7px;
|
|
680
|
+
padding: 7px 9px;
|
|
681
|
+
background: transparent;
|
|
682
|
+
color: inherit;
|
|
683
|
+
cursor: pointer;
|
|
684
|
+
font: inherit;
|
|
685
|
+
font-size: 12px;
|
|
686
|
+
text-align: left;
|
|
687
|
+
white-space: nowrap;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.selArrangeItem:hover {
|
|
691
|
+
background: var(--castle-panel);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.selArrangeItemDisabled,
|
|
695
|
+
.selArrangeItemDisabled:hover {
|
|
696
|
+
opacity: 0.4;
|
|
697
|
+
background: transparent;
|
|
698
|
+
cursor: default;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.selBtn {
|
|
702
|
+
width: 32px;
|
|
703
|
+
height: 32px;
|
|
704
|
+
border-radius: 999px;
|
|
705
|
+
border: 1px solid var(--castle-border);
|
|
706
|
+
background: var(--castle-panel-raised);
|
|
707
|
+
color: var(--castle-text);
|
|
708
|
+
display: inline-flex;
|
|
709
|
+
align-items: center;
|
|
710
|
+
justify-content: center;
|
|
711
|
+
padding: 0;
|
|
712
|
+
font-size: 14px;
|
|
713
|
+
cursor: pointer;
|
|
714
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
|
|
715
|
+
touch-action: none;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
.selBtn:hover {
|
|
719
|
+
background: var(--castle-panel);
|
|
720
|
+
border-color: var(--castle-text-dim);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.selBtn svg {
|
|
724
|
+
width: 1em;
|
|
725
|
+
height: 1em;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.selBtnGrab {
|
|
729
|
+
cursor: grab;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
.selBtnRotate {
|
|
733
|
+
cursor: grab;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/* Touch targets: larger hit area on coarse pointers / compact layout. */
|
|
737
|
+
@media (pointer: coarse), (max-width: 600px) {
|
|
738
|
+
.selBtn {
|
|
739
|
+
width: 44px;
|
|
740
|
+
height: 44px;
|
|
741
|
+
font-size: 18px;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
.selBtnGroup {
|
|
745
|
+
gap: 12px;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.selScaleCorner {
|
|
749
|
+
width: 17px;
|
|
750
|
+
height: 17px;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
.selScaleEdge[data-handle='n'],
|
|
754
|
+
.selScaleEdge[data-handle='s'] {
|
|
755
|
+
width: 38px;
|
|
756
|
+
height: 15px;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.selScaleEdge[data-handle='e'],
|
|
760
|
+
.selScaleEdge[data-handle='w'] {
|
|
761
|
+
width: 15px;
|
|
762
|
+
height: 38px;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
.inspector {
|
|
767
|
+
grid-column: 2;
|
|
768
|
+
grid-row: 1 / span 2;
|
|
769
|
+
min-width: 0;
|
|
770
|
+
border-left: 1px solid var(--castle-inspector-divider);
|
|
771
|
+
background: var(--castle-workspace-bg);
|
|
772
|
+
color: var(--castle-inspector-text);
|
|
773
|
+
font-size: 14px;
|
|
774
|
+
overflow: auto;
|
|
775
|
+
padding: 0;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
.panel {
|
|
779
|
+
border: 0;
|
|
780
|
+
border-bottom: 1px solid var(--castle-inspector-divider);
|
|
781
|
+
border-radius: 0;
|
|
782
|
+
background: var(--castle-inspector-bg);
|
|
783
|
+
color: var(--castle-inspector-text);
|
|
784
|
+
font-size: 14px;
|
|
785
|
+
margin: 0;
|
|
786
|
+
overflow: visible;
|
|
787
|
+
box-shadow: none;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
.panel:last-child {
|
|
791
|
+
border-bottom: 0;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
.panelHeader {
|
|
795
|
+
display: flex;
|
|
796
|
+
align-items: center;
|
|
797
|
+
justify-content: space-between;
|
|
798
|
+
gap: 12px;
|
|
799
|
+
padding: 14px 16px 6px;
|
|
800
|
+
border-bottom: 0;
|
|
801
|
+
color: var(--castle-inspector-text);
|
|
802
|
+
font-size: 14px;
|
|
803
|
+
font-weight: 650;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
.panelBody {
|
|
807
|
+
padding: 8px 16px 4px;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
.fieldRow {
|
|
811
|
+
display: grid;
|
|
812
|
+
grid-template-columns: minmax(82px, 0.5fr) minmax(0, 1fr);
|
|
813
|
+
align-items: center;
|
|
814
|
+
gap: 12px;
|
|
815
|
+
padding-bottom: 12px;
|
|
816
|
+
margin-bottom: 0;
|
|
817
|
+
min-height: 28px;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.fieldRow:last-child {
|
|
821
|
+
margin-bottom: 0;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
.fieldLabel {
|
|
825
|
+
color: var(--castle-inspector-text);
|
|
826
|
+
font-size: 14px;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.input,
|
|
830
|
+
.select,
|
|
831
|
+
.textarea {
|
|
832
|
+
width: 100%;
|
|
833
|
+
border: 1px solid var(--castle-inspector-border);
|
|
834
|
+
border-radius: var(--castle-radius);
|
|
835
|
+
background: var(--castle-inspector-input-bg);
|
|
836
|
+
color: var(--castle-inspector-text);
|
|
837
|
+
padding: 5px 8px;
|
|
838
|
+
outline: 0;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.select {
|
|
842
|
+
appearance: none;
|
|
843
|
+
-webkit-appearance: none;
|
|
844
|
+
padding-right: 26px;
|
|
845
|
+
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='%23888888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
846
|
+
background-repeat: no-repeat;
|
|
847
|
+
background-position: right 8px center;
|
|
848
|
+
text-overflow: ellipsis;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.numberField {
|
|
852
|
+
position: relative;
|
|
853
|
+
width: 100%;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
.numberInput {
|
|
857
|
+
padding-right: 22px;
|
|
858
|
+
appearance: textfield;
|
|
859
|
+
-moz-appearance: textfield;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
.numberInput::-webkit-inner-spin-button,
|
|
863
|
+
.numberInput::-webkit-outer-spin-button {
|
|
864
|
+
-webkit-appearance: none;
|
|
865
|
+
appearance: none;
|
|
866
|
+
margin: 0;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
.numberSteppers {
|
|
870
|
+
position: absolute;
|
|
871
|
+
top: 1px;
|
|
872
|
+
right: 1px;
|
|
873
|
+
bottom: 1px;
|
|
874
|
+
width: 18px;
|
|
875
|
+
display: flex;
|
|
876
|
+
flex-direction: column;
|
|
877
|
+
border-left: 1px solid var(--castle-inspector-divider);
|
|
878
|
+
opacity: 0;
|
|
879
|
+
pointer-events: none;
|
|
880
|
+
transition: opacity 0.1s;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.numberField:hover .numberSteppers,
|
|
884
|
+
.numberField:focus-within .numberSteppers {
|
|
885
|
+
opacity: 1;
|
|
886
|
+
pointer-events: auto;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.numberStepper {
|
|
890
|
+
flex: 1;
|
|
891
|
+
display: flex;
|
|
892
|
+
align-items: center;
|
|
893
|
+
justify-content: center;
|
|
894
|
+
border: 0;
|
|
895
|
+
padding: 0;
|
|
896
|
+
background: transparent;
|
|
897
|
+
color: var(--castle-inspector-muted);
|
|
898
|
+
cursor: pointer;
|
|
899
|
+
font-size: 14px;
|
|
900
|
+
line-height: 1;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.numberStepper:first-child {
|
|
904
|
+
border-bottom: 1px solid var(--castle-inspector-divider);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
.numberStepper:hover {
|
|
908
|
+
background: var(--castle-inspector-input-bg);
|
|
909
|
+
color: var(--castle-inspector-text);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.numberStepper:disabled {
|
|
913
|
+
opacity: 0.3;
|
|
914
|
+
cursor: default;
|
|
915
|
+
background: transparent;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.colorInput {
|
|
919
|
+
width: 100%;
|
|
920
|
+
height: 28px;
|
|
921
|
+
border: 1px solid var(--castle-inspector-border);
|
|
922
|
+
border-radius: var(--castle-radius);
|
|
923
|
+
background: var(--castle-inspector-input-bg);
|
|
924
|
+
padding: 2px;
|
|
925
|
+
outline: 0;
|
|
926
|
+
cursor: pointer;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
.toggle {
|
|
930
|
+
width: 44px;
|
|
931
|
+
height: 24px;
|
|
932
|
+
border: 1px solid var(--castle-inspector-border);
|
|
933
|
+
border-radius: 999px;
|
|
934
|
+
background: var(--castle-inspector-input-bg);
|
|
935
|
+
padding: 2px;
|
|
936
|
+
cursor: pointer;
|
|
937
|
+
display: flex;
|
|
938
|
+
align-items: center;
|
|
939
|
+
justify-content: flex-start;
|
|
940
|
+
box-shadow: none;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.toggleOn {
|
|
944
|
+
background: var(--castle-black);
|
|
945
|
+
justify-content: flex-end;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.toggleKnob {
|
|
949
|
+
width: 18px;
|
|
950
|
+
height: 18px;
|
|
951
|
+
border-radius: 999px;
|
|
952
|
+
background: var(--castle-inspector-muted);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.toggleOn .toggleKnob {
|
|
956
|
+
background: var(--castle-text);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
.textarea {
|
|
960
|
+
min-height: 0;
|
|
961
|
+
resize: none;
|
|
962
|
+
font-family: var(--castle-font-mono);
|
|
963
|
+
font-size: 14px;
|
|
964
|
+
line-height: 1.45;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
/* Shared chrome for the inspector "Button" and every square icon button: a 1px
|
|
968
|
+
border, sunken fill, text-colored glyph, and a subtle drop line. */
|
|
969
|
+
.button,
|
|
970
|
+
.iconButton {
|
|
971
|
+
border: 1px solid var(--castle-inspector-border);
|
|
972
|
+
border-radius: var(--castle-radius);
|
|
973
|
+
background: var(--castle-inspector-button-bg);
|
|
974
|
+
color: var(--castle-inspector-text);
|
|
975
|
+
cursor: pointer;
|
|
976
|
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.button {
|
|
980
|
+
padding: 6px 10px;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/* The square icon button -- the single source of truth every other square icon
|
|
984
|
+
button across the editor matches. Default/hover/active follow the pixel
|
|
985
|
+
editor's eyedropper; the disabled dimming follows the undo button. Fixed
|
|
986
|
+
28x28, never shrinks in a toolbar row, and centers a 14px glyph. */
|
|
987
|
+
.iconButton {
|
|
988
|
+
width: 28px;
|
|
989
|
+
height: 28px;
|
|
990
|
+
flex: 0 0 auto;
|
|
991
|
+
padding: 0;
|
|
992
|
+
display: inline-flex;
|
|
993
|
+
align-items: center;
|
|
994
|
+
justify-content: center;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.iconButton svg {
|
|
998
|
+
width: 14px;
|
|
999
|
+
height: 14px;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.dashedSquareIcon {
|
|
1003
|
+
width: 14px;
|
|
1004
|
+
height: 14px;
|
|
1005
|
+
border: 2px dashed currentColor;
|
|
1006
|
+
border-radius: 2px;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
.button:hover,
|
|
1010
|
+
.iconButton:hover {
|
|
1011
|
+
background: var(--castle-inspector-input-bg);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
.buttonDanger {
|
|
1015
|
+
color: var(--castle-danger);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.button:disabled,
|
|
1019
|
+
.iconButton:disabled {
|
|
1020
|
+
opacity: 0.35;
|
|
1021
|
+
cursor: default;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.actorList {
|
|
1025
|
+
display: grid;
|
|
1026
|
+
gap: 4px;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.actorRow {
|
|
1030
|
+
width: 100%;
|
|
1031
|
+
border: 1px solid transparent;
|
|
1032
|
+
background: transparent;
|
|
1033
|
+
color: var(--castle-inspector-text);
|
|
1034
|
+
border-radius: var(--castle-radius);
|
|
1035
|
+
padding: 7px 8px;
|
|
1036
|
+
text-align: left;
|
|
1037
|
+
cursor: pointer;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
.actorRowSelected {
|
|
1041
|
+
background: var(--castle-black);
|
|
1042
|
+
border-color: var(--castle-black);
|
|
1043
|
+
color: var(--castle-text);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
.drawingEditor,
|
|
1047
|
+
.codeEditor {
|
|
1048
|
+
flex: 1;
|
|
1049
|
+
min-width: 0;
|
|
1050
|
+
min-height: 0;
|
|
1051
|
+
display: grid;
|
|
1052
|
+
grid-template-columns: minmax(320px, 1fr) 280px;
|
|
1053
|
+
background: var(--castle-workspace-bg);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
.drawingEditor {
|
|
1057
|
+
grid-template-columns: minmax(320px, 1fr) minmax(50px, 250px);
|
|
1058
|
+
grid-template-rows: minmax(0, 1fr);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
.drawingEditor > .pxArtInspector {
|
|
1062
|
+
grid-column: 2;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.artboardToolColumn,
|
|
1066
|
+
.paintColumn {
|
|
1067
|
+
flex: 0 0 50px;
|
|
1068
|
+
display: flex;
|
|
1069
|
+
align-items: flex-start;
|
|
1070
|
+
justify-content: center;
|
|
1071
|
+
height: 100%;
|
|
1072
|
+
padding: 8px;
|
|
1073
|
+
box-sizing: border-box;
|
|
1074
|
+
background: var(--castle-workspace-bg);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
.paintColumn {
|
|
1078
|
+
display: none;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.drawingToolColumn {
|
|
1082
|
+
display: flex;
|
|
1083
|
+
align-items: flex-start;
|
|
1084
|
+
justify-content: center;
|
|
1085
|
+
width: 50px;
|
|
1086
|
+
min-width: 0;
|
|
1087
|
+
min-height: 0;
|
|
1088
|
+
height: 100%;
|
|
1089
|
+
padding: 8px;
|
|
1090
|
+
box-sizing: border-box;
|
|
1091
|
+
background: var(--castle-workspace-bg);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
.drawingCanvasWrap {
|
|
1095
|
+
flex: 1 1 0;
|
|
1096
|
+
min-width: 0;
|
|
1097
|
+
min-height: 0;
|
|
1098
|
+
display: flex;
|
|
1099
|
+
align-items: center;
|
|
1100
|
+
justify-content: center;
|
|
1101
|
+
padding: 16px 24px;
|
|
1102
|
+
overflow: hidden;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.artboardStack {
|
|
1106
|
+
display: flex;
|
|
1107
|
+
flex-direction: column;
|
|
1108
|
+
align-items: center;
|
|
1109
|
+
gap: 10px;
|
|
1110
|
+
min-width: 0;
|
|
1111
|
+
max-width: 100%;
|
|
1112
|
+
max-height: 100%;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
.canvasSizeBar {
|
|
1116
|
+
display: flex;
|
|
1117
|
+
align-items: center;
|
|
1118
|
+
gap: 6px;
|
|
1119
|
+
flex: 0 0 auto;
|
|
1120
|
+
font-size: 12px;
|
|
1121
|
+
color: var(--castle-inspector-muted);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
.canvasSizeSep {
|
|
1125
|
+
color: var(--castle-inspector-muted);
|
|
1126
|
+
user-select: none;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
.canvasSizeSelect {
|
|
1130
|
+
width: 52px;
|
|
1131
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1132
|
+
border-radius: var(--castle-radius);
|
|
1133
|
+
background: var(--castle-inspector-input-bg);
|
|
1134
|
+
color: var(--castle-inspector-text);
|
|
1135
|
+
padding: 3px 22px 3px 6px;
|
|
1136
|
+
font-size: 12px;
|
|
1137
|
+
text-align: center;
|
|
1138
|
+
appearance: none;
|
|
1139
|
+
-webkit-appearance: none;
|
|
1140
|
+
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='%23888888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
1141
|
+
background-repeat: no-repeat;
|
|
1142
|
+
background-position: right 6px center;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
.pxArtInspector {
|
|
1146
|
+
min-width: 0;
|
|
1147
|
+
border-left: 1px solid var(--castle-inspector-divider);
|
|
1148
|
+
background: var(--castle-workspace-bg);
|
|
1149
|
+
color: var(--castle-inspector-text);
|
|
1150
|
+
font-size: 14px;
|
|
1151
|
+
overflow: hidden;
|
|
1152
|
+
display: flex;
|
|
1153
|
+
flex-direction: column;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
.paintStrip {
|
|
1157
|
+
display: flex;
|
|
1158
|
+
flex-direction: column;
|
|
1159
|
+
width: 34px;
|
|
1160
|
+
flex: 0 0 auto;
|
|
1161
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1162
|
+
border-radius: var(--castle-radius);
|
|
1163
|
+
overflow: hidden;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.paintStrip > * + * {
|
|
1167
|
+
border-top: 1px solid var(--castle-inspector-border);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
.paintStripColor {
|
|
1171
|
+
width: 34px;
|
|
1172
|
+
height: 34px;
|
|
1173
|
+
padding: 0;
|
|
1174
|
+
border: 0;
|
|
1175
|
+
border-radius: 0;
|
|
1176
|
+
cursor: pointer;
|
|
1177
|
+
flex: 0 0 auto;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.paintStripSlider {
|
|
1181
|
+
height: 100px;
|
|
1182
|
+
display: flex;
|
|
1183
|
+
align-items: center;
|
|
1184
|
+
justify-content: center;
|
|
1185
|
+
padding: 8px 0;
|
|
1186
|
+
flex: 0 0 auto;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
.paintStripModeButton {
|
|
1190
|
+
width: 34px;
|
|
1191
|
+
height: 34px;
|
|
1192
|
+
padding: 0;
|
|
1193
|
+
display: inline-flex;
|
|
1194
|
+
align-items: center;
|
|
1195
|
+
justify-content: center;
|
|
1196
|
+
border: 0;
|
|
1197
|
+
border-radius: 0;
|
|
1198
|
+
background: var(--castle-inspector-button-bg);
|
|
1199
|
+
color: var(--castle-inspector-text);
|
|
1200
|
+
cursor: pointer;
|
|
1201
|
+
font-size: 14px;
|
|
1202
|
+
line-height: 1;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
.paintStripModeButton svg {
|
|
1206
|
+
width: 1em;
|
|
1207
|
+
height: 1em;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
.paintStripModeButton:hover {
|
|
1211
|
+
background: var(--castle-inspector-input-bg);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.drawingSizeSliderVertical {
|
|
1215
|
+
width: 88px;
|
|
1216
|
+
height: 14px;
|
|
1217
|
+
margin: 0;
|
|
1218
|
+
cursor: pointer;
|
|
1219
|
+
transform: rotate(-90deg);
|
|
1220
|
+
appearance: none;
|
|
1221
|
+
-webkit-appearance: none;
|
|
1222
|
+
background: transparent;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.drawingSizeSliderVertical:disabled {
|
|
1226
|
+
cursor: default;
|
|
1227
|
+
opacity: 0.45;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
.drawingSizeSliderVertical::-webkit-slider-runnable-track {
|
|
1231
|
+
height: 4px;
|
|
1232
|
+
border-radius: 999px;
|
|
1233
|
+
background: #4a4a4a;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
.drawingSizeSliderVertical::-webkit-slider-thumb {
|
|
1237
|
+
appearance: none;
|
|
1238
|
+
-webkit-appearance: none;
|
|
1239
|
+
width: 14px;
|
|
1240
|
+
height: 14px;
|
|
1241
|
+
margin-top: -5px;
|
|
1242
|
+
border-radius: 999px;
|
|
1243
|
+
border: 1px solid #d8d8d8;
|
|
1244
|
+
background: #fff;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
.drawingSizeSliderVertical::-moz-range-track {
|
|
1248
|
+
height: 4px;
|
|
1249
|
+
border-radius: 999px;
|
|
1250
|
+
background: #4a4a4a;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
.drawingSizeSliderVertical::-moz-range-thumb {
|
|
1254
|
+
width: 14px;
|
|
1255
|
+
height: 14px;
|
|
1256
|
+
border-radius: 999px;
|
|
1257
|
+
border: 1px solid #d8d8d8;
|
|
1258
|
+
background: #fff;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
.palettePopover {
|
|
1262
|
+
position: fixed;
|
|
1263
|
+
z-index: 200;
|
|
1264
|
+
width: min(280px, calc(100vw - 16px));
|
|
1265
|
+
max-height: min(420px, calc(100vh - 16px));
|
|
1266
|
+
overflow: auto;
|
|
1267
|
+
padding: 12px 14px 14px;
|
|
1268
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1269
|
+
border-radius: var(--castle-radius);
|
|
1270
|
+
background: var(--castle-workspace-bg);
|
|
1271
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
.palettePopoverHeader {
|
|
1275
|
+
display: flex;
|
|
1276
|
+
align-items: center;
|
|
1277
|
+
justify-content: space-between;
|
|
1278
|
+
gap: 10px;
|
|
1279
|
+
margin-bottom: 10px;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
.palettePopoverTitle {
|
|
1283
|
+
font-size: 14px;
|
|
1284
|
+
font-weight: 650;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
.drawingArtboard {
|
|
1288
|
+
min-width: 0;
|
|
1289
|
+
min-height: 0;
|
|
425
1290
|
display: flex;
|
|
426
1291
|
align-items: center;
|
|
427
1292
|
justify-content: center;
|
|
428
|
-
border: 0;
|
|
429
|
-
padding: 0;
|
|
430
|
-
background: transparent;
|
|
431
|
-
color: var(--castle-inspector-muted);
|
|
432
|
-
cursor: pointer;
|
|
433
|
-
font-size: 8px;
|
|
434
|
-
line-height: 1;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
.numberStepper:first-child {
|
|
438
|
-
border-bottom: 1px solid var(--castle-inspector-divider);
|
|
439
1293
|
}
|
|
440
1294
|
|
|
441
|
-
.
|
|
442
|
-
|
|
443
|
-
|
|
1295
|
+
.drawingCanvas {
|
|
1296
|
+
image-rendering: pixelated;
|
|
1297
|
+
background:
|
|
1298
|
+
linear-gradient(45deg, #1a1a1a 25%, transparent 25%),
|
|
1299
|
+
linear-gradient(-45deg, #1a1a1a 25%, transparent 25%),
|
|
1300
|
+
linear-gradient(45deg, transparent 75%, #1a1a1a 75%),
|
|
1301
|
+
linear-gradient(-45deg, transparent 75%, #1a1a1a 75%);
|
|
1302
|
+
background-color: #121212;
|
|
1303
|
+
background-size: 16px 16px;
|
|
1304
|
+
background-position:
|
|
1305
|
+
0 0,
|
|
1306
|
+
0 8px,
|
|
1307
|
+
8px -8px,
|
|
1308
|
+
-8px 0;
|
|
1309
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1310
|
+
flex: 0 0 auto;
|
|
444
1311
|
}
|
|
445
1312
|
|
|
446
|
-
.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1313
|
+
.palette {
|
|
1314
|
+
display: grid;
|
|
1315
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
1316
|
+
gap: 4px;
|
|
1317
|
+
padding-bottom: 12px;
|
|
450
1318
|
}
|
|
451
1319
|
|
|
452
|
-
.
|
|
453
|
-
|
|
454
|
-
height: 28px;
|
|
1320
|
+
.swatch {
|
|
1321
|
+
aspect-ratio: 1;
|
|
455
1322
|
border: 1px solid var(--castle-inspector-border);
|
|
456
1323
|
border-radius: var(--castle-radius);
|
|
457
|
-
background: var(--castle-inspector-input-bg);
|
|
458
|
-
padding: 2px;
|
|
459
|
-
outline: 0;
|
|
460
1324
|
cursor: pointer;
|
|
461
1325
|
}
|
|
462
1326
|
|
|
463
|
-
.
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
border-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
display: flex;
|
|
472
|
-
align-items: center;
|
|
473
|
-
justify-content: flex-start;
|
|
474
|
-
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
|
|
1327
|
+
/* Selected paint color. A double ring — light on the inside, dark on the
|
|
1328
|
+
outside — so the selection stays legible over ANY of the 64 swatch colors
|
|
1329
|
+
(a single-color border can vanish against a similar swatch). */
|
|
1330
|
+
.swatchSelected {
|
|
1331
|
+
border-color: transparent;
|
|
1332
|
+
box-shadow:
|
|
1333
|
+
inset 0 0 0 2px #fff,
|
|
1334
|
+
0 0 0 2px var(--castle-black);
|
|
475
1335
|
}
|
|
476
1336
|
|
|
477
|
-
.
|
|
478
|
-
|
|
479
|
-
|
|
1337
|
+
.drawingToolStrip {
|
|
1338
|
+
display: flex;
|
|
1339
|
+
flex-direction: column;
|
|
1340
|
+
width: 34px;
|
|
1341
|
+
flex: 0 0 auto;
|
|
1342
|
+
max-height: 100%;
|
|
1343
|
+
overflow: auto;
|
|
1344
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1345
|
+
border-radius: var(--castle-radius);
|
|
480
1346
|
}
|
|
481
1347
|
|
|
482
|
-
.
|
|
483
|
-
|
|
484
|
-
height: 18px;
|
|
485
|
-
border-radius: 999px;
|
|
486
|
-
background: var(--castle-black);
|
|
1348
|
+
.drawingToolStrip > * + * {
|
|
1349
|
+
border-top: 1px solid var(--castle-inspector-border);
|
|
487
1350
|
}
|
|
488
1351
|
|
|
489
|
-
.
|
|
490
|
-
|
|
1352
|
+
.drawingToolsPanel {
|
|
1353
|
+
overflow: hidden;
|
|
1354
|
+
display: flex;
|
|
1355
|
+
flex-direction: column;
|
|
491
1356
|
}
|
|
492
1357
|
|
|
493
|
-
.
|
|
1358
|
+
.drawingToolsPanelBody {
|
|
1359
|
+
flex: 1 1 0;
|
|
494
1360
|
min-height: 0;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
font-size: 12px;
|
|
498
|
-
line-height: 1.45;
|
|
1361
|
+
display: grid;
|
|
1362
|
+
grid-template-columns: 58px minmax(0, 1fr);
|
|
499
1363
|
}
|
|
500
1364
|
|
|
501
|
-
.
|
|
502
|
-
|
|
503
|
-
|
|
1365
|
+
.drawingSettingsColumn {
|
|
1366
|
+
min-width: 0;
|
|
1367
|
+
height: 100%;
|
|
1368
|
+
overflow: auto;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
.drawingToolButton,
|
|
1372
|
+
.drawingSizeButton {
|
|
504
1373
|
background: var(--castle-inspector-button-bg);
|
|
505
1374
|
color: var(--castle-inspector-text);
|
|
506
|
-
padding: 6px 10px;
|
|
507
1375
|
cursor: pointer;
|
|
508
|
-
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
|
|
509
1376
|
}
|
|
510
1377
|
|
|
511
|
-
.
|
|
1378
|
+
.drawingToolButton {
|
|
512
1379
|
width: 34px;
|
|
513
1380
|
height: 34px;
|
|
514
1381
|
padding: 0;
|
|
515
1382
|
display: inline-flex;
|
|
516
1383
|
align-items: center;
|
|
517
1384
|
justify-content: center;
|
|
1385
|
+
font-size: 14px;
|
|
1386
|
+
line-height: 1;
|
|
1387
|
+
border: 0;
|
|
1388
|
+
border-radius: 0;
|
|
518
1389
|
}
|
|
519
1390
|
|
|
520
|
-
.
|
|
1391
|
+
.drawingToolButton svg {
|
|
521
1392
|
width: 1em;
|
|
522
1393
|
height: 1em;
|
|
523
1394
|
}
|
|
524
1395
|
|
|
525
|
-
.
|
|
526
|
-
background:
|
|
1396
|
+
.drawingToolButton:hover {
|
|
1397
|
+
background: var(--castle-inspector-input-bg);
|
|
527
1398
|
}
|
|
528
1399
|
|
|
529
|
-
.
|
|
530
|
-
.
|
|
531
|
-
|
|
532
|
-
border-color: var(--castle-black);
|
|
533
|
-
color: var(--castle-text);
|
|
1400
|
+
.drawingToolButton:disabled {
|
|
1401
|
+
opacity: 0.35;
|
|
1402
|
+
cursor: default;
|
|
534
1403
|
}
|
|
535
1404
|
|
|
536
|
-
|
|
537
|
-
.
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
1405
|
+
/* Active / selected square icon button -- the eyedropper reference: a light
|
|
1406
|
+
fill with a dark glyph. The single selected/engaged look shared by the
|
|
1407
|
+
IconButton component (`active`), the onion-skin toggle, and the pixel
|
|
1408
|
+
editors' tool strip.
|
|
1409
|
+
|
|
1410
|
+
These use COMPOUND selectors (`.button.buttonActive`,
|
|
1411
|
+
`.drawingToolButton.drawingToolSelected`) on purpose: every active button
|
|
1412
|
+
already carries both classes, so the (0,2,0)/(0,3,0) specificity beats the
|
|
1413
|
+
equal-specificity base + size rules (`.button`/`.iconButton`,
|
|
1414
|
+
`.drawingToolButton`) NO MATTER the source order. A bare `.buttonActive`
|
|
1415
|
+
ties those base rules on specificity and only wins if it happens to appear
|
|
1416
|
+
later in the file -- which Vite HMR can reshuffle when this module is edited,
|
|
1417
|
+
silently dropping the active fill. The compound selector removes that
|
|
1418
|
+
fragility. */
|
|
1419
|
+
.button.buttonActive,
|
|
1420
|
+
.drawingToolButton.drawingToolSelected,
|
|
1421
|
+
.paintStripModeButton.drawingToolSelected {
|
|
1422
|
+
background: var(--castle-selected);
|
|
1423
|
+
border-color: var(--castle-selected);
|
|
1424
|
+
color: var(--castle-selected-ink);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
.button.buttonActive:hover,
|
|
1428
|
+
.drawingToolButton.drawingToolSelected:hover,
|
|
1429
|
+
.paintStripModeButton.drawingToolSelected:hover {
|
|
1430
|
+
background: var(--castle-selected);
|
|
1431
|
+
border-color: var(--castle-selected);
|
|
1432
|
+
color: var(--castle-selected-ink);
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
.drawingToolHint {
|
|
1436
|
+
color: var(--castle-inspector-muted);
|
|
1437
|
+
font-size: 14px;
|
|
1438
|
+
line-height: 1.35;
|
|
1439
|
+
padding-bottom: 8px;
|
|
541
1440
|
}
|
|
542
1441
|
|
|
543
|
-
.
|
|
544
|
-
|
|
1442
|
+
.drawingToolSettings {
|
|
1443
|
+
padding-bottom: 8px;
|
|
545
1444
|
}
|
|
546
1445
|
|
|
547
|
-
.
|
|
548
|
-
|
|
549
|
-
|
|
1446
|
+
.drawingSizePicker {
|
|
1447
|
+
display: grid;
|
|
1448
|
+
gap: 8px;
|
|
1449
|
+
padding-bottom: 8px;
|
|
550
1450
|
}
|
|
551
1451
|
|
|
552
|
-
.
|
|
1452
|
+
.drawingSizeLabel {
|
|
1453
|
+
display: flex;
|
|
1454
|
+
align-items: baseline;
|
|
1455
|
+
justify-content: space-between;
|
|
1456
|
+
gap: 10px;
|
|
1457
|
+
color: var(--castle-inspector-muted);
|
|
1458
|
+
font-size: 14px;
|
|
1459
|
+
line-height: 1.35;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
.drawingSizeLabel span:last-child {
|
|
1463
|
+
color: var(--castle-inspector-text);
|
|
1464
|
+
font-variant-numeric: tabular-nums;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
.drawingSizeControlRow {
|
|
553
1468
|
display: grid;
|
|
554
|
-
|
|
1469
|
+
grid-template-columns: minmax(0, 1fr);
|
|
1470
|
+
align-items: center;
|
|
1471
|
+
gap: 10px;
|
|
555
1472
|
}
|
|
556
1473
|
|
|
557
|
-
.
|
|
1474
|
+
.drawingSizeSlider {
|
|
558
1475
|
width: 100%;
|
|
559
|
-
border: 1px solid transparent;
|
|
560
|
-
background: transparent;
|
|
561
|
-
color: var(--castle-inspector-text);
|
|
562
|
-
border-radius: var(--castle-radius);
|
|
563
|
-
padding: 7px 8px;
|
|
564
|
-
text-align: left;
|
|
565
1476
|
cursor: pointer;
|
|
1477
|
+
appearance: none;
|
|
1478
|
+
-webkit-appearance: none;
|
|
1479
|
+
background: transparent;
|
|
566
1480
|
}
|
|
567
1481
|
|
|
568
|
-
.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
color: var(--castle-text);
|
|
1482
|
+
.drawingSizeSlider:disabled {
|
|
1483
|
+
cursor: default;
|
|
1484
|
+
opacity: 0.45;
|
|
572
1485
|
}
|
|
573
1486
|
|
|
574
|
-
.
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
min-height: 0;
|
|
579
|
-
display: grid;
|
|
580
|
-
grid-template-columns: minmax(320px, 1fr) 280px;
|
|
581
|
-
background: var(--castle-workspace-bg);
|
|
1487
|
+
.drawingSizeSlider::-webkit-slider-runnable-track {
|
|
1488
|
+
height: 4px;
|
|
1489
|
+
border-radius: 999px;
|
|
1490
|
+
background: #4a4a4a;
|
|
582
1491
|
}
|
|
583
1492
|
|
|
584
|
-
.
|
|
585
|
-
|
|
1493
|
+
.drawingSizeSlider::-webkit-slider-thumb {
|
|
1494
|
+
appearance: none;
|
|
1495
|
+
-webkit-appearance: none;
|
|
1496
|
+
width: 14px;
|
|
1497
|
+
height: 14px;
|
|
1498
|
+
margin-top: -5px;
|
|
1499
|
+
border-radius: 999px;
|
|
1500
|
+
border: 1px solid #d8d8d8;
|
|
1501
|
+
background: #fff;
|
|
586
1502
|
}
|
|
587
1503
|
|
|
588
|
-
.
|
|
589
|
-
|
|
590
|
-
|
|
1504
|
+
.drawingFillToggle {
|
|
1505
|
+
min-height: 28px;
|
|
1506
|
+
padding: 4px 9px;
|
|
1507
|
+
border: 1px solid var(--castle-inspector-border);
|
|
1508
|
+
border-radius: var(--castle-radius);
|
|
1509
|
+
background: var(--castle-inspector-button-bg);
|
|
1510
|
+
color: var(--castle-inspector-text);
|
|
1511
|
+
cursor: pointer;
|
|
1512
|
+
font-size: 14px;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
.drawingFillToggleOn {
|
|
1516
|
+
background: var(--castle-selected);
|
|
1517
|
+
border-color: var(--castle-selected);
|
|
1518
|
+
color: var(--castle-selected-ink);
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
.drawingModeRow {
|
|
591
1522
|
display: flex;
|
|
592
1523
|
align-items: center;
|
|
593
|
-
justify-content:
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
1524
|
+
justify-content: space-between;
|
|
1525
|
+
gap: 12px;
|
|
1526
|
+
color: var(--castle-inspector-muted);
|
|
1527
|
+
font-size: 14px;
|
|
1528
|
+
line-height: 1.35;
|
|
597
1529
|
}
|
|
598
1530
|
|
|
599
|
-
.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
linear-gradient(45deg, transparent 75%, #ddd 75%),
|
|
605
|
-
linear-gradient(-45deg, transparent 75%, #ddd 75%);
|
|
606
|
-
background-size: 16px 16px;
|
|
607
|
-
background-position:
|
|
608
|
-
0 0,
|
|
609
|
-
0 8px,
|
|
610
|
-
8px -8px,
|
|
611
|
-
-8px 0;
|
|
1531
|
+
.drawingSwitch {
|
|
1532
|
+
position: relative;
|
|
1533
|
+
width: 34px;
|
|
1534
|
+
height: 20px;
|
|
1535
|
+
padding: 0;
|
|
612
1536
|
border: 1px solid var(--castle-inspector-border);
|
|
613
|
-
|
|
614
|
-
|
|
1537
|
+
border-radius: 999px;
|
|
1538
|
+
background: #343434;
|
|
1539
|
+
cursor: pointer;
|
|
615
1540
|
}
|
|
616
1541
|
|
|
617
|
-
.
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
gap: 6px;
|
|
621
|
-
padding-bottom: 12px;
|
|
1542
|
+
.drawingSwitchOn {
|
|
1543
|
+
border-color: var(--castle-selected);
|
|
1544
|
+
background: var(--castle-selected);
|
|
622
1545
|
}
|
|
623
1546
|
|
|
624
|
-
.
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
1547
|
+
.drawingSwitchKnob {
|
|
1548
|
+
position: absolute;
|
|
1549
|
+
top: 2px;
|
|
1550
|
+
left: 2px;
|
|
1551
|
+
width: 14px;
|
|
1552
|
+
height: 14px;
|
|
1553
|
+
border-radius: 999px;
|
|
1554
|
+
background: #fff;
|
|
1555
|
+
box-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
|
|
1556
|
+
transition: transform 120ms ease;
|
|
629
1557
|
}
|
|
630
1558
|
|
|
631
|
-
.
|
|
632
|
-
|
|
633
|
-
|
|
1559
|
+
.drawingSwitchOn .drawingSwitchKnob {
|
|
1560
|
+
transform: translateX(14px);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
.drawingSizeSlider::-moz-range-track {
|
|
1564
|
+
height: 4px;
|
|
1565
|
+
border-radius: 999px;
|
|
1566
|
+
background: #4a4a4a;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
.drawingSizeSlider::-moz-range-thumb {
|
|
1570
|
+
width: 14px;
|
|
1571
|
+
height: 14px;
|
|
1572
|
+
border-radius: 999px;
|
|
1573
|
+
border: 1px solid #d8d8d8;
|
|
1574
|
+
background: #fff;
|
|
634
1575
|
}
|
|
635
1576
|
|
|
636
1577
|
.codeEditor {
|
|
@@ -643,28 +1584,8 @@
|
|
|
643
1584
|
height: 100%;
|
|
644
1585
|
}
|
|
645
1586
|
|
|
646
|
-
.headerFilesButton {
|
|
647
|
-
width: 34px;
|
|
648
|
-
height: 34px;
|
|
649
|
-
border: 1px solid var(--castle-inspector-border);
|
|
650
|
-
border-radius: var(--castle-radius);
|
|
651
|
-
background: var(--castle-inspector-button-bg);
|
|
652
|
-
color: var(--castle-inspector-text);
|
|
653
|
-
cursor: pointer;
|
|
654
|
-
align-items: center;
|
|
655
|
-
justify-content: center;
|
|
656
|
-
flex: 0 0 34px;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
.headerFilesButton[aria-pressed='true'] {
|
|
660
|
-
background: var(--castle-black);
|
|
661
|
-
border-color: var(--castle-black);
|
|
662
|
-
color: var(--castle-text);
|
|
663
|
-
}
|
|
664
|
-
|
|
665
1587
|
/* mobileOnly comes AFTER element-specific rules so `display: none` wins on desktop. */
|
|
666
1588
|
.mobileOnly,
|
|
667
|
-
.headerFilesButton,
|
|
668
1589
|
.sheetBackdrop,
|
|
669
1590
|
.sheetGrab,
|
|
670
1591
|
.sheetGrabBar,
|
|
@@ -674,7 +1595,7 @@
|
|
|
674
1595
|
display: none;
|
|
675
1596
|
}
|
|
676
1597
|
|
|
677
|
-
@media (max-width:
|
|
1598
|
+
@media (max-width: 600px) {
|
|
678
1599
|
:root {
|
|
679
1600
|
--sheet-high-height: 62vh;
|
|
680
1601
|
--sheet-low-height: 18vh;
|
|
@@ -686,10 +1607,6 @@
|
|
|
686
1607
|
display: contents;
|
|
687
1608
|
}
|
|
688
1609
|
|
|
689
|
-
.headerFilesButton {
|
|
690
|
-
display: inline-flex;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
1610
|
/* Backdrop sits below the header so the files toggle stays interactive. */
|
|
694
1611
|
.sheetBackdrop {
|
|
695
1612
|
display: block;
|
|
@@ -735,7 +1652,7 @@
|
|
|
735
1652
|
}
|
|
736
1653
|
|
|
737
1654
|
.editorTitle {
|
|
738
|
-
font-size:
|
|
1655
|
+
font-size: 14px;
|
|
739
1656
|
overflow: hidden;
|
|
740
1657
|
text-overflow: ellipsis;
|
|
741
1658
|
white-space: nowrap;
|
|
@@ -747,15 +1664,11 @@
|
|
|
747
1664
|
white-space: nowrap;
|
|
748
1665
|
}
|
|
749
1666
|
|
|
750
|
-
/*
|
|
751
|
-
|
|
752
|
-
.drawingTools {
|
|
753
|
-
display: none;
|
|
754
|
-
}
|
|
755
|
-
|
|
1667
|
+
/* Scene hotbar row stays visible when compact (it holds drag-and-drop
|
|
1668
|
+
blueprints later). Drawing playback lives in the header instead. */
|
|
756
1669
|
.sceneWorkspace {
|
|
757
1670
|
grid-template-columns: 1fr;
|
|
758
|
-
grid-template-rows: minmax(0, 1fr);
|
|
1671
|
+
grid-template-rows: var(--castle-hotbar-row-full) minmax(0, 1fr);
|
|
759
1672
|
}
|
|
760
1673
|
|
|
761
1674
|
.drawingEditor {
|
|
@@ -765,29 +1678,33 @@
|
|
|
765
1678
|
|
|
766
1679
|
.stageWrap {
|
|
767
1680
|
grid-column: 1;
|
|
768
|
-
grid-row:
|
|
1681
|
+
grid-row: 2;
|
|
769
1682
|
align-items: flex-start;
|
|
770
1683
|
padding: 10px 12px 12px;
|
|
771
1684
|
background: var(--castle-stage-workspace-bg);
|
|
772
1685
|
}
|
|
773
1686
|
|
|
1687
|
+
/* One-column layout: the card MUST keep a definite width. Its clip/canvas
|
|
1688
|
+
children are absolutely positioned (no intrinsic size), so a flex item with
|
|
1689
|
+
`width: auto` + `aspect-ratio` collapses to 0x0 -- the stage went blank and
|
|
1690
|
+
only the dark `.stageWrap` showed. Drive width from the viewport (capped by
|
|
1691
|
+
480px and by 62vh so the aspect-derived height always fits without
|
|
1692
|
+
`max-height` clamping and distorting the maze). */
|
|
774
1693
|
.stageCard {
|
|
775
|
-
|
|
1694
|
+
width: min(92vw, 480px, 62vh);
|
|
1695
|
+
max-width: 100%;
|
|
776
1696
|
max-height: 100%;
|
|
777
|
-
width: auto;
|
|
778
1697
|
}
|
|
779
1698
|
|
|
780
|
-
/*
|
|
1699
|
+
/* PxArt artboard: keep flanking tool/paint columns; fit hook drives canvas size. */
|
|
781
1700
|
.drawingCanvasWrap {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
align-items: flex-start;
|
|
785
|
-
padding: 6vh 16px 16px;
|
|
1701
|
+
align-items: center;
|
|
1702
|
+
padding: 10px 8px 12px;
|
|
786
1703
|
}
|
|
787
1704
|
|
|
788
|
-
.
|
|
789
|
-
|
|
790
|
-
|
|
1705
|
+
.artboardToolColumn,
|
|
1706
|
+
.paintColumn {
|
|
1707
|
+
padding: 8px 4px;
|
|
791
1708
|
}
|
|
792
1709
|
|
|
793
1710
|
/* File-browser + inspector sheets share fixed-bottom positioning, height,
|
|
@@ -823,23 +1740,17 @@
|
|
|
823
1740
|
transform: translateY(0);
|
|
824
1741
|
}
|
|
825
1742
|
|
|
826
|
-
/* Hide the desktop fileBrowserHeader on mobile (the grab handle replaces it). */
|
|
827
|
-
.fileBrowserHeader {
|
|
828
|
-
display: none;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
1743
|
.fileTree {
|
|
832
1744
|
flex: 1 1 0;
|
|
833
1745
|
min-height: 0;
|
|
834
1746
|
overflow-y: auto;
|
|
835
|
-
padding: 4px 6px 12px;
|
|
836
1747
|
}
|
|
837
1748
|
|
|
838
1749
|
/* Inspector sheet: hidden off-screen by default; slides up to high (full) or low (partial). */
|
|
839
1750
|
.inspector {
|
|
840
1751
|
z-index: 45;
|
|
841
1752
|
border-left: 0;
|
|
842
|
-
background: var(--castle-
|
|
1753
|
+
background: var(--castle-workspace-bg);
|
|
843
1754
|
padding: 0;
|
|
844
1755
|
}
|
|
845
1756
|
|
|
@@ -875,7 +1786,7 @@
|
|
|
875
1786
|
}
|
|
876
1787
|
|
|
877
1788
|
.inspector .sheetGrab {
|
|
878
|
-
background: var(--castle-
|
|
1789
|
+
background: var(--castle-workspace-bg);
|
|
879
1790
|
}
|
|
880
1791
|
|
|
881
1792
|
.sheetGrabBar {
|
|
@@ -907,7 +1818,7 @@
|
|
|
907
1818
|
|
|
908
1819
|
.sheetGrabHint {
|
|
909
1820
|
display: inline;
|
|
910
|
-
font-size:
|
|
1821
|
+
font-size: 14px;
|
|
911
1822
|
color: var(--castle-inspector-muted);
|
|
912
1823
|
overflow: hidden;
|
|
913
1824
|
text-overflow: ellipsis;
|
|
@@ -922,7 +1833,7 @@
|
|
|
922
1833
|
}
|
|
923
1834
|
|
|
924
1835
|
.inspectorBody {
|
|
925
|
-
background: var(--castle-
|
|
1836
|
+
background: var(--castle-workspace-bg);
|
|
926
1837
|
}
|
|
927
1838
|
|
|
928
1839
|
.codeInspectorInfo {
|
|
@@ -930,38 +1841,63 @@
|
|
|
930
1841
|
grid-template-columns: 80px 1fr;
|
|
931
1842
|
gap: 6px 12px;
|
|
932
1843
|
padding: 14px 16px;
|
|
933
|
-
font-size:
|
|
1844
|
+
font-size: 14px;
|
|
934
1845
|
color: var(--castle-inspector-text);
|
|
935
1846
|
word-break: break-all;
|
|
936
1847
|
}
|
|
937
1848
|
}
|
|
938
1849
|
|
|
939
|
-
/* Bare (panel) editor wrapper: fills the panel iframe; single column.
|
|
1850
|
+
/* Bare (panel) editor wrapper: fills the panel iframe; single column.
|
|
1851
|
+
Use 100% not 100vw/100vh — in a dock iframe vw/vh are the TOP-LEVEL
|
|
1852
|
+
viewport, so the editor "thinks" it is full-window-wide and container
|
|
1853
|
+
queries on .editorBody never flip to compact. */
|
|
940
1854
|
.panelBare {
|
|
941
1855
|
display: grid;
|
|
942
1856
|
grid-template-columns: 1fr;
|
|
943
|
-
width:
|
|
944
|
-
height:
|
|
1857
|
+
width: 100%;
|
|
1858
|
+
height: 100%;
|
|
1859
|
+
min-width: 0;
|
|
1860
|
+
min-height: 0;
|
|
945
1861
|
background: var(--castle-workspace-bg);
|
|
946
1862
|
}
|
|
947
|
-
/* In a panel the editor
|
|
948
|
-
|
|
949
|
-
|
|
1863
|
+
/* In a panel the scene editor's tools row must stay visible even below 860px --
|
|
1864
|
+
it normally moves into the mobile header, which bare mode removes. Restore the
|
|
1865
|
+
full-height tools row (--castle-hotbar-row-full, same as the desktop track) and
|
|
1866
|
+
put the stage back in row 2 (the narrow layout moves it up into row 1). The row
|
|
1867
|
+
must use the full height -- a shorter hardcoded track left the centered 46px
|
|
1868
|
+
hotbar buttons overhanging the stage, which clipped their bottoms.
|
|
1869
|
+
|
|
1870
|
+
The PxArt editor (.drawingEditor) is intentionally NOT included here: it has
|
|
1871
|
+
no docked tools row (its controls live in the header), and its left column
|
|
1872
|
+
(.editorLeft) is pinned to grid-row 1, so injecting a 48px first row collapsed
|
|
1873
|
+
the artboard to zero height across the 600-860px band. PxArt compact layout
|
|
1874
|
+
is driven by the @container editor (max-width: 620px) rule on .editorBody. */
|
|
950
1875
|
@media (max-width: 860px) {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
.panelBare .sceneWorkspace,
|
|
954
|
-
.panelBare .drawingEditor {
|
|
955
|
-
grid-template-rows: 48px minmax(0, 1fr);
|
|
1876
|
+
.panelBare .sceneWorkspace {
|
|
1877
|
+
grid-template-rows: var(--castle-hotbar-row-full) minmax(0, 1fr);
|
|
956
1878
|
}
|
|
957
1879
|
.panelBare .sceneTools {
|
|
958
1880
|
display: grid;
|
|
959
1881
|
}
|
|
960
|
-
.panelBare .
|
|
961
|
-
display: flex;
|
|
962
|
-
}
|
|
963
|
-
.panelBare .stageWrap,
|
|
964
|
-
.panelBare .drawingCanvasWrap {
|
|
1882
|
+
.panelBare .stageWrap {
|
|
965
1883
|
grid-row: 2;
|
|
966
1884
|
}
|
|
967
1885
|
}
|
|
1886
|
+
|
|
1887
|
+
/* PxArt compact layout — MUST stay after .drawingToolsPanel / .paintColumn base
|
|
1888
|
+
rules so these container-query overrides win the cascade (same element carries
|
|
1889
|
+
pxArtInspector + drawingToolsPanel; a later bare .drawingToolsPanel{display:flex}
|
|
1890
|
+
was keeping the sidebar visible beside the paint strip). */
|
|
1891
|
+
@container editor (max-width: 620px) {
|
|
1892
|
+
.drawingEditor {
|
|
1893
|
+
grid-template-columns: 1fr;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
.drawingEditor > .pxArtInspector.drawingToolsPanel {
|
|
1897
|
+
display: none;
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
.paintColumn {
|
|
1901
|
+
display: flex;
|
|
1902
|
+
}
|
|
1903
|
+
}
|