Spaces:
Paused
Paused
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> | |
| <!-- Page Title (keyword-rich, action-oriented) --> | |
| <title>Gemma Avatar + V.AI STUDIO -- Real-Time 3D Chat & 8000+ Products</title> | |
| <!-- SEO: Canonical URL --> | |
| <link rel="canonical" href="https://huggingface.co/spaces/bep40/gemma-avatar" /> | |
| <!-- SEO: Meta Description (155 chars, unique, actionable) --> | |
| <meta name="description" content="Gemma Avatar + V.AI STUDIO: Talk to Gemma 4 with a 3D talking-head avatar and real-time lip-sync. Search 8000+ kitchen appliances & smart locks from Malloca, Eurogold, Grob, Canzy, Demax." /> | |
| <!-- SEO: Keywords --> | |
| <meta name="keywords" content="Gemma Avatar, V.AI STUDIO, 3D avatar, lip-sync, talking head, voice AI, Gemma 4, real-time chat, kitchen appliances, smart locks, Malloca, Eurogold, Grob, Canzy, Demax" /> | |
| <!-- SEO: Author & Publisher --> | |
| <meta name="author" content="bep40" /> | |
| <meta name="publisher" content="Hugging Face" /> | |
| <!-- Open Graph (Facebook, LinkedIn, Discord, WhatsApp) --> | |
| <meta property="og:type" content="website" /> | |
| <meta property="og:locale" content="en_US" /> | |
| <meta property="og:locale:alternate" content="vi_VN" /> | |
| <meta property="og:site_name" content="Hugging Face Spaces" /> | |
| <meta property="og:title" content="Gemma Avatar + V.AI STUDIO -- 3D Talking Avatar & 8000+ Products" /> | |
| <meta property="og:description" content="Talk to Gemma 4 face-to-face with a 3D talking-head avatar and real-time lip-sync. Search 8000+ kitchen appliances & smart locks from Malloca, Eurogold, Grob, Canzy, Demax." /> | |
| <meta property="og:url" content="https://huggingface.co/spaces/bep40/gemma-avatar" /> | |
| <meta property="og:image" content="https://huggingface.co/spaces/bep40/gemma-avatar/resolve/main/thumbnail.webp" /> | |
| <meta property="og:image:width" content="1200" /> | |
| <meta property="og:image:height" content="630" /> | |
| <meta property="og:image:alt" content="Gemma Avatar + V.AI STUDIO -- Real-Time 3D Talking Avatar and 8000+ Product Search" /> | |
| <meta property="og:image:type" content="image/webp" /> | |
| <!-- Twitter Card (summary_large_image) --> | |
| <meta name="twitter:card" content="summary_large_image" /> | |
| <meta name="twitter:site" content="@huggingface" /> | |
| <meta name="twitter:creator" content="@bep40" /> | |
| <meta name="twitter:title" content="Gemma Avatar + V.AI STUDIO -- 3D Talking Avatar & 8000+ Products" /> | |
| <meta name="twitter:description" content="Talk to Gemma 4 face-to-face with a 3D talking-head avatar and real-time lip-sync. Search 8000+ kitchen appliances & smart locks." /> | |
| <meta name="twitter:image" content="https://huggingface.co/spaces/bep40/gemma-avatar/resolve/main/thumbnail.webp" /> | |
| <meta name="twitter:image:alt" content="Gemma Avatar + V.AI STUDIO -- Real-Time 3D Talking Avatar and 8000+ Product Search" /> | |
| <!-- SEO: Robots --> | |
| <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" /> | |
| <!-- SEO: Language --> | |
| <link rel="alternate" hreflang="en" href="https://huggingface.co/spaces/bep40/gemma-avatar" /> | |
| <link rel="alternate" hreflang="vi" href="https://huggingface.co/spaces/bep40/gemma-avatar" /> | |
| <meta name="language" content="English, Vietnamese" /> | |
| <!-- SEO: Theme & App --> | |
| <meta name="theme-color" content="#4f46e5" /> | |
| <meta name="msapplication-TileColor" content="#4f46e5" /> | |
| <meta name="apple-mobile-web-app-title" content="Gemma Avatar" /> | |
| <meta name="apple-mobile-web-app-capable" content="yes" /> | |
| <meta name="apple-mobile-web-app-status-bar-style" content="default" /> | |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Geist+Mono:wght@500&display=swap" rel="stylesheet" /> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" /> | |
| <link rel="stylesheet" href="./src/style.css" /> | |
| </head> | |
| <body> | |
| <main id="app"> | |
| <div id="stage" aria-label="3D avatar"></div> | |
| <div id="loading">Loading avatar…</div> | |
| <header id="topbar"> | |
| <div id="identity"> | |
| <h1>Gemma Avatar + V.AI STUDIO</h1> | |
| <p>Chat or talk to <strong>Gemma 4</strong>. Text → Qwen3-TTS → lip-sync avatar. Control V.AI STUDIO catalog.</p> | |
| </div> | |
| <button id="settings-btn" class="icon-btn" aria-label="Settings" title="Settings"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| <circle cx="12" cy="12" r="3"></circle> | |
| <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a2 2 0 1 1-2.83 2.83l-.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06.06a2 2 0 1 1-2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0-1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path> | |
| </svg> | |
| </button> | |
| </header> | |
| <div id="subtitles" aria-live="polite"></div> | |
| <div id="text-chat" hidden> | |
| <div id="chat-header"> | |
| <span id="chat-title">Text Chat</span> | |
| <div id="chat-header-actions"> | |
| <select id="chat-avatar-select" title="Switch avatar"></select> | |
| <button id="chat-close-btn" class="icon-btn small" aria-label="Close text chat" title="Close"> | |
| <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> | |
| <line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div id="chat-messages"></div> | |
| <div id="chat-input-container"> | |
| <input id="chat-input" type="text" placeholder="Type a message..." autocomplete="off" /> | |
| <button id="chat-send-btn" class="icon-btn" aria-label="Send message"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> | |
| </svg> | |
| </button> | |
| </div> | |
| <div id="chat-resize-handle"></div> | |
| </div> | |
| <footer id="controls"> | |
| <div id="caption">LOADING…</div> | |
| <div id="buttons"> | |
| <button id="main-btn" disabled><span id="main-btn-label">Loading…</span></button> | |
| <button id="mute-btn" class="icon-btn" hidden aria-label="Mute microphone" title="Mute microphone"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> | |
| <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path> | |
| <path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line> | |
| </svg> | |
| </button> | |
| <button id="text-mode-btn" class="icon-btn" hidden aria-label="Text chat mode" title="Text chat mode"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path> | |
| </svg> | |
| </button> | |
| </div> | |
| </footer> | |
| <dialog id="settings"> | |
| <form method="dialog"> | |
| <h2>Settings</h2> | |
| <label>Voice<select id="voice"></select></label> | |
| <label>Avatar model<select id="settings-avatar-select"></select></label> | |
| <label class="check-row"><input type="checkbox" id="subtitles-toggle" />Show subtitles while she speaks</label> | |
| <label>Extra instructions<textarea id="instructions" rows="4" placeholder="Anything you want her to know or do (persona stays)."></textarea></label> | |
| <label id="direct-url-row" hidden>Direct server URL<input id="direct-url" type="url" placeholder="ws://localhost:8080/v1/realtime" spellcheck="false" /></label> | |
| <div class="dialog-actions"><button value="close" class="primary">Done</button></div> | |
| </form> | |
| </dialog> | |
| </main> | |
| <!-- V.AISTUDIO floating button --> | |
| <button id="vaistudio-toggle" aria-label="Open V.AI STUDIO catalog" title="Open V.AI STUDIO catalog" style="position:fixed;bottom:24px;right:24px;z-index:180;width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#003f62,#0077b6);color:#fff;border:none;cursor:pointer;box-shadow:0 4px 20px rgba(0,63,98,0.4);display:flex;align-items:center;justify-content:center;font-size:1.4rem;transition:all 0.25s ease" onmouseover="this.style.transform='scale(1.1)';this.style.boxShadow='0 6px 28px rgba(0,63,98,0.5)'" onmouseout="this.style.transform='scale(1)';this.style.boxShadow='0 4px 20px rgba(0,63,98,0.4)'"> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path><polyline points="17 8 12 13 7 8"></polyline></svg> | |
| </button> | |
| <!-- V.AISTUDIO Panel --> | |
| <div id="vaistudio-panel" role="dialog" aria-label="V.AI STUDIO Catalog" style="position:fixed;bottom:0;right:0;width:400px;max-width:100vw;height:560px;max-height:calc(100vh - 48px);background:#fff;border-radius:20px 20px 0 0;box-shadow:0 8px 40px rgba(0,0,0,0.18);z-index:160;display:none;flex-direction:column;overflow:hidden"> | |
| <div id="vaistudio-header" style="background:linear-gradient(135deg,#003f62,#0077b6);color:#fff;padding:14px 16px;display:flex;align-items:center;gap:12px;flex-shrink:0"> | |
| <div style="width:38px;height:38px;border-radius:12px;background:rgba(255,255,255,0.15);display:flex;align-items:center;justify-content:center;font-size:1.1rem;flex-shrink:0"><i class="fas fa-store"></i></div> | |
| <div style="flex:1;min-width:0"> | |
| <h4 style="font-size:0.9rem;font-weight:700;margin:0">V.AI STUDIO</h4> | |
| <span id="vaistudio-count" style="font-size:0.68rem;opacity:0.75">Đang tải sản phẩm…</span> | |
| </div> | |
| <button id="vaistudio-close" aria-label="Close" style="width:40px;height:40px;min-width:40px;min-height:40px;border-radius:50%;background:rgba(255,255,255,0.25);border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.1rem;transition:all 0.2s" onmouseover="this.style.background='rgba(255,255,255,0.4)'" onmouseout="this.style.background='rgba(255,255,255,0.25)'"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| </div> | |
| <!-- Search + Suggestions dropdown --> | |
| <div style="padding:8px 12px 4px;flex-shrink:0;background:#f8fafc;border-bottom:1px solid #e2e8f0;position:relative"> | |
| <input id="vaix-search" type="text" placeholder="🔍 Tìm sản phẩm..." autocomplete="off" style="width:100%;padding:10px 14px;border:1px solid #e2e8f0;border-radius:10px;font-size:0.85rem;outline:none;background:#fff;box-sizing:border-box" onfocus="this.style.borderColor='#0077b6'" onblur="this.style.borderColor='#e2e8f0'" /> | |
| <div id="vaix-suggestions" style="position:absolute;top:100%;left:12px;right:12px;z-index:50;background:#fff;border:1px solid #e2e8f0;border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,0.12);display:none;max-height:360px;overflow-y:auto"></div> | |
| </div> | |
| <div id="vaix-category-chips" style="padding:4px 12px 8px;flex-shrink:0;background:#f8fafc;border-bottom:1px solid #e2e8f0;display:none;flex-wrap:wrap;gap:4px;overflow-x:auto"></div> | |
| <div id="vaistudio-body" style="flex:1;overflow:hidden;position:relative;background:#f8fafc"> | |
| <div id="vaistudio-loading" style="position:absolute;inset:0;background:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;z-index:10"> | |
| <div style="width:32px;height:32px;border:3px solid #e2e8f0;border-top-color:#003f62;border-radius:50%;animation:spin 1s linear infinite"></div> | |
| <div style="font-size:0.85rem;color:#64748b">Đang tải sản phẩm V.AI STUDIO…</div> | |
| </div> | |
| <div id="vaistudio-products" style="overflow-y:auto;height:100%;padding:12px;display:none"></div> | |
| <div id="vaistudio-error" style="position:absolute;inset:0;background:#fff;display:none;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:24px;text-align:center"> | |
| <div style="font-size:2rem;margin-bottom:8px">⚠️</div> | |
| <div id="vaistudio-error-text" style="font-size:0.9rem;color:#64748b">Không thể tải sản phẩm</div> | |
| <button id="vaistudio-retry-btn" style="padding:8px 20px;background:#003f62;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:0.85rem">Thử lại</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Product Detail Modal --> | |
| <div id="vaistudio-detail-overlay" style="position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:200;display:none;align-items:center;justify-content:center;padding:20px" onclick="if(event.target===this)this.style.display='none'"> | |
| <div id="vaistudio-detail-modal" style="background:#fff;border-radius:20px;max-width:480px;width:100%;max-height:85vh;overflow-y:auto;padding:0;box-shadow:0 20px 60px rgba(0,0,0,0.25);animation:modalIn 0.2s ease"> | |
| <div style="position:sticky;top:0;z-index:2;display:flex;justify-content:flex-end;padding:12px" onclick="document.getElementById('vaistudio-detail-overlay').style.display='none'"> | |
| <button style="width:36px;height:36px;border-radius:50%;border:none;background:rgba(0,0,0,0.06);cursor:pointer;font-size:1.1rem;display:flex;align-items:center;justify-content:center">✕</button> | |
| </div> | |
| <div id="detail-images" style="display:flex;gap:8px;overflow-x:auto;padding:0 16px 12px;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch"></div> | |
| <div style="padding:0 16px 12px;border-bottom:1px solid #e2e8f0"> | |
| <h2 id="detail-title" style="font-size:1.05rem;font-weight:700;color:#1e293b;margin:0 0 6px;line-height:1.4"></h2> | |
| <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap"> | |
| <span id="detail-brand" style="font-size:0.75rem;color:#64748b;background:#f1f5f9;padding:3px 10px;border-radius:8px"></span> | |
| <span id="detail-model" style="font-size:0.7rem;color:#94a3b8"></span> | |
| </div> | |
| <div id="detail-price" style="font-size:1.2rem;font-weight:800;color:#c2410c;margin-top:8px"></div> | |
| </div> | |
| <div id="detail-summary" style="padding:12px 16px;font-size:0.82rem;color:#475569;line-height:1.6;border-bottom:1px solid #f1f5f9;display:none"></div> | |
| <div id="detail-features" style="padding:12px 16px;border-bottom:1px solid #f1f5f9;display:none"> | |
| <h3 style="font-size:0.8rem;font-weight:700;color:#003f62;margin:0 0 8px;text-transform:uppercase;letter-spacing:0.04em">Tính năng nổi bật</h3> | |
| <ul id="detail-features-list" style="margin:0;padding:0;list-style:none"></ul> | |
| </div> | |
| <div id="detail-specs" style="padding:12px 16px 20px;display:none"> | |
| <h3 style="font-size:0.8rem;font-weight:700;color:#003f62;margin:0 0 8px;text-transform:uppercase;letter-spacing:0.04em">Thông số kỹ thuật</h3> | |
| <table id="detail-specs-table" style="width:100%;border-collapse:collapse;font-size:0.78rem"><tbody></tbody></table> | |
| </div> | |
| <!-- Section sản phẩm tương tự và share button được render động bởi vaix-rag.js --> | |
| </div> | |
| </div> | |
| <style> | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| @keyframes modalIn { from { opacity:0;transform:translateY(20px) scale(0.96) } to { opacity:1;transform:translateY(0) scale(1) } } | |
| #vaistudio-panel.open { display: flex ; } | |
| #vaistudio-loading.hidden { display: none ; } | |
| @media (max-width:768px) { #vaistudio-toggle { bottom:16px;right:16px;width:50px;height:50px } #vaistudio-panel { width:100%;max-width:100%;height:100%;max-height:100vh;border-radius:0 } } | |
| .product-card { display:flex;gap:12px;padding:12px;background:#fff;border-radius:12px;margin-bottom:8px;border:1px solid #e2e8f0;cursor:pointer;transition:all 0.2s } | |
| .product-card:hover { border-color:#0077b6;box-shadow:0 2px 8px rgba(0,63,98,0.12) } | |
| .product-card-img { width:80px;height:80px;border-radius:8px;object-fit:cover;background:#f1f5f9;flex-shrink:0 } | |
| .product-card-info { flex:1;min-width:0 } | |
| .product-card-title { font-size:0.85rem;font-weight:600;color:#1e293b;margin:0 0 4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap } | |
| .product-card-brand { font-size:0.75rem;color:#64748b;margin:0 0 4px } | |
| .product-card-price { font-size:0.85rem;font-weight:700;color:#003f62;margin:0 } | |
| .product-card-cat { font-size:0.7rem;color:#94a3b8;background:#f1f5f9;padding:2px 8px;border-radius:10px;display:inline-block;margin-top:4px } | |
| /* ── Search suggestions ── */ | |
| .vaix-suggestion-item { display:flex;align-items:center;gap:10px;padding:10px 12px;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:background 0.15s } | |
| .vaix-suggestion-item:last-child { border-bottom:none } | |
| .vaix-suggestion-item:hover { background:#f0f9ff } | |
| #vaix-suggestions::-webkit-scrollbar { width:5px } | |
| #vaix-suggestions::-webkit-scrollbar-thumb { background:#e2e8f0;border-radius:3px } | |
| /* ── Category chips ── */ | |
| .vaix-category-chip { display:inline-flex;align-items:center;padding:4px 10px;background:#eef2ff;color:#003f62;border:1px solid #d0dfed;border-radius:14px;font-size:0.7rem;cursor:pointer;white-space:nowrap;transition:all 0.2s;font-family:inherit } | |
| .vaix-category-chip:hover { background:#dbeafe;border-color:#0077b6;transform:translateY(-1px) } | |
| /* ── Chat Product Cards ── */ | |
| .chat-product-cards { display:flex;flex-direction:column;gap:8px;margin:6px 0;max-width:100% } | |
| .chat-product-card { background:#1e293b;border:1px solid #334155;border-radius:12px;overflow:hidden;transition:all 0.2s } | |
| .chat-product-card:hover { border-color:#0077b6;box-shadow:0 2px 8px rgba(0,119,182,0.15) } | |
| .chat-product-card-inner { display:flex;gap:10px;padding:10px;cursor:pointer } | |
| .chat-product-card-img-wrap { width:64px;height:64px;border-radius:8px;overflow:hidden;flex-shrink:0;background:#1a1f2e } | |
| .chat-product-card-img { width:100%;height:100%;object-fit:cover } | |
| .chat-product-card-img-placeholder { width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:1.3rem } | |
| .chat-product-card-body { flex:1;min-width:0;display:flex;flex-direction:column;gap:2px } | |
| .chat-product-card-name { font-size:0.8rem;font-weight:600;color:#e2e8f0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3 } | |
| .chat-product-card-meta { display:flex;align-items:center;gap:6px;flex-wrap:wrap } | |
| .chat-product-card-brand { font-size:0.68rem;color:#94a3b8 } | |
| .chat-product-card-stars { font-size:0.6rem;color:#f59e0b;letter-spacing:1px } | |
| .chat-product-card-price { font-size:0.82rem;font-weight:700;color:#22d3ee;margin-top:1px } | |
| .chat-product-card-cat { font-size:0.6rem;color:#64748b;background:#2d3748;padding:1px 6px;border-radius:4px;display:inline-block;width:fit-content;margin-top:1px } | |
| .chat-product-card-actions { display:flex;gap:0;border-top:1px solid #334155 } | |
| .chat-product-card-btn { flex:1;padding:7px 8px;background:transparent;border:none;color:#94a3b8;cursor:pointer;font-size:0.7rem;font-family:inherit;transition:all 0.15s;display:flex;align-items:center;justify-content:center;gap:4px } | |
| .chat-product-card-btn:hover { background:#2d3748;color:#e2e8f0 } | |
| .chat-product-card-btn:first-child { border-right:1px solid #334155 } | |
| .chat-product-card-btn.detail-btn:hover { color:#22d3ee } | |
| .chat-product-card-btn.share-btn:hover { color:#f59e0b } | |
| .chat-message.assistant .chat-product-card { background:#1e293b;border:1px solid #334155;margin:4px 0 } | |
| /* ── Share button inline style overrides for dark theme ── */ | |
| #detail-share-btn { display:inline-flex } | |
| </style> | |
| <!-- V.AI STUDIO RAG Module - loads products + integrates search/showProduct --> | |
| <script src="./src/vaix-rag.js"></script> | |
| <script type="module" src="./src/app.js"></script> | |
| </body> | |
| </html> |