| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> |
| <title>Minimal Conversation</title> |
| <link rel="icon" href="/icon.svg" type="image/svg+xml" /> |
| <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;700;800&display=swap" |
| rel="stylesheet" |
| /> |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <style> |
| body.booting #app, |
| body.booting #settings-modal { |
| display: none !important; |
| } |
| </style> |
|
|
| |
| |
| |
| |
| |
| |
| <script> |
| (function () { |
| try { |
| var params = new URLSearchParams(window.location.search); |
| var raw = params.get("theme"); |
| var mode; |
| if (raw === "dark" || raw === "light") { |
| mode = raw; |
| } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches === false) { |
| mode = "light"; |
| } else { |
| mode = "dark"; |
| } |
| document.documentElement.setAttribute("data-theme", mode); |
| } catch (_) { |
| document.documentElement.setAttribute("data-theme", "dark"); |
| } |
| })(); |
| </script> |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| <script type="module" crossorigin src="/assets/index-COur_VG-.js"></script> |
| </head> |
| |
| |
| |
| |
| <body class="booting"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <div id="app" class="hidden"> |
| <main class="stage"> |
| <div class="orb-wrap"> |
| <button id="mic-btn" class="side-btn" type="button" aria-label="Mute" title="Mute" aria-hidden="true"> |
| <svg class="mic-on" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M5 10a7 7 0 0 0 14 0"/><line x1="12" y1="19" x2="12" y2="22"/></svg> |
| <svg class="mic-off" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><line x1="2" y1="2" x2="22" y2="22"/><path d="M9 5a3 3 0 0 1 6 0v4"/><path d="M9 10v1a3 3 0 0 0 5.1 2.1"/><path d="M19 10a7 7 0 0 1-1.24 3.97"/><path d="M5 10a7 7 0 0 0 11 5.67"/><line x1="12" y1="19" x2="12" y2="22"/></svg> |
| </button> |
|
|
| <button |
| id="main-circle" |
| class="circle state-starting" |
| type="button" |
| aria-label="Voice conversation" |
| > |
| <span class="circle-glow" aria-hidden="true"></span> |
| <span class="circle-ring" aria-hidden="true"></span> |
| <span class="circle-ring-outer" aria-hidden="true"></span> |
| <span class="circle-core"> |
| <span class="circle-indicator" aria-hidden="true"> |
| <svg class="ind ind-mic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
| <rect x="9" y="2" width="6" height="12" rx="3" fill="currentColor" stroke="none"/> |
| <path d="M5 10a7 7 0 0 0 14 0"/> |
| <line x1="12" y1="19" x2="12" y2="22"/> |
| <line x1="8" y1="22" x2="16" y2="22"/> |
| </svg> |
| <svg class="ind ind-error" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="8" x2="12" y2="13"/><line x1="12" y1="16" x2="12" y2="16"/></svg> |
| <span class="ind ind-spinner"></span> |
| <span class="ind ind-thinking"> |
| <span class="dot"></span> |
| <span class="dot"></span> |
| <span class="dot"></span> |
| </span> |
| <span class="ind ind-bars"> |
| <span class="bar"></span> |
| <span class="bar"></span> |
| <span class="bar"></span> |
| <span class="bar"></span> |
| <span class="bar"></span> |
| </span> |
| <svg class="ind ind-voice" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
| <path d="M3 10v4a1 1 0 0 0 1 1h3l5 4V5L7 9H4a1 1 0 0 0-1 1z" fill="currentColor" stroke="none"/> |
| <path class="wave wave-1" d="M16 8a5 5 0 0 1 0 8"/> |
| <path class="wave wave-2" d="M19 5a9 9 0 0 1 0 14"/> |
| </svg> |
| </span> |
| </span> |
| </button> |
|
|
| <button id="stop-btn" class="side-btn" type="button" aria-label="End" title="End" aria-hidden="true"> |
| <svg viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12" rx="2"/></svg> |
| </button> |
| </div> |
|
|
| <p id="circle-caption" class="circle-caption" role="status">Starting</p> |
|
|
| <div id="tool-toast" class="tool-toast" role="status" aria-live="polite" aria-hidden="true"> |
| <svg class="tool-toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
| <circle cx="12" cy="12" r="3"/> |
| <path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M4.9 19.1l2.1-2.1M17 7l2.1-2.1"/> |
| </svg> |
| <span class="tool-toast-text"></span> |
| </div> |
|
|
| <button id="settings-btn" class="settings-fab" type="button" title="Settings" aria-label="Settings"> |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><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-.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-.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.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.82V9c0 .66.39 1.25 1 1.51H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg> |
| </button> |
| </main> |
| </div> |
|
|
| <dialog id="settings-modal" class="modal"> |
| <form method="dialog" class="modal-content"> |
| <header class="modal-header"> |
| <h2>Settings</h2> |
| <button class="icon-btn" value="close" aria-label="Close"> |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> |
| </button> |
| </header> |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="settings-body"> |
| <label class="field"> |
| <span>Instructions</span> |
| <textarea id="openai-instructions" rows="6" placeholder="You are Reachy Mini, a friendly robot assistant..."></textarea> |
| <small>System prompt sent to the model. Applied on next conversation start.</small> |
| </label> |
|
|
| |
| |
| |
| |
| |
| <div class="field"> |
| <button id="restart-conversation" type="button" class="btn primary wide" disabled> |
| Restart conversation with these instructions |
| </button> |
| <small id="restart-hint">Connect first, then come back here to apply live changes.</small> |
| </div> |
| </div> |
|
|
| <footer class="modal-footer"> |
| <button id="settings-save" type="submit" class="btn primary" value="save">Save</button> |
| </footer> |
| </form> |
| </dialog> |
|
|
| |
| |
| |
| |
| </body> |
| </html> |
|
|