@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.
@@ -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
- display: grid;
29
- grid-template-areas:
30
- "game stats"
31
- "logs logs";
32
- grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);
33
- grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);
34
- gap: 1rem;
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: 2vw 1fr 2vw;
48
- grid-template-rows: 2vh 1fr 2vh;
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: 2vw;
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
- padding: 0 8px;
146
- gap: 8px;
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
- width: 1.5vh;
158
- height: 1.5vh;
159
- min-width: 18px;
160
- min-height: 18px;
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: 10px;
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
- height: 16px;
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
  `;