From 0b672447f6d2478aebe231a8ce6a6fae82d6908d Mon Sep 17 00:00:00 2001 From: juanatsap Date: Thu, 9 Apr 2026 18:39:51 +0100 Subject: [PATCH] feat: cog menu for layout modes, mobile viewport fix, better separation Header UX: - Replace 5 icon buttons with single cog (gear) dropdown menu - Cog menu shows all layout options with icons + labels - Help and Close buttons stay visible outside the cog - Active mode highlighted in green Mobile fixes: - Fix viewport overflow (100vw + max-width: 100vw) - Stronger shadow (0 -4px 20px) for clear CV/chat separation - Rounded corners (12px) on top for recognizable chat window - Hide desktop-only modes (side panel, floating, full) from cog on mobile - max-height: 50vh ensures CV always visible above Dark mode: - Cog menu styled for dark backgrounds --- static/css/04-interactive/_chat.css | 161 +++++++++++++------- templates/partials/widgets/chat-widget.html | 63 +++++--- 2 files changed, 147 insertions(+), 77 deletions(-) diff --git a/static/css/04-interactive/_chat.css b/static/css/04-interactive/_chat.css index 078d503..4ab09ec 100644 --- a/static/css/04-interactive/_chat.css +++ b/static/css/04-interactive/_chat.css @@ -224,12 +224,12 @@ font-size: 1.1rem; } -/* Header actions — icon buttons with tooltips */ +/* Header actions — cog menu + help + close */ .chat-header-actions { margin-left: auto; display: flex; align-items: center; - gap: 1px; + gap: 2px; } .chat-mode-btn { @@ -244,7 +244,6 @@ justify-content: center; border-radius: 4px; transition: all 0.15s; - position: relative; } .chat-mode-btn:hover { @@ -252,36 +251,60 @@ background: rgba(255,255,255,0.15); } -.chat-mode-btn.active { - color: #fff; - background: rgba(255,255,255,0.2); +/* Cog dropdown wrapper */ +.chat-cog-wrapper { + position: relative; } -/* Native tooltip via title attr — enhanced with CSS for consistent look */ -.chat-mode-btn[title]:hover::after { - content: attr(title); +.chat-cog-menu { + display: none; position: absolute; top: calc(100% + 6px); - left: 50%; - transform: translateX(-50%); - background: var(--black-bar, #2b2b2b); - color: #fff; - padding: 4px 8px; - border-radius: 4px; - font-size: 0.65rem; - font-family: 'Source Sans Pro', sans-serif; - font-weight: 400; - white-space: nowrap; - z-index: 1001; - pointer-events: none; - box-shadow: 0 2px 8px rgba(0,0,0,0.3); + right: 0; + background: var(--paper-bg, #fff); + border: 1px solid var(--border-light, #e0e0e0); + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0,0,0,0.2); + padding: 4px; + z-index: 1002; + min-width: 140px; } -.chat-header-divider { - width: 1px; - height: 16px; - background: rgba(255,255,255,0.25); - margin: 0 3px; +.chat-cog-menu.chat-cog-open { + display: flex; + flex-direction: column; +} + +.chat-cog-item { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 10px; + border: none; + background: none; + border-radius: 5px; + font-size: 0.72rem; + font-family: 'Source Sans Pro', sans-serif; + color: var(--text-secondary, #333); + cursor: pointer; + transition: all 0.15s; + white-space: nowrap; +} + +.chat-cog-item:hover { + background: var(--accent-green, #27ae60); + color: #fff; +} + +.chat-cog-item.active { + background: rgba(39, 174, 96, 0.12); + color: var(--accent-green, #27ae60); + font-weight: 600; +} + +.chat-cog-item iconify-icon { + font-size: 0.9rem; + flex-shrink: 0; } /* ========================================================================== @@ -751,6 +774,20 @@ border-bottom-color: #4eca81; } +[data-color-theme="dark"] .chat-cog-menu { + background: #333; + border-color: #555; +} + +[data-color-theme="dark"] .chat-cog-item { + color: #ddd; +} + +[data-color-theme="dark"] .chat-cog-item.active { + background: rgba(78, 202, 129, 0.15); + color: #4eca81; +} + /* Auto dark (system preference) */ @media (prefers-color-scheme: dark) { [data-color-theme="auto"] .chat-panel { @@ -787,6 +824,20 @@ color: #4eca81; border-bottom-color: #4eca81; } + + [data-color-theme="auto"] .chat-cog-menu { + background: #333; + border-color: #555; + } + + [data-color-theme="auto"] .chat-cog-item { + color: #ddd; + } + + [data-color-theme="auto"] .chat-cog-item.active { + background: rgba(78, 202, 129, 0.15); + color: #4eca81; + } } /* ========================================================================== @@ -794,14 +845,17 @@ ========================================================================== */ @media (max-width: 480px) { - /* Default compact: bottom sheet */ + /* Default compact: bottom sheet with clear separation */ .chat-panel { bottom: 0; left: 0; right: 0; - width: 100%; - max-height: 55vh; - border-radius: 8px 8px 0 0; + width: 100vw; + max-width: 100vw; + max-height: 50vh; + border-radius: 12px 12px 0 0; + box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.25); + overflow: hidden; } .chat-toggle-btn { @@ -810,31 +864,28 @@ } .chat-messages { - max-height: 180px; + max-height: 160px; } - /* Hide desktop-only layout modes on mobile */ - .chat-mode-btn[data-mode="chat-half"], - .chat-mode-btn[data-mode="chat-float"], - .chat-mode-btn[data-mode="chat-full"] { + /* Hide desktop-only cog items on mobile */ + .chat-cog-item[data-mode="chat-half"], + .chat-cog-item[data-mode="chat-float"], + .chat-cog-item[data-mode="chat-full"] { display: none; } - /* Show mobile split button */ - .chat-mode-btn[data-mode="chat-split"] { - display: flex; - } - /* Mobile split: CV on top, chat on bottom half */ .chat-panel.chat-split { bottom: 0; left: 0; right: 0; top: auto; - width: 100%; + width: 100vw; + max-width: 100vw; height: 50vh; max-height: 50vh; - border-radius: 8px 8px 0 0; + border-radius: 12px 12px 0 0; + box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.3); border-top: 2px solid var(--accent-green, #27ae60); } @@ -851,12 +902,14 @@ left: 0; right: 0; top: auto; - width: 100%; + width: 100vw; + max-width: 100vw; height: auto; - max-height: 55vh; - border-radius: 8px 8px 0 0; - border: 1px solid var(--border-light, #e0e0e0); + max-height: 50vh; + border-radius: 12px 12px 0 0; + border: none; resize: none; + box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.25); } /* Wave position follows mobile button */ @@ -865,11 +918,6 @@ right: calc(1rem + 38px); } - /* Tooltips: prevent overflow on mobile */ - .chat-mode-btn[title]:hover::after { - display: none; - } - /* Tighter header on mobile */ .chat-header { padding: 8px 10px; @@ -880,11 +928,10 @@ font-size: 0.85rem; padding: 3px; } -} -/* Hide mobile split button on desktop */ -@media (min-width: 481px) { - .chat-mode-btn[data-mode="chat-split"] { - display: none; + /* Cog menu on mobile */ + .chat-cog-menu { + right: -8px; + min-width: 120px; } } diff --git a/templates/partials/widgets/chat-widget.html b/templates/partials/widgets/chat-widget.html index 49fb751..15ce20a 100644 --- a/templates/partials/widgets/chat-widget.html +++ b/templates/partials/widgets/chat-widget.html @@ -17,29 +17,40 @@ {{if eq .Lang "es"}}Asistente del CV{{else}}CV Assistant{{end}}
- - - - - - + +
+ +
+ + + + + +
+
- @@ -142,6 +153,18 @@ function toggleChatPanel() { } } +// Cog menu toggle +function toggleChatCog() { + document.getElementById('chat-cog-menu').classList.toggle('chat-cog-open'); +} +function closeChatCog() { + document.getElementById('chat-cog-menu').classList.remove('chat-cog-open'); +} +// Close cog when clicking outside +document.addEventListener('click', function(e) { + if (!e.target.closest('.chat-cog-wrapper')) closeChatCog(); +}); + // Show user message bubble immediately in chat var chatBubblePending = false; function appendUserBubble(text) { @@ -228,9 +251,9 @@ function setChatSize(size) { panel.style.width = ''; panel.style.height = ''; if (size) panel.classList.add(size); - // Update active button - document.querySelectorAll('.chat-mode-btn[data-mode]').forEach(function(btn) { - btn.classList.toggle('active', btn.getAttribute('data-mode') === size); + // Update active item in cog menu + document.querySelectorAll('.chat-cog-item[data-mode]').forEach(function(item) { + item.classList.toggle('active', item.getAttribute('data-mode') === size); }); // Enable/disable drag if (size === 'chat-float') {