Spaces:
Running
Running
Download index.html from venmugilrajan/SignLens: direct link, hf CLI and curl.
- Browser
- Download file 30.3 kB
-
https://huggingface.co/spaces/venmugilrajan/SignLens/resolve/main/index.html
- Command line
-
hf download hf://spaces/venmugilrajan/SignLens/index.html
-
curl -L -o index.html https://huggingface.co/spaces/venmugilrajan/SignLens/resolve/main/index.html
30.3 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <meta name="color-scheme" content="dark" /> | |
| <title>SignLens</title> | |
| <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=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet" /> | |
| <link rel="stylesheet" href="style.css?v=27" /> | |
| <!-- Three.js pinned local importmap (no CDN) --> | |
| <script type="importmap"> | |
| { | |
| "imports": { | |
| "three": "./vendor/three/three.module.js" | |
| } | |
| } | |
| </script> | |
| <script> | |
| // Feature flag: set window.USE_3D_AVATAR = false in the browser console to revert to 2D | |
| window.USE_3D_AVATAR = true; | |
| </script> | |
| </head> | |
| <body> | |
| <!-- โโ TOP BAR โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <header class="topbar"> | |
| <div class="brand"> | |
| <!-- Single geometric mark: three ascending strokes, a hand reading as signal. --> | |
| <svg class="brand-mark" viewBox="0 0 24 24" aria-hidden="true" focusable="false"> | |
| <rect x="3" y="13" width="4" height="8" rx="2" /> | |
| <rect x="10" y="7" width="4" height="14" rx="2" /> | |
| <rect x="17" y="3" width="4" height="18" rx="2" /> | |
| </svg> | |
| <span class="brand-name">SignLens</span> | |
| </div> | |
| <div class="mode-toggle" id="mode-toggle" role="group" aria-label="Sign language"> | |
| <button class="mode-btn active" data-mode="asl" id="btn-asl" aria-pressed="true">ASL</button> | |
| <button class="mode-btn" data-mode="isl" id="btn-isl" aria-pressed="false">ISL</button> | |
| <button class="mode-btn" data-mode="visually" id="btn-visually" aria-pressed="false">VISUALLY</button> | |
| <button class="mode-btn" data-mode="upload" id="btn-upload" aria-pressed="false">UPLOAD</button> | |
| <span class="mode-slider" aria-hidden="true"></span> | |
| </div> | |
| <div class="topbar-right"> | |
| <button class="ghost-btn guide-btn" popovertarget="panel-guide" id="btn-open-guide" aria-label="Open Sign Guide"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: -2px; margin-right: 5px;"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path></svg><span>Sign Guide</span> | |
| </button> | |
| <button class="ghost-btn" id="btn-open-settings" popovertarget="panel-settings">Settings</button> | |
| <button class="ghost-btn" id="btn-open-shortcuts" popovertarget="panel-help">Shortcuts</button> | |
| <button class="ghost-btn theme-toggle-btn" id="btn-theme-toggle" aria-label="Toggle Light or Dark Mode" title="Toggle Light / Dark Mode"> | |
| <span id="theme-toggle-icon" aria-hidden="true">โ๏ธ</span> | |
| </button> | |
| <div class="status-pill" id="status-pill"> | |
| <span class="status-dot" aria-hidden="true"></span> | |
| <span id="status-text" role="status" aria-live="polite">Connecting</span> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- โโ WORKSPACE (LIVE CAMERA) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <main class="workspace" id="live-workspace"> | |
| <!-- โโ Camera stage โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <section class="stage" aria-label="Camera"> | |
| <div class="viewport"> | |
| <video id="webcam-video" autoplay playsinline muted></video> | |
| <canvas id="display-canvas"></canvas> | |
| <div class="no-hand-overlay visible" id="no-hand-overlay"> | |
| <div class="idle-title">Show your hand to the camera</div> | |
| <div class="idle-sub">Tracking starts as soon as a hand is in frame.</div> | |
| </div> | |
| </div> | |
| <!-- Live readout: the one thing the user actually watches --> | |
| <div class="readout"> | |
| <div class="readout-dial"> | |
| <div class="dial-ring" aria-hidden="true"></div> | |
| <div class="detected-letter" id="detected-letter" role="status" aria-live="polite" aria-atomic="true"></div> | |
| </div> | |
| <div class="readout-body"> | |
| <div class="readout-line"> | |
| <span class="detected-sub" id="detected-conf">Waiting</span> | |
| <span class="hand-badge" id="hand-badge" role="status" aria-live="polite">NO HAND</span> | |
| </div> | |
| <div class="streak-row"> | |
| <div class="streak-track"><div class="streak-fill" id="streak-bar"></div></div> | |
| <span class="streak-label" id="streak-label">0 / 5</span> | |
| </div> | |
| </div> | |
| <div class="stage-actions"> | |
| <button class="ctrl-btn" id="btn-mirror-toggle" title="Switch between mirror selfie view and normal non-mirrored view">๐ช Mirror: On</button> | |
| <button class="ctrl-btn" popovertarget="panel-guide" id="stage-guide-btn" title="View official sign chart">Guide</button> | |
| <button class="ctrl-btn" id="btn-pause-detection">Pause</button> | |
| <button class="ctrl-btn active-btn" id="btn-camera-toggle">Stop Camera</button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- โโ Output rail โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <aside class="rail"> | |
| <article class="panel" id="word-panel"> | |
| <header class="panel-head"> | |
| <h2 class="panel-title">Building word</h2> | |
| </header> | |
| <div class="word-display" id="word-display"> | |
| <span class="ph">Start signing</span> | |
| </div> | |
| <div class="panel-actions"> | |
| <button class="btn" id="btn-backspace">Delete</button> | |
| <button class="btn" id="btn-add-space">Next word</button> | |
| <button class="btn btn-quiet" id="btn-clear-word">Clear</button> | |
| </div> | |
| </article> | |
| <article class="panel panel-grow" id="sentence-panel"> | |
| <header class="panel-head"> | |
| <h2 class="panel-title">Sentence</h2> | |
| <div class="panel-head-actions"> | |
| <div class="lang-dropdown-wrapper" id="lang-dropdown-wrapper"> | |
| <button type="button" class="lang-picker-btn" id="lang-picker-btn" aria-haspopup="listbox" aria-expanded="false" title="Choose translation language"> | |
| <span class="lang-picker-icon">๐</span> | |
| <span class="lang-picker-label" id="lang-picker-current-label">English</span> | |
| <svg class="lang-picker-chevron" viewBox="0 0 20 20" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"> | |
| <polyline points="6 8 10 12 14 8"></polyline> | |
| </svg> | |
| </button> | |
| <div class="lang-menu" id="lang-menu" role="listbox" aria-label="Select translation language"> | |
| <div class="lang-menu-header">Translate Sentence To</div> | |
| <div class="lang-menu-list"> | |
| <button type="button" class="lang-item is-selected" data-lang="en"> | |
| <span class="lang-name">English</span> | |
| <span class="lang-sub">Original</span> | |
| </button> | |
| <div class="lang-menu-divider"></div> | |
| <button type="button" class="lang-item" data-lang="ta"> | |
| <span class="lang-name">Tamil</span> | |
| <span class="lang-sub">เฎคเฎฎเฎฟเฎดเฏ</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="hi"> | |
| <span class="lang-name">Hindi</span> | |
| <span class="lang-sub">เคนเคฟเคจเฅเคฆเฅ</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="te"> | |
| <span class="lang-name">Telugu</span> | |
| <span class="lang-sub">เฐคเฑเฐฒเฑเฐเฑ</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="ml"> | |
| <span class="lang-name">Malayalam</span> | |
| <span class="lang-sub">เดฎเดฒเดฏเดพเดณเด</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="kn"> | |
| <span class="lang-name">Kannada</span> | |
| <span class="lang-sub">เฒเฒจเณเฒจเฒก</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="es"> | |
| <span class="lang-name">Spanish</span> | |
| <span class="lang-sub">Espaรฑol</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="fr"> | |
| <span class="lang-name">French</span> | |
| <span class="lang-sub">Franรงais</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="de"> | |
| <span class="lang-name">German</span> | |
| <span class="lang-sub">Deutsch</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="ja"> | |
| <span class="lang-name">Japanese</span> | |
| <span class="lang-sub">ๆฅๆฌ่ช</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="zh"> | |
| <span class="lang-name">Chinese</span> | |
| <span class="lang-sub">ไธญๆ</span> | |
| </button> | |
| <button type="button" class="lang-item" data-lang="ar"> | |
| <span class="lang-name">Arabic</span> | |
| <span class="lang-sub">ุงูุนุฑุจูุฉ</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <button class="btn btn-sm" id="btn-speak">Speak</button> | |
| <button class="btn btn-sm" id="btn-copy">Copy</button> | |
| </div> | |
| </header> | |
| <div class="sentence-display is-single" id="sentence-display" role="status" aria-live="polite"> | |
| <!-- Left Side: English Original --> | |
| <div class="sentence-col sentence-col-orig" id="sentence-col-orig"> | |
| <div class="sentence-col-header" id="sentence-orig-header"> | |
| <span class="sentence-col-tag">English (Original)</span> | |
| </div> | |
| <div class="sentence-col-body" id="sentence-original-text"> | |
| <em class="ph">Your sentence will appear here</em> | |
| </div> | |
| </div> | |
| <!-- Right Side: Selected Translated Language (shown only when a translated language is selected) --> | |
| <div class="sentence-col sentence-col-trans" id="translation-box" style="display: none;"> | |
| <div class="sentence-col-header"> | |
| <span class="sentence-col-tag" id="translation-lang-tag">Translation</span> | |
| <span class="translation-status" id="translation-status"></span> | |
| </div> | |
| <div class="sentence-col-body translation-text" id="translation-text"></div> | |
| </div> | |
| </div> | |
| <div class="word-chips" id="word-chips"></div> | |
| <button class="btn btn-danger" id="btn-clear-sentence">Clear all</button> | |
| </article> | |
| </aside> | |
| </main> | |
| <!-- โโ VISUALLY (PRACTICE STUDIO) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <section class="workspace visually-workspace hidden" id="visually-workspace" aria-label="Practice Studio"> | |
| <!-- Left Column: Input, Speech Dictation, and Sequence Breakdown --> | |
| <aside class="practice-input-rail"> | |
| <article class="panel panel-grow practice-panel"> | |
| <header class="panel-head"> | |
| <div class="practice-head-title"> | |
| <span class="practice-badge">PRACTICE STUDIO</span> | |
| <h2 class="panel-title">Text to Sign</h2> | |
| </div> | |
| <div class="practice-dialect-toggle" id="practice-dialect-toggle"> | |
| <button class="dialect-pill active" id="btn-practice-asl">ASL</button> | |
| <button class="dialect-pill" id="btn-practice-isl">ISL</button> | |
| </div> | |
| </header> | |
| <!-- Textarea with integrated voice mic & actions --> | |
| <div class="practice-textarea-box"> | |
| <textarea id="practice-input" placeholder="Type words or sentence (e.g. 'HI BABY', 'HOW ARE YOU')..." rows="4"></textarea> | |
| <div class="practice-input-tools"> | |
| <button class="tool-btn mic-btn" id="btn-mic" title="Voice Input (Speech-to-Sign)"> | |
| <svg class="icon" viewBox="0 0 24 24" fill="currentColor"> | |
| <path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5-3c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z"/> | |
| </svg> | |
| <span id="mic-label">Speak</span> | |
| </button> | |
| <button class="tool-btn" id="btn-speak-input" title="Speak text aloud"> | |
| <svg class="icon" viewBox="0 0 24 24" fill="currentColor"> | |
| <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/> | |
| </svg> | |
| </button> | |
| <button class="tool-btn" id="btn-clear-practice" title="Clear text">Clear</button> | |
| <span class="char-count" id="practice-char-count">0/200</span> | |
| </div> | |
| </div> | |
| <!-- Quick sample prompts --> | |
| <div class="quick-samples"> | |
| <span class="quick-label">Try:</span> | |
| <button class="sample-chip" data-text="HI">HI</button> | |
| <button class="sample-chip" data-text="HELLO">HELLO</button> | |
| <button class="sample-chip" data-text="THANK YOU">THANK YOU</button> | |
| <button class="sample-chip" data-text="HOW ARE YOU">HOW ARE YOU</button> | |
| <button class="sample-chip" data-text="BABY">BABY</button> | |
| </div> | |
| <!-- Main Trigger & Speed --> | |
| <div class="practice-action-row"> | |
| <button class="btn btn-primary btn-demo" id="btn-start-sign"> | |
| <svg class="icon-play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg> | |
| <span>Demonstrate Sign</span> | |
| </button> | |
| <div class="speed-control"> | |
| <span class="speed-label">Speed</span> | |
| <button class="speed-btn" data-speed="0.5">0.5x</button> | |
| <button class="speed-btn active" data-speed="1.0">1.0x</button> | |
| <button class="speed-btn" data-speed="1.5">1.5x</button> | |
| </div> | |
| </div> | |
| <!-- Letter Tape Progression --> | |
| <div class="sequence-section"> | |
| <div class="sequence-head"> | |
| <span class="seq-title">Sign Sequence Timeline</span> | |
| <span class="seq-counter" id="seq-counter">0 / 0</span> | |
| </div> | |
| <div class="sequence-chips" id="sequence-chips"> | |
| <span class="ph">Enter text above to preview gesture timelineโฆ</span> | |
| </div> | |
| </div> | |
| </article> | |
| </aside> | |
| <!-- Right Column: Interactive 3D Avatar Skeleton Stage --> | |
| <section class="practice-stage" aria-label="Avatar Stage"> | |
| <div class="avatar-viewport"> | |
| <canvas id="avatar-canvas-3d"></canvas> | |
| <canvas id="avatar-canvas"></canvas> | |
| <!-- 3D Avatar Loading Indicator Overlay --> | |
| <div class="avatar-3d-loading-overlay" id="avatar-3d-loading-overlay"> | |
| <div class="avatar-loading-box"> | |
| <div class="avatar-loading-spinner-ring"> | |
| <div class="avatar-loading-core-dot"></div> | |
| </div> | |
| <div class="avatar-loading-title">Initializing 3D Sign Studio</div> | |
| <div class="avatar-loading-subtitle" id="avatar-loading-status">Downloading 3D avatar assetsโฆ</div> | |
| <div class="avatar-loading-progress-track"> | |
| <div class="avatar-loading-progress-bar" id="avatar-loading-bar"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Active Letter Glow Badge --> | |
| <div class="avatar-hud-letter" id="avatar-hud-letter"> | |
| <span class="hud-letter-char" id="hud-letter-char">โ</span> | |
| <span class="hud-letter-sub" id="hud-letter-sub">Waiting for input</span> | |
| <span class="hud-letter-cue" id="hud-letter-cue" style="display: none;"></span> | |
| </div> | |
| <!-- Avatar Status Badge --> | |
| <div class="avatar-hud-status" id="avatar-hud-status"> | |
| <span class="status-badge-dot"></span> | |
| <span id="avatar-status-text">Ready</span> | |
| </div> | |
| <!-- Real Human Sign Reference Card (Top-Right) --> | |
| <div class="avatar-sign-preview" id="avatar-sign-preview" title="Official sign gesture photo reference" style="display: none;"> | |
| <div class="avatar-sign-img-wrap"> | |
| <img id="avatar-sign-img" src="" alt="Sign Gesture Reference" /> | |
| <span class="avatar-sign-badge" id="avatar-sign-badge">ISL</span> | |
| </div> | |
| <div class="avatar-sign-info"> | |
| <div class="avatar-sign-char-row"> | |
| <span class="avatar-sign-char" id="avatar-sign-char">A</span> | |
| <span class="avatar-sign-hands" id="avatar-sign-hands">1 Hand</span> | |
| </div> | |
| <span class="avatar-sign-desc" id="avatar-sign-desc">Sign gesture reference</span> | |
| </div> | |
| </div> | |
| <!-- Playback Controls Floating Bar --> | |
| <div class="avatar-controls-bar"> | |
| <button class="avatar-ctrl-btn" id="btn-avatar-prev" title="Previous letter">โฎ</button> | |
| <button class="avatar-ctrl-btn play-pause-btn" id="btn-avatar-playpause" title="Play/Pause">โธ</button> | |
| <button class="avatar-ctrl-btn" id="btn-avatar-next" title="Next letter">โญ</button> | |
| <button class="avatar-ctrl-btn" id="btn-avatar-replay" title="Replay all">โฒ</button> | |
| <div class="avatar-progress-wrap"> | |
| <input type="range" class="avatar-scrubber" id="avatar-scrubber" min="0" max="100" value="0" step="0.1" /> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </section> | |
| <!-- โโ UPLOAD (IMAGE SIGN RECOGNITION STUDIO) โโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <section class="workspace upload-workspace hidden" id="upload-workspace" aria-label="Upload Sign Recognition"> | |
| <!-- Left Column: Upload Dropzone, Controls & Sample Images --> | |
| <aside class="upload-sidebar"> | |
| <article class="panel upload-panel"> | |
| <header class="panel-head"> | |
| <div class="upload-head-title"> | |
| <span class="upload-badge">IMAGE RECOGNITION</span> | |
| <h2 class="panel-title">Sign Image Classifier</h2> | |
| </div> | |
| <div class="upload-dialect-toggle" id="upload-dialect-toggle"> | |
| <button class="upload-dialect-btn active" id="upload-dialect-asl" data-dialect="asl">ASL</button> | |
| <button class="upload-dialect-btn" id="upload-dialect-isl" data-dialect="isl">ISL</button> | |
| </div> | |
| </header> | |
| <!-- Drag & Drop Zone --> | |
| <div class="upload-dropzone" id="upload-dropzone"> | |
| <input type="file" id="upload-file-input" accept="image/*" class="upload-file-hidden" /> | |
| <div class="dropzone-icon"> | |
| <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path> | |
| <polyline points="17 8 12 3 7 8"></polyline> | |
| <line x1="12" y1="3" x2="12" y2="15"></line> | |
| </svg> | |
| </div> | |
| <div class="dropzone-title">Drop your hand sign image here</div> | |
| <div class="dropzone-sub">or <span class="dropzone-browse">browse from computer</span></div> | |
| <div class="dropzone-formats">Supports JPG, PNG, WEBP, Camera photos</div> | |
| </div> | |
| <!-- Quick Test Sample Signs --> | |
| <div class="upload-samples-wrap"> | |
| <div class="upload-samples-label">Or test with quick reference signs:</div> | |
| <div class="upload-samples-chips" id="upload-sample-chips"> | |
| <!-- Dynamically populated or static samples --> | |
| <button class="sample-img-chip" data-dialect="asl" data-letter="A">ASL: A</button> | |
| <button class="sample-img-chip" data-dialect="asl" data-letter="B">ASL: B</button> | |
| <button class="sample-img-chip" data-dialect="asl" data-letter="C">ASL: C</button> | |
| <button class="sample-img-chip" data-dialect="asl" data-letter="L">ASL: L</button> | |
| <button class="sample-img-chip" data-dialect="asl" data-letter="V">ASL: V</button> | |
| <button class="sample-img-chip" data-dialect="isl" data-letter="5">ISL: 5</button> | |
| <button class="sample-img-chip" data-dialect="isl" data-letter="C">ISL: C</button> | |
| <button class="sample-img-chip" data-dialect="isl" data-letter="O">ISL: O</button> | |
| </div> | |
| </div> | |
| <div class="upload-actions-bar"> | |
| <button class="btn btn-danger" id="btn-clear-upload" style="display: none;">Remove Image</button> | |
| </div> | |
| </article> | |
| </aside> | |
| <!-- Right Column: Visual Stage with Annotated Canvas & Prediction Results Card --> | |
| <section class="upload-stage" aria-label="Upload Analysis Stage"> | |
| <div class="upload-viewport" id="upload-viewport"> | |
| <!-- Empty Placeholder State --> | |
| <div class="upload-empty-state" id="upload-empty-state"> | |
| <div class="upload-empty-icon">๐๏ธ</div> | |
| <h3>No Image Uploaded Yet</h3> | |
| <p>Upload any picture with hand signs (ASL or ISL) to analyze 21 MediaPipe skeletal landmarks and classify the sign with top confidence matches.</p> | |
| <button class="btn btn-primary" id="btn-trigger-browse">Choose Sign Image</button> | |
| </div> | |
| <!-- Image Canvas Container --> | |
| <div class="upload-canvas-wrap hidden" id="upload-canvas-wrap"> | |
| <canvas id="upload-canvas"></canvas> | |
| </div> | |
| <!-- Prediction Floating HUD Overlay --> | |
| <div class="upload-result-hud hidden" id="upload-result-hud"> | |
| <div class="result-hud-header"> | |
| <span class="result-badge-dialect" id="result-dialect-tag">ASL</span> | |
| <span class="result-badge-hands" id="result-hands-tag">1 Hand Detected</span> | |
| </div> | |
| <div class="result-main-row"> | |
| <div class="result-letter-huge" id="result-letter">โ</div> | |
| <div class="result-details"> | |
| <div class="result-conf-row"> | |
| <span class="result-conf-label">Confidence</span> | |
| <span class="result-conf-val" id="result-confidence">99.8%</span> | |
| </div> | |
| <div class="result-desc" id="result-desc">Detecting sign...</div> | |
| </div> | |
| </div> | |
| <!-- Top 3 Probability Breakdown --> | |
| <div class="result-top3-section"> | |
| <div class="result-top3-title">Top Model Predictions</div> | |
| <div class="result-top3-bars" id="result-top3-bars"> | |
| <!-- Rendered dynamically --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </section> | |
| <!-- โโ SETTINGS (top layer) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <div popover id="panel-settings" class="sheet"> | |
| <header class="sheet-head"> | |
| <h2 class="sheet-title">Detection</h2> | |
| <div style="display: flex; gap: 8px; align-items: center;"> | |
| <button class="ghost-btn" id="btn-reset-settings" title="Reset detection settings to defaults" style="font-size: 11px; padding: 4px 8px;">Reset</button> | |
| <button class="ghost-btn" id="btn-close-settings" popovertarget="panel-settings" popovertargetaction="hide">Close</button> | |
| </div> | |
| </header> | |
| <div class="field"> | |
| <label for="set-confidence">Minimum confidence</label> | |
| <div class="field-row"> | |
| <input type="range" id="set-confidence" min="40" max="95" step="5" value="50" /> | |
| <output class="field-value" id="out-confidence">50%</output> | |
| </div> | |
| <p class="field-help">Predictions below this are ignored. Raise it if letters are captured too eagerly.</p> | |
| </div> | |
| <div class="field"> | |
| <label for="set-streak">Hold sign duration</label> | |
| <div class="field-row"> | |
| <input type="range" id="set-streak" min="0.5" max="6.0" step="0.5" value="1.0" /> | |
| <output class="field-value" id="out-streak">1.0s</output> | |
| </div> | |
| <p class="field-help">How many seconds you must hold the hand sign steady before the letter is captured.</p> | |
| </div> | |
| <div class="field"> | |
| <label for="set-timeout">Auto-push word delay</label> | |
| <div class="field-row"> | |
| <input type="range" id="set-timeout" min="1.0" max="5.0" step="0.5" value="3.0" /> | |
| <output class="field-value" id="out-timeout">3.0s</output> | |
| </div> | |
| <p class="field-help">How long you must lower your hand before the word commits to sentence.</p> | |
| </div> | |
| </div> | |
| <!-- โโ SHORTCUTS (top layer) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <div popover id="panel-help" class="sheet"> | |
| <header class="sheet-head"> | |
| <h2 class="sheet-title">How it works</h2> | |
| <button class="ghost-btn" popovertarget="panel-help" popovertargetaction="hide">Close</button> | |
| </header> | |
| <ol class="steps"> | |
| <li><span class="step-n">1</span> Show a hand sign to the camera.</li> | |
| <li><span class="step-n">2</span> Hold it steady while the ring fills.</li> | |
| <li><span class="step-n">3</span> The letter is captured and added to the word.</li> | |
| <li><span class="step-n">4</span> Drop your hand to commit the word to the sentence.</li> | |
| </ol> | |
| <div class="keys"> | |
| <div class="key-row"><kbd>Space</kbd><span>Commit current word</span></div> | |
| <div class="key-row"><kbd>Backspace</kbd><span>Delete last letter</span></div> | |
| <div class="key-row"><kbd>1</kbd><span>Switch to ASL</span></div> | |
| <div class="key-row"><kbd>2</kbd><span>Switch to ISL</span></div> | |
| <div class="key-row"><kbd>3</kbd><span>Switch to Practice (VISUALLY)</span></div> | |
| </div> | |
| </div> | |
| <!-- โโ SIGN REFERENCE GUIDE (top layer modal) โโโโโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <div popover id="panel-guide" class="sheet sheet-wide" style="display: none;"> | |
| <header class="sheet-head"> | |
| <div class="sheet-title-group"> | |
| <h2 class="sheet-title">Sign Reference Guide</h2> | |
| <span class="sheet-sub">Official hand gestures, required hand counts & poses</span> | |
| </div> | |
| <div class="guide-tabs" role="tablist"> | |
| <button class="guide-tab-btn active" id="tab-guide-isl" role="tab" aria-selected="true">๐ฎ๐ณ ISL (Indian Sign Language)</button> | |
| <button class="guide-tab-btn" id="tab-guide-asl" role="tab" aria-selected="false">๐บ๐ธ ASL (American Sign Language)</button> | |
| </div> | |
| <button class="ghost-btn" id="btn-close-guide" popovertarget="panel-guide" popovertargetaction="hide">Close</button> | |
| </header> | |
| <!-- ISL Tab Content --> | |
| <div class="guide-tab-content" id="guide-content-isl"> | |
| <div class="guide-alert-banner"> | |
| <span class="banner-icon">โ ๏ธ</span> | |
| <div> | |
| <strong>Crucial Rule in ISL:</strong> 20 alphabet letters (<kbd>A, B, D, E, F, G, H, J, K, M, N, P, Q, R, S, T, W, X, Y, Z</kbd>) strictly require <strong>TWO HANDS</strong>. Only numbers <kbd>1-9</kbd> and letters <kbd>C, I, L, O, U, V</kbd> use a single hand! | |
| </div> | |
| </div> | |
| <div class="guide-section"> | |
| <div class="guide-section-head"> | |
| <h3 class="guide-section-title">Single-Hand Gestures (15 Signs)</h3> | |
| <span class="pill-badge pill-amber">1-Hand Required</span> | |
| </div> | |
| <div class="guide-cards-grid" id="isl-single-cards"></div> | |
| </div> | |
| <div class="guide-section" style="margin-top: 28px;"> | |
| <div class="guide-section-head"> | |
| <h3 class="guide-section-title">Dual-Hand Gestures (20 Signs)</h3> | |
| <span class="pill-badge pill-blue">2-Hands Required</span> | |
| </div> | |
| <div class="guide-cards-grid" id="isl-dual-cards"></div> | |
| </div> | |
| </div> | |
| <!-- ASL Tab Content --> | |
| <div class="guide-tab-content hidden" id="guide-content-asl"> | |
| <div class="guide-alert-banner"> | |
| <span class="banner-icon">๐ก</span> | |
| <div> | |
| <strong>Rule in ASL:</strong> All 26 alphabet letters (<kbd>A to Z</kbd>) are performed using <strong>ONE dominant hand</strong>. | |
| </div> | |
| </div> | |
| <div class="guide-section"> | |
| <div class="guide-section-head"> | |
| <h3 class="guide-section-title">ASL Alphabet (26 Signs)</h3> | |
| <span class="pill-badge pill-amber">1-Hand Only</span> | |
| </div> | |
| <div class="guide-cards-grid" id="asl-cards"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- โโ SIGN GUIDE LIGHTBOX POPUP (Top-layer native dialog) โโโโโโโโโโโโโโโโโโโโโโโโ --> | |
| <dialog class="sign-lightbox-dialog" id="sign-lightbox-overlay"> | |
| <div class="sign-lightbox" id="sign-lightbox"> | |
| <button class="sign-lightbox-close" id="sign-lightbox-close" aria-label="Close preview">×</button> | |
| <div class="sign-lightbox-img-wrap"> | |
| <img id="sign-lightbox-img" src="" alt="Sign preview" /> | |
| </div> | |
| <div class="sign-lightbox-letter" id="sign-lightbox-letter"></div> | |
| <span class="sign-lightbox-type" id="sign-lightbox-type"></span> | |
| <p class="sign-lightbox-desc" id="sign-lightbox-desc"></p> | |
| <div class="sign-lightbox-lang" id="sign-lightbox-lang"></div> | |
| </div> | |
| </dialog> | |
| <div class="toast" id="toast" role="status" aria-live="polite"></div> | |
| <script type="module" src="app.js?v=39"></script> | |
| </body> | |
| </html> | |