+
Select a profile and start a new chat
diff --git a/client/js/app.js b/client/js/app.js
index 3522ee2..64b00dd 100644
--- a/client/js/app.js
+++ b/client/js/app.js
@@ -15,6 +15,9 @@
const profileSelect = document.getElementById('profile-select');
const btnNew = document.getElementById('btn-new');
+const btnSidebarToggle = document.getElementById('btn-sidebar-toggle');
+const sidebarEl = document.querySelector('.sidebar');
+const sidebarBackdrop = document.getElementById('sidebar-backdrop');
const sessionListEl = document.getElementById('session-list');
const chatHeaderEl = document.getElementById('chat-header');
const tokenCounterEl = document.getElementById('token-counter');
@@ -58,6 +61,8 @@
btnAttach.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', onFileChange);
profileSelect.addEventListener('change', onProfileChange);
+ btnSidebarToggle.addEventListener('click', toggleSidebar);
+ sidebarBackdrop.addEventListener('click', closeSidebar);
sessionListEl.innerHTML = '';
@@ -363,6 +368,18 @@
// Don't clear pendingImages/pendingFiles — those belong to the user's draft
}
+// ── Sidebar (mobile) ──────────────────────────────────────────────────────────
+
+function toggleSidebar() {
+ sidebarEl.classList.toggle('open');
+ sidebarBackdrop.classList.toggle('visible');
+}
+
+function closeSidebar() {
+ sidebarEl.classList.remove('open');
+ sidebarBackdrop.classList.remove('visible');
+}
+
// ── Sending ───────────────────────────────────────────────────────────────────
async function sendMessage() {
@@ -419,7 +436,7 @@
? sessions.filter(s => s.profile_id === profileId)
: sessions;
renderSessions(sessionListEl, visible, currentId, {
- onSelect: (id) => { if (id !== currentId) openSession(id); },
+ onSelect: (id) => { if (id !== currentId) openSession(id); closeSidebar(); },
onDelete: deleteSession,
onPin: pinSession,
});
diff --git a/client/style.css b/client/style.css
index 4f1c84d..4070371 100644
--- a/client/style.css
+++ b/client/style.css
@@ -803,3 +803,76 @@
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #333; border-radius: 99px; }
+
+/* ── Sidebar toggle button (hidden on desktop) ───────── */
+
+.btn-sidebar-toggle {
+ display: none;
+ width: 36px;
+ height: 36px;
+ flex-shrink: 0;
+ background: none;
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ color: var(--text-muted);
+ font-size: 18px;
+ cursor: pointer;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.15s, color 0.15s;
+}
+.btn-sidebar-toggle:hover { background: #222; color: var(--text); }
+
+/* ── Sidebar backdrop (mobile overlay) ───────────────── */
+
+.sidebar-backdrop {
+ display: none;
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.55);
+ z-index: 99;
+ opacity: 0;
+ transition: opacity 0.25s ease;
+}
+.sidebar-backdrop.visible {
+ display: block;
+ opacity: 1;
+}
+
+/* ── Responsive breakpoint ───────────────────────────── */
+
+@media (max-width: 768px) {
+ /* Sidebar becomes a fixed drawer */
+ .sidebar {
+ position: fixed;
+ left: 0;
+ top: 0;
+ height: 100%;
+ z-index: 100;
+ transform: translateX(-100%);
+ transition: transform 0.25s ease;
+ box-shadow: 4px 0 24px rgba(0, 0, 0, 0.5);
+ }
+ .sidebar.open { transform: translateX(0); }
+
+ /* Hamburger button visible */
+ .btn-sidebar-toggle { display: flex; }
+
+ /* Chat fills the full width */
+ .chat { width: 100%; }
+
+ /* Wider bubbles on small screens */
+ .msg { max-width: 90%; }
+ .tool-card,
+ .thinking-card,
+ .summary-card { max-width: 96%; }
+
+ /* Tighter message padding */
+ .messages { padding: 16px 12px; gap: 12px; }
+
+ /* Input bar tighter */
+ .input-bar { padding: 10px 12px 12px; }
+
+ /* Chat header smaller */
+ .chat-header { padding: 10px 14px; min-height: 44px; }
+}