From 989f8386b1ac424a98fc443d62e93bdd53908c87 Mon Sep 17 00:00:00 2001 From: arkon Date: Wed, 18 Feb 2026 20:05:01 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20mobile=20subagent=20dropdown=20=E2=80=94?= =?UTF-8?q?=20single-tap=20restore,=20position=20at=20top?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move subagent dropdown to top (near badge) instead of bottom on mobile - Fix iOS double-tap issue: wrap :hover styles in @media(hover:hover) - Pin dropdown immediately on first tap (prevent mouseleave auto-close) - Hide subagents panel by default on mobile (floating windows sufficient) - Revert broken mobile auto-minimize (agents auto-pop up again) Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 2 +- package.json | 2 +- src/web/public/app.js | 17 ++++++++++++- src/web/public/styles.css | 50 +++++++++++++++++++++++++-------------- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 29d8fd7f..2866e463 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ When user says "COM": 1. Increment version in BOTH `package.json` AND `CLAUDE.md` (verify they match with `grep version package.json && grep Version CLAUDE.md`) 2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web` -**Version**: 0.1543 (must match `package.json` for npm publish) +**Version**: 0.1544 (must match `package.json` for npm publish) ## Project Overview diff --git a/package.json b/package.json index e3c559e3..6d510a6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1543", + "version": "0.1544", "description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence", "type": "module", "main": "dist/index.js", diff --git a/src/web/public/app.js b/src/web/public/app.js index cb709e6f..1c61d751 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -4062,6 +4062,21 @@ class ClaudemanApp { const dropdown = document.querySelector('.subagent-dropdown.open'); if (!dropdown) { this.showSubagentDropdown(badgeEl); + // On mobile/touch, pin immediately so onmouseleave doesn't close it + const openedDropdown = document.querySelector('.subagent-dropdown.open'); + if (openedDropdown) { + openedDropdown.classList.add('pinned'); + const closeHandler = (e) => { + if (!badgeEl.contains(e.target) && !openedDropdown.contains(e.target)) { + openedDropdown.classList.remove('open', 'pinned'); + if (openedDropdown._originalParent) { + openedDropdown._originalParent.appendChild(openedDropdown); + } + document.removeEventListener('click', closeHandler); + } + }; + setTimeout(() => document.addEventListener('click', closeHandler), 0); + } return; } dropdown.classList.toggle('pinned'); @@ -9766,7 +9781,7 @@ class ClaudemanApp { showMonitor: false, showProjectInsights: false, showFileBrowser: false, - showSubagents: true, + showSubagents: false, // Feature toggles - keep tracking on even on mobile subagentTrackingEnabled: true, subagentActiveTabOnly: true, // Only show subagents for active tab diff --git a/src/web/public/styles.css b/src/web/public/styles.css index da2f5370..12a7303c 100644 --- a/src/web/public/styles.css +++ b/src/web/public/styles.css @@ -4224,9 +4224,11 @@ kbd { transition: transform 0.1s, background 0.15s; } -.session-tab .tab-subagent-badge:hover { - background: var(--accent-hover); - transform: scale(1.05); +@media (hover: hover) { + .session-tab .tab-subagent-badge:hover { + background: var(--accent-hover); + transform: scale(1.05); + } } .session-tab .tab-subagent-badge .subagent-label { @@ -4278,8 +4280,33 @@ kbd { transition: background 0.1s; } -.subagent-dropdown-item:hover { - background: var(--bg-hover); +/* Hover styles only for devices with real hover (mouse/trackpad). + On iOS Safari, :hover triggers a "double-tap" requirement — first tap activates + hover state, second tap fires click. Guarding with @media(hover:hover) avoids this. */ +@media (hover: hover) { + .subagent-dropdown-item:hover { + background: var(--bg-hover); + } + .subagent-dropdown-item:hover .subagent-dropdown-name { + color: var(--accent-hover); + } + .subagent-dropdown-item:hover .subagent-dropdown-close { + opacity: 0.6; + } + .subagent-dropdown-close:hover { + opacity: 1; + color: var(--red); + } +} + +/* Touch devices: show active state on tap instead of hover */ +@media (hover: none) { + .subagent-dropdown-item:active { + background: var(--bg-hover); + } + .subagent-dropdown-close { + opacity: 0.6; /* Always visible on touch (no hover to reveal) */ + } } /* Status dot instead of text label */ @@ -4313,10 +4340,6 @@ kbd { white-space: nowrap; } -.subagent-dropdown-item:hover .subagent-dropdown-name { - color: var(--accent-hover); -} - .subagent-dropdown-close { font-size: 0.9rem; color: var(--text-muted); @@ -4326,15 +4349,6 @@ kbd { transition: opacity 0.1s, color 0.1s; } -.subagent-dropdown-item:hover .subagent-dropdown-close { - opacity: 0.6; -} - -.subagent-dropdown-close:hover { - opacity: 1; - color: var(--red); -} - /* Task Panel */ .task-panel { position: fixed;