@bloopjs/web 0.0.90 → 0.0.92
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/App.d.ts.map +1 -1
- package/dist/debugui/components/BottomBar.d.ts.map +1 -1
- package/dist/debugui/components/LoadTapeDialog.d.ts +2 -0
- package/dist/debugui/components/LoadTapeDialog.d.ts.map +1 -0
- package/dist/debugui/state.d.ts +9 -0
- package/dist/debugui/state.d.ts.map +1 -1
- package/dist/debugui/styles.d.ts +1 -1
- package/dist/debugui/styles.d.ts.map +1 -1
- package/dist/mod.js +560 -64
- package/dist/mod.js.map +10 -9
- package/package.json +3 -3
- package/src/App.ts +3 -1
- package/src/debugui/components/BottomBar.tsx +25 -5
- package/src/debugui/components/LoadTapeDialog.tsx +112 -0
- package/src/debugui/state.ts +105 -0
- package/src/debugui/styles.ts +256 -18
package/src/debugui/styles.ts
CHANGED
|
@@ -4,10 +4,26 @@ export const styles = /*css*/ `
|
|
|
4
4
|
box-sizing: border-box;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
/* Mobile-first CSS variables */
|
|
8
|
+
:host {
|
|
9
|
+
--bar-size: 10vw;
|
|
10
|
+
--bar-size-h: 10vh;
|
|
11
|
+
--bar-size-h: 10dvh;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Desktop overrides */
|
|
15
|
+
@media (min-width: 769px) {
|
|
16
|
+
:host {
|
|
17
|
+
--bar-size: 2vw;
|
|
18
|
+
--bar-size-h: 2vh;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
/* Layout */
|
|
8
23
|
.fullscreen {
|
|
9
24
|
width: 100vw;
|
|
10
25
|
height: 100vh;
|
|
26
|
+
height: 100dvh;
|
|
11
27
|
margin: 0;
|
|
12
28
|
padding: 0;
|
|
13
29
|
overflow: hidden;
|
|
@@ -24,17 +40,96 @@ export const styles = /*css*/ `
|
|
|
24
40
|
display: block;
|
|
25
41
|
}
|
|
26
42
|
|
|
43
|
+
/* Mobile-first: vertical scroll layout */
|
|
27
44
|
.layout {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
/* Use fixed position on mobile to escape parent overflow:hidden */
|
|
46
|
+
position: fixed;
|
|
47
|
+
top: 0;
|
|
48
|
+
left: 0;
|
|
49
|
+
right: 0;
|
|
50
|
+
bottom: 0;
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
overflow-y: auto;
|
|
54
|
+
overflow-x: hidden;
|
|
55
|
+
-webkit-overflow-scrolling: touch;
|
|
56
|
+
overscroll-behavior-y: contain;
|
|
57
|
+
padding: 0;
|
|
58
|
+
gap: 0;
|
|
59
|
+
background: #1a1a1a;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.layout .game {
|
|
63
|
+
/* Use dvh with vh fallback for mobile Safari address bar */
|
|
64
|
+
height: 100vh;
|
|
65
|
+
height: 100dvh;
|
|
66
|
+
width: 100%;
|
|
67
|
+
flex-shrink: 0;
|
|
68
|
+
/* Mobile: no border radius, fullscreen game */
|
|
69
|
+
border-radius: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Mobile: stretch canvas to fill game area */
|
|
73
|
+
.layout .game .canvas-container {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.layout .game .canvas-container canvas {
|
|
35
79
|
width: 100%;
|
|
36
80
|
height: 100%;
|
|
81
|
+
max-width: none;
|
|
82
|
+
max-height: none;
|
|
83
|
+
display: block;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.layout .stats,
|
|
87
|
+
.layout .logs {
|
|
88
|
+
width: 100%;
|
|
89
|
+
min-height: 50vh;
|
|
90
|
+
min-height: 50dvh;
|
|
37
91
|
padding: 1rem;
|
|
92
|
+
flex-shrink: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Desktop: 2x2 grid layout */
|
|
96
|
+
@media (min-width: 769px) {
|
|
97
|
+
.layout {
|
|
98
|
+
position: static;
|
|
99
|
+
display: grid;
|
|
100
|
+
grid-template-areas:
|
|
101
|
+
"game stats"
|
|
102
|
+
"logs logs";
|
|
103
|
+
grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);
|
|
104
|
+
grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);
|
|
105
|
+
gap: 1rem;
|
|
106
|
+
padding: 1rem;
|
|
107
|
+
height: 100%;
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
-webkit-overflow-scrolling: auto;
|
|
110
|
+
overscroll-behavior-y: auto;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.layout .game {
|
|
114
|
+
height: auto;
|
|
115
|
+
flex-shrink: initial;
|
|
116
|
+
border-radius: 8px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Desktop: restore centered canvas with constraints */
|
|
120
|
+
.layout .game .canvas-container canvas {
|
|
121
|
+
width: auto;
|
|
122
|
+
height: auto;
|
|
123
|
+
max-width: 100%;
|
|
124
|
+
max-height: 100%;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.layout .stats,
|
|
128
|
+
.layout .logs {
|
|
129
|
+
min-height: auto;
|
|
130
|
+
padding: 1rem;
|
|
131
|
+
flex-shrink: initial;
|
|
132
|
+
}
|
|
38
133
|
}
|
|
39
134
|
|
|
40
135
|
/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */
|
|
@@ -44,10 +139,12 @@ export const styles = /*css*/ `
|
|
|
44
139
|
"top-bar top-bar top-bar"
|
|
45
140
|
"left-bar game right-bar"
|
|
46
141
|
"bottom-bar bottom-bar bottom-bar";
|
|
47
|
-
grid-template-columns:
|
|
48
|
-
grid-template-rows:
|
|
142
|
+
grid-template-columns: var(--bar-size) 1fr var(--bar-size);
|
|
143
|
+
grid-template-rows: var(--bar-size-h) 1fr var(--bar-size-h);
|
|
49
144
|
width: 100vw;
|
|
145
|
+
/* Use dvh with vh fallback for mobile Safari address bar */
|
|
50
146
|
height: 100vh;
|
|
147
|
+
height: 100dvh;
|
|
51
148
|
background: #1a1a1a;
|
|
52
149
|
overflow: hidden;
|
|
53
150
|
overscroll-behavior: none;
|
|
@@ -66,7 +163,7 @@ export const styles = /*css*/ `
|
|
|
66
163
|
}
|
|
67
164
|
|
|
68
165
|
.top-bar-side-label {
|
|
69
|
-
width:
|
|
166
|
+
width: var(--bar-size);
|
|
70
167
|
text-align: center;
|
|
71
168
|
font-size: 9px;
|
|
72
169
|
text-transform: uppercase;
|
|
@@ -74,6 +171,17 @@ export const styles = /*css*/ `
|
|
|
74
171
|
color: #666;
|
|
75
172
|
}
|
|
76
173
|
|
|
174
|
+
/* Mobile: larger top bar text */
|
|
175
|
+
@media (max-width: 768px) {
|
|
176
|
+
.top-bar-side-label {
|
|
177
|
+
font-size: 12px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.top-bar {
|
|
181
|
+
font-size: 14px;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
77
185
|
.top-bar-center {
|
|
78
186
|
display: flex;
|
|
79
187
|
align-items: center;
|
|
@@ -142,8 +250,17 @@ export const styles = /*css*/ `
|
|
|
142
250
|
display: flex;
|
|
143
251
|
align-items: center;
|
|
144
252
|
background: #111;
|
|
145
|
-
|
|
146
|
-
|
|
253
|
+
/* Mobile-first: more padding */
|
|
254
|
+
padding: 0 16px;
|
|
255
|
+
gap: 12px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Desktop: tighter padding */
|
|
259
|
+
@media (min-width: 769px) {
|
|
260
|
+
.bottom-bar {
|
|
261
|
+
padding: 0 8px;
|
|
262
|
+
gap: 8px;
|
|
263
|
+
}
|
|
147
264
|
}
|
|
148
265
|
|
|
149
266
|
.playbar-controls {
|
|
@@ -153,16 +270,35 @@ export const styles = /*css*/ `
|
|
|
153
270
|
flex-shrink: 0;
|
|
154
271
|
}
|
|
155
272
|
|
|
273
|
+
/* Mobile-first: hide step/jump buttons */
|
|
274
|
+
.playbar-btn.jump-back,
|
|
275
|
+
.playbar-btn.step-back,
|
|
276
|
+
.playbar-btn.step-forward,
|
|
277
|
+
.playbar-btn.jump-forward {
|
|
278
|
+
display: none;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Desktop: show all controls */
|
|
282
|
+
@media (min-width: 769px) {
|
|
283
|
+
.playbar-btn.jump-back,
|
|
284
|
+
.playbar-btn.step-back,
|
|
285
|
+
.playbar-btn.step-forward,
|
|
286
|
+
.playbar-btn.jump-forward {
|
|
287
|
+
display: flex;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
156
291
|
.playbar-btn {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
min-
|
|
292
|
+
/* Mobile-first: larger buttons */
|
|
293
|
+
width: 4vh;
|
|
294
|
+
height: 4vh;
|
|
295
|
+
min-width: 32px;
|
|
296
|
+
min-height: 32px;
|
|
161
297
|
border: none;
|
|
162
298
|
outline: none;
|
|
163
299
|
background: transparent;
|
|
164
300
|
color: #888;
|
|
165
|
-
font-size:
|
|
301
|
+
font-size: 16px;
|
|
166
302
|
cursor: pointer;
|
|
167
303
|
border-radius: 2px;
|
|
168
304
|
display: flex;
|
|
@@ -172,6 +308,17 @@ export const styles = /*css*/ `
|
|
|
172
308
|
position: relative;
|
|
173
309
|
}
|
|
174
310
|
|
|
311
|
+
/* Desktop: smaller buttons */
|
|
312
|
+
@media (min-width: 769px) {
|
|
313
|
+
.playbar-btn {
|
|
314
|
+
width: 1.5vh;
|
|
315
|
+
height: 1.5vh;
|
|
316
|
+
min-width: 18px;
|
|
317
|
+
min-height: 18px;
|
|
318
|
+
font-size: 10px;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
175
322
|
.playbar-btn:hover {
|
|
176
323
|
background: #333;
|
|
177
324
|
color: #fff;
|
|
@@ -215,7 +362,8 @@ export const styles = /*css*/ `
|
|
|
215
362
|
|
|
216
363
|
.seek-bar {
|
|
217
364
|
flex: 1;
|
|
218
|
-
|
|
365
|
+
/* Mobile-first: larger seek bar */
|
|
366
|
+
height: 32px;
|
|
219
367
|
background: #222;
|
|
220
368
|
border-radius: 4px;
|
|
221
369
|
position: relative;
|
|
@@ -223,6 +371,13 @@ export const styles = /*css*/ `
|
|
|
223
371
|
overflow: hidden;
|
|
224
372
|
}
|
|
225
373
|
|
|
374
|
+
/* Desktop: smaller seek bar */
|
|
375
|
+
@media (min-width: 769px) {
|
|
376
|
+
.seek-bar {
|
|
377
|
+
height: 16px;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
226
381
|
.seek-bar-fill {
|
|
227
382
|
position: absolute;
|
|
228
383
|
top: 0;
|
|
@@ -445,4 +600,87 @@ export const styles = /*css*/ `
|
|
|
445
600
|
border-radius: 4px;
|
|
446
601
|
border: 1px inset lavender;
|
|
447
602
|
}
|
|
603
|
+
|
|
604
|
+
/* Load Tape Dialog */
|
|
605
|
+
.load-tape-dialog {
|
|
606
|
+
background: #1a1a1a;
|
|
607
|
+
border: 1px solid #333;
|
|
608
|
+
border-radius: 8px;
|
|
609
|
+
padding: 0;
|
|
610
|
+
color: #ccc;
|
|
611
|
+
font-family: monospace;
|
|
612
|
+
max-width: 320px;
|
|
613
|
+
width: 90vw;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.load-tape-dialog::backdrop {
|
|
617
|
+
background: rgba(0, 0, 0, 0.7);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.load-tape-dialog-content {
|
|
621
|
+
padding: 16px;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.load-tape-dialog h3 {
|
|
625
|
+
margin: 0 0 16px 0;
|
|
626
|
+
font-size: 14px;
|
|
627
|
+
font-weight: 600;
|
|
628
|
+
color: #fff;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.drop-zone {
|
|
632
|
+
border: 2px dashed #444;
|
|
633
|
+
border-radius: 8px;
|
|
634
|
+
padding: 32px 16px;
|
|
635
|
+
text-align: center;
|
|
636
|
+
cursor: pointer;
|
|
637
|
+
transition: border-color 0.15s, background 0.15s;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.drop-zone:hover {
|
|
641
|
+
border-color: #666;
|
|
642
|
+
background: #222;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.drop-zone.drag-over {
|
|
646
|
+
border-color: #7b3fa0;
|
|
647
|
+
background: rgba(123, 63, 160, 0.1);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
.drop-zone-text {
|
|
651
|
+
color: #888;
|
|
652
|
+
font-size: 12px;
|
|
653
|
+
line-height: 1.5;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
.hidden-file-input {
|
|
657
|
+
display: none;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
.replay-last-btn {
|
|
661
|
+
width: 100%;
|
|
662
|
+
margin-top: 12px;
|
|
663
|
+
padding: 8px 12px;
|
|
664
|
+
background: #333;
|
|
665
|
+
border: none;
|
|
666
|
+
border-radius: 4px;
|
|
667
|
+
color: #ccc;
|
|
668
|
+
font-family: monospace;
|
|
669
|
+
font-size: 12px;
|
|
670
|
+
cursor: pointer;
|
|
671
|
+
transition: background 0.15s;
|
|
672
|
+
text-align: left;
|
|
673
|
+
overflow: hidden;
|
|
674
|
+
text-overflow: ellipsis;
|
|
675
|
+
white-space: nowrap;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
.replay-last-btn:hover {
|
|
679
|
+
background: #444;
|
|
680
|
+
color: #fff;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.load-tape-btn {
|
|
684
|
+
margin-left: 4px;
|
|
685
|
+
}
|
|
448
686
|
`;
|