Files
typo/index.html

58 lines
3.0 KiB
HTML
Raw Normal View History

Initial build: typo, a typing test built from your own code No backend, no build step -- static HTML/CSS/JS, themed identically to flit/wisp (same CSS vars, same "> " title prefix, same dark/mono/green aesthetic). Snippets are real, shipped code pulled from six repos in this family (flit, wisp, keep, stash, delve-term, goonk) rather than generic pangrams. Stats: WPM = (correct chars / 5) / minutes elapsed, timing from first keystroke not page load. Accuracy = correct keystrokes / total keystrokes tracked at the keydown level (comparing the pressed key against the exact next expected character before it's inserted), so backspaced-over mistakes still count against it rather than only diffing the final text. Keys/sec updates live via a 200ms tick. Tabs in source are rendered as two spaces so players never need to press Tab -- sidesteps a browser default-Tab-moves-focus fight entirely rather than fighting it with preventDefault. Verified via simulated typing sessions (puppeteer), not just static review -- both an artificially fast pass (confirms the math is internally consistent: 308 correct/310 total keystrokes -> 99%, matches displayed) and a realistic ~60wpm-paced pass (confirms no unit-conversion bug that only a slow, deliberate typist would hit tests-at-lightspeed wouldn't surface). That process caught two real bugs before they'd have hit a real player: 1. A stray `tabindex="0"` on the code display let the browser's native click-to-focus behavior steal focus away from the hidden textarea before our own focus() call ran -- typing silently did nothing. Fixed by removing the tabindex and switching to a mousedown+preventDefault handler instead of click. 2. The help modal's CSS set `display: flex` unconditionally, which (author CSS always beats the UA stylesheet) overrode the `hidden` attribute's default `display: none` -- the modal was invisibly covering the entire viewport and intercepting every click, at all times, whether or not it had been opened. Fixed with an explicit `.modal-overlay:not([hidden])` rule. Also verified the actual Docker image builds and serves correctly (nginx, no build stage needed since there's nothing to compile). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 14:12:44 +02:00
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>typo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="A typing test built from your own code and lore — real snippets from real repos.">
Initial build: typo, a typing test built from your own code No backend, no build step -- static HTML/CSS/JS, themed identically to flit/wisp (same CSS vars, same "> " title prefix, same dark/mono/green aesthetic). Snippets are real, shipped code pulled from six repos in this family (flit, wisp, keep, stash, delve-term, goonk) rather than generic pangrams. Stats: WPM = (correct chars / 5) / minutes elapsed, timing from first keystroke not page load. Accuracy = correct keystrokes / total keystrokes tracked at the keydown level (comparing the pressed key against the exact next expected character before it's inserted), so backspaced-over mistakes still count against it rather than only diffing the final text. Keys/sec updates live via a 200ms tick. Tabs in source are rendered as two spaces so players never need to press Tab -- sidesteps a browser default-Tab-moves-focus fight entirely rather than fighting it with preventDefault. Verified via simulated typing sessions (puppeteer), not just static review -- both an artificially fast pass (confirms the math is internally consistent: 308 correct/310 total keystrokes -> 99%, matches displayed) and a realistic ~60wpm-paced pass (confirms no unit-conversion bug that only a slow, deliberate typist would hit tests-at-lightspeed wouldn't surface). That process caught two real bugs before they'd have hit a real player: 1. A stray `tabindex="0"` on the code display let the browser's native click-to-focus behavior steal focus away from the hidden textarea before our own focus() call ran -- typing silently did nothing. Fixed by removing the tabindex and switching to a mousedown+preventDefault handler instead of click. 2. The help modal's CSS set `display: flex` unconditionally, which (author CSS always beats the UA stylesheet) overrode the `hidden` attribute's default `display: none` -- the modal was invisibly covering the entire viewport and intercepting every click, at all times, whether or not it had been opened. Fixed with an explicit `.modal-overlay:not([hidden])` rule. Also verified the actual Docker image builds and serves correctly (nginx, no build stage needed since there's nothing to compile). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 14:12:44 +02:00
<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=JetBrains+Mono:wght@400;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<div class="header-row">
<h1>typo</h1>
<button class="help-btn" id="help-btn" title="How this works">?</button>
</div>
<p class="hint">real code and lore, from real repos — type it as fast and cleanly as you can</p>
Initial build: typo, a typing test built from your own code No backend, no build step -- static HTML/CSS/JS, themed identically to flit/wisp (same CSS vars, same "> " title prefix, same dark/mono/green aesthetic). Snippets are real, shipped code pulled from six repos in this family (flit, wisp, keep, stash, delve-term, goonk) rather than generic pangrams. Stats: WPM = (correct chars / 5) / minutes elapsed, timing from first keystroke not page load. Accuracy = correct keystrokes / total keystrokes tracked at the keydown level (comparing the pressed key against the exact next expected character before it's inserted), so backspaced-over mistakes still count against it rather than only diffing the final text. Keys/sec updates live via a 200ms tick. Tabs in source are rendered as two spaces so players never need to press Tab -- sidesteps a browser default-Tab-moves-focus fight entirely rather than fighting it with preventDefault. Verified via simulated typing sessions (puppeteer), not just static review -- both an artificially fast pass (confirms the math is internally consistent: 308 correct/310 total keystrokes -> 99%, matches displayed) and a realistic ~60wpm-paced pass (confirms no unit-conversion bug that only a slow, deliberate typist would hit tests-at-lightspeed wouldn't surface). That process caught two real bugs before they'd have hit a real player: 1. A stray `tabindex="0"` on the code display let the browser's native click-to-focus behavior steal focus away from the hidden textarea before our own focus() call ran -- typing silently did nothing. Fixed by removing the tabindex and switching to a mousedown+preventDefault handler instead of click. 2. The help modal's CSS set `display: flex` unconditionally, which (author CSS always beats the UA stylesheet) overrode the `hidden` attribute's default `display: none` -- the modal was invisibly covering the entire viewport and intercepting every click, at all times, whether or not it had been opened. Fixed with an explicit `.modal-overlay:not([hidden])` rule. Also verified the actual Docker image builds and serves correctly (nginx, no build stage needed since there's nothing to compile). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 14:12:44 +02:00
<div class="card" id="game-card">
<div class="source-line" id="source-line">loading a snippet…</div>
<pre class="code-display" id="code-display"></pre>
<textarea id="typing-input" class="sr-input" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" aria-label="Type the code shown above"></textarea>
<div class="stat-row" id="stat-row">
<div class="stat"><span class="stat-value" id="stat-wpm">0</span><span class="stat-label">wpm</span></div>
<div class="stat"><span class="stat-value" id="stat-acc">100%</span><span class="stat-label">accuracy</span></div>
<div class="stat"><span class="stat-value" id="stat-kps">0.0</span><span class="stat-label">keys/sec</span></div>
<div class="stat"><span class="stat-value" id="stat-time">0.0s</span><span class="stat-label">time</span></div>
</div>
<div class="actions">
<button class="btn btn-primary" id="restart-btn">new snippet</button>
</div>
</div>
<div class="modal-overlay" id="help-modal" hidden>
<div class="modal-card">
<div class="modal-header">
<span>how it works</span>
<button class="help-btn" id="close-help">&times;</button>
</div>
<ul>
<li>Every snippet is real — either code pulled from real, shipped repos (flit, wisp, keep, stash, delve-term, goonk itself), or in-world lore/flavor text from the games (Delve's chronicle, djupet's event log — some of that in Swedish, on purpose).</li>
<li>Click the block and start typing. Timing starts on your first keystroke, not on page load.</li>
Initial build: typo, a typing test built from your own code No backend, no build step -- static HTML/CSS/JS, themed identically to flit/wisp (same CSS vars, same "> " title prefix, same dark/mono/green aesthetic). Snippets are real, shipped code pulled from six repos in this family (flit, wisp, keep, stash, delve-term, goonk) rather than generic pangrams. Stats: WPM = (correct chars / 5) / minutes elapsed, timing from first keystroke not page load. Accuracy = correct keystrokes / total keystrokes tracked at the keydown level (comparing the pressed key against the exact next expected character before it's inserted), so backspaced-over mistakes still count against it rather than only diffing the final text. Keys/sec updates live via a 200ms tick. Tabs in source are rendered as two spaces so players never need to press Tab -- sidesteps a browser default-Tab-moves-focus fight entirely rather than fighting it with preventDefault. Verified via simulated typing sessions (puppeteer), not just static review -- both an artificially fast pass (confirms the math is internally consistent: 308 correct/310 total keystrokes -> 99%, matches displayed) and a realistic ~60wpm-paced pass (confirms no unit-conversion bug that only a slow, deliberate typist would hit tests-at-lightspeed wouldn't surface). That process caught two real bugs before they'd have hit a real player: 1. A stray `tabindex="0"` on the code display let the browser's native click-to-focus behavior steal focus away from the hidden textarea before our own focus() call ran -- typing silently did nothing. Fixed by removing the tabindex and switching to a mousedown+preventDefault handler instead of click. 2. The help modal's CSS set `display: flex` unconditionally, which (author CSS always beats the UA stylesheet) overrode the `hidden` attribute's default `display: none` -- the modal was invisibly covering the entire viewport and intercepting every click, at all times, whether or not it had been opened. Fixed with an explicit `.modal-overlay:not([hidden])` rule. Also verified the actual Docker image builds and serves correctly (nginx, no build stage needed since there's nothing to compile). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 14:12:44 +02:00
<li><strong>WPM</strong> = (correct characters / 5) / minutes elapsed — the standard typing-test formula.</li>
<li><strong>Accuracy</strong> = correct keystrokes / total keystrokes, including ones you backspaced over.</li>
<li>Mistakes are highlighted in place. You can backspace to fix them or keep going — either way, they count against accuracy.</li>
<li>Tabs in the original source are shown as two spaces, so you never need to press Tab.</li>
</ul>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>