File size: 9,387 Bytes
7135dbd 9f074fb 7135dbd 9f074fb 7135dbd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lingo Bridge — Watch a sentence become another language</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=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/style.css?v=21" />
<link rel="icon" type="image/svg+xml" href="/static/logo.svg" />
</head>
<body>
<div id="bg-glow"></div>
<header class="topbar">
<div class="brand">
<img src="/static/logo.svg" class="logo-img" alt="Lingo Bridge Logo" />
<div>
<h1>Lingo Bridge</h1>
<p class="tag">Watch & hear a sentence gradually become another language.</p>
</div>
</div>
<div class="badges">
<span class="badge" id="badge-llm">LLM: …</span>
<span class="badge" id="badge-tts">TTS: …</span>
</div>
</header>
<section class="controls">
<textarea id="input" rows="1" placeholder="Type a sentence…">The cat sat quietly on the warm mat</textarea>
<div class="langrow">
<select id="source" class="sel" aria-label="Source language"></select>
<button id="swap" class="swap" title="Swap languages">⇄</button>
<select id="target" class="sel" aria-label="Target language"></select>
<button id="example" class="playall" title="Load a random example sentence">🎲 Surprise me</button>
<button id="go" class="go">Translate →</button>
</div>
<div class="viewrow">
<div class="perspective-control">
<span class="lbl">2D</span>
<input type="range" id="perspective-slider" min="0" max="1" step="0.001" value="1" aria-label="Perspective Morph" />
<span class="lbl">3D</span>
</div>
<button id="playall" class="playall" title="Play every layer in sequence">▶ Play all layers</button>
</div>
</section>
<main id="stage">
<div id="view-cards" class="view"></div>
<!-- Floating Zoom & Rotation Widget -->
<div class="zoom-controls">
<div class="zoom-slider-wrap" title="Magnification (Zoom)">
<button id="btn-zoom-in" class="zoom-btn" title="Zoom In (Magnification)" style="display: flex; align-items: center; justify-content: center; padding: 2px; height: 20px; width: 20px; border-radius: 3px; border: none; background: transparent; cursor: pointer; color: var(--muted); transition: color 0.15s;">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.85;">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
<line x1="11" y1="8" x2="11" y2="14"></line>
<line x1="8" y1="11" x2="14" y2="11"></line>
</svg>
</button>
<input type="range" id="zoom-slider" min="0" max="1" step="0.001" value="0.5" class="zoom-slider" aria-label="Magnification Slider" />
<button id="btn-zoom-out" class="zoom-btn" title="Zoom Out (Magnification)" style="display: flex; align-items: center; justify-content: center; padding: 2px; height: 20px; width: 20px; border-radius: 3px; border: none; background: transparent; cursor: pointer; color: var(--muted); transition: color 0.15s;">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.85;">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
<line x1="8" y1="11" x2="14" y2="11"></line>
</svg>
</button>
</div>
<div style="height: 1px; background: rgba(150, 170, 255, 0.15); margin: 4px 0;"></div>
<button id="btn-rotate-left" class="zoom-btn" title="Rotate Left" style="display: flex; align-items: center; justify-content: center; padding: 2px;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.85;">
<!-- Back of revolve (dashed) -->
<path d="M 4 12 C 4 7.5, 20 7.5, 20 12" stroke-dasharray="3 3" opacity="0.45" />
<!-- Vertical axis bar -->
<line x1="12" y1="3" x2="12" y2="21" stroke-width="2.5" />
<!-- Front of revolve (solid) -->
<path d="M 20 12 C 20 16.5, 4 16.5, 4 12" />
<polyline points="8 9 4 12 8 15" />
</svg>
</button>
<button id="btn-rotate-right" class="zoom-btn" title="Rotate Right" style="display: flex; align-items: center; justify-content: center; padding: 2px;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.85;">
<!-- Back of revolve (dashed) -->
<path d="M 20 12 C 20 7.5, 4 7.5, 4 12" stroke-dasharray="3 3" opacity="0.45" />
<!-- Vertical axis bar -->
<line x1="12" y1="3" x2="12" y2="21" stroke-width="2.5" />
<!-- Front of revolve (solid) -->
<path d="M 4 12 C 4 16.5, 20 16.5, 20 12" />
<polyline points="16 9 20 12 16 15" />
</svg>
</button>
<div style="height: 1px; background: rgba(150, 170, 255, 0.15); margin: 4px 0;"></div>
<button id="btn-move-forward" class="zoom-btn" title="Move Forward (Push In)" style="display: flex; align-items: center; justify-content: center; padding: 2px;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="none" xmlns="http://www.w3.org/2000/svg" style="opacity: 0.85;">
<!-- 3D Tapered Arrow pointing Up/Away (Move Forward) - Wide Observable Wings -->
<!-- Thickness / Shadow Faces -->
<polygon points="6.5,17.5 17.5,17.5 17.5,20 6.5,20" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<polygon points="5.5,8.5 10,8.5 10,10.5 5.5,10.5" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<polygon points="14,8.5 18.5,8.5 18.5,10.5 14,10.5" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<!-- Main Front Face -->
<polygon points="6.5,17.5 17.5,17.5 14,8.5 18.5,8.5 12,4 5.5,8.5 10,8.5" fill="currentColor" fill-opacity="0.95" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
</svg>
</button>
<button id="btn-move-backward" class="zoom-btn" title="Move Backward (Push Out)" style="display: flex; align-items: center; justify-content: center; padding: 2px;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="none" xmlns="http://www.w3.org/2000/svg" style="opacity: 0.85;">
<!-- 3D Tapered Arrow pointing Down/Towards (Move Backward) - Wide Observable Wings -->
<!-- Thickness / Shadow Faces -->
<polygon points="6.5,6.5 17.5,6.5 17.5,4 6.5,4" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<polygon points="5.5,15.5 10,15.5 10,13.5 5.5,13.5" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<polygon points="14,15.5 18.5,15.5 18.5,13.5 14,13.5" fill="currentColor" fill-opacity="0.5" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
<!-- Main Front Face -->
<polygon points="6.5,6.5 17.5,6.5 14,15.5 18.5,15.5 12,20 5.5,15.5 10,15.5" fill="currentColor" fill-opacity="0.95" stroke="var(--bg)" stroke-width="0.8" stroke-linejoin="round" />
</svg>
</button>
</div>
<div id="loader" class="loader hidden"><div class="spin"></div><span id="loadmsg">Thinking…</span></div>
<div id="hint" class="hint">
<div class="hint-icon-wrap">
<img src="/static/logo.svg" class="hint-logo" alt="Lingo Bridge Logo" />
</div>
<h2>Welcome to Lingo Bridge</h2>
<p class="hint-tagline">An interactive toy exploring the migration of language, grammar, and word order.</p>
<div class="hint-steps">
<div class="hint-step">
<span class="step-num">1</span>
<p>Type a sentence above or click <b>🎲 Surprise me</b></p>
</div>
<div class="hint-step">
<span class="step-num">2</span>
<p>Click <b>Translate →</b> to decompose it into 7 layered steps</p>
</div>
<div class="hint-step">
<span class="step-num">3</span>
<p>Hover over phrases to trace the path, or click <b>▶ Play</b> to hear them</p>
</div>
</div>
</div>
</main>
<audio id="player"></audio>
<script type="importmap">
{ "imports": {
"three": "/static/vendor/three.module.js",
"three/addons/controls/OrbitControls.js": "/static/vendor/OrbitControls.js"
}}
</script>
<script src="/static/app.js?v=21" type="module"></script>
</body>
</html>
|