Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Reachy Mini Minder — Voice-First Care Companion</title> | |
| <meta | |
| name="description" | |
| content="An empathy-driven, voice-first care companion for Reachy Mini, helping users log medication and track headaches through natural conversation." | |
| /> | |
| <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=Atkinson+Hyperlegible:wght@400;700&family=Poppins:wght@300;400;500;600;700&display=swap" | |
| rel="stylesheet" | |
| /> | |
| <script src="https://unpkg.com/lucide@latest"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | |
| <link rel="stylesheet" href="style.css" /> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <!-- Hero --> | |
| <header class="hero-panel"> | |
| <div class="hero-content"> | |
| <div class="hero-text"> | |
| <div class="pill"> | |
| <i data-lucide="bot" class="pill-icon"></i> Reachy Mini App | |
| </div> | |
| <h1>Reachy Mini<br />Minder</h1> | |
| <p class="subtitle"> | |
| A voice-first care companion for Reachy Mini — helping users log | |
| medication, track headaches, and manage daily wellness through | |
| natural conversation. | |
| </p> | |
| <div class="hero-actions"> | |
| <a href="#features" class="btn-primary" | |
| ><i data-lucide="sparkles" class="btn-icon"></i> Explore | |
| Features</a | |
| > | |
| <a href="#demos" class="btn-secondary" | |
| ><i data-lucide="play-circle" class="btn-icon"></i> Watch | |
| Demos</a | |
| > | |
| </div> | |
| </div> | |
| <div class="hero-video"> | |
| <div class="demo-placeholder hero-demo"> | |
| <div class="demo-play"> | |
| <i data-lucide="play" class="demo-play-icon"></i> | |
| </div> | |
| <div class="demo-duration">1:30</div> | |
| <div class="demo-badge">Coming Soon</div> | |
| </div> | |
| <p class="hero-video-caption"> | |
| Quick overview of Reachy Mini Minder | |
| </p> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Core Features --> | |
| <section class="panel" id="features"> | |
| <div class="panel-heading"> | |
| <p class="eyebrow">Core Features</p> | |
| <h2>What It Does</h2> | |
| </div> | |
| <div class="feature-grid"> | |
| <div class="feature-card"> | |
| <div class="feature-icon cyan"><i data-lucide="mic"></i></div> | |
| <h3>Voice-First Interaction</h3> | |
| <p> | |
| Speak naturally to log medications, report symptoms, and get | |
| wellness check-ins via OpenAI Realtime API. | |
| </p> | |
| </div> | |
| <div class="feature-card"> | |
| <div class="feature-icon pink"><i data-lucide="pill"></i></div> | |
| <h3>Medication Tracking</h3> | |
| <p> | |
| Log doses, get gentle check-ins, and review your history — all | |
| through conversation. | |
| </p> | |
| </div> | |
| <div class="feature-card"> | |
| <div class="feature-icon purple"><i data-lucide="brain"></i></div> | |
| <h3>Headache Journal</h3> | |
| <p>Track severity, triggers, and duration through conversation.</p> | |
| </div> | |
| <div class="feature-card"> | |
| <div class="feature-icon cyan"> | |
| <i data-lucide="layout-dashboard"></i> | |
| </div> | |
| <h3>Live Dashboard</h3> | |
| <p> | |
| A React bento-grid UI showing medication schedules, headache | |
| trends, and session summaries in real time. | |
| </p> | |
| </div> | |
| <div class="feature-card"> | |
| <div class="feature-icon pink"> | |
| <i data-lucide="heart-handshake"></i> | |
| </div> | |
| <h3>Dignity-First Design</h3> | |
| <p> | |
| Supportive, never patronising. Health records stay on your device; | |
| voice is processed via OpenAI with your consent. | |
| </p> | |
| </div> | |
| <div class="feature-card"> | |
| <div class="feature-icon purple"> | |
| <i data-lucide="sparkles"></i> | |
| </div> | |
| <h3>Generative UI</h3> | |
| <p> | |
| Say "I have a headache" and a structured medical form fills in | |
| field-by-field through conversation — zero taps, zero navigation. | |
| 23 components the AI invokes by voice. | |
| </p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Video Demos --> | |
| <section class="panel" id="demos"> | |
| <div class="panel-heading"> | |
| <p class="eyebrow">Demos</p> | |
| <h2>See It in Action</h2> | |
| </div> | |
| <div class="demo-grid"> | |
| <div class="demo-card"> | |
| <div class="demo-placeholder"> | |
| <div class="demo-play"> | |
| <i data-lucide="play" class="demo-play-icon"></i> | |
| </div> | |
| <div class="demo-duration">2:30</div> | |
| <div class="demo-badge">Coming Soon</div> | |
| </div> | |
| <div class="demo-info"> | |
| <h3>Voice Conversation & Medication Logging</h3> | |
| <p> | |
| A full session showing wakeword activation, natural | |
| conversation, and medication dose logging with real-time | |
| dashboard updates. | |
| </p> | |
| </div> | |
| </div> | |
| <div class="demo-card"> | |
| <div class="demo-placeholder"> | |
| <div class="demo-play"> | |
| <i data-lucide="play" class="demo-play-icon"></i> | |
| </div> | |
| <div class="demo-duration">1:45</div> | |
| <div class="demo-badge">Coming Soon</div> | |
| </div> | |
| <div class="demo-info"> | |
| <h3>Headache Tracking & Generative UI</h3> | |
| <p> | |
| Voice-driven clinical capture: say "I have a headache" and watch | |
| intensity, triggers, and medication fields fill in progressively | |
| as the conversation happens. | |
| </p> | |
| </div> | |
| </div> | |
| <div class="demo-card"> | |
| <div class="demo-screenshot-single"> | |
| <div class="screenshot-frame"> | |
| <img | |
| src="frontend/public/reachy-mini-minder-onboarding-completed.png" | |
| alt="Onboarding — All steps completed" | |
| loading="lazy" | |
| /> | |
| </div> | |
| </div> | |
| <div class="demo-info"> | |
| <h3>Voice-Guided Onboarding</h3> | |
| <p> | |
| Five-step setup — name, medications, and caregiver contacts — | |
| guided entirely by voice. The GenUI progress tracker updates | |
| in real time as each step completes. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Architecture --> | |
| <section class="panel"> | |
| <div class="panel-heading"> | |
| <p class="eyebrow">Architecture</p> | |
| <h2>How It Works</h2> | |
| </div> | |
| <div class="arch-grid"> | |
| <div class="arch-card"> | |
| <div class="feature-icon cyan"><i data-lucide="monitor"></i></div> | |
| <p class="arch-label">Frontend</p> | |
| <p class="arch-value">React + Next.js</p> | |
| <p class="arch-detail"> | |
| Real-time dashboard with WebSocket event bridge for instant UI | |
| updates. | |
| </p> | |
| </div> | |
| <div class="arch-card"> | |
| <div class="feature-icon pink"><i data-lucide="server"></i></div> | |
| <p class="arch-label">Backend</p> | |
| <p class="arch-value">LangGraph + FastAPI</p> | |
| <p class="arch-detail"> | |
| Agent orchestration with tool-calling, session management, and | |
| data persistence. | |
| </p> | |
| </div> | |
| <div class="arch-card"> | |
| <div class="feature-icon purple"><i data-lucide="mic-2"></i></div> | |
| <p class="arch-label">Voice</p> | |
| <p class="arch-value">OpenAI Realtime API</p> | |
| <p class="arch-detail"> | |
| Low-latency voice conversations with wakeword detection and VAD. | |
| </p> | |
| </div> | |
| <div class="arch-card"> | |
| <div class="feature-icon cyan"><i data-lucide="cpu"></i></div> | |
| <p class="arch-label">Robot</p> | |
| <p class="arch-value">Reachy Mini SDK</p> | |
| <p class="arch-detail"> | |
| Audio-reactive movement, head tracking, and expressive antenna | |
| control. | |
| </p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Documentation Tabs --> | |
| <section class="panel"> | |
| <div class="panel-heading"> | |
| <p class="eyebrow">Documentation</p> | |
| <h2>Learn More</h2> | |
| </div> | |
| <div class="tabs" role="tablist"> | |
| <button | |
| class="tab active" | |
| role="tab" | |
| aria-selected="true" | |
| data-tab="readme" | |
| > | |
| README | |
| </button> | |
| <button | |
| class="tab" | |
| role="tab" | |
| aria-selected="false" | |
| data-tab="quickstart" | |
| > | |
| Quick Start | |
| </button> | |
| <button | |
| class="tab" | |
| role="tab" | |
| aria-selected="false" | |
| data-tab="dignity" | |
| > | |
| Dignity-First | |
| </button> | |
| <button | |
| class="tab" | |
| role="tab" | |
| aria-selected="false" | |
| data-tab="design" | |
| > | |
| Design System | |
| </button> | |
| </div> | |
| <div class="tab-content" id="tab-content"> | |
| <div class="tab-loading">Loading documentation…</div> | |
| </div> | |
| </section> | |
| <footer class="footer"> | |
| <p> | |
| Built with <i data-lucide="heart" class="footer-heart"></i> for | |
| <a href="https://www.pollen-robotics.com/" class="link" | |
| >Reachy Mini</a | |
| > | |
| </p> | |
| </footer> | |
| </div> | |
| <script> | |
| const TAB_FILES = { | |
| readme: "README.md", | |
| quickstart: "documentation/quickstart.md", | |
| dignity: "documentation/dignity_first_design_principles.md", | |
| design: "documentation/design_system.md", | |
| }; | |
| const cache = {}; | |
| const contentEl = document.getElementById("tab-content"); | |
| async function loadTab(tabId) { | |
| if (cache[tabId]) { | |
| contentEl.innerHTML = cache[tabId]; | |
| return; | |
| } | |
| contentEl.innerHTML = '<div class="tab-loading">Loading…</div>'; | |
| try { | |
| const res = await fetch(TAB_FILES[tabId]); | |
| if (!res.ok) throw new Error(res.statusText); | |
| let md = await res.text(); | |
| md = md.replace(/^---[\s\S]*?---\s*/, ""); | |
| const html = marked.parse(md); | |
| cache[tabId] = '<div class="md-body">' + html + "</div>"; | |
| contentEl.innerHTML = cache[tabId]; | |
| } catch (e) { | |
| contentEl.innerHTML = | |
| '<div class="tab-error">Could not load this document.</div>'; | |
| } | |
| } | |
| document.querySelectorAll(".tab").forEach((btn) => { | |
| btn.addEventListener("click", () => { | |
| document.querySelectorAll(".tab").forEach((t) => { | |
| t.classList.remove("active"); | |
| t.setAttribute("aria-selected", "false"); | |
| }); | |
| btn.classList.add("active"); | |
| btn.setAttribute("aria-selected", "true"); | |
| loadTab(btn.dataset.tab); | |
| }); | |
| }); | |
| loadTab("readme"); | |
| lucide.createIcons(); | |
| </script> | |
| </body> | |
| </html> | |