@bloopjs/web 0.0.96 → 0.0.98

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 CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,YAAY,EAEjB,KAAK,GAAG,EACT,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQhE,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,MAAM,YAAY,GAAG;IACzB,4BAA4B;IAC5B,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,yEAAyE;IACzE,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,sDAAsD;IACtD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,qFAAqF;IACrF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wFAAwF;IACxF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IACnC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAIF,oCAAoC;AACpC,wBAAsB,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAuB5D;AAED;;;;;;GAMG;AACH,qBAAa,GAAG;;IAEd,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAUzB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,cAAc;IAuB9B,uDAAuD;IACvD,IAAI,GAAG,IAAI,GAAG,CAEb;IAED,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAEf;IAeD,+BAA+B;IAC/B,IAAI,OAAO,IAAI,OAAO,GAAG,IAAI,CAE5B;IAED,gEAAgE;IAChE,IAAI,MAAM,IAAI,iBAAiB,GAAG,IAAI,CAErC;IAED,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI;IAIrD,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;IAc3D,sDAAsD;IACtD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAA8B;IAC5E,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAA8B;IAC3E,qCAAqC;IACrC,KAAK,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAgC;IAExE,gEAAgE;IAChE,SAAS,IAAI,IAAI;IA2QjB,kDAAkD;IAClD,OAAO,IAAI,IAAI;IAUf;;;;;;;;;;;;OAYG;IACG,SAAS,CACb,MAAM,EAAE,GAAG,EACX,IAAI,CAAC,EAAE,YAAY,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GACzC,OAAO,CAAC,IAAI,CAAC;CAuBjB;AAED,iBAAS,cAAc,CAAC,CAAC,SAAS,GAAG,EAAE,KAAK;IAC1C,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,aAAa,CAAC;IAC7D,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,cAAc,EAAE,aAAa,CAAC;CAC/B,CAuBA;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DebugUi.d.ts","sourceRoot":"","sources":["../../src/debugui/DebugUi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAA2B,MAAM,YAAY,CAAC;AAGtE,MAAM,MAAM,cAAc,GAAG;IAC3B,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,qBAAa,OAAO;;gBAQN,OAAO,GAAE,cAAmB;IAgExC,4CAA4C;IAC5C,IAAI,MAAM,IAAI,iBAAiB,CAE9B;IAED,mDAAmD;IACnD,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED,mDAAmD;IACnD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED,OAAO,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"DebugUi.d.ts","sourceRoot":"","sources":["../../src/debugui/DebugUi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,UAAU,EAAc,MAAM,YAAY,CAAC;AAGtE,MAAM,MAAM,cAAc,GAAG;IAC3B,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,qBAAa,OAAO;;gBAQN,OAAO,GAAE,cAAmB;IAgExC,4CAA4C;IAC5C,IAAI,MAAM,IAAI,iBAAiB,CAE9B;IAED,mDAAmD;IACnD,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED,mDAAmD;IACnD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED,OAAO,IAAI,IAAI;CAKhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AAiFA,wBAAgB,SAAS,4CAuGxB"}
1
+ {"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AA+HA,wBAAgB,SAAS,4CAsHxB"}
@@ -29,6 +29,8 @@ export type DebugState = {
29
29
  frameNumber: Signal<number>;
30
30
  hmrFlash: Signal<boolean>;
31
31
  isPlaying: Signal<boolean>;
32
+ isRecording: Signal<boolean>;
33
+ isReplaying: Signal<boolean>;
32
34
  tapeUtilization: Signal<number>;
33
35
  playheadPosition: Signal<number>;
34
36
  tapeStartFrame: Signal<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
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";
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/* Recording indicator - mobile: just the dot */\n.recording-indicator {\n display: flex;\n align-items: center;\n margin-right: 4px;\n}\n\n.recording-indicator .recording-label {\n display: none;\n}\n\n.recording-dot {\n width: 10px;\n height: 10px;\n background: #ff4444;\n border-radius: 50%;\n animation: recording-pulse 1s ease-in-out infinite;\n}\n\n@keyframes recording-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n/* Replay indicator - mobile: hidden */\n.replay-indicator {\n display: none;\n}\n\n/* Desktop: full indicators with text */\n@media (min-width: 769px) {\n .recording-indicator {\n gap: 4px;\n padding: 2px 6px;\n background: rgba(255, 0, 0, 0.2);\n border: 1px solid #ff4444;\n border-radius: 3px;\n }\n\n .recording-indicator .recording-label {\n display: inline;\n color: #ff4444;\n font-size: 10px;\n font-weight: bold;\n font-family: monospace;\n }\n\n .recording-dot {\n width: 8px;\n height: 8px;\n }\n\n .replay-indicator {\n display: flex;\n align-items: center;\n padding: 2px 6px;\n background: rgba(100, 100, 255, 0.2);\n border: 1px solid #6666ff;\n border-radius: 3px;\n color: #6666ff;\n font-size: 10px;\n font-weight: bold;\n font-family: monospace;\n margin-right: 4px;\n }\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: sized to match indicators */\n@media (min-width: 769px) {\n .playbar-btn {\n width: 24px;\n height: 24px;\n min-width: 24px;\n min-height: 24px;\n }\n\n /* Save/Load buttons need room for icon + text */\n .playbar-btn.save-tape-btn,\n .playbar-btn.load-tape-btn {\n width: auto;\n padding: 0 6px;\n gap: 4px;\n }\n}\n\n/* Mobile-first: hide button text labels, show only icons */\n.btn-label {\n display: none;\n}\n\n/* Desktop: show button text labels */\n@media (min-width: 769px) {\n .btn-label {\n display: inline;\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,itXA6qBlB,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debugui/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,43aAmwBlB,CAAC"}
package/dist/mod.js CHANGED
@@ -1450,7 +1450,7 @@ function readTapeHeader(tape) {
1450
1450
  eventCount: view.getUint16(14, true)
1451
1451
  };
1452
1452
  }
1453
- var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.96/wasm/bloop.wasm");
1453
+ var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.98/wasm/bloop.wasm");
1454
1454
  var MAX_ROLLBACK_FRAMES = 500;
1455
1455
  var TIME_CTX_OFFSET = 0;
1456
1456
  var INPUT_CTX_OFFSET = TIME_CTX_OFFSET + 4;
@@ -3308,7 +3308,7 @@ function readTapeHeader2(tape) {
3308
3308
  eventCount: view.getUint16(14, true)
3309
3309
  };
3310
3310
  }
