@bloopjs/web 0.0.91 → 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/debugui/components/BottomBar.d.ts.map +1 -1
- package/dist/debugui/state.d.ts +1 -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 +214 -26
- package/dist/mod.js.map +7 -7
- package/package.json +3 -3
- package/src/debugui/components/BottomBar.tsx +15 -5
- package/src/debugui/state.ts +18 -3
- package/src/debugui/styles.ts +173 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AAiFA,wBAAgB,SAAS,
|
|
1
|
+
{"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AAiFA,wBAAgB,SAAS,4CAuGxB"}
|
package/dist/debugui/state.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export type DebugState = {
|
|
|
41
41
|
onSeek: Signal<((position: number) => void) | null>;
|
|
42
42
|
onLoadTape: Signal<((bytes: Uint8Array, fileName: string) => void) | null>;
|
|
43
43
|
onReplayLastTape: Signal<(() => void) | null>;
|
|
44
|
+
onSaveTape: Signal<(() => void) | null>;
|
|
44
45
|
lastTapeName: Signal<string | null>;
|
|
45
46
|
isLoadDialogOpen: Signal<boolean>;
|
|
46
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,MAAM,EAEZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,aAAa,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,IAAI,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,WAAW,CAAC;IACjB,GAAG,EAAE,WAAW,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/B,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAClC,SAAS,EAAE,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAE5B,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAE1B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAE/B,UAAU,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpD,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3E,gBAAgB,EAAE,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9C,YAAY,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"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"}
|
package/dist/debugui/styles.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const styles = "\n/* Reset for shadow DOM */\n* {\n box-sizing: border-box;\n}\n\n/* Layout */\n.fullscreen {\n width: 100vw;\n height: 100vh;\n margin: 0;\n padding: 0;\n overflow: hidden;\n}\n\n.fullscreen .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.fullscreen canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.layout {\n display: grid;\n grid-template-areas:\n \"game stats\"\n \"logs logs\";\n grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);\n grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);\n gap: 1rem;\n width: 100%;\n height: 100%;\n padding: 1rem;\n}\n\n/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */\n.layout-letterboxed {\n display: grid;\n grid-template-areas:\n \"top-bar top-bar top-bar\"\n \"left-bar game right-bar\"\n \"bottom-bar bottom-bar bottom-bar\";\n grid-template-columns: 2vw 1fr 2vw;\n grid-template-rows: 2vh 1fr 2vh;\n width: 100vw;\n height: 100vh;\n background: #1a1a1a;\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n.top-bar {\n grid-area: top-bar;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #111;\n color: #aaa;\n font-family: monospace;\n font-size: 12px;\n padding: 0;\n}\n\n.top-bar-side-label {\n width: 2vw;\n text-align: center;\n font-size: 9px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #666;\n}\n\n.top-bar-center {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 24px;\n flex: 1;\n}\n\n.top-bar-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.top-bar-label {\n opacity: 0.6;\n}\n\n.top-bar-value {\n color: #fff;\n font-weight: 500;\n}\n\n.left-bar {\n grid-area: left-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.right-bar {\n grid-area: right-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.vertical-bar {\n width: 12px;\n flex: 1;\n background: #333;\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n}\n\n.vertical-bar-fill {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: #4a9eff;\n border-radius: 2px;\n transition: height 0.1s ease-out;\n}\n\n\n.bottom-bar {\n grid-area: bottom-bar;\n display: flex;\n align-items: center;\n background: #111;\n padding: 0 8px;\n gap: 8px;\n}\n\n.playbar-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.playbar-btn {\n width: 1.5vh;\n height: 1.5vh;\n min-width: 18px;\n min-height: 18px;\n border: none;\n outline: none;\n background: transparent;\n color: #888;\n font-size: 10px;\n cursor: pointer;\n border-radius: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n position: relative;\n}\n\n.playbar-btn:hover {\n background: #333;\n color: #fff;\n}\n\n.playbar-btn:hover .tooltip {\n opacity: 1;\n visibility: visible;\n}\n\n.tooltip {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 50%;\n transform: translateX(-50%);\n background: #222;\n color: #ccc;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s;\n pointer-events: none;\n z-index: 10;\n}\n\n.tooltip-left {\n left: 0;\n transform: none;\n}\n\n.tooltip kbd {\n background: #444;\n padding: 1px 4px;\n border-radius: 2px;\n margin-left: 4px;\n font-family: monospace;\n}\n\n.seek-bar {\n flex: 1;\n height: 16px;\n background: #222;\n border-radius: 4px;\n position: relative;\n cursor: pointer;\n overflow: hidden;\n}\n\n.seek-bar-fill {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: linear-gradient(to right, #4a2070, #7b3fa0);\n border-radius: 4px;\n transition: width 0.1s ease-out;\n}\n\n.seek-bar-position {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #fff;\n}\n\n.letterboxed-game {\n grid-area: game;\n overflow: hidden;\n}\n\n.letterboxed-game .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.letterboxed-game canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.letterboxed-game {\n position: relative;\n}\n\n.letterboxed-game.hmr-flash::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n animation: hmr-pulse 0.3s ease-out forwards;\n}\n\n@keyframes hmr-pulse {\n 0% { box-shadow: inset 0 0 0 36px #7b3fa0; }\n 100% { box-shadow: inset 0 0 0 0 #7b3fa0; }\n}\n\n.game {\n grid-area: game;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.stats {\n grid-area: stats;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.logs {\n grid-area: logs;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n/* Canvas container */\n.canvas-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.canvas-container canvas {\n max-width: 100%;\n max-height: 100%;\n}\n\n/* Debug toggle button */\n.debug-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: rgba(0, 0, 0, 0.5);\n color: white;\n font-size: 18px;\n cursor: pointer;\n z-index: 1000;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n}\n\n.debug-toggle:hover {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Stats panel */\n.stats-panel {\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 12px;\n border-radius: 8px;\n font-family: monospace;\n font-size: 14px;\n max-width: 100%;\n overflow: hidden;\n}\n\n.stats-panel h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.stats-panel table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n}\n\n.stats-panel tr {\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.stats-panel tr:last-child {\n border-bottom: none;\n}\n\n.stats-panel td {\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.stats-panel td:first-child {\n opacity: 0.7;\n width: 60%;\n}\n\n.stats-panel td:last-child {\n text-align: right;\n font-weight: 600;\n width: 40%;\n}\n\n.stats-panel p {\n margin: 0;\n opacity: 0.7;\n}\n\n/* Logs panel */\n.logs-list {\n width: 100%;\n height: 100%;\n overflow: auto;\n margin: 0;\n padding: 0;\n}\n\n.logs-list li {\n margin: 0 0 24px 0;\n list-style: none;\n}\n\n.logs-list h3 {\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n}\n\n.logs-list .ws {\n color: darkolivegreen;\n}\n\n.logs-list .webrtc {\n color: darkmagenta;\n}\n\n.logs-list .rollback {\n color: darkblue;\n}\n\n.logs-list .local {\n color: #333;\n}\n\n.logs-list .content {\n font-size: 16px;\n}\n\n.logs-list p {\n margin: 4px 0;\n}\n\n.logs-list pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n background-color: oldlace;\n padding: 8px;\n border-radius: 4px;\n border: 1px inset lavender;\n}\n\n/* Load Tape Dialog */\n.load-tape-dialog {\n background: #1a1a1a;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 0;\n color: #ccc;\n font-family: monospace;\n max-width: 320px;\n width: 90vw;\n}\n\n.load-tape-dialog::backdrop {\n background: rgba(0, 0, 0, 0.7);\n}\n\n.load-tape-dialog-content {\n padding: 16px;\n}\n\n.load-tape-dialog h3 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n}\n\n.drop-zone {\n border: 2px dashed #444;\n border-radius: 8px;\n padding: 32px 16px;\n text-align: center;\n cursor: pointer;\n transition: border-color 0.15s, background 0.15s;\n}\n\n.drop-zone:hover {\n border-color: #666;\n background: #222;\n}\n\n.drop-zone.drag-over {\n border-color: #7b3fa0;\n background: rgba(123, 63, 160, 0.1);\n}\n\n.drop-zone-text {\n color: #888;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hidden-file-input {\n display: none;\n}\n\n.replay-last-btn {\n width: 100%;\n margin-top: 12px;\n padding: 8px 12px;\n background: #333;\n border: none;\n border-radius: 4px;\n color: #ccc;\n font-family: monospace;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.15s;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.replay-last-btn:hover {\n background: #444;\n color: #fff;\n}\n\n.load-tape-btn {\n margin-left: 4px;\n}\n";
|
|
1
|
+
export declare const styles = "\n/* Reset for shadow DOM */\n* {\n box-sizing: border-box;\n}\n\n/* Mobile-first CSS variables */\n:host {\n --bar-size: 10vw;\n --bar-size-h: 10vh;\n --bar-size-h: 10dvh;\n}\n\n/* Desktop overrides */\n@media (min-width: 769px) {\n :host {\n --bar-size: 2vw;\n --bar-size-h: 2vh;\n }\n}\n\n/* Layout */\n.fullscreen {\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n margin: 0;\n padding: 0;\n overflow: hidden;\n}\n\n.fullscreen .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.fullscreen canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n/* Mobile-first: vertical scroll layout */\n.layout {\n /* Use fixed position on mobile to escape parent overflow:hidden */\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior-y: contain;\n padding: 0;\n gap: 0;\n background: #1a1a1a;\n}\n\n.layout .game {\n /* Use dvh with vh fallback for mobile Safari address bar */\n height: 100vh;\n height: 100dvh;\n width: 100%;\n flex-shrink: 0;\n /* Mobile: no border radius, fullscreen game */\n border-radius: 0;\n}\n\n/* Mobile: stretch canvas to fill game area */\n.layout .game .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.layout .game .canvas-container canvas {\n width: 100%;\n height: 100%;\n max-width: none;\n max-height: none;\n display: block;\n}\n\n.layout .stats,\n.layout .logs {\n width: 100%;\n min-height: 50vh;\n min-height: 50dvh;\n padding: 1rem;\n flex-shrink: 0;\n}\n\n/* Desktop: 2x2 grid layout */\n@media (min-width: 769px) {\n .layout {\n position: static;\n display: grid;\n grid-template-areas:\n \"game stats\"\n \"logs logs\";\n grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);\n grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);\n gap: 1rem;\n padding: 1rem;\n height: 100%;\n overflow: hidden;\n -webkit-overflow-scrolling: auto;\n overscroll-behavior-y: auto;\n }\n\n .layout .game {\n height: auto;\n flex-shrink: initial;\n border-radius: 8px;\n }\n\n /* Desktop: restore centered canvas with constraints */\n .layout .game .canvas-container canvas {\n width: auto;\n height: auto;\n max-width: 100%;\n max-height: 100%;\n }\n\n .layout .stats,\n .layout .logs {\n min-height: auto;\n padding: 1rem;\n flex-shrink: initial;\n }\n}\n\n/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */\n.layout-letterboxed {\n display: grid;\n grid-template-areas:\n \"top-bar top-bar top-bar\"\n \"left-bar game right-bar\"\n \"bottom-bar bottom-bar bottom-bar\";\n grid-template-columns: var(--bar-size) 1fr var(--bar-size);\n grid-template-rows: var(--bar-size-h) 1fr var(--bar-size-h);\n width: 100vw;\n /* Use dvh with vh fallback for mobile Safari address bar */\n height: 100vh;\n height: 100dvh;\n background: #1a1a1a;\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n.top-bar {\n grid-area: top-bar;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #111;\n color: #aaa;\n font-family: monospace;\n font-size: 12px;\n padding: 0;\n}\n\n.top-bar-side-label {\n width: var(--bar-size);\n text-align: center;\n font-size: 9px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #666;\n}\n\n/* Mobile: larger top bar text */\n@media (max-width: 768px) {\n .top-bar-side-label {\n font-size: 12px;\n }\n\n .top-bar {\n font-size: 14px;\n }\n}\n\n.top-bar-center {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 24px;\n flex: 1;\n}\n\n.top-bar-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.top-bar-label {\n opacity: 0.6;\n}\n\n.top-bar-value {\n color: #fff;\n font-weight: 500;\n}\n\n.left-bar {\n grid-area: left-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.right-bar {\n grid-area: right-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.vertical-bar {\n width: 12px;\n flex: 1;\n background: #333;\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n}\n\n.vertical-bar-fill {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: #4a9eff;\n border-radius: 2px;\n transition: height 0.1s ease-out;\n}\n\n\n.bottom-bar {\n grid-area: bottom-bar;\n display: flex;\n align-items: center;\n background: #111;\n /* Mobile-first: more padding */\n padding: 0 16px;\n gap: 12px;\n}\n\n/* Desktop: tighter padding */\n@media (min-width: 769px) {\n .bottom-bar {\n padding: 0 8px;\n gap: 8px;\n }\n}\n\n.playbar-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n\n/* Mobile-first: hide step/jump buttons */\n.playbar-btn.jump-back,\n.playbar-btn.step-back,\n.playbar-btn.step-forward,\n.playbar-btn.jump-forward {\n display: none;\n}\n\n/* Desktop: show all controls */\n@media (min-width: 769px) {\n .playbar-btn.jump-back,\n .playbar-btn.step-back,\n .playbar-btn.step-forward,\n .playbar-btn.jump-forward {\n display: flex;\n }\n}\n\n.playbar-btn {\n /* Mobile-first: larger buttons */\n width: 4vh;\n height: 4vh;\n min-width: 32px;\n min-height: 32px;\n border: none;\n outline: none;\n background: transparent;\n color: #888;\n font-size: 16px;\n cursor: pointer;\n border-radius: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n position: relative;\n}\n\n/* Desktop: smaller buttons */\n@media (min-width: 769px) {\n .playbar-btn {\n width: 1.5vh;\n height: 1.5vh;\n min-width: 18px;\n min-height: 18px;\n font-size: 10px;\n }\n}\n\n.playbar-btn:hover {\n background: #333;\n color: #fff;\n}\n\n.playbar-btn:hover .tooltip {\n opacity: 1;\n visibility: visible;\n}\n\n.tooltip {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 50%;\n transform: translateX(-50%);\n background: #222;\n color: #ccc;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s;\n pointer-events: none;\n z-index: 10;\n}\n\n.tooltip-left {\n left: 0;\n transform: none;\n}\n\n.tooltip kbd {\n background: #444;\n padding: 1px 4px;\n border-radius: 2px;\n margin-left: 4px;\n font-family: monospace;\n}\n\n.seek-bar {\n flex: 1;\n /* Mobile-first: larger seek bar */\n height: 32px;\n background: #222;\n border-radius: 4px;\n position: relative;\n cursor: pointer;\n overflow: hidden;\n}\n\n/* Desktop: smaller seek bar */\n@media (min-width: 769px) {\n .seek-bar {\n height: 16px;\n }\n}\n\n.seek-bar-fill {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: linear-gradient(to right, #4a2070, #7b3fa0);\n border-radius: 4px;\n transition: width 0.1s ease-out;\n}\n\n.seek-bar-position {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #fff;\n}\n\n.letterboxed-game {\n grid-area: game;\n overflow: hidden;\n}\n\n.letterboxed-game .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.letterboxed-game canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.letterboxed-game {\n position: relative;\n}\n\n.letterboxed-game.hmr-flash::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n animation: hmr-pulse 0.3s ease-out forwards;\n}\n\n@keyframes hmr-pulse {\n 0% { box-shadow: inset 0 0 0 36px #7b3fa0; }\n 100% { box-shadow: inset 0 0 0 0 #7b3fa0; }\n}\n\n.game {\n grid-area: game;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.stats {\n grid-area: stats;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.logs {\n grid-area: logs;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n/* Canvas container */\n.canvas-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.canvas-container canvas {\n max-width: 100%;\n max-height: 100%;\n}\n\n/* Debug toggle button */\n.debug-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: rgba(0, 0, 0, 0.5);\n color: white;\n font-size: 18px;\n cursor: pointer;\n z-index: 1000;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n}\n\n.debug-toggle:hover {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Stats panel */\n.stats-panel {\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 12px;\n border-radius: 8px;\n font-family: monospace;\n font-size: 14px;\n max-width: 100%;\n overflow: hidden;\n}\n\n.stats-panel h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.stats-panel table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n}\n\n.stats-panel tr {\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.stats-panel tr:last-child {\n border-bottom: none;\n}\n\n.stats-panel td {\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.stats-panel td:first-child {\n opacity: 0.7;\n width: 60%;\n}\n\n.stats-panel td:last-child {\n text-align: right;\n font-weight: 600;\n width: 40%;\n}\n\n.stats-panel p {\n margin: 0;\n opacity: 0.7;\n}\n\n/* Logs panel */\n.logs-list {\n width: 100%;\n height: 100%;\n overflow: auto;\n margin: 0;\n padding: 0;\n}\n\n.logs-list li {\n margin: 0 0 24px 0;\n list-style: none;\n}\n\n.logs-list h3 {\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n}\n\n.logs-list .ws {\n color: darkolivegreen;\n}\n\n.logs-list .webrtc {\n color: darkmagenta;\n}\n\n.logs-list .rollback {\n color: darkblue;\n}\n\n.logs-list .local {\n color: #333;\n}\n\n.logs-list .content {\n font-size: 16px;\n}\n\n.logs-list p {\n margin: 4px 0;\n}\n\n.logs-list pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n background-color: oldlace;\n padding: 8px;\n border-radius: 4px;\n border: 1px inset lavender;\n}\n\n/* Load Tape Dialog */\n.load-tape-dialog {\n background: #1a1a1a;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 0;\n color: #ccc;\n font-family: monospace;\n max-width: 320px;\n width: 90vw;\n}\n\n.load-tape-dialog::backdrop {\n background: rgba(0, 0, 0, 0.7);\n}\n\n.load-tape-dialog-content {\n padding: 16px;\n}\n\n.load-tape-dialog h3 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n}\n\n.drop-zone {\n border: 2px dashed #444;\n border-radius: 8px;\n padding: 32px 16px;\n text-align: center;\n cursor: pointer;\n transition: border-color 0.15s, background 0.15s;\n}\n\n.drop-zone:hover {\n border-color: #666;\n background: #222;\n}\n\n.drop-zone.drag-over {\n border-color: #7b3fa0;\n background: rgba(123, 63, 160, 0.1);\n}\n\n.drop-zone-text {\n color: #888;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hidden-file-input {\n display: none;\n}\n\n.replay-last-btn {\n width: 100%;\n margin-top: 12px;\n padding: 8px 12px;\n background: #333;\n border: none;\n border-radius: 4px;\n color: #ccc;\n font-family: monospace;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.15s;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.replay-last-btn:hover {\n background: #444;\n color: #fff;\n}\n\n.load-tape-btn {\n margin-left: 4px;\n}\n";
|
|
2
2
|
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debugui/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debugui/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,itXA6qBlB,CAAC"}
|
package/dist/mod.js
CHANGED
|
@@ -1432,7 +1432,7 @@ function readTapeHeader(tape) {
|
|
|
1432
1432
|
eventCount: view.getUint16(14, true)
|
|
1433
1433
|
};
|
|
1434
1434
|
}
|
|
1435
|
-
var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.
|
|
1435
|
+
var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.92/wasm/bloop.wasm");
|
|
1436
1436
|
var MAX_ROLLBACK_FRAMES = 500;
|
|
1437
1437
|
var TIME_CTX_OFFSET = 0;
|
|
1438
1438
|
var INPUT_CTX_OFFSET = TIME_CTX_OFFSET + 4;
|
|
@@ -3273,7 +3273,7 @@ function readTapeHeader2(tape) {
|
|
|
3273
3273
|
eventCount: view.getUint16(14, true)
|
|
3274
3274
|
};
|
|
3275
3275
|
}
|
|
3276
|
-
var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.
|
|
3276
|
+
var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.92/wasm/bloop.wasm");
|
|
3277
3277
|
var TIME_CTX_OFFSET2 = 0;
|
|
3278
3278
|
var INPUT_CTX_OFFSET2 = TIME_CTX_OFFSET2 + 4;
|
|
3279
3279
|
var EVENTS_OFFSET2 = INPUT_CTX_OFFSET2 + 4;
|
|
@@ -4394,6 +4394,7 @@ var onJumpForward = d3(null);
|
|
|
4394
4394
|
var onSeek = d3(null);
|
|
4395
4395
|
var onLoadTape = d3(null);
|
|
4396
4396
|
var onReplayLastTape = d3(null);
|
|
4397
|
+
var onSaveTape = d3(null);
|
|
4397
4398
|
var lastTapeName = d3(null);
|
|
4398
4399
|
var isLoadDialogOpen = d3(false);
|
|
4399
4400
|
var debugState = {
|
|
@@ -4424,6 +4425,7 @@ var debugState = {
|
|
|
4424
4425
|
onSeek,
|
|
4425
4426
|
onLoadTape,
|
|
4426
4427
|
onReplayLastTape,
|
|
4428
|
+
onSaveTape,
|
|
4427
4429
|
lastTapeName,
|
|
4428
4430
|
isLoadDialogOpen
|
|
4429
4431
|
};
|
|
@@ -4634,6 +4636,18 @@ function wireTapeLoadHandlers(app) {
|
|
|
4634
4636
|
debugState.isLoadDialogOpen.value = false;
|
|
4635
4637
|
}
|
|
4636
4638
|
};
|
|
4639
|
+
debugState.onSaveTape.value = () => {
|
|
4640
|
+
if (!app.sim.hasHistory)
|
|
4641
|
+
return;
|
|
4642
|
+
const tape = app.sim.saveTape();
|
|
4643
|
+
const blob = new Blob([tape], { type: "application/octet-stream" });
|
|
4644
|
+
const url = URL.createObjectURL(blob);
|
|
4645
|
+
const a4 = document.createElement("a");
|
|
4646
|
+
a4.href = url;
|
|
4647
|
+
a4.download = `tape-${Date.now()}.bloop`;
|
|
4648
|
+
a4.click();
|
|
4649
|
+
URL.revokeObjectURL(url);
|
|
4650
|
+
};
|
|
4637
4651
|
checkForSavedTape();
|
|
4638
4652
|
}
|
|
4639
4653
|
// ../../node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
|
|
@@ -5187,6 +5201,9 @@ function BottomBar() {
|
|
|
5187
5201
|
const handleLoadTapeClick = q2(() => {
|
|
5188
5202
|
debugState.isLoadDialogOpen.value = true;
|
|
5189
5203
|
}, []);
|
|
5204
|
+
const handleSaveTapeClick = q2(() => {
|
|
5205
|
+
debugState.onSaveTape.value?.();
|
|
5206
|
+
}, []);
|
|
5190
5207
|
return /* @__PURE__ */ u4("div", {
|
|
5191
5208
|
className: "bottom-bar",
|
|
5192
5209
|
children: [
|
|
@@ -5194,7 +5211,7 @@ function BottomBar() {
|
|
|
5194
5211
|
className: "playbar-controls",
|
|
5195
5212
|
children: [
|
|
5196
5213
|
/* @__PURE__ */ u4("button", {
|
|
5197
|
-
className: "playbar-btn",
|
|
5214
|
+
className: "playbar-btn jump-back",
|
|
5198
5215
|
...jumpBackRepeat,
|
|
5199
5216
|
children: [
|
|
5200
5217
|
"<<",
|
|
@@ -5210,7 +5227,7 @@ function BottomBar() {
|
|
|
5210
5227
|
]
|
|
5211
5228
|
}, undefined, true, undefined, this),
|
|
5212
5229
|
/* @__PURE__ */ u4("button", {
|
|
5213
|
-
className: "playbar-btn",
|
|
5230
|
+
className: "playbar-btn step-back",
|
|
5214
5231
|
...stepBackRepeat,
|
|
5215
5232
|
children: [
|
|
5216
5233
|
"<",
|
|
@@ -5226,7 +5243,7 @@ function BottomBar() {
|
|
|
5226
5243
|
]
|
|
5227
5244
|
}, undefined, true, undefined, this),
|
|
5228
5245
|
/* @__PURE__ */ u4("button", {
|
|
5229
|
-
className: "playbar-btn",
|
|
5246
|
+
className: "playbar-btn play-pause",
|
|
5230
5247
|
onClick: handlePlayPause,
|
|
5231
5248
|
children: [
|
|
5232
5249
|
isPlaying2 ? "||" : ">",
|
|
@@ -5243,7 +5260,7 @@ function BottomBar() {
|
|
|
5243
5260
|
]
|
|
5244
5261
|
}, undefined, true, undefined, this),
|
|
5245
5262
|
/* @__PURE__ */ u4("button", {
|
|
5246
|
-
className: "playbar-btn",
|
|
5263
|
+
className: "playbar-btn step-forward",
|
|
5247
5264
|
...stepForwardRepeat,
|
|
5248
5265
|
children: [
|
|
5249
5266
|
">",
|
|
@@ -5259,7 +5276,7 @@ function BottomBar() {
|
|
|
5259
5276
|
]
|
|
5260
5277
|
}, undefined, true, undefined, this),
|
|
5261
5278
|
/* @__PURE__ */ u4("button", {
|
|
5262
|
-
className: "playbar-btn",
|
|
5279
|
+
className: "playbar-btn jump-forward",
|
|
5263
5280
|
...jumpForwardRepeat,
|
|
5264
5281
|
children: [
|
|
5265
5282
|
">>",
|
|
@@ -5274,6 +5291,22 @@ function BottomBar() {
|
|
|
5274
5291
|
}, undefined, true, undefined, this)
|
|
5275
5292
|
]
|
|
5276
5293
|
}, undefined, true, undefined, this),
|
|
5294
|
+
/* @__PURE__ */ u4("button", {
|
|
5295
|
+
className: "playbar-btn save-tape-btn",
|
|
5296
|
+
onClick: handleSaveTapeClick,
|
|
5297
|
+
children: [
|
|
5298
|
+
"Save",
|
|
5299
|
+
/* @__PURE__ */ u4("span", {
|
|
5300
|
+
className: "tooltip",
|
|
5301
|
+
children: [
|
|
5302
|
+
"Save tape ",
|
|
5303
|
+
/* @__PURE__ */ u4("kbd", {
|
|
5304
|
+
children: "Cmd+S"
|
|
5305
|
+
}, undefined, false, undefined, this)
|
|
5306
|
+
]
|
|
5307
|
+
}, undefined, true, undefined, this)
|
|
5308
|
+
]
|
|
5309
|
+
}, undefined, true, undefined, this),
|
|
5277
5310
|
/* @__PURE__ */ u4("button", {
|
|
5278
5311
|
className: "playbar-btn load-tape-btn",
|
|
5279
5312
|
onClick: handleLoadTapeClick,
|
|
@@ -5427,10 +5460,26 @@ var styles = `
|
|
|
5427
5460
|
box-sizing: border-box;
|
|
5428
5461
|
}
|
|
5429
5462
|
|
|
5463
|
+
/* Mobile-first CSS variables */
|
|
5464
|
+
:host {
|
|
5465
|
+
--bar-size: 10vw;
|
|
5466
|
+
--bar-size-h: 10vh;
|
|
5467
|
+
--bar-size-h: 10dvh;
|
|
5468
|
+
}
|
|
5469
|
+
|
|
5470
|
+
/* Desktop overrides */
|
|
5471
|
+
@media (min-width: 769px) {
|
|
5472
|
+
:host {
|
|
5473
|
+
--bar-size: 2vw;
|
|
5474
|
+
--bar-size-h: 2vh;
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5477
|
+
|
|
5430
5478
|
/* Layout */
|
|
5431
5479
|
.fullscreen {
|
|
5432
5480
|
width: 100vw;
|
|
5433
5481
|
height: 100vh;
|
|
5482
|
+
height: 100dvh;
|
|
5434
5483
|
margin: 0;
|
|
5435
5484
|
padding: 0;
|
|
5436
5485
|
overflow: hidden;
|
|
@@ -5447,17 +5496,96 @@ var styles = `
|
|
|
5447
5496
|
display: block;
|
|
5448
5497
|
}
|
|
5449
5498
|
|
|
5499
|
+
/* Mobile-first: vertical scroll layout */
|
|
5450
5500
|
.layout {
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5501
|
+
/* Use fixed position on mobile to escape parent overflow:hidden */
|
|
5502
|
+
position: fixed;
|
|
5503
|
+
top: 0;
|
|
5504
|
+
left: 0;
|
|
5505
|
+
right: 0;
|
|
5506
|
+
bottom: 0;
|
|
5507
|
+
display: flex;
|
|
5508
|
+
flex-direction: column;
|
|
5509
|
+
overflow-y: auto;
|
|
5510
|
+
overflow-x: hidden;
|
|
5511
|
+
-webkit-overflow-scrolling: touch;
|
|
5512
|
+
overscroll-behavior-y: contain;
|
|
5513
|
+
padding: 0;
|
|
5514
|
+
gap: 0;
|
|
5515
|
+
background: #1a1a1a;
|
|
5516
|
+
}
|
|
5517
|
+
|
|
5518
|
+
.layout .game {
|
|
5519
|
+
/* Use dvh with vh fallback for mobile Safari address bar */
|
|
5520
|
+
height: 100vh;
|
|
5521
|
+
height: 100dvh;
|
|
5522
|
+
width: 100%;
|
|
5523
|
+
flex-shrink: 0;
|
|
5524
|
+
/* Mobile: no border radius, fullscreen game */
|
|
5525
|
+
border-radius: 0;
|
|
5526
|
+
}
|
|
5527
|
+
|
|
5528
|
+
/* Mobile: stretch canvas to fill game area */
|
|
5529
|
+
.layout .game .canvas-container {
|
|
5458
5530
|
width: 100%;
|
|
5459
5531
|
height: 100%;
|
|
5532
|
+
}
|
|
5533
|
+
|
|
5534
|
+
.layout .game .canvas-container canvas {
|
|
5535
|
+
width: 100%;
|
|
5536
|
+
height: 100%;
|
|
5537
|
+
max-width: none;
|
|
5538
|
+
max-height: none;
|
|
5539
|
+
display: block;
|
|
5540
|
+
}
|
|
5541
|
+
|
|
5542
|
+
.layout .stats,
|
|
5543
|
+
.layout .logs {
|
|
5544
|
+
width: 100%;
|
|
5545
|
+
min-height: 50vh;
|
|
5546
|
+
min-height: 50dvh;
|
|
5460
5547
|
padding: 1rem;
|
|
5548
|
+
flex-shrink: 0;
|
|
5549
|
+
}
|
|
5550
|
+
|
|
5551
|
+
/* Desktop: 2x2 grid layout */
|
|
5552
|
+
@media (min-width: 769px) {
|
|
5553
|
+
.layout {
|
|
5554
|
+
position: static;
|
|
5555
|
+
display: grid;
|
|
5556
|
+
grid-template-areas:
|
|
5557
|
+
"game stats"
|
|
5558
|
+
"logs logs";
|
|
5559
|
+
grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);
|
|
5560
|
+
grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);
|
|
5561
|
+
gap: 1rem;
|
|
5562
|
+
padding: 1rem;
|
|
5563
|
+
height: 100%;
|
|
5564
|
+
overflow: hidden;
|
|
5565
|
+
-webkit-overflow-scrolling: auto;
|
|
5566
|
+
overscroll-behavior-y: auto;
|
|
5567
|
+
}
|
|
5568
|
+
|
|
5569
|
+
.layout .game {
|
|
5570
|
+
height: auto;
|
|
5571
|
+
flex-shrink: initial;
|
|
5572
|
+
border-radius: 8px;
|
|
5573
|
+
}
|
|
5574
|
+
|
|
5575
|
+
/* Desktop: restore centered canvas with constraints */
|
|
5576
|
+
.layout .game .canvas-container canvas {
|
|
5577
|
+
width: auto;
|
|
5578
|
+
height: auto;
|
|
5579
|
+
max-width: 100%;
|
|
5580
|
+
max-height: 100%;
|
|
5581
|
+
}
|
|
5582
|
+
|
|
5583
|
+
.layout .stats,
|
|
5584
|
+
.layout .logs {
|
|
5585
|
+
min-height: auto;
|
|
5586
|
+
padding: 1rem;
|
|
5587
|
+
flex-shrink: initial;
|
|
5588
|
+
}
|
|
5461
5589
|
}
|
|
5462
5590
|
|
|
5463
5591
|
/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */
|
|
@@ -5467,10 +5595,12 @@ var styles = `
|
|
|
5467
5595
|
"top-bar top-bar top-bar"
|
|
5468
5596
|
"left-bar game right-bar"
|
|
5469
5597
|
"bottom-bar bottom-bar bottom-bar";
|
|
5470
|
-
grid-template-columns:
|
|
5471
|
-
grid-template-rows:
|
|
5598
|
+
grid-template-columns: var(--bar-size) 1fr var(--bar-size);
|
|
5599
|
+
grid-template-rows: var(--bar-size-h) 1fr var(--bar-size-h);
|
|
5472
5600
|
width: 100vw;
|
|
5601
|
+
/* Use dvh with vh fallback for mobile Safari address bar */
|
|
5473
5602
|
height: 100vh;
|
|
5603
|
+
height: 100dvh;
|
|
5474
5604
|
background: #1a1a1a;
|
|
5475
5605
|
overflow: hidden;
|
|
5476
5606
|
overscroll-behavior: none;
|
|
@@ -5489,7 +5619,7 @@ var styles = `
|
|
|
5489
5619
|
}
|
|
5490
5620
|
|
|
5491
5621
|
.top-bar-side-label {
|
|
5492
|
-
width:
|
|
5622
|
+
width: var(--bar-size);
|
|
5493
5623
|
text-align: center;
|
|
5494
5624
|
font-size: 9px;
|
|
5495
5625
|
text-transform: uppercase;
|
|
@@ -5497,6 +5627,17 @@ var styles = `
|
|
|
5497
5627
|
color: #666;
|
|
5498
5628
|
}
|
|
5499
5629
|
|
|
5630
|
+
/* Mobile: larger top bar text */
|
|
5631
|
+
@media (max-width: 768px) {
|
|
5632
|
+
.top-bar-side-label {
|
|
5633
|
+
font-size: 12px;
|
|
5634
|
+
}
|
|
5635
|
+
|
|
5636
|
+
.top-bar {
|
|
5637
|
+
font-size: 14px;
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
|
|
5500
5641
|
.top-bar-center {
|
|
5501
5642
|
display: flex;
|
|
5502
5643
|
align-items: center;
|
|
@@ -5565,8 +5706,17 @@ var styles = `
|
|
|
5565
5706
|
display: flex;
|
|
5566
5707
|
align-items: center;
|
|
5567
5708
|
background: #111;
|
|
5568
|
-
|
|
5569
|
-
|
|
5709
|
+
/* Mobile-first: more padding */
|
|
5710
|
+
padding: 0 16px;
|
|
5711
|
+
gap: 12px;
|
|
5712
|
+
}
|
|
5713
|
+
|
|
5714
|
+
/* Desktop: tighter padding */
|
|
5715
|
+
@media (min-width: 769px) {
|
|
5716
|
+
.bottom-bar {
|
|
5717
|
+
padding: 0 8px;
|
|
5718
|
+
gap: 8px;
|
|
5719
|
+
}
|
|
5570
5720
|
}
|
|
5571
5721
|
|
|
5572
5722
|
.playbar-controls {
|
|
@@ -5576,16 +5726,35 @@ var styles = `
|
|
|
5576
5726
|
flex-shrink: 0;
|
|
5577
5727
|
}
|
|
5578
5728
|
|
|
5729
|
+
/* Mobile-first: hide step/jump buttons */
|
|
5730
|
+
.playbar-btn.jump-back,
|
|
5731
|
+
.playbar-btn.step-back,
|
|
5732
|
+
.playbar-btn.step-forward,
|
|
5733
|
+
.playbar-btn.jump-forward {
|
|
5734
|
+
display: none;
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
/* Desktop: show all controls */
|
|
5738
|
+
@media (min-width: 769px) {
|
|
5739
|
+
.playbar-btn.jump-back,
|
|
5740
|
+
.playbar-btn.step-back,
|
|
5741
|
+
.playbar-btn.step-forward,
|
|
5742
|
+
.playbar-btn.jump-forward {
|
|
5743
|
+
display: flex;
|
|
5744
|
+
}
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5579
5747
|
.playbar-btn {
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
min-
|
|
5748
|
+
/* Mobile-first: larger buttons */
|
|
5749
|
+
width: 4vh;
|
|
5750
|
+
height: 4vh;
|
|
5751
|
+
min-width: 32px;
|
|
5752
|
+
min-height: 32px;
|
|
5584
5753
|
border: none;
|
|
5585
5754
|
outline: none;
|
|
5586
5755
|
background: transparent;
|
|
5587
5756
|
color: #888;
|
|
5588
|
-
font-size:
|
|
5757
|
+
font-size: 16px;
|
|
5589
5758
|
cursor: pointer;
|
|
5590
5759
|
border-radius: 2px;
|
|
5591
5760
|
display: flex;
|
|
@@ -5595,6 +5764,17 @@ var styles = `
|
|
|
5595
5764
|
position: relative;
|
|
5596
5765
|
}
|
|
5597
5766
|
|
|
5767
|
+
/* Desktop: smaller buttons */
|
|
5768
|
+
@media (min-width: 769px) {
|
|
5769
|
+
.playbar-btn {
|
|
5770
|
+
width: 1.5vh;
|
|
5771
|
+
height: 1.5vh;
|
|
5772
|
+
min-width: 18px;
|
|
5773
|
+
min-height: 18px;
|
|
5774
|
+
font-size: 10px;
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5598
5778
|
.playbar-btn:hover {
|
|
5599
5779
|
background: #333;
|
|
5600
5780
|
color: #fff;
|
|
@@ -5638,7 +5818,8 @@ var styles = `
|
|
|
5638
5818
|
|
|
5639
5819
|
.seek-bar {
|
|
5640
5820
|
flex: 1;
|
|
5641
|
-
|
|
5821
|
+
/* Mobile-first: larger seek bar */
|
|
5822
|
+
height: 32px;
|
|
5642
5823
|
background: #222;
|
|
5643
5824
|
border-radius: 4px;
|
|
5644
5825
|
position: relative;
|
|
@@ -5646,6 +5827,13 @@ var styles = `
|
|
|
5646
5827
|
overflow: hidden;
|
|
5647
5828
|
}
|
|
5648
5829
|
|
|
5830
|
+
/* Desktop: smaller seek bar */
|
|
5831
|
+
@media (min-width: 769px) {
|
|
5832
|
+
.seek-bar {
|
|
5833
|
+
height: 16px;
|
|
5834
|
+
}
|
|
5835
|
+
}
|
|
5836
|
+
|
|
5649
5837
|
.seek-bar-fill {
|
|
5650
5838
|
position: absolute;
|
|
5651
5839
|
top: 0;
|
|
@@ -7262,5 +7450,5 @@ export {
|
|
|
7262
7450
|
App
|
|
7263
7451
|
};
|
|
7264
7452
|
|
|
7265
|
-
//# debugId=
|
|
7453
|
+
//# debugId=B02D4DB9DDB2D5FC64756E2164756E21
|
|
7266
7454
|
//# sourceMappingURL=mod.js.map
|