| <!doctype html> |
| <html lang="en"> |
|
|
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Judgy Reachy No Phone - Reachy Mini App</title> |
| <meta name="description" content="A Reachy Mini app that detects when you pick up your phone and shames you with snarky comments using AI vision and text-to-speech."> |
| <link rel="stylesheet" href="style.css" /> |
| <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📱</text></svg>"> |
| </head> |
|
|
| <body> |
| |
| <header class="header"> |
| <div class="header-content"> |
| <div class="logo"> |
| <span class="logo-icon">📱</span> |
| <span class="logo-text">Judgy Reachy</span> |
| </div> |
|
|
| <nav class="nav"> |
| <a href="#demo" class="nav-link" id="nav-demo">Try Demo</a> |
| <a href="#setup" class="nav-link" id="nav-setup">Quick Setup</a> |
| <a href="#config" class="nav-link" id="nav-config">Config</a> |
| <a href="#personalities" class="nav-link" id="nav-personalities">Personalities</a> |
| <a href="#features" class="nav-link" id="nav-features">Features</a> |
| </nav> |
|
|
| <a href="https://github.com/yaseminozkut/judgy_reachy_no_phone" class="github-btn" target="_blank"> |
| <svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"> |
| <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/> |
| </svg> |
| GitHub |
| </a> |
| </div> |
| </header> |
|
|
| |
| <div class="mode-toggle-bar"> |
| <div class="mode-toggle"> |
| <button class="toggle-option active" id="toggle-info">Info</button> |
| <button class="toggle-option" id="toggle-robot">🤖 Connect Robot</button> |
| </div> |
| </div> |
|
|
| <div id="info-view"> |
| |
| <section class="hero-section"> |
| <div class="container"> |
| <div class="hero-grid"> |
| <div class="hero-left"> |
| <div class="hero-label">Reachy Mini App</div> |
| <h1 class="hero-title">Get off <span>your phone!</span></h1> |
| <p class="hero-description"> |
| Your robot companion catches you scrolling with AI vision. Shames you back to productivity. Brutal, funny, pure chaos. |
| </p> |
| <div class="hero-tags"> |
| <span class="tag">⚡ Real-time Detection</span> |
| <span class="tag">👾 LLM</span> |
| <span class="tag">🔈 TTS</span> |
| <span class="tag">😌 9 Personalities</span> |
| <span class="tag">🔒 100% Local or API</span> |
| </div> |
| <div class="hero-tech" style="margin-top: 1.5rem;"> |
| <div class="hero-tech-stack"> |
| <span class="tech-pill">YOLO26m</span> |
| <span class="tech-pill">NVIDIA TensorRT</span> |
| <span class="tech-pill">OpenCV</span> |
| <span class="tech-pill">Groq (Llama 3.1)</span> |
| <span class="tech-pill">Edge TTS</span> |
| <span class="tech-pill">ElevenLabs</span> |
| </div> |
| </div> |
|
|
| <div class="hero-cta"> |
| <a href="#demo" class="cta-button">🎮 Try Demo in Browser</a> |
| <a href="#setup" id="download-btn" class="cta-button-secondary">📥 Download for Robot</a> |
| <a href="https://github.com/yaseminozkut/judgy_reachy_no_phone?tab=readme-ov-file#-judgy-reachy-no-phone-" class="cta-button-secondary" target="_blank">📖 Full Documentation</a> |
| </div> |
|
|
| </div> |
|
|
| <div class="hero-right"> |
| <div id="demo-preview" style="border-radius: 16px; overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,0.3); margin-top: 2rem; max-width: 600px; margin-left: auto; margin-right: auto;"> |
| <img src="quick_demo.gif" alt="Judgy Reachy demo - phone detection in action" style="width: 100%; display: block;"> |
| </div> |
|
|
| </div> |
| </div> |
|
|
| </div> |
| </section> |
|
|
| |
| <section id="demo" class="demo-section"> |
| <div class="container"> |
| <h2 class="section-title">Interactive Browser Demo</h2> |
| <p class="section-subtitle">Just a quick teaser demo! If you haven't tried Reachy Mini yet, this is a fun way to get a taste of what it can do. Hope it makes you smile :) and sparks your curiosity to try the full real simulation/robot. For the complete experience with expressive robot animations, head movements, and all 9 personalities, download this app to your Reachy Mini robot!</p> |
|
|
| |
| <div id="mobile-alternative" class="mobile-alternative"> |
| <h4 class="mobile-hero-title">📱🤔</h4> |
| <h4 class="mobile-hero-title">Wait a second...</h4> |
| <p class="mobile-hero-text"> |
| You're on your phone right now! How can we detect you picking up your phone... when you're already holding it? :) |
| </p> |
| <p class="mobile-hero-subtext"> |
| This interactive demo needs a laptop browser (Chrome/Edge) to work properly. Mobile browsers aren't optimized for WebGPU real-time inference yet. |
| </p> |
|
|
| |
| <div class="like-reminder"> |
| <div class="like-icon">❤️</div> |
| <div class="like-text"> |
| <strong>Enjoying this?</strong> Click the ❤️ at the top to like this Space! |
| </div> |
| </div> |
|
|
| <div class="laptop-hint">💻 Open on your laptop to try the live interactive demo!</div> |
| </div> |
|
|
| <div class="demo-grid" id="demo-grid"> |
| |
| <div class="camera-column"> |
| <div class="video-wrapper"> |
| <video id="webcam" autoplay playsinline muted></video> |
| <canvas id="canvas"></canvas> |
|
|
| |
| <div class="robot-pip"> |
| <div class="robot-bg-pip"> |
| <object type="image/svg+xml" data="reachy-happy.svg" class="robot-svg-pip" id="robot-svg"> |
| Reachy Robot |
| </object> |
| </div> |
| </div> |
|
|
| |
| <div class="demo-status"> |
| <span id="status-indicator" class="status-dot"></span> |
| <span id="status-text">Click Start to begin</span> |
| </div> |
|
|
| |
| <div class="fps-counter"> |
| <span id="fps">0</span> FPS |
| </div> |
|
|
| |
| <div id="loader" class="loader-overlay"> |
| <div class="spinner"></div> |
| <p id="loader-text">Loading AI model...</p> |
| </div> |
| </div> |
|
|
| |
| <div class="demo-controls"> |
| <button id="camera-btn" class="btn-demo btn-secondary"> |
| <span id="camera-icon">📹</span> |
| <span id="camera-text">Open Camera</span> |
| </button> |
| <button id="start-btn" class="btn-demo btn-primary" disabled> |
| <span id="btn-icon">▶️</span> |
| <span id="btn-text">Start Detection</span> |
| </button> |
| </div> |
|
|
| |
| <div id="response-box" class="response-box"> |
| <div class="response-label">💬 Latest Emotion:</div> |
| <div id="response-text" class="response-text">Pick up your phone to hear Reachy react!</div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="setup" class="getting-started-section"> |
| <div class="container"> |
| <div class="section-label">Getting Started</div> |
| <h2 class="section-title">Quick Setup</h2> |
|
|
| <div class="guide-card"> |
| <ol class="guide-list"> |
| <li> |
| <strong>Install Reachy Mini SDK</strong> - Follow the <a href="https://github.com/pollen-robotics/reachy_mini/blob/main/docs/source/SDK/installation.md" target="_blank" class="setup-link">installation guide</a> |
| </li> |
| <li> |
| <strong>Install this app</strong> - Via <a href="https://github.com/pollen-robotics/reachy_mini/" target="_blank" class="setup-link">Reachy Mini SDK</a> or <a href="https://github.com/pollen-robotics/reachy-mini-desktop-app" target="_blank" class="setup-link">Desktop App</a> |
| </li> |
| <li> |
| <strong>Start Reachy daemon</strong> - See <a href="https://github.com/pollen-robotics/reachy_mini/blob/main/docs/source/SDK/quickstart.md" target="_blank" class="setup-link">quickstart guide</a> (simulation or real robot) |
| </li> |
| <li> |
| <strong>Launch & open UI</strong> - Start the app and visit <code>http://localhost:8042</code> |
| </li> |
| </ol> |
|
|
| |
| <h3 style="font-family: 'Space Grotesk', sans-serif; font-size: 1.5rem; font-weight: 700; margin: 3rem 0 1.5rem; color: var(--coral-light);">Using the App</h3> |
|
|
| <ol class="guide-list" style="counter-reset: step-counter;"> |
| <li> |
| <strong>Choose a personality</strong> - All 9 work immediately with pre-written responses |
| </li> |
| <li> |
| <strong>Add API keys</strong> (optional) - <a href="https://console.groq.com" target="_blank" class="setup-link">Groq</a> for LLM, <a href="https://elevenlabs.io" target="_blank" class="setup-link">ElevenLabs</a> for premium voices |
| </li> |
| <li> |
| <strong>Adjust settings</strong> (optional) - Cooldown time, enable/disable praise mode |
| </li> |
| <li> |
| <strong>Customize voices</strong> (optional) - Custom voice IDs per personality with auto-fallback |
| </li> |
| </ol> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="config" class="config-section"> |
| <div class="container"> |
|
|
| <div class="section-label">Configuration</div> |
| <h2 class="section-title">Fully Customizable for Every Need</h2> |
| <p class="section-subtitle">Choose what fits your setup</p> |
|
|
| <div class="config-grid"> |
| <div class="config-card highlight"> |
| <h3>Local Mode (Default)</h3> |
| <p>Complete experience. Zero external dependencies. No limitations.</p> |
| <ul class="config-list"> |
| <li>YOLO26n AI detection (runs locally)</li> |
| <li>20+ curated snarky lines</li> |
| <li>Edge TTS voice (unlimited, free forever)</li> |
| <li>All 9 personalities work perfectly</li> |
| </ul> |
| </div> |
|
|
| <div class="config-card"> |
| <h3>API-Enhanced (Optional)</h3> |
| <p>Add dynamic AI and premium voices. Free tiers available, no credit card.</p> |
| <ul class="config-list"> |
| <li>Same YOLO26n detection</li> |
| <li>Groq API - Dynamic LLM responses (free tier)</li> |
| <li>ElevenLabs ultra-realistic voices (free tier)</li> |
| <li>Auto-fallback to Edge TTS if needed</li> |
| </ul> |
| </div> |
| </div> |
|
|
| <div class="config-note"> |
| <p><strong>💡 About Free Tiers:</strong> Groq and ElevenLabs both offer generous free tiers. With ElevenLabs, you can save up to 3 custom voices from their library to your account. The app comes with pre-selected default voices and automatically falls back to Edge TTS if anything fails. Fully customizable for your needs.</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="personalities" class="personalities-section"> |
| <div class="container"> |
| <div class="section-label">Personalities</div> |
| <h2 class="section-title">Pick Your Flavor of Shame</h2> |
| <p class="section-subtitle">Nine unique personalities with matched voices and attitudes</p> |
|
|
| <div class="personalities-grid"> |
| <div class="personality-card"> |
| <div class="personality-emoji">🤖</div> |
| <h3>Pure Reachy</h3> |
| <p>No speech, pure authentic Reachy emotions from Pollen Robotics library.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Cute</span> |
| <span class="personality-tag">Emotions</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">😠</div> |
| <h3>Angry Boss</h3> |
| <p>A furious manager at their absolute limit. Explosive, zero patience. |
| </p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Explosive</span> |
| <span class="personality-tag">Commanding</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">🎭</div> |
| <h3>Sarcastic</h3> |
| <p>Dripping with dry wit. Mock enthusiasm, feigned interest. Peak passive aggression.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Passive-aggressive</span> |
| <span class="personality-tag">Ironic</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">😔</div> |
| <h3>Disappointed Parent</h3> |
| <p>Not angry—just deeply let down. Maximum guilt.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Guilt-inducing</span> |
| <span class="personality-tag">Wounded</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">💪</div> |
| <h3>Motivational Coach</h3> |
| <p>Intense drill-sergeant who believes in you but won't tolerate weakness.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">High Energy</span> |
| <span class="personality-tag">Tough Love</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">🤡</div> |
| <h3>Absurdist</h3> |
| <p>Surreal, unexpected, playful.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Whimsical</span> |
| <span class="personality-tag">Weird</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">🖥️</div> |
| <h3>Corporate AI</h3> |
| <p>Emotionless robot productivity system.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Robotic</span> |
| <span class="personality-tag">Clinical</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">🎩</div> |
| <h3>British Butler</h3> |
| <p>Impeccably polite yet quietly judgmental.</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Formal</span> |
| <span class="personality-tag">Polite</span> |
| </div> |
| </div> |
|
|
| <div class="personality-card"> |
| <div class="personality-emoji">🐣</div> |
| <h3>Chaos Baby</h3> |
| <p>Unpredictable wildcard. Every response is a different random personality!</p> |
| <div class="personality-tags"> |
| <span class="personality-tag">Random</span> |
| <span class="personality-tag">Chaotic</span> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="features" class="features-section"> |
| <div class="container"> |
| <div class="section-label">Features</div> |
| <h2 class="section-title">Everything You Need</h2> |
| <p class="section-subtitle">Break your phone addiction with AI-powered shame</p> |
|
|
| <div class="features-grid"> |
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <circle cx="12" cy="12" r="10"/> |
| <circle cx="12" cy="12" r="4"/> |
| <line x1="21.17" y1="8" x2="12" y2="8"/> |
| <line x1="3.95" y1="6.06" x2="8.54" y2="14"/> |
| <line x1="10.88" y1="21.94" x2="15.46" y2="14"/> |
| </svg> |
| </div> |
| <h3>Real-Time Phone Detection</h3> |
| <p>Powered by YOLO26n. 3-frame confirmation prevents false positives.</p> |
| </div> |
|
|
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/> |
| </svg> |
| </div> |
| <h3>Snarky AI Responses</h3> |
| <p>Curated pre-written or dynamic LLM-generated shame. Escalates with repeat offenses.</p> |
| </div> |
|
|
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <circle cx="12" cy="12" r="10"/> |
| <path d="M8 14s1.5 2 4 2 4-2 4-2"/> |
| <line x1="9" y1="9" x2="9.01" y2="9"/> |
| <line x1="15" y1="9" x2="15.01" y2="9"/> |
| </svg> |
| </div> |
| <h3>Expressive Animations</h3> |
| <p>Robot reacts with emotions and moves.</p> |
| </div> |
|
|
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/> |
| <path d="M19 10v2a7 7 0 0 1-14 0v-2M12 19v4M8 23h8"/> |
| </svg> |
| </div> |
| <h3>Text-to-Speech</h3> |
| <p>Unlimited Edge TTS or limited ultra-realistic ElevenLabs voices. Personalities with matched voice profiles.</p> |
| </div> |
|
|
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <path d="M3 3v18h18"/> |
| <path d="M18.7 8l-5.1 5.2-2.8-2.7L7 14.3"/> |
| </svg> |
| </div> |
| <h3>Stats Tracking</h3> |
| <p>Monitor pickup count, current streak, and longest phone-free streak. Track your progress.</p> |
| </div> |
|
|
| <div class="feature-item"> |
| <div class="feature-icon-badge"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <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 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-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 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| </svg> |
| </div> |
| <h3>Fully Configurable</h3> |
| <p>Adjust cooldown (10-120s), enable praise mode, switch personalities via intuitive web UI.</p> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <footer class="footer"> |
| <div class="container"> |
| <div class="footer-links"> |
| <a href="https://github.com/pollen-robotics" target="_blank">Pollen Robotics</a> |
| <span>•</span> |
| <a href="https://huggingface.co/spaces/pollen-robotics/reachy-mini-landing-page#apps" target="_blank">More Apps</a> |
| <span>•</span> |
| <a href="https://www.pollen-robotics.com/" target="_blank">Get Reachy Mini</a> |
| </div> |
| <p class="footer-text">Open Source • Built for productivity 🤖</p> |
| </div> |
| </footer> |
|
|
| </div> |
|
|
| |
| <div id="robot-view" style="display:none"> |
| <div class="container rv-container"> |
|
|
| |
| <div id="rv-signin" class="rv-state"> |
| <div class="rv-connect-card"> |
| <div class="rv-connect-icon">🤖</div> |
| <h2 class="rv-connect-title">Connect your Reachy Mini</h2> |
| <p class="rv-connect-desc">Sign in with Hugging Face to connect your robot and start monitoring</p> |
| <button id="rv-signin-btn" class="cta-button">Sign in with Hugging Face 🤗</button> |
| </div> |
| </div> |
|
|
| |
| <div id="rv-picker" class="rv-state" style="display:none"> |
| <div class="rv-picker-header"> |
| <h2 class="rv-picker-title">Select Your Robot</h2> |
| <p class="rv-picker-sub">Your online robots appear below</p> |
| </div> |
| <div id="rv-robot-list" class="rv-robot-list"></div> |
| <button id="rv-connect-btn" class="cta-button" style="margin-top:1.25rem;display:none">Connect →</button> |
| </div> |
|
|
| |
| <div id="rv-monitoring" class="rv-state" style="display:none"> |
|
|
| |
| <div class="rv-topbar"> |
| <div class="rv-topbar-left"> |
| <span id="rv-robot-badge" class="rv-badge">🟢 Connected</span> |
| </div> |
| <div class="rv-topbar-right"> |
| <button id="rv-settings-btn" class="btn-icon-sm">⚙️</button> |
| <button id="rv-disconnect-btn" class="btn-icon-sm btn-danger-sm">✕ Disconnect</button> |
| </div> |
| </div> |
|
|
| |
| <div class="rv-grid"> |
|
|
| |
| <div class="rv-camera-col"> |
|
|
| |
| <div class="rv-status-bar"> |
| <div class="rv-status-badge"> |
| <span id="rv-detect-dot" class="status-dot"></span> |
| <span id="rv-detect-text">Not Monitoring</span> |
| </div> |
| <div id="rv-tech-badge" class="rv-tech-badge">Emotion sounds</div> |
| <div class="rv-mode-badge">Mode: <span id="rv-mode-name">Pure Reachy</span></div> |
| </div> |
|
|
| |
| <div class="video-wrapper"> |
| <video id="rv-video" autoplay playsinline muted></video> |
| <canvas id="rv-canvas"></canvas> |
| <div id="rv-video-placeholder" class="video-placeholder"> |
| <svg class="camera-off-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| <path d="M16 16v1a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2m5.66 0H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10"/> |
| <line x1="1" y1="1" x2="23" y2="23"/> |
| </svg> |
| <div class="camera-status">Camera Inactive</div> |
| <div class="camera-message">Waiting for robot camera feed…</div> |
| </div> |
| <div id="rv-loader" class="loader-overlay"> |
| <div class="spinner"></div> |
| <p id="rv-loader-text">Loading AI model...</p> |
| </div> |
| <div class="fps-counter"><span id="rv-fps">0</span> FPS</div> |
| </div> |
|
|
| |
| <div class="demo-controls"> |
| <button id="rv-toggle-btn" class="btn-demo btn-primary">▶️ Start Monitoring</button> |
| <button id="rv-test-btn" class="btn-demo btn-secondary">⚡ Test</button> |
| </div> |
|
|
| |
| <div class="rv-stats"> |
| <div class="rv-stat-card" style="border-color: var(--coral)"> |
| <div class="rv-stat-value" id="rv-stat-count">0</div> |
| <div class="rv-stat-label">BUSTED BY REACHY</div> |
| </div> |
| <div class="rv-stat-card" style="border-color: var(--sky)"> |
| <div class="rv-stat-value" id="rv-stat-streak">0s</div> |
| <div class="rv-stat-label">CURRENT STREAK</div> |
| </div> |
| <div class="rv-stat-card" style="border-color: var(--lavender)"> |
| <div class="rv-stat-value" id="rv-stat-longest">0s</div> |
| <div class="rv-stat-label">LONGEST STREAK</div> |
| </div> |
| </div> |
|
|
| |
| <div id="rv-reset-section" style="display:none"> |
| <button id="rv-reset-btn" class="btn-demo btn-secondary" style="width:100%">🔄 Reset Stats</button> |
| </div> |
|
|
| <div class="response-box"> |
| <div class="response-label">💬 Latest response:</div> |
| <div id="rv-response-text" class="response-text">Start monitoring to begin</div> |
| </div> |
| </div> |
|
|
| |
| <div class="rv-control-col"> |
| <div class="rv-personality-panel" id="rv-personality-panel"> |
| <h2 class="rv-panel-title">🤖 Robot Personality</h2> |
| <p class="rv-panel-subtitle">Choose how the robot judges you</p> |
|
|
| |
| <button class="rv-personality-toggle" id="rv-personality-toggle"> |
| <span class="rv-personality-toggle-hint">Choose Personality</span> |
| <span id="rv-personality-toggle-label">🤖 Pure Reachy</span> |
| <span class="rv-personality-chevron">▼</span> |
| </button> |
|
|
| <div class="rv-personality-collapsible" id="rv-personality-collapsible"> |
| <div id="rv-api-notice" class="rv-api-notice"> |
| <div class="notice-icon">💡</div> |
| <div> |
| <strong>Using Pre-written Lines</strong><br> |
| <span class="notice-small">Add Groq API key in ⚙️ settings for AI responses</span> |
| </div> |
| </div> |
|
|
| <div id="rv-personalities" class="rv-personality-list"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="rv-settings-modal" class="modal-backdrop" style="display:none"> |
| <div class="modal-box"> |
| <div class="modal-header"> |
| <h3>⚙️ Settings</h3> |
| <button class="modal-close" id="rv-settings-close">✕</button> |
| </div> |
| <div class="modal-body"> |
| <label class="modal-label">Groq API Key (optional)</label> |
| <input id="rv-set-groq" type="password" class="modal-input" placeholder="gsk_..."> |
| <p class="modal-hint">Free at <a href="https://console.groq.com" target="_blank">console.groq.com</a> — enables dynamic LLM responses</p> |
|
|
| <label class="modal-label">ElevenLabs API Key (optional)</label> |
| <input id="rv-set-eleven" type="password" class="modal-input" placeholder="sk_..."> |
| <p class="modal-hint">Free tier at <a href="https://elevenlabs.io" target="_blank">elevenlabs.io</a> — premium voices</p> |
|
|
| <label class="modal-label">Cooldown between shames: <span id="rv-set-cooldown-val">10s</span></label> |
| <input id="rv-set-cooldown" type="range" min="10" max="120" value="10" step="5" class="modal-range"> |
|
|
| <label class="modal-checkbox-label"> |
| <input id="rv-set-praise" type="checkbox" checked> Praise when phone is put down |
| </label> |
| </div> |
| <div class="modal-footer"> |
| <button id="rv-settings-save" class="cta-button">✓ Done</button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="rv-voices-modal" class="modal-backdrop" style="display:none"> |
| <div class="modal-box"> |
| <div class="modal-header"> |
| <h3 id="rv-voice-modal-title">Voice Settings</h3> |
| <button class="modal-close" id="rv-voices-close">✕</button> |
| </div> |
| <div class="modal-body"> |
| <label class="modal-label">ElevenLabs Voice ID</label> |
| <input id="rv-voice-eleven" type="text" class="modal-input" placeholder="Leave empty for default"> |
| <p class="modal-hint" id="rv-voice-eleven-hint"></p> |
|
|
| <label class="modal-label">Web Speech Voice Name</label> |
| <input id="rv-voice-edge" type="text" class="modal-input" placeholder="Leave empty for default"> |
| <p class="modal-hint" id="rv-voice-edge-hint"></p> |
| </div> |
| <div class="modal-footer"> |
| <button id="rv-voices-save" class="cta-button">✓ Save</button> |
| </div> |
| </div> |
| </div> |
|
|
| </div> |
| </div> |
| </div> |
|
|
| |
| <script type="module" src="demo.js"></script> |
| <script type="module" src="port_hf.js"></script> |
| </body> |
|
|
| </html> |
|
|