3311
- var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.96/wasm/bloop.wasm");
3311
+ var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.98/wasm/bloop.wasm");
3312
3312
  var TIME_CTX_OFFSET2 = 0;
3313
3313
  var INPUT_CTX_OFFSET2 = TIME_CTX_OFFSET2 + 4;
3314
3314
  var EVENTS_OFFSET2 = INPUT_CTX_OFFSET2 + 4;
@@ -4417,6 +4417,8 @@ var snapshotSize = d3(0);
4417
4417
  var frameNumber = d3(0);
4418
4418
  var hmrFlash = d3(false);
4419
4419
  var isPlaying = d3(true);
4420
+ var isRecording = d3(false);
4421
+ var isReplaying = d3(false);
4420
4422
  var tapeUtilization = d3(0);
4421
4423
  var playheadPosition = d3(0);
4422
4424
  var tapeStartFrame = d3(0);
@@ -4448,6 +4450,8 @@ var debugState = {
4448
4450
  frameNumber,
4449
4451
  hmrFlash,
4450
4452
  isPlaying,
4453
+ isRecording,
4454
+ isReplaying,
4451
4455
  tapeUtilization,
4452
4456
  playheadPosition,
4453
4457
  tapeStartFrame,
@@ -4563,6 +4567,8 @@ function resetState() {
4563
4567
  debugState.frameNumber.value = 0;
4564
4568
  debugState.hmrFlash.value = false;
4565
4569
  debugState.isPlaying.value = true;
4570
+ debugState.isRecording.value = false;
4571
+ debugState.isReplaying.value = false;
4566
4572
  debugState.tapeUtilization.value = 0;
4567
4573
  debugState.playheadPosition.value = 0;
4568
4574
  debugState.tapeStartFrame.value = 0;
@@ -5148,6 +5154,57 @@ function LoadTapeDialog() {
5148
5154
  }
5149
5155
 
5150
5156
  // src/debugui/components/BottomBar.tsx
5157
+ var iconProps = { width: 14, height: 14, viewBox: "0 0 24 24", fill: "currentColor" };
5158
+ var Icons = {
5159
+ jumpBack: /* @__PURE__ */ u4("svg", {
5160
+ ...iconProps,
5161
+ children: /* @__PURE__ */ u4("path", {
5162
+ d: "M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"
5163
+ }, undefined, false, undefined, this)
5164
+ }, undefined, false, undefined, this),
5165
+ stepBack: /* @__PURE__ */ u4("svg", {
5166
+ ...iconProps,
5167
+ children: /* @__PURE__ */ u4("path", {
5168
+ d: "M6 6h2v12H6zm3.5 6l8.5 6V6z"
5169
+ }, undefined, false, undefined, this)
5170
+ }, undefined, false, undefined, this),
5171
+ play: /* @__PURE__ */ u4("svg", {
5172
+ ...iconProps,
5173
+ children: /* @__PURE__ */ u4("path", {
5174
+ d: "M8 5v14l11-7z"
5175
+ }, undefined, false, undefined, this)
5176
+ }, undefined, false, undefined, this),
5177
+ pause: /* @__PURE__ */ u4("svg", {
5178
+ ...iconProps,
5179
+ children: /* @__PURE__ */ u4("path", {
5180
+ d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z"
5181
+ }, undefined, false, undefined, this)
5182
+ }, undefined, false, undefined, this),
5183
+ stepForward: /* @__PURE__ */ u4("svg", {
5184
+ ...iconProps,
5185
+ children: /* @__PURE__ */ u4("path", {
5186
+ d: "M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"
5187
+ }, undefined, false, undefined, this)
5188
+ }, undefined, false, undefined, this),
5189
+ jumpForward: /* @__PURE__ */ u4("svg", {
5190
+ ...iconProps,
5191
+ children: /* @__PURE__ */ u4("path", {
5192
+ d: "M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"
5193
+ }, undefined, false, undefined, this)
5194
+ }, undefined, false, undefined, this),
5195
+ save: /* @__PURE__ */ u4("svg", {
5196
+ ...iconProps,
5197
+ children: /* @__PURE__ */ u4("path", {
5198
+ d: "M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"
5199
+ }, undefined, false, undefined, this)
5200
+ }, undefined, false, undefined, this),
5201
+ load: /* @__PURE__ */ u4("svg", {
5202
+ ...iconProps,
5203
+ children: /* @__PURE__ */ u4("path", {
5204
+ d: "M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"
5205
+ }, undefined, false, undefined, this)
5206
+ }, undefined, false, undefined, this)
5207
+ };
5151
5208
  function useRepeatOnHold(action) {
5152
5209
  const rafId = A2(null);
5153
5210
  const timeoutId = A2(null);
@@ -5208,6 +5265,8 @@ function useSeekDrag(onSeek2) {
5208
5265
  }
5209
5266
  function BottomBar() {
5210
5267
  const isPlaying2 = debugState.isPlaying.value;
5268
+ const isRecording2 = debugState.isRecording.value;
5269
+ const isReplaying2 = debugState.isReplaying.value;
5211
5270
  const tapeUtilization2 = debugState.tapeUtilization.value;
5212
5271
  const playheadPosition2 = debugState.playheadPosition.value;
5213
5272
  const handleJumpBack = q2(() => {
@@ -5245,11 +5304,29 @@ function BottomBar() {
5245
5304
  /* @__PURE__ */ u4("div", {
5246
5305
  className: "playbar-controls",
5247
5306
  children: [
5307
+ isRecording2 && /* @__PURE__ */ u4("span", {
5308
+ className: "recording-indicator",
5309
+ title: "Recording",
5310
+ children: [
5311
+ /* @__PURE__ */ u4("span", {
5312
+ className: "recording-dot"
5313
+ }, undefined, false, undefined, this),
5314
+ /* @__PURE__ */ u4("span", {
5315
+ className: "recording-label",
5316
+ children: "REC"
5317
+ }, undefined, false, undefined, this)
5318
+ ]
5319
+ }, undefined, true, undefined, this),
5320
+ isReplaying2 && /* @__PURE__ */ u4("span", {
5321
+ className: "replay-indicator",
5322
+ title: "Replaying tape",
5323
+ children: "REPLAY"
5324
+ }, undefined, false, undefined, this),
5248
5325
  /* @__PURE__ */ u4("button", {
5249
5326
  className: "playbar-btn jump-back",
5250
5327
  ...jumpBackRepeat,
5251
5328
  children: [
5252
- "<<",
5329
+ Icons.jumpBack,
5253
5330
  /* @__PURE__ */ u4("span", {
5254
5331
  className: "tooltip tooltip-left",
5255
5332
  children: [
@@ -5265,7 +5342,7 @@ function BottomBar() {
5265
5342
  className: "playbar-btn step-back",
5266
5343
  ...stepBackRepeat,
5267
5344
  children: [
5268
- "<",
5345
+ Icons.stepBack,
5269
5346
  /* @__PURE__ */ u4("span", {
5270
5347
  className: "tooltip",
5271
5348
  children: [
@@ -5281,7 +5358,7 @@ function BottomBar() {
5281
5358
  className: "playbar-btn play-pause",
5282
5359
  onClick: handlePlayPause,
5283
5360
  children: [
5284
- isPlaying2 ? "||" : ">",
5361
+ isPlaying2 ? Icons.pause : Icons.play,
5285
5362
  /* @__PURE__ */ u4("span", {
5286
5363
  className: "tooltip",
5287
5364
  children: [
@@ -5298,7 +5375,7 @@ function BottomBar() {
5298
5375
  className: "playbar-btn step-forward",
5299
5376
  ...stepForwardRepeat,
5300
5377
  children: [
5301
- ">",
5378
+ Icons.stepForward,
5302
5379
  /* @__PURE__ */ u4("span", {
5303
5380
  className: "tooltip",
5304
5381
  children: [
@@ -5314,7 +5391,7 @@ function BottomBar() {
5314
5391
  className: "playbar-btn jump-forward",
5315
5392
  ...jumpForwardRepeat,
5316
5393
  children: [
5317
- ">>",
5394
+ Icons.jumpForward,
5318
5395
  /* @__PURE__ */ u4("span", {
5319
5396
  className: "tooltip",
5320
5397
  children: [
@@ -5330,7 +5407,11 @@ function BottomBar() {
5330
5407
  className: "playbar-btn save-tape-btn",
5331
5408
  onClick: handleSaveTapeClick,
5332
5409
  children: [
5333
- "Save",
5410
+ Icons.save,
5411
+ /* @__PURE__ */ u4("span", {
5412
+ className: "btn-label",
5413
+ children: "Save"
5414
+ }, undefined, false, undefined, this),
5334
5415
  /* @__PURE__ */ u4("span", {
5335
5416
  className: "tooltip",
5336
5417
  children: [
@@ -5346,7 +5427,11 @@ function BottomBar() {
5346
5427
  className: "playbar-btn load-tape-btn",
5347
5428
  onClick: handleLoadTapeClick,
5348
5429
  children: [
5349
- "Load",
5430
+ Icons.load,
5431
+ /* @__PURE__ */ u4("span", {
5432
+ className: "btn-label",
5433
+ children: "Load"
5434
+ }, undefined, false, undefined, this),
5350
5435
  /* @__PURE__ */ u4("span", {
5351
5436
  className: "tooltip",
5352
5437
  children: "Load tape"
@@ -5761,6 +5846,73 @@ var styles = `
5761
5846
  flex-shrink: 0;
5762
5847
  }
5763
5848
 
5849
+ /* Recording indicator - mobile: just the dot */
5850
+ .recording-indicator {
5851
+ display: flex;
5852
+ align-items: center;
5853
+ margin-right: 4px;
5854
+ }
5855
+
5856
+ .recording-indicator .recording-label {
5857
+ display: none;
5858
+ }
5859
+
5860
+ .recording-dot {
5861
+ width: 10px;
5862
+ height: 10px;
5863
+ background: #ff4444;
5864
+ border-radius: 50%;
5865
+ animation: recording-pulse 1s ease-in-out infinite;
5866
+ }
5867
+
5868
+ @keyframes recording-pulse {
5869
+ 0%, 100% { opacity: 1; }
5870
+ 50% { opacity: 0.4; }
5871
+ }
5872
+
5873
+ /* Replay indicator - mobile: hidden */
5874
+ .replay-indicator {
5875
+ display: none;
5876
+ }
5877
+
5878
+ /* Desktop: full indicators with text */
5879
+ @media (min-width: 769px) {
5880
+ .recording-indicator {
5881
+ gap: 4px;
5882
+ padding: 2px 6px;
5883
+ background: rgba(255, 0, 0, 0.2);
5884
+ border: 1px solid #ff4444;
5885
+ border-radius: 3px;
5886
+ }
5887
+
5888
+ .recording-indicator .recording-label {
5889
+ display: inline;
5890
+ color: #ff4444;
5891
+ font-size: 10px;
5892
+ font-weight: bold;
5893
+ font-family: monospace;
5894
+ }
5895
+
5896
+ .recording-dot {
5897
+ width: 8px;
5898
+ height: 8px;
5899
+ }
5900
+
5901
+ .replay-indicator {
5902
+ display: flex;
5903
+ align-items: center;
5904
+ padding: 2px 6px;
5905
+ background: rgba(100, 100, 255, 0.2);
5906
+ border: 1px solid #6666ff;
5907
+ border-radius: 3px;
5908
+ color: #6666ff;
5909
+ font-size: 10px;
5910
+ font-weight: bold;
5911
+ font-family: monospace;
5912
+ margin-right: 4px;
5913
+ }
5914
+ }
5915
+
5764
5916
  /* Mobile-first: hide step/jump buttons */
5765
5917
  .playbar-btn.jump-back,
5766
5918
  .playbar-btn.step-back,
@@ -5799,14 +5951,33 @@ var styles = `
5799
5951
  position: relative;
5800
5952
  }
5801
5953
 
5802
- /* Desktop: smaller buttons */
5954
+ /* Desktop: sized to match indicators */
5803
5955
  @media (min-width: 769px) {
5804
5956
  .playbar-btn {
5805
- width: 1.5vh;
5806
- height: 1.5vh;
5807
- min-width: 18px;
5808
- min-height: 18px;
5809
- font-size: 10px;
5957
+ width: 24px;
5958
+ height: 24px;
5959
+ min-width: 24px;
5960
+ min-height: 24px;
5961
+ }
5962
+
5963
+ /* Save/Load buttons need room for icon + text */
5964
+ .playbar-btn.save-tape-btn,
5965
+ .playbar-btn.load-tape-btn {
5966
+ width: auto;
5967
+ padding: 0 6px;
5968
+ gap: 4px;
5969
+ }
5970
+ }
5971
+
5972
+ /* Mobile-first: hide button text labels, show only icons */
5973
+ .btn-label {
5974
+ display: none;
5975
+ }
5976
+
5977
+ /* Desktop: show button text labels */
5978
+ @media (min-width: 769px) {
5979
+ .btn-label {
5980
+ display: inline;
5810
5981
  }
5811
5982
  }
5812
5983
 
@@ -7028,6 +7199,8 @@ var actual = {
7028
7199
  };
7029
7200
  async function reconcile(app, signal) {
7030
7201
  app.beforeFrame.subscribe((_frame) => {
7202
+ if (app.sim.isReplaying)
7203
+ return;
7031
7204
  if (!app.game.context.net.isInSession) {
7032
7205
  return;
7033
7206
  }
@@ -7042,6 +7215,10 @@ async function reconcile(app, signal) {
7042
7215
  addLog(log);
7043
7216
  };
7044
7217
  while (!signal.aborted) {
7218
+ if (app.sim.isReplaying) {
7219
+ await sleep(150);
7220
+ continue;
7221
+ }
7045
7222
  const { net } = app.game.context;
7046
7223
  if (net.wantsRoomCode && actual.roomCode !== net.wantsRoomCode) {
7047
7224
  console.log("[netcode] wants a room code", {
@@ -7253,6 +7430,13 @@ class App {
7253
7430
  } else {
7254
7431
  window.addEventListener("resize", emitResize);
7255
7432
  }
7433
+ const toCanvasCoords = (clientX, clientY) => {
7434
+ if (canvas) {
7435
+ const rect = canvas.getBoundingClientRect();
7436
+ return { x: clientX - rect.left, y: clientY - rect.top };
7437
+ }
7438
+ return { x: clientX, y: clientY };
7439
+ };
7256
7440
  const updatePixelRatioListener = () => {
7257
7441
  const mediaQuery = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
7258
7442
  const handler = () => {
@@ -7275,8 +7459,10 @@ class App {
7275
7459
  };
7276
7460
  window.addEventListener("keyup", handleKeyup);
7277
7461
  const handleMousemove = (event) => {
7278
- if (shouldEmitInputs())
7279
- this.sim.emit.mousemove(event.clientX, event.clientY);
7462
+ if (shouldEmitInputs()) {
7463
+ const { x: x2, y: y4 } = toCanvasCoords(event.clientX, event.clientY);
7464
+ this.sim.emit.mousemove(x2, y4);
7465
+ }
7280
7466
  };
7281
7467
  window.addEventListener("mousemove", handleMousemove);
7282
7468
  const handleMousedown = (event) => {
@@ -7299,7 +7485,8 @@ class App {
7299
7485
  return;
7300
7486
  const touch = event.touches[0];
7301
7487
  if (touch) {
7302
- this.sim.emit.mousemove(touch.clientX, touch.clientY);
7488
+ const { x: x2, y: y4 } = toCanvasCoords(touch.clientX, touch.clientY);
7489
+ this.sim.emit.mousemove(x2, y4);
7303
7490
  this.sim.emit.mousedown("Left");
7304
7491
  }
7305
7492
  };
@@ -7314,7 +7501,8 @@ class App {
7314
7501
  return;
7315
7502
  const touch = event.touches[0];
7316
7503
  if (touch) {
7317
- this.sim.emit.mousemove(touch.clientX, touch.clientY);
7504
+ const { x: x2, y: y4 } = toCanvasCoords(touch.clientX, touch.clientY);
7505
+ this.sim.emit.mousemove(x2, y4);
7318
7506
  }
7319
7507
  };
7320
7508
  window.addEventListener("touchmove", handleTouchmove);
@@ -7385,6 +7573,8 @@ class App {
7385
7573
  }
7386
7574
  }
7387
7575
  debugState.isPlaying.value = !this.sim.isPaused;
7576
+ debugState.isRecording.value = this.sim.isRecording;
7577
+ debugState.isReplaying.value = this.sim.isReplaying;
7388
7578
  if (this.sim.hasHistory && debugState.tapeFrameCount.value > 0) {
7389
7579
  const currentFrame = this.sim.time.frame;
7390
7580
  const startFrame = debugState.tapeStartFrame.value;
@@ -7485,5 +7675,5 @@ export {
7485
7675
  App
7486
7676
  };
7487
7677
 
7488
- //# debugId=29BC9A3A0F18708064756E2164756E21
7678
+ //# debugId=42A08D0FB8399EAE64756E2164756E21
7489
7679
  //# sourceMappingURL=mod.js.map