| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <title>Tiny Narrator</title> |
| <link rel="stylesheet" href="/static/app.css" /> |
| </head> |
| <body> |
| <header class="topbar"> |
| <a class="brand" href="#article" aria-label="Tiny Narrator home"> |
| <span class="brand-mark" aria-hidden="true">TN</span> |
| <span>Tiny Narrator</span> |
| </a> |
| <nav class="topnav" aria-label="Primary routes"> |
| <a href="/" aria-current="page">Reader</a> |
| <a href="/generate">Generate</a> |
| </nav> |
| <button id="readerToggle" class="reader-toggle" type="button" aria-pressed="false"> |
| <span class="toggle-dot" aria-hidden="true"></span> |
| Screen reader off |
| </button> |
| </header> |
|
|
| <main id="article" class="article-shell"> |
| <article class="article" aria-labelledby="articleTitle"> |
| <p class="kicker speakable" data-reader-type="paragraph">Build Small Hackathon concept</p> |
| <h1 id="articleTitle" class="speakable" data-reader-type="heading"> |
| A tiny model reader that turns articles into guided narration |
| </h1> |
| <p class="dek speakable" data-reader-type="paragraph"> |
| Tiny Narrator is an accessibility-first article experience. It can describe generated images, |
| build a reading path, and speak each part of the page with a lightweight local voice. |
| </p> |
|
|
| <figure class="hero-figure speakable" data-reader-type="image" data-image-id="desk-reader"> |
| <img |
| src="/static/generated/desk-reader.svg" |
| alt="Illustration of an article reader with narration controls and a highlighted reading path." |
| /> |
| <figcaption> |
| The article view doubles as the demo surface, so every feature has a real reading task. |
| </figcaption> |
| </figure> |
|
|
| <section id="why" aria-labelledby="whyTitle"> |
| <h2 id="whyTitle" class="speakable" data-reader-type="heading">Why it belongs in a tiny-model hackathon</h2> |
| <p class="speakable" data-reader-type="paragraph"> |
| Accessibility tools should feel immediate, private, and personal. Small models help because they |
| can run closer to the reader, keep latency low, and make the experience easier to inspect. |
| </p> |
| <blockquote class="speakable" data-reader-type="quote"> |
| The goal is not to read the whole page at the user. The goal is to make the page navigable by sound. |
| </blockquote> |
| </section> |
|
|
| <section id="models" aria-labelledby="modelsTitle"> |
| <h2 id="modelsTitle" class="speakable" data-reader-type="heading">The model map</h2> |
| <p class="speakable" data-reader-type="paragraph"> |
| The reader brain runs through llama.cpp, the vision model writes practical alt text, Kokoro speaks |
| the final narration, and a four-billion-parameter image model creates article illustrations. |
| </p> |
| <figure class="inline-figure speakable" data-reader-type="image" data-image-id="model-map"> |
| <img |
| src="/static/generated/model-map.svg" |
| alt="Diagram showing the reader brain, vision, speech, and image generation models working together." |
| /> |
| <figcaption>Each model stays at or below four billion parameters for Tiny Titan eligibility.</figcaption> |
| </figure> |
| </section> |
|
|
| </article> |
|
|
| <aside class="status-panel" aria-label="Tiny Narrator status"> |
| <h2>Session</h2> |
| <dl> |
| <div> |
| <dt>Mode</dt> |
| <dd id="modeStatus">Reader off</dd> |
| </div> |
| <div> |
| <dt>Current</dt> |
| <dd id="currentStatus">No item selected</dd> |
| </div> |
| <div> |
| <dt>Runtime</dt> |
| <dd id="runtimeStatus">Waiting</dd> |
| </div> |
| <div> |
| <dt>Image Alt</dt> |
| <dd id="imageStatus">Waiting</dd> |
| </div> |
| <div> |
| <dt>Voice</dt> |
| <dd id="voiceStatus">Waiting</dd> |
| </div> |
| <div> |
| <dt>Latency</dt> |
| <dd id="latencyStatus">Waiting</dd> |
| </div> |
| </dl> |
| <p id="liveNarration" class="live-narration" aria-live="polite"> |
| Turn on screen reader mode to begin. |
| </p> |
| <div class="history-header"> |
| <h3>Transcript</h3> |
| <button id="copyTranscriptButton" type="button">Copy</button> |
| <button id="clearTranscriptButton" type="button">Clear</button> |
| </div> |
| <ol id="transcriptLog" class="transcript-log" aria-label="Narration transcript"></ol> |
| <div class="budget-header"> |
| <h3>Model Stack</h3> |
| <span id="modelBudgetStatus">Checking</span> |
| </div> |
| <ul id="modelStackList" class="budget-list" aria-label="Tiny Titan model stack"></ul> |
| </aside> |
| </main> |
|
|
| <section class="reader-bar" aria-label="Screen reader controls" hidden> |
| <button id="prevButton" type="button" title="Previous item" aria-keyshortcuts="P">Prev</button> |
| <button id="playButton" type="button" title="Play or pause" aria-keyshortcuts="Space">Play</button> |
| <button id="nextButton" type="button" title="Next item" aria-keyshortcuts="N">Next</button> |
| <button id="headingButton" type="button" title="Next heading" aria-keyshortcuts="H">Heading</button> |
| <button id="imageButton" type="button" title="Next image" aria-keyshortcuts="I">Image</button> |
| <button id="summaryButton" type="button" title="Summarize current section" aria-keyshortcuts="S">Summary</button> |
| <button id="repeatButton" type="button" title="Repeat current item" aria-keyshortcuts="R">Repeat</button> |
| <button id="stopButton" type="button" title="Stop audio" aria-keyshortcuts="Escape">Stop</button> |
| <label> |
| Voice |
| <select id="voiceControl" aria-label="Reader voice"></select> |
| </label> |
| <label> |
| Speed |
| <input id="speedControl" type="range" min="0.75" max="1.35" value="1" step="0.05" /> |
| <output id="speedValue" for="speedControl">1.00x</output> |
| </label> |
| <label> |
| Auto |
| <input id="autoAdvanceControl" type="checkbox" /> |
| </label> |
| <audio id="speechAudio"></audio> |
| </section> |
|
|
| <script src="/static/app.js" type="module"></script> |
| </body> |
| </html> |
|
|