chitrark's picture
update index.html
1b501a0 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ReadingBuddy β€’ Reachy Mini</title>
<style>
:root{
--bg:#0f172a;
--card:rgba(255,255,255,.06);
--text:#e5e7eb;
--muted:#94a3b8;
--brand:#818cf8;
--success:#22c55e;
}
*{ box-sizing:border-box; margin:0; }
body{
margin:0;
font-family: system-ui, -apple-system, sans-serif;
color:var(--text);
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
line-height:1.6;
padding:40px 20px;
}
.container{
max-width: 1000px;
margin: 0 auto;
}
.hero{
text-align:center;
margin-bottom:50px;
}
.logo{
font-size:80px;
margin-bottom:20px;
}
h1{
font-size:3rem;
margin:0 0 16px;
background: linear-gradient(135deg, #818cf8, #22c55e);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.tagline{
font-size:1.3rem;
color:var(--muted);
margin-bottom:32px;
}
h2{
font-size:1.8rem;
margin:40px 0 24px;
text-align:center;
}
.voice-grid{
display:grid;
grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
gap:16px;
margin:32px 0;
}
.voice-card{
position:relative;
aspect-ratio: 3/2;
border-radius:16px;
overflow:hidden;
border:3px solid rgba(129,140,248,.3);
background-size:cover;
background-position:center;
display:flex;
flex-direction:column;
justify-content:flex-end;
padding:16px;
transition: transform 0.2s, border-color 0.2s;
}
.voice-card:hover{
transform: translateY(-4px);
border-color: rgba(129,140,248,.6);
}
.voice-card::before{
content:'';
position:absolute;
inset:0;
background: linear-gradient(to top, rgba(0,0,0,.85) 0%, rgba(0,0,0,.3) 60%, transparent 100%);
}
.voice-card .name{
position:relative;
font-size:1.2rem;
font-weight:700;
margin-bottom:4px;
}
.voice-card .desc{
position:relative;
font-size:0.9rem;
color:rgba(255,255,255,.8);
}
.pills{
display:flex;
gap:12px;
justify-content:center;
flex-wrap:wrap;
margin:32px 0;
}
.pill{
padding:8px 16px;
border-radius:999px;
background:rgba(129,140,248,.15);
border:1px solid rgba(129,140,248,.3);
font-size:0.95rem;
}
.section{
background:var(--card);
border:1px solid rgba(255,255,255,.1);
border-radius:20px;
padding:40px;
margin:40px 0;
}
.section h2{
margin-top:0;
text-align:left;
}
.steps{
display:grid;
gap:16px;
}
.step{
display:flex;
gap:16px;
align-items:start;
}
.num{
width:36px;
height:36px;
border-radius:50%;
background:rgba(129,140,248,.2);
border:2px solid rgba(129,140,248,.4);
display:grid;
place-items:center;
font-weight:700;
flex-shrink:0;
}
code{
background:rgba(255,255,255,.08);
padding:4px 10px;
border-radius:8px;
font-size:0.9em;
word-break:break-all;
}
.code-block{
background:rgba(0,0,0,.3);
border:1px solid rgba(255,255,255,.1);
border-radius:12px;
padding:16px;
margin:16px 0;
font-family: monospace;
font-size:0.9em;
overflow-x:auto;
line-height:1.8;
white-space:pre-wrap;
}
.code-block code{
background:transparent;
padding:0;
}
.features{
display:grid;
grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
gap:20px;
margin:40px 0;
}
.feature{
background:var(--card);
border:1px solid rgba(255,255,255,.1);
border-radius:16px;
padding:24px;
text-align:center;
}
.feature-icon{
font-size:48px;
margin-bottom:12px;
}
.feature h3{
font-size:1.1rem;
margin-bottom:8px;
}
.feature p{
color:var(--muted);
font-size:0.95rem;
}
.note{
background:rgba(34,197,94,.1);
border:1px solid rgba(34,197,94,.3);
border-radius:12px;
padding:16px;
margin:16px 0;
color:#d1fae5;
}
.note strong{
color:#ecfdf5;
}
.tier-grid{
display:grid;
grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
gap:16px;
margin:24px 0;
}
.tier-card{
background:rgba(0,0,0,.2);
border:1px solid rgba(255,255,255,.1);
border-radius:16px;
padding:20px;
text-align:center;
}
.tier-card .tier-icon{
font-size:36px;
margin-bottom:10px;
}
.tier-card h3{
font-size:1rem;
margin-bottom:6px;
}
.tier-card p{
font-size:0.85rem;
color:var(--muted);
}
.tier-card .tier-badge{
display:inline-block;
padding:3px 10px;
border-radius:999px;
font-size:0.75rem;
font-weight:700;
margin-bottom:10px;
}
.badge-default{ background:rgba(34,197,94,.2); color:#86efac; border:1px solid rgba(34,197,94,.3); }
.badge-premium{ background:rgba(129,140,248,.2); color:#c7d2fe; border:1px solid rgba(129,140,248,.3); }
.badge-fallback{ background:rgba(255,255,255,.1); color:var(--muted); border:1px solid rgba(255,255,255,.1); }
footer{
text-align:center;
margin-top:60px;
padding-top:30px;
border-top:1px solid rgba(255,255,255,.1);
color:var(--muted);
font-size:0.9rem;
}
a{ color:#c7d2fe; text-decoration:none; }
a:hover{ text-decoration:underline; }
</style>
</head>
<body>
<div class="container">
<div class="hero">
<div class="logo">πŸ€–πŸ“š</div>
<h1>ReadingBuddy</h1>
<p class="tagline">Your Reachy Mini reads books aloud with character voices</p>
<div class="pills">
<span class="pill">πŸ“Έ Camera OCR</span>
<span class="pill">🎭 4 Voices</span>
<span class="pill">🧠 Page Memory</span>
<span class="pill">πŸ“– Story Library</span>
</div>
</div>
<h2>🎭 Character Voices</h2>
<div class="voice-grid">
<div class="voice-card" style="background-image: url('reachy_mini_bookreader/static/voices/techstoryteller.jpg')">
<div class="name">Tech Storyteller</div>
<div class="desc">GPU Dad mode</div>
</div>
<div class="voice-card" style="background-image: url('reachy_mini_bookreader/static/voices/superhero.jpg')">
<div class="name">Superhero</div>
<div class="desc">Big energy</div>
</div>
<div class="voice-card" style="background-image: url('reachy_mini_bookreader/static/voices/princess.jpg')">
<div class="name">Princess</div>
<div class="desc">Sweet + bright</div>
</div>
<div class="voice-card" style="background-image: url('reachy_mini_bookreader/static/voices/robothero.jpg')">
<div class="name">Robot Hero</div>
<div class="desc">Strong + brave</div>
</div>
</div>
<div class="features">
<div class="feature">
<div class="feature-icon">πŸ“Έ</div>
<h3>Smart Camera</h3>
<p>Capture pages, extract text instantly</p>
</div>
<div class="feature">
<div class="feature-icon">πŸ”Š</div>
<h3>Three-Tier TTS</h3>
<p>ElevenLabs β†’ Piper β†’ espeak fallback</p>
</div>
<div class="feature">
<div class="feature-icon">🧠</div>
<h3>Page Memory</h3>
<p>Remembers where you left off</p>
</div>
<div class="feature">
<div class="feature-icon">πŸ“š</div>
<h3>Story Library</h3>
<p>Classic tales pre-loaded</p>
</div>
</div>
<!-- Voice Tiers Section -->
<div class="section">
<h2>πŸ”Š Voice Quality Tiers</h2>
<p style="color:var(--muted); margin-bottom:24px; text-align:center;">
ReadingBuddy uses a smart three-tier voice system β€” great voices out of the box, upgradeable anytime!
</p>
<div class="tier-grid">
<div class="tier-card">
<div class="tier-icon">πŸ†</div>
<div class="tier-badge badge-premium">Premium</div>
<h3>ElevenLabs</h3>
<p>Professional character voices with emotion and expression. Requires API key.</p>
</div>
<div class="tier-card">
<div class="tier-icon">πŸ₯ˆ</div>
<div class="tier-badge badge-default">Default βœ“</div>
<h3>Piper TTS</h3>
<p>Natural-sounding voices, runs locally on your robot. Completely free!</p>
</div>
<div class="tier-card">
<div class="tier-icon">πŸ₯‰</div>
<div class="tier-badge badge-fallback">Fallback</div>
<h3>espeak-ng</h3>
<p>Robotic backup voice. Always available, no setup needed.</p>
</div>
</div>
<div class="note">
<strong>πŸ’‘ Out of the box:</strong> You get Piper TTS β€” natural voices, completely free, no API key needed!
Each character has a distinct voice personality.
</div>
</div>
<!-- Install Section -->
<div class="section">
<h2>πŸš€ Install on Reachy Mini</h2>
<div class="steps">
<div class="step">
<div class="num">1</div>
<div>Open dashboard at <code>http://REACHY_IP:8000</code></div>
</div>
<div class="step">
<div class="num">2</div>
<div>Click <strong>Install from Hugging Face</strong></div>
</div>
<div class="step">
<div class="num">3</div>
<div>Search <code>reachy_mini_bookreader</code></div>
</div>
<div class="step">
<div class="num">4</div>
<div>Click <strong>Install</strong> β†’ <strong>Run</strong> β†’ <strong>βš™οΈ</strong></div>
</div>
</div>
</div>
<!-- Piper Setup Section -->
<div class="section">
<h2>πŸ₯ˆ Setup Piper Voices (One-Time)</h2>
<p style="color:var(--muted); margin-bottom:20px;">
After installing, download the voice models once via SSH:
</p>
<div class="steps">
<div class="step">
<div class="num">1</div>
<div>SSH into your Reachy Mini:
<div class="code-block"><code>ssh pollen@YOUR_REACHY_IP</code></div>
</div>
</div>
<div class="step">
<div class="num">2</div>
<div>Create the voices folder:
<div class="code-block"><code>mkdir -p ~/.local/share/piper-voices
cd ~/.local/share/piper-voices</code></div>
</div>
</div>
<div class="step">
<div class="num">3</div>
<div>Download all 4 character voices:
<div class="code-block"><code>wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/arctic/medium/en_US-arctic-medium.onnx
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/arctic/medium/en_US-arctic-medium.onnx.json
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/danny/low/en_US-danny-low.onnx
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/danny/low/en_US-danny-low.onnx.json
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/amy/medium/en_US-amy-medium.onnx
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/amy/medium/en_US-amy-medium.onnx.json
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/john/medium/en_US-john-medium.onnx
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/john/medium/en_US-john-medium.onnx.json</code></div>
</div>
</div>
<div class="step">
<div class="num">4</div>
<div>Restart the app and enjoy natural voices! 🎀</div>
</div>
</div>
</div>
<!-- ElevenLabs Section -->
<div class="section">
<h2>πŸ† Enable Premium ElevenLabs Voices (Optional)</h2>
<p style="color:var(--muted); margin-bottom:20px;">
For the absolute best quality with theatrical character voices:
</p>
<div class="steps">
<div class="step">
<div class="num">1</div>
<div>Get API key from <a href="https://elevenlabs.io" target="_blank">elevenlabs.io</a></div>
</div>
<div class="step">
<div class="num">2</div>
<div>On your Reachy Mini, create a <code>.env</code> file:
<div class="code-block"><code>cd ~/.local/share/reachy-mini/apps/reachy_mini_bookreader
nano .env</code></div>
</div>
</div>
<div class="step">
<div class="num">3</div>
<div>Add these credentials (using our recommended voices):
<div class="code-block"><code>ELEVENLABS_API_KEY=your_api_key_here
ELEVEN_VOICE_TECH=9lv4qqEb8CqLgosI5Due
ELEVEN_VOICE_SUPERHERO=248nvfaZe8BXhKntjmpp
ELEVEN_VOICE_PRINCESS=mHX7OoPk2G45VMAuinIt
ELEVEN_VOICE_ROBOTHERO=Q8ZbQAANLFvLw8uPBR8d</code></div>
</div>
</div>
<div class="step">
<div class="num">4</div>
<div>Save (<code>Ctrl+X</code>, <code>Y</code>, <code>Enter</code>) and restart the app</div>
</div>
</div>
<div class="note">
<strong>πŸ’‘ Note:</strong> These are our curated voice IDs that work great for each character!
You can also choose your own voices from the <a href="https://elevenlabs.io/app/voice-library" target="_blank" style="color:#a7f3d0;">ElevenLabs Voice Library</a>.
</div>
</div>
<footer>
<p>Requires <a href="https://www.pollen-robotics.com/reachy-mini/">Reachy Mini</a> robot hardware</p>
<p style="margin-top:8px;">Made with ❀️ for educational robotics</p>
</footer>
</div>
</body>
</html>