⌘
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 91e3ffd..edf3959 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -60,6 +60,9 @@ const chatForm = document.getElementById('chat-form');
const chatInput = document.getElementById('chat-input');
const clearChatBtn = document.getElementById('clear-chat-btn');
const chatSendBtn = document.getElementById('chat-send-btn');
+const sidebarEl = document.querySelector('.sidebar');
+const menuToggle = document.getElementById('menu-toggle');
+const sidebarOverlay = document.getElementById('sidebar-overlay');
function updateState(newState) {
Object.assign(state, newState);
@@ -240,6 +243,11 @@ function selectTask(id, runId = null) {
renderTaskList();
renderRunHistory(task);
showTaskView(task);
+
+ // Close sidebar on mobile after selection
+ if (window.innerWidth <= 768) {
+ closeMobileMenu();
+ }
}
function renderRunHistory(task) {
@@ -753,6 +761,23 @@ document.querySelectorAll('.tab-btn').forEach(btn => {
});
});
+function toggleMobileMenu() {
+ sidebarEl.classList.toggle('open');
+ menuToggle.classList.toggle('active');
+ sidebarOverlay.classList.toggle('hidden');
+ document.body.style.overflow = sidebarEl.classList.contains('open') ? 'hidden' : '';
+}
+
+function closeMobileMenu() {
+ sidebarEl.classList.remove('open');
+ menuToggle.classList.remove('active');
+ sidebarOverlay.classList.add('hidden');
+ document.body.style.overflow = '';
+}
+
+menuToggle.addEventListener('click', toggleMobileMenu);
+sidebarOverlay.addEventListener('click', closeMobileMenu);
+
async function initializeApp() {
const hasSession = await checkSession();
diff --git a/frontend/src/style.css b/frontend/src/style.css
index f34da31..048ad46 100644
--- a/frontend/src/style.css
+++ b/frontend/src/style.css
@@ -1043,4 +1043,146 @@ textarea:focus {
.logout-btn:hover {
color: var(--primary);
+}
+
+/* Mobile Menu Toggle */
+.menu-toggle {
+ display: none;
+ position: fixed;
+ top: 16px;
+ right: 16px;
+ z-index: 1100;
+ background: var(--primary);
+ border: none;
+ width: 44px;
+ height: 44px;
+ border-radius: 10px;
+ cursor: pointer;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 5px;
+ box-shadow: 0 4px 15px var(--primary-glow);
+ transition: var(--transition);
+}
+
+.menu-toggle .bar {
+ display: block;
+ width: 20px;
+ height: 2px;
+ background: white;
+ border-radius: 2px;
+ transition: var(--transition);
+}
+
+.menu-toggle.active .bar:nth-child(1) {
+ transform: translateY(7px) rotate(45deg);
+}
+
+.menu-toggle.active .bar:nth-child(2) {
+ opacity: 0;
+}
+
+.menu-toggle.active .bar:nth-child(3) {
+ transform: translateY(-7px) rotate(-45deg);
+}
+
+.sidebar-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(4px);
+ z-index: 1000;
+ transition: opacity 0.3s ease;
+}
+
+/* Responsive Styles */
+@media (max-width: 768px) {
+ .menu-toggle {
+ display: flex;
+ }
+
+ .sidebar {
+ position: fixed;
+ left: -320px;
+ top: 0;
+ height: 100%;
+ z-index: 1050;
+ transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ box-shadow: 10px 0 30px rgba(0, 0, 0, 0.5);
+ }
+
+ .sidebar.open {
+ left: 0;
+ }
+
+ .dashboard-view, .task-view {
+ padding: 20px;
+ padding-top: 80px; /* Space for menu button */
+ height: auto;
+ min-height: 100%;
+ overflow-y: auto;
+ }
+
+ .dashboard-header h2 {
+ font-size: 24px;
+ }
+
+ .task-content {
+ flex-direction: column;
+ height: auto;
+ overflow: visible;
+ }
+
+ .run-history {
+ width: 100%;
+ max-height: 200px;
+ flex-shrink: 0;
+ }
+
+ .run-details {
+ flex-direction: column;
+ height: auto;
+ overflow: visible;
+ gap: 16px;
+ }
+
+ .logs-container {
+ width: 100%;
+ height: 400px;
+ flex-shrink: 0;
+ }
+
+ .view-header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+ }
+
+ .header-actions {
+ width: 100%;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 8px;
+ }
+
+ .header-actions .btn {
+ justify-content: center;
+ }
+
+ .modal {
+ width: 95%;
+ padding: 20px;
+ }
+
+ .preset-group {
+ grid-template-columns: 1fr;
+ }
+
+ .chat-container {
+ height: 500px;
+ }
}
\ No newline at end of file