diff --git a/docs/elena_live.html b/docs/elena_live.html index 9ad95ae..f04b47e 100644 --- a/docs/elena_live.html +++ b/docs/elena_live.html @@ -38,6 +38,14 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ .inp:focus{border-color:var(--mid);box-shadow:0 0 0 3px rgba(16,185,129,.1)} .send{width:44px;height:44px;border-radius:11px;background:var(--primary);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0} .send:hover{background:var(--dark)}.send:disabled{opacity:.4;cursor:default} +/* Microphone */ +.mic{width:44px;height:44px;border-radius:11px;background:var(--light);border:1.5px solid rgba(4,120,87,.2);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--primary);transition:all .15s;position:relative} +.mic:hover{background:#D1FAE5;border-color:var(--primary)} +.mic.rec{background:#FEF2F2;border-color:#EF4444;color:#EF4444} +.mic.rec::after{content:'';position:absolute;inset:-4px;border-radius:14px;border:2px solid #EF4444;animation:micPulse 1.3s ease-out infinite;pointer-events:none} +@keyframes micPulse{0%{transform:scale(1);opacity:.7}100%{transform:scale(1.25);opacity:0}} +.mic-hint{position:absolute;bottom:64px;left:50%;transform:translateX(-50%);background:var(--ink);color:#fff;font-size:12px;padding:6px 12px;border-radius:8px;white-space:nowrap;display:none;z-index:20} +.mic-hint.show{display:block} .build-btn{margin:0 20px 14px;padding:13px;border-radius:12px;background:linear-gradient(135deg,var(--dark),var(--primary));color:#fff;border:none;cursor:pointer;font-family:'Inter';font-weight:700;font-size:14px;flex-shrink:0;display:flex;align-items:center;justify-content:center;gap:8px} .build-btn:hover{opacity:.92}.build-btn:disabled{opacity:.5;cursor:default} .model-col{width:42%;max-width:560px;overflow-y:auto;padding:24px;background:#fafbfc;display:none} @@ -92,7 +100,11 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ Построить мою бизнес-модель →
- + + @@ -112,6 +124,47 @@ const inp = document.getElementById("inp"); function esc(s){return s.replace(/&/g,"&").replace(//g,">")} function fmt(s){return esc(s).replace(/\*\*(.+?)\*\*/g,"$1")} +// ── Голосовой ввод (Web Speech API, русский) ────────── +let recog=null, recording=false; +const SR = window.SpeechRecognition || window.webkitSpeechRecognition; +if(SR){ + recog = new SR(); + recog.lang = "ru-RU"; + recog.continuous = true; + recog.interimResults = true; + let baseText = ""; + recog.onresult = e=>{ + let fin="", interim=""; + for(let i=e.resultIndex;i{ baseText = inp.value ? inp.value+" " : ""; }; + recog.onend = ()=>{ if(recording){ try{recog.start()}catch(e){} } }; + recog.onerror = e=>{ if(e.error==="not-allowed"){ alert("Разрешите доступ к микрофону в браузере"); stopMic(); } }; +} +function toggleMic(){ + if(!recog){ alert("Голосовой ввод не поддерживается этим браузером. Используйте Chrome."); return; } + recording ? stopMic() : startMic(); +} +function startMic(){ + recording=true; + document.getElementById("micBtn").classList.add("rec"); + document.getElementById("micHint").classList.add("show"); + try{ recog.start() }catch(e){} +} +function stopMic(){ + recording=false; + document.getElementById("micBtn").classList.remove("rec"); + document.getElementById("micHint").classList.remove("show"); + try{ recog.stop() }catch(e){} + inp.focus(); +} + function addMsg(role, text){ const m = document.createElement("div"); m.className = "msg " + (role==="user"?"user":"elena"); @@ -144,6 +197,7 @@ async function init(){ } async function sendMsg(){ + if(recording) stopMic(); const text = inp.value.trim(); if(!text) return; inp.value=""; inp.style.height="auto";