diff --git a/dashboard/css/replay.css b/dashboard/css/replay.css
new file mode 100644
index 0000000..6ec0124
--- /dev/null
+++ b/dashboard/css/replay.css
@@ -0,0 +1,464 @@
+/* ============================================
+ Time-Travel Replay Mode Styles
+ ============================================ */
+
+/* ----- Replay Control Bar ----- */
+.replay-control-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ background: linear-gradient(180deg, rgba(30, 30, 58, 0.98) 0%, rgba(20, 20, 40, 0.95) 100%);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
+ z-index: 100;
+ padding: 12px 20px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 20px;
+ backdrop-filter: blur(10px);
+}
+
+.replay-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ flex: 1;
+}
+
+.replay-btn {
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 8px;
+ color: #eee;
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ flex-shrink: 0;
+}
+
+.replay-btn:hover {
+ background: rgba(255, 255, 255, 0.15);
+ border-color: rgba(255, 255, 255, 0.25);
+ transform: translateY(-1px);
+}
+
+.replay-btn:active {
+ background: rgba(255, 255, 255, 0.1);
+ transform: translateY(0);
+}
+
+.replay-btn svg {
+ width: 18px;
+ height: 18px;
+}
+
+.replay-info {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ min-width: 150px;
+}
+
+.replay-timestamp {
+ font-size: 16px;
+ font-weight: 600;
+ color: #4fc3f7;
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
+ letter-spacing: 0.5px;
+}
+
+.replay-range {
+ font-size: 12px;
+ color: #888;
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
+}
+
+.replay-playback {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.replay-speed {
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 6px;
+ color: #ccc;
+ padding: 6px 10px;
+ font-size: 13px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.replay-speed:hover {
+ background: rgba(255, 255, 255, 0.1);
+ border-color: rgba(255, 255, 255, 0.2);
+}
+
+.replay-speed:focus {
+ outline: none;
+ border-color: #4fc3f7;
+}
+
+.replay-timeline {
+ flex: 1;
+ max-width: 400px;
+}
+
+.replay-scrubber {
+ width: 100%;
+ height: 6px;
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 3px;
+ outline: none;
+ -webkit-appearance: none;
+ cursor: pointer;
+}
+
+.replay-scrubber::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 16px;
+ height: 16px;
+ background: #4fc3f7;
+ border-radius: 50%;
+ cursor: grab;
+ transition: all 0.15s ease;
+ box-shadow: 0 2px 6px rgba(79, 195, 247, 0.4);
+}
+
+.replay-scrubber::-webkit-slider-thumb:hover {
+ transform: scale(1.2);
+ box-shadow: 0 2px 10px rgba(79, 195, 247, 0.6);
+}
+
+.replay-scrubber::-webkit-slider-thumb:active {
+ cursor: grabbing;
+ transform: scale(1.1);
+}
+
+.replay-scrubber::-moz-range-thumb {
+ width: 16px;
+ height: 16px;
+ background: #4fc3f7;
+ border: none;
+ border-radius: 50%;
+ cursor: grab;
+ transition: all 0.15s ease;
+ box-shadow: 0 2px 6px rgba(79, 195, 247, 0.4);
+}
+
+.replay-scrubber::-moz-range-thumb:hover {
+ transform: scale(1.2);
+ box-shadow: 0 2px 10px rgba(79, 195, 247, 0.6);
+}
+
+.replay-scrubber::-moz-range-thumb:active {
+ cursor: grabbing;
+}
+
+.replay-scrubber::-moz-range-track {
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 3px;
+ height: 6px;
+}
+
+.replay-tuning {
+ display: flex;
+ align-items: center;
+}
+
+.replay-tune-btn {
+ background: rgba(76, 175, 80, 0.15);
+ border: 1px solid rgba(76, 175, 80, 0.3);
+ border-radius: 8px;
+ color: #81c784;
+ padding: 8px 14px;
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.replay-tune-btn:hover {
+ background: rgba(76, 175, 80, 0.25);
+ border-color: rgba(76, 175, 80, 0.5);
+ transform: translateY(-1px);
+}
+
+.replay-tune-btn:active {
+ transform: translateY(0);
+}
+
+.replay-tune-btn svg {
+ width: 16px;
+ height: 16px;
+}
+
+/* ----- Replay Tuning Panel ----- */
+.replay-tuning-panel {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(4px);
+ z-index: 1000;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+}
+
+.replay-tuning-content {
+ background: linear-gradient(135deg, #1e1e3a 0%, #15152a 100%);
+ border-radius: 16px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
+ width: 100%;
+ max-width: 500px;
+ max-height: 90vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.replay-tuning-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 20px 24px;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ flex-shrink: 0;
+}
+
+.replay-tuning-header h2 {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 600;
+ color: #eee;
+}
+
+.replay-tuning-close {
+ background: none;
+ border: none;
+ color: #888;
+ font-size: 24px;
+ line-height: 1;
+ cursor: pointer;
+ padding: 0;
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+}
+
+.replay-tuning-close:hover {
+ background: rgba(255, 255, 255, 0.1);
+ color: #eee;
+}
+
+.replay-tuning-body {
+ padding: 24px;
+ overflow-y: auto;
+ flex: 1;
+}
+
+.tuning-param {
+ margin-bottom: 24px;
+}
+
+.tuning-param:last-child {
+ margin-bottom: 0;
+}
+
+.tuning-param label {
+ display: block;
+ font-size: 13px;
+ font-weight: 500;
+ color: #ccc;
+ margin-bottom: 8px;
+}
+
+.tuning-param input[type="range"] {
+ width: 100%;
+ height: 6px;
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 3px;
+ outline: none;
+ -webkit-appearance: none;
+ margin-bottom: 8px;
+}
+
+.tuning-param input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 16px;
+ height: 16px;
+ background: #4fc3f7;
+ border-radius: 50%;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ box-shadow: 0 2px 6px rgba(79, 195, 247, 0.4);
+}
+
+.tuning-param input[type="range"]::-webkit-slider-thumb:hover {
+ transform: scale(1.15);
+}
+
+.tuning-param input[type="range"]::-moz-range-thumb {
+ width: 16px;
+ height: 16px;
+ background: #4fc3f7;
+ border: none;
+ border-radius: 50%;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ box-shadow: 0 2px 6px rgba(79, 195, 247, 0.4);
+}
+
+.tuning-param input[type="range"]::-moz-range-thumb:hover {
+ transform: scale(1.15);
+}
+
+.tuning-param input[type="range"]::-moz-range-track {
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 3px;
+ height: 6px;
+}
+
+.tuning-value {
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
+ font-size: 13px;
+ color: #4fc3f7;
+ float: right;
+}
+
+.tuning-actions {
+ display: flex;
+ gap: 12px;
+ margin-top: 28px;
+}
+
+.tuning-btn {
+ flex: 1;
+ padding: 12px 20px;
+ border: none;
+ border-radius: 8px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.tuning-btn {
+ background: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);
+ color: #000;
+}
+
+.tuning-btn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(79, 195, 247, 0.4);
+}
+
+.tuning-btn:active {
+ transform: translateY(0);
+}
+
+.tuning-btn-secondary {
+ background: rgba(255, 255, 255, 0.08);
+ color: #ccc;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.tuning-btn-secondary:hover {
+ background: rgba(255, 255, 255, 0.12);
+ border-color: rgba(255, 255, 255, 0.2);
+}
+
+/* ----- Responsive Adjustments ----- */
+@media (max-width: 768px) {
+ .replay-control-bar {
+ flex-wrap: wrap;
+ padding: 10px 16px;
+ }
+
+ .replay-controls {
+ flex-wrap: wrap;
+ gap: 12px;
+ }
+
+ .replay-info {
+ min-width: 120px;
+ }
+
+ .replay-timeline {
+ max-width: 200px;
+ }
+
+ .replay-tuning-content {
+ max-width: 100%;
+ margin: 0;
+ }
+}
+
+/* ----- Replay Mode Indicator ----- */
+.replay-mode-indicator {
+ position: fixed;
+ bottom: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ background: rgba(79, 195, 247, 0.9);
+ color: #000;
+ padding: 8px 16px;
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 600;
+ z-index: 99;
+ box-shadow: 0 2px 10px rgba(79, 195, 247, 0.4);
+ display: none;
+}
+
+.replay-mode-indicator.visible {
+ display: block;
+ animation: slideUp 0.3s ease;
+}
+
+@keyframes slideUp {
+ from {
+ transform: translateX(-50%) translateY(20px);
+ opacity: 0;
+ }
+ to {
+ transform: translateX(-50%) translateY(0);
+ opacity: 1;
+ }
+}
+
+/* ----- Loading State ----- */
+.replay-loading {
+ display: inline-block;
+ width: 14px;
+ height: 14px;
+ border: 2px solid rgba(255, 255, 255, 0.2);
+ border-top-color: #4fc3f7;
+ border-radius: 50%;
+ animation: replaySpin 0.8s linear infinite;
+}
+
+@keyframes replaySpin {
+ to {
+ transform: rotate(360deg);
+ }
+}
diff --git a/dashboard/index.html b/dashboard/index.html
index 4b118df..582a4b3 100644
--- a/dashboard/index.html
+++ b/dashboard/index.html
@@ -14,6 +14,7 @@
+