157 lines
13 KiB
HTML
157 lines
13 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
||
<meta name="theme-color" content="#f5f3ec">
|
||
<!--OG-->
|
||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||
<link rel="stylesheet" href="/style.css">
|
||
<script type="module" src="/app.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="shell">
|
||
<header class="masthead">
|
||
<a class="brand" href="/" aria-label="typy home">typy<span class="brand-dot" aria-hidden="true"></span></a>
|
||
<span class="brand-note">a little more in the moment.</span>
|
||
<nav class="top-nav" aria-label="Main">
|
||
<a href="/daily" id="daily-link"><span class="sun" aria-hidden="true">✳</span> the daily</a>
|
||
<button class="icon-button" id="settings-open" aria-label="Typing settings" title="Typing settings">
|
||
<svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M4 7h16M4 17h16"/><circle cx="9" cy="7" r="3" fill="var(--paper)"/><circle cx="15" cy="17" r="3" fill="var(--paper)"/></svg>
|
||
</button>
|
||
<button class="icon-button help-button" id="help-open" aria-label="How to play">?</button>
|
||
</nav>
|
||
</header>
|
||
|
||
<main id="main">
|
||
<section class="toolbar" aria-label="Run options">
|
||
<div class="mode-switch" id="mode-switch" aria-label="Run length">
|
||
<button data-mode="30" aria-pressed="true">30s</button>
|
||
<button data-mode="60" aria-pressed="false">60s</button>
|
||
<button data-mode="50" aria-pressed="false">50 words</button>
|
||
<button data-mode="endless" aria-pressed="false" aria-label="Endless">∞</button>
|
||
<span class="mode-divider" aria-hidden="true"></span>
|
||
<button data-mode="tempo" class="tempo-option" aria-pressed="false"><span class="tempo-icon" aria-hidden="true"><i></i><i></i><i></i></span>tempo</button>
|
||
</div>
|
||
<button class="source-button" id="source-open"><span id="source-label">common words</span><span aria-hidden="true">↗</span></button>
|
||
</section>
|
||
|
||
<section id="load-panel" class="load-panel" hidden aria-live="polite">
|
||
<div class="spinner" id="loading-spinner" aria-hidden="true"></div>
|
||
<p class="eyebrow" id="load-kicker">one moment</p>
|
||
<h1 id="load-title">finding the words…</h1>
|
||
<p id="load-description"></p>
|
||
<div class="button-row" id="load-actions" hidden><button class="button primary" id="load-retry">try again</button><button class="button" id="load-common">use common words</button></div>
|
||
</section>
|
||
|
||
<section id="play-panel" class="play-panel" aria-label="Typing stage">
|
||
<div class="run-strip">
|
||
<div class="run-status"><span class="status-dot" id="status-dot"></span><span id="run-status">a fresh start</span></div>
|
||
<div id="best-score" class="best-score"></div>
|
||
</div>
|
||
<div class="metrics" aria-label="Live score">
|
||
<div><span class="metric-label">pace</span><span class="metric-value" id="live-wpm">0</span><span class="metric-unit">wpm</span></div>
|
||
<div><span class="metric-label">accuracy</span><span class="metric-value" id="live-accuracy">100</span><span class="metric-unit">%</span></div>
|
||
<div class="time-metric"><span class="metric-label" id="time-label">remaining</span><span class="metric-value" id="live-time">30</span><span class="metric-unit" id="time-unit">s</span></div>
|
||
</div>
|
||
<div id="ghost-race" class="ghost-race" hidden aria-live="off"><span>you <b id="race-you">0</b></span><span class="race-separator">/</span><span class="ghost-label">ghost <b id="race-them">0</b></span><span id="race-delta"></span></div>
|
||
<div class="stage" id="stage">
|
||
<span class="word-number" id="word-number" aria-hidden="true">001</span>
|
||
<div class="word-wrap">
|
||
<div class="word-pair" id="word-pair">
|
||
<div class="word" id="word" aria-live="off" aria-label="Word to type"></div>
|
||
<div class="upcoming" id="upcoming" aria-hidden="true"><b id="next-word"></b></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="tempo-track" class="tempo-track" hidden><div class="tempo-rail"><div id="tempo-progress"></div></div><div class="tempo-caption"><span id="tempo-caption">find the beat</span><span id="tempo-lives" aria-label="Three beats remaining"><i></i><i></i><i></i></span></div></div>
|
||
<div class="input-row" id="input-row">
|
||
<input id="typing-input" class="typing-input" type="text" inputmode="text" enterkeyhint="next" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" maxlength="64" aria-label="Type the word shown above" placeholder="tap here to type">
|
||
<p class="run-hint" id="run-hint"><span class="hint-start">type the word to begin</span><span class="hint-separator">·</span><span id="advance-hint"><kbd>space</kbd> next word</span></p>
|
||
<button id="finish-run" class="text-button" hidden>finish run ↵</button>
|
||
</div>
|
||
<section id="replay-controls" class="replay-controls" hidden aria-label="Replay controls">
|
||
<button class="button small" id="replay-play">pause</button>
|
||
<input type="range" id="replay-scrubber" min="0" max="1000" step="10" value="0" aria-label="Replay position">
|
||
<span class="replay-time" id="replay-time">0:00 / 0:30</span>
|
||
<button class="text-button" id="replay-back">back to result ↗</button>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="result-panel" class="result-panel" hidden aria-labelledby="result-title">
|
||
<div class="result-heading"><p class="eyebrow" id="result-kicker">30 seconds, well spent</p><span class="new-best" id="new-best" hidden>personal best ↗</span></div>
|
||
<h1 id="result-title">there’s your rhythm.</h1>
|
||
<div class="result-grid">
|
||
<div class="result-main"><span id="result-wpm">0</span><span>words per minute</span></div>
|
||
<dl class="result-detail">
|
||
<div><dt>accuracy</dt><dd id="result-accuracy">100%</dd></div>
|
||
<div><dt>best clean streak</dt><dd id="result-streak">0 words</dd></div>
|
||
<div><dt>words completed</dt><dd id="result-words">0</dd></div>
|
||
</dl>
|
||
</div>
|
||
<div class="rhythm-chart"><div class="chart-label"><span>your rhythm</span><span>each word, in wpm</span></div><svg id="speed-chart" viewBox="0 0 900 95" role="img" aria-label="Speed for each completed word"></svg></div>
|
||
<div class="slow-words"><span>room to grow</span><div id="slow-words"></div></div>
|
||
<div class="result-actions">
|
||
<button class="button primary" id="again-button">go again <span aria-hidden="true">↵</span></button>
|
||
<button class="button" id="replay-button">replay <span aria-hidden="true">▷</span></button>
|
||
<button class="button" id="share-button">share result <span aria-hidden="true">↗</span></button>
|
||
<button class="text-button" id="race-button">race this →</button>
|
||
</div>
|
||
<div class="result-note" id="result-note"></div>
|
||
<button class="text-button daily-board-button" id="board-open" hidden>today’s board ↗</button>
|
||
</section>
|
||
</main>
|
||
|
||
<footer class="footer"><span>one word. then the next.</span><div><button class="text-button" id="footer-board" hidden>today’s board ↗</button><span id="restart-tip"><kbd>esc</kbd> restart</span><a href="https://teahub.xyz/teahubxyz/time/issues/254" target="_blank" rel="noopener" aria-label="About typy on Teahub">a small experiment ↗</a></div></footer>
|
||
</div>
|
||
|
||
<dialog id="settings-dialog" class="dialog">
|
||
<form method="dialog"><button class="dialog-close" aria-label="Close settings">×</button></form>
|
||
<p class="eyebrow">make yourself comfortable</p><h2>your rhythm, your rules.</h2>
|
||
<label class="setting-row"><span><b>Next word</b><small>Choose what moves you forward.</small></span><select id="advance-setting"><option value="space">press space</option><option value="letter">last letter</option></select></label>
|
||
<label class="setting-row"><span><b>A little look ahead</b><small>Show the upcoming word.</small></span><input class="switch" id="preview-setting" type="checkbox" checked></label>
|
||
<p class="dialog-note">Changes start a fresh run. Your best scores stay on this device.</p>
|
||
<button class="button primary full" id="settings-done">all set</button>
|
||
</dialog>
|
||
|
||
<dialog id="source-dialog" class="dialog wide">
|
||
<form method="dialog"><button class="dialog-close" aria-label="Close text sources">×</button></form>
|
||
<p class="eyebrow">words worth spending time with</p><h2>what’s on your mind?</h2>
|
||
<div class="source-tabs" role="tablist" aria-label="Text source"><button id="tab-topic" role="tab" aria-selected="true" aria-controls="source-topic">a topic</button><button id="tab-paste" role="tab" aria-selected="false" aria-controls="source-paste">your own text</button><button id="tab-common" role="tab" aria-selected="false" aria-controls="source-common">common words</button></div>
|
||
<form id="source-topic" class="source-pane" role="tabpanel" aria-labelledby="tab-topic">
|
||
<label for="topic-input">Turn something you’re curious about into a passage.</label>
|
||
<div class="field-with-button"><input id="topic-input" name="topic" type="text" placeholder="e.g. why leaves change color" maxlength="64" required autocomplete="off"><button class="button primary" type="submit" aria-label="Create topic passage">↗</button></div>
|
||
<div class="topic-chips"><button type="button" data-topic="react-hooks">react hooks</button><button type="button" data-topic="fano-plane">the fano plane</button><button type="button" data-topic="deep-sea">the deep sea</button></div>
|
||
<p class="dialog-note">A short, AI-written passage. The topic becomes the URL, so you can send it to a friend.</p>
|
||
</form>
|
||
<form id="source-paste" class="source-pane" role="tabpanel" aria-labelledby="tab-paste" hidden>
|
||
<label for="paste-input">A paragraph, a poem, something you want to remember.</label><textarea id="paste-input" rows="6" maxlength="18000" placeholder="Your words go here…" required></textarea>
|
||
<div class="paste-footer"><span id="paste-count">up to 300 words</span><button class="button primary" type="submit">use these words ↗</button></div>
|
||
<p class="dialog-note">Pasted text stays on this device until you choose to share a result.</p>
|
||
</form>
|
||
<div id="source-common" class="source-pane" role="tabpanel" aria-labelledby="tab-common" hidden><p>Familiar words, picked by frequency. Nothing to think about except the next one.</p><button class="button primary full" id="common-start">find your flow ↗</button></div>
|
||
</dialog>
|
||
|
||
<dialog id="share-dialog" class="dialog">
|
||
<form method="dialog"><button class="dialog-close" aria-label="Close sharing">×</button></form>
|
||
<p class="eyebrow" id="share-kicker">a good rhythm is worth sharing</p><h2 id="share-title">leave a little ghost.</h2>
|
||
<div id="share-create"><label for="share-name">Your name <span class="optional">(optional)</span></label><input id="share-name" type="text" maxlength="24" placeholder="anonymous" autocomplete="nickname"><p class="dialog-note">The link makes this passage, score, and replay public. Your mistyped characters are never saved.</p><button class="button primary full" id="save-result">create share link ↗</button></div>
|
||
<div id="share-ready" hidden><label for="share-url" id="share-url-label">Your result link</label><div class="field-with-button"><input id="share-url" type="url" readonly><button class="button primary" id="copy-link">copy</button></div><p class="dialog-note" id="share-ready-note">Anyone with this link can watch your replay or race your ghost.</p></div>
|
||
<p class="inline-error" id="share-error" role="alert" hidden></p>
|
||
</dialog>
|
||
|
||
<dialog id="board-dialog" class="dialog wide">
|
||
<form method="dialog"><button class="dialog-close" aria-label="Close daily board">×</button></form>
|
||
<p class="eyebrow" id="board-date">same words. a different rhythm.</p><h2>the daily board.</h2><p class="dialog-note">One passage. Sixty seconds. A fresh start at midnight UTC.</p><div id="board-content" aria-live="polite"></div><button class="text-button" id="board-refresh">refresh ↻</button>
|
||
</dialog>
|
||
|
||
<dialog id="help-dialog" class="dialog">
|
||
<form method="dialog"><button class="dialog-close" aria-label="Close help">×</button></form>
|
||
<p class="eyebrow">less looking. more doing.</p><h2>one word at a time.</h2>
|
||
<div class="help-steps"><p><span>01</span>Type the word in the middle. Your first letter starts the clock.</p><p><span>02</span>Use Backspace to fix a mistake, then Space for the next word. Switch to “last letter” in settings for automatic advances.</p><p><span>03</span>Try tempo: finish each word before the beat. Keep up and it gets faster. Three missed beats end the run.</p></div>
|
||
<p class="dialog-note">WPM counts five correct output characters as one word. Accuracy measures correct key attempts. Your best scores and settings stay on this device.</p><button class="button primary full" id="help-done">let’s type ↗</button>
|
||
</dialog>
|
||
<div id="toast" class="toast" role="status" hidden></div>
|
||
</body>
|
||
</html>
|