From 0a26fb6b9cc3077999a2fff8d59a5acbf7ea7f0c Mon Sep 17 00:00:00 2001 From: root Date: Sun, 29 Jun 2025 21:55:23 +0200 Subject: [PATCH] Comprehensive mobile optimization for KidsAI Explorer - Added extensive mobile-responsive CSS with proper breakpoints - Optimized chat interface for mobile devices with better touch targets - Improved mobile scrolling with hardware acceleration and touch-friendly scrollbars - Added mobile device detection for enhanced UX on smartphones/tablets - Prevented iOS zoom on input focus with proper font sizing - Enhanced textarea auto-resize functionality for mobile - Added mobile-friendly keyboard handling and focus management - Improved button sizing to meet iOS 44px minimum touch target requirements - Optimized conversation container for better mobile viewport handling - Added landscape orientation support and extra small device breakpoints - Enhanced visual feedback with proper active states for touch interactions - Fixed viewport jumping issues when virtual keyboard appears - Improved mobile-specific JavaScript event handling and scrolling behavior --- html/kidsai/script-new.js | 68 +++++- html/kidsai/server.js | 0 html/kidsai/style.css | 434 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 479 insertions(+), 23 deletions(-) mode change 100644 => 100755 html/kidsai/server.js diff --git a/html/kidsai/script-new.js b/html/kidsai/script-new.js index d6ff1d4..55ce6bc 100644 --- a/html/kidsai/script-new.js +++ b/html/kidsai/script-new.js @@ -43,6 +43,12 @@ class KidsAIExplorer { console.log('✅ KidsAI constructor completed'); } + // Detect mobile device + isMobileDevice() { + return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + || window.innerWidth <= 768; + } + initializeEventListeners() { console.log('🔗 Setting up event listeners'); @@ -64,6 +70,15 @@ class KidsAIExplorer { this.handleQuestion(); } }); + + // Add mobile-friendly input event for better responsiveness + if (this.isMobileDevice()) { + this.questionInput.addEventListener('input', () => { + // Auto-resize textarea on mobile for better UX + this.questionInput.style.height = 'auto'; + this.questionInput.style.height = Math.min(this.questionInput.scrollHeight, 120) + 'px'; + }); + } } // Suggestion cards @@ -502,7 +517,7 @@ class KidsAIExplorer { // Show AI response with animation setTimeout(() => { responseBubble.classList.add('visible'); - this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight; + this.scrollToBottomSmoothly(); }, 100); // Ask next question @@ -534,7 +549,7 @@ class KidsAIExplorer { setTimeout(() => { responseBubble.classList.add('visible'); - this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight; + this.scrollToBottomSmoothly(); }, 100); setTimeout(() => { @@ -563,7 +578,7 @@ class KidsAIExplorer { setTimeout(() => { revealDiv.classList.add('visible'); - this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight; + this.scrollToBottomSmoothly(); }, 500); return; } @@ -611,17 +626,45 @@ class KidsAIExplorer { questionBubble.classList.add('visible'); inputContainer.classList.add('visible'); - // Smooth scroll to bottom of conversation instead of specific element + // Better mobile scrolling + this.scrollToBottomSmoothly(); + + // Focus on the textarea with mobile-friendly delay and add event listeners + const textarea = document.getElementById(`user-input-${this.currentQuestionIndex}`); + if (textarea) { + // Add Enter key support for chat + textarea.addEventListener('keypress', (e) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + this.submitChatAnswer(this.currentQuestionIndex); + } + }); + + // Add mobile-friendly auto-resize + if (this.isMobileDevice()) { + textarea.addEventListener('input', () => { + textarea.style.height = 'auto'; + textarea.style.height = Math.min(textarea.scrollHeight, 80) + 'px'; + }); + } + + // Delay focus on mobile to prevent keyboard jumping + if (this.isMobileDevice()) { + setTimeout(() => textarea.focus(), 300); + } else { + textarea.focus(); + } + } + }, 300); + } + + // Helper method for better mobile scrolling + scrollToBottomSmoothly() { + if (this.conversationContainer) { setTimeout(() => { this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight; }, 100); - - // Focus on the textarea - const textarea = document.getElementById(`user-input-${this.currentQuestionIndex}`); - if (textarea) { - textarea.focus(); - } - }, 300); + } } submitChatAnswer(questionIndex) { @@ -665,6 +708,9 @@ class KidsAIExplorer { setTimeout(() => { userBubble.classList.add('visible'); + // Better mobile scrolling before generating AI response + this.scrollToBottomSmoothly(); + // Generate AI response using server-side AI this.generateChatAIResponse(answer, questionIndex); diff --git a/html/kidsai/server.js b/html/kidsai/server.js old mode 100644 new mode 100755 diff --git a/html/kidsai/style.css b/html/kidsai/style.css index 008b75f..e49cd17 100755 --- a/html/kidsai/style.css +++ b/html/kidsai/style.css @@ -5,12 +5,23 @@ box-sizing: border-box; } +/* Better mobile touch targets and text rendering */ +html { + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; +} + body { font-family: 'Open Sans', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; color: #333; overflow-x: hidden; + /* Prevent horizontal scrolling on mobile */ + position: relative; + /* Better text rendering on mobile */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } .container { @@ -980,30 +991,407 @@ body { animation: answerReveal 0.6s ease-out; } -/* Mobile responsiveness for answer section */ +/* Comprehensive Mobile Responsiveness */ @media (max-width: 768px) { - .answer-reveal-section { - padding: 20px; - margin-top: 20px; + /* Container and Layout */ + .container { + padding: 10px; + margin: 0; } - .reveal-answer-btn { - padding: 12px 25px; + /* Header Optimizations */ + .header { + margin-bottom: 20px; + } + + .header-top { + margin-bottom: 15px; + } + + .logo { + gap: 8px; + margin-bottom: 8px; + } + + .logo i, + .logo .brain-icon { + font-size: 2rem; + } + + .logo h1 { + font-size: 1.8rem; + text-align: center; + line-height: 1.2; + } + + .subtitle { + font-size: 1rem; + padding: 0 10px; + } + + /* Language Switcher */ + .language-switcher { + gap: 5px; + padding: 3px; + } + + .lang-btn { + padding: 6px 10px; + font-size: 0.8rem; + } + + /* Main Question Section */ + .main-section { + padding: 20px 15px; + margin-bottom: 20px; + } + + .main-section h2 { + font-size: 1.5rem; + margin-bottom: 15px; + } + + .question-input-container { + flex-direction: column; + gap: 15px; + } + + .question-input { + padding: 15px; + font-size: 16px; /* Prevents zoom on iOS */ + min-height: 50px; + } + + .ask-button { + padding: 15px 25px; + font-size: 1.1rem; + width: 100%; + min-height: 50px; + } + + /* Suggestions Grid */ + .suggestions-grid { + grid-template-columns: 1fr; + gap: 15px; + } + + .suggestion-card { + padding: 15px; + text-align: left; + display: flex; + align-items: center; + gap: 15px; + } + + .suggestion-card i, + .suggestion-card .sun-icon, + .suggestion-card .bird-icon, + .suggestion-card .water-icon, + .suggestion-card .computer-icon, + .suggestion-card .moon-icon, + .suggestion-card .rainbow-icon { + font-size: 1.5rem; + margin-bottom: 0; + flex-shrink: 0; + } + + .suggestion-card p { + margin: 0; + font-size: 0.95rem; + line-height: 1.3; + } + + /* Conversation Container */ + .conversation-container { + padding: 15px; + border-radius: 15px; + max-height: 70vh; + margin: 0 -5px; + } + + /* Chat Messages */ + .chat-message { + max-width: 92%; + margin-bottom: 12px; + } + + .chat-message.ai-message { + padding: 12px 15px; + border-radius: 15px 15px 15px 4px; + font-size: 0.95rem; + } + + .chat-message.user-message { + padding: 12px 15px; + border-radius: 15px 15px 4px 15px; + font-size: 0.95rem; + } + + .message-header { + gap: 6px; + margin-bottom: 6px; + } + + .ai-avatar { font-size: 1rem; } - .answer-box { - padding: 20px; + .ai-label { + font-size: 0.8rem; } - .answer-header { + .message-content { + line-height: 1.4; + } + + /* Chat Input */ + .chat-input-container { + margin: 15px 0; + } + + .chat-input-container .input-area { + padding: 8px 12px; + border-radius: 20px; + gap: 8px; + min-height: 50px; + } + + .chat-textarea { + padding: 8px 0; + font-size: 16px; /* Prevents zoom on iOS */ + min-height: 22px; + max-height: 80px; + } + + .chat-input-container .reply-btn { + padding: 10px 12px; + font-size: 12px; + border-radius: 18px; + min-height: 36px; + min-width: 50px; + } + + /* Reveal Section */ + .reveal-section { + margin-top: 20px; + padding: 20px 15px; + border-radius: 15px; + } + + .reveal-prompt p { + font-size: 1rem; + margin-bottom: 12px; + } + + .reveal-btn { + padding: 12px 20px; + font-size: 1rem; + border-radius: 20px; + width: 100%; + justify-content: center; + } + + /* Final Answer */ + .final-answer { + padding: 20px 15px; + border-radius: 12px; + margin: 15px 0; + } + + .final-answer .answer-header { flex-direction: column; align-items: flex-start; - gap: 8px; + gap: 10px; + margin-bottom: 15px; + padding-bottom: 12px; } - .answer-source { - margin-left: 0; + .final-answer .answer-icon { + font-size: 1.5rem; + padding: 6px; + } + + .final-answer h4 { + font-size: 1.2rem; + } + + .final-answer .answer-source { + align-self: stretch; + text-align: center; + padding: 8px 12px; + font-size: 0.75rem; + } + + .final-answer .answer-text { + font-size: 1rem; + line-height: 1.6; + padding: 15px; + margin-bottom: 15px; + } + + .final-answer .answer-footer { + padding: 12px 15px; + } + + .final-answer .answer-footer p { + font-size: 1rem; + } + + /* Action Buttons */ + .action-buttons { + flex-direction: column; + gap: 10px; + margin-top: 15px; + } + + .action-btn { + width: 100%; + justify-content: center; + padding: 12px 20px; + font-size: 1rem; + } + + /* Encouragement Section */ + .encouragement-section { + padding: 15px; + margin-bottom: 20px; + } + + .encouragement-text { + font-size: 1.1rem; + line-height: 1.3; + } + + /* Footer */ + .footer { + padding: 15px 10px; + margin-top: 20px; + } + + .footer p { + font-size: 1rem; + } + + .safety-note { + font-size: 0.85rem; + flex-direction: column; + gap: 4px; + } + + /* Loading Overlay */ + .loading-spinner { + width: 80px; + height: 80px; + } + + .gear1 { + width: 50px; + height: 50px; + top: 15px; + left: 15px; + } + + .gear2 { + width: 35px; + height: 35px; + } + + .gear3 { + width: 25px; + height: 25px; + } + + /* Touch Improvements */ + .suggestion-card:hover { + transform: none; /* Disable hover effects on mobile */ + } + + .suggestion-card:active { + transform: scale(0.98); + background: linear-gradient(135deg, #e2e8f0, #cbd5e0); + } + + .ask-button:active, + .action-btn:active, + .reply-btn:active, + .reveal-btn:active { + transform: scale(0.98); + } + + /* Prevent viewport jumping when keyboard appears */ + .conversation-container { + /* Use viewport units that don't change with keyboard */ + max-height: 70vh; + /* Ensure container stays in place */ + position: relative; + } + + /* Better handling of focus states on mobile */ + .chat-textarea:focus { + outline: none; + border-color: #4299e1; + } + + /* Improve button touch targets */ + .reply-btn, + .reveal-btn, + .ask-button { + min-height: 44px; /* iOS recommended minimum touch target */ + min-width: 44px; + } +} + +/* Extra small devices (phones in portrait mode) */ +@media (max-width: 480px) { + .container { + padding: 5px; + } + + .logo h1 { + font-size: 1.5rem; + } + + .main-section { + padding: 15px 10px; + } + + .conversation-container { + padding: 10px; + margin: 0 -2px; + } + + .chat-message { + max-width: 95%; + } + + .chat-message.ai-message, + .chat-message.user-message { + padding: 10px 12px; + font-size: 0.9rem; + } + + .final-answer { + padding: 15px 10px; + } + + .final-answer .answer-text { + font-size: 0.95rem; + padding: 12px; + } +} + +/* Landscape orientation adjustments */ +@media (max-width: 768px) and (orientation: landscape) { + .conversation-container { + max-height: 60vh; + } + + .logo h1 { + font-size: 1.6rem; + } + + .main-section h2 { + font-size: 1.3rem; } } @@ -1202,6 +1590,28 @@ body { max-height: 600px; overflow-y: auto; scroll-behavior: smooth; + /* Better scrolling on mobile */ + -webkit-overflow-scrolling: touch; + /* Improve scroll performance */ + transform: translateZ(0); +} + +/* Better scrollbar styling for mobile */ +.conversation-container::-webkit-scrollbar { + width: 4px; +} + +.conversation-container::-webkit-scrollbar-track { + background: transparent; +} + +.conversation-container::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 2px; +} + +.conversation-container::-webkit-scrollbar-thumb:hover { + background: rgba(0, 0, 0, 0.3); } /* Make reveal section part of the chat flow */