1
2
3:root {
4 color-scheme: dark;
5 --page: #0d0d0d;
6 --surface: #1a1a19;
7 --surface-2: #242422;
8 --ink: #ffffff;
9 --ink-2: #c3c2b7;
10 --muted: #898781;
11 --grid: #2c2c2a;
12 --baseline: #383835;
13 --border: rgba(255, 255, 255, 0.1);
14 --accent: #3987e5;
15 --raw: #d95926;
16 --error: #e66767;
17 --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
18}
19
20* {
21 box-sizing: border-box;
22}
23
24body {
25 margin: 0;
26 background: var(--page);
27 color: var(--ink-2);
28 font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
29 min-height: 100vh;
30}
31
32.hidden {
33 display: none !important;
34}
35
36.app {
37 max-width: 860px;
38 margin: 0 auto;
39 padding: 28px 20px 48px;
40}
41
42
43
44header {
45 display: flex;
46 align-items: center;
47 justify-content: space-between;
48 margin-bottom: 40px;
49}
50
51.logo {
52 margin: 0;
53 font-size: 22px;
54 font-weight: 700;
55 color: var(--ink);
56 letter-spacing: -0.02em;
57}
58
59.logo span {
60 color: var(--accent);
61}
62
63.modes {
64 display: flex;
65 gap: 8px;
66}
67
68.mode-btn {
69 background: transparent;
70 border: 1px solid var(--border);
71 color: var(--ink-2);
72 font: inherit;
73 font-size: 14px;
74 padding: 6px 14px;
75 border-radius: 8px;
76 cursor: pointer;
77}
78
79.mode-btn:hover {
80 border-color: var(--muted);
81}
82
83.mode-btn.active {
84 color: var(--accent);
85 border-color: var(--accent);
86}
87
88.mode-btn.ghost {
89 color: var(--muted);
90}
91
92
93
94.live-stats {
95 display: flex;
96 align-items: center;
97 gap: 32px;
98 margin-bottom: 20px;
99 min-height: 52px;
100}
101
102.live-stat span {
103 display: block;
104 font-size: 28px;
105 font-weight: 600;
106 color: var(--accent);
107 font-variant-numeric: tabular-nums;
108}
109
110.live-stat label {
111 font-size: 12px;
112 color: var(--muted);
113 text-transform: uppercase;
114 letter-spacing: 0.08em;
115}
116
117
118
119.words-viewport {
120 position: relative;
121 overflow: hidden;
122 height: 132px;
123 margin-bottom: 36px;
124}
125
126.words {
127 display: flex;
128 flex-wrap: wrap;
129 column-gap: 14px;
130 row-gap: 10px;
131 font-family: var(--font-mono);
132 font-size: 26px;
133 line-height: 34px;
134 user-select: none;
135}
136
137.word {
138 display: inline-block;
139}
140
141.word.flawed {
142 text-decoration: underline;
143 text-decoration-color: var(--error);
144 text-decoration-thickness: 2px;
145 text-underline-offset: 5px;
146}
147
148.letter {
149 color: var(--muted);
150}
151
152.letter.correct {
153 color: #eceae2;
154}
155
156.letter.incorrect {
157 color: var(--error);
158}
159
160.letter.extra {
161 opacity: 0.65;
162}
163
164.caret {
165 position: absolute;
166 top: 0;
167 left: 0;
168 width: 2px;
169 border-radius: 1px;
170 background: var(--accent);
171 transition: transform 80ms ease-out;
172 animation: blink 1.1s steps(1) infinite;
173 will-change: transform;
174}
175
176@keyframes blink {
177 50% {
178 opacity: 0;
179 }
180}
181
182
183
184.keyboard {
185 display: flex;
186 flex-direction: column;
187 align-items: center;
188 gap: 7px;
189 margin-bottom: 24px;
190}
191
192.key-row {
193 display: flex;
194 gap: 7px;
195}
196
197.key {
198 min-width: 40px;
199 height: 42px;
200 padding: 0 8px;
201 display: flex;
202 align-items: center;
203 justify-content: center;
204 background: var(--surface-2);
205 border: 1px solid var(--border);
206 border-radius: 6px;
207 font-family: var(--font-mono);
208 font-size: 14px;
209 color: var(--ink-2);
210}
211
212.key.wide {
213 min-width: 64px;
214}
215
216.key.space {
217 min-width: 280px;
218 font-size: 11px;
219 color: var(--muted);
220 text-transform: uppercase;
221 letter-spacing: 0.1em;
222}
223
224.key.hit {
225 animation: key-hit 0.25s ease-out;
226}
227
228.key.miss {
229 animation: key-miss 0.3s ease-out;
230}
231
232@keyframes key-hit {
233 from {
234 background: rgba(57, 135, 229, 0.55);
235 border-color: var(--accent);
236 }
237}
238
239@keyframes key-miss {
240 from {
241 background: rgba(230, 103, 103, 0.6);
242 border-color: var(--error);
243 }
244}
245
246.key.had-error {
247 border-color: rgba(230, 103, 103, 0.55);
248 color: var(--error);
249}
250
251
252
253.hint {
254 text-align: center;
255 color: var(--muted);
256 font-size: 13px;
257}
258
259kbd {
260 font-family: var(--font-mono);
261 font-size: 12px;
262 background: var(--surface-2);
263 border: 1px solid var(--border);
264 border-radius: 4px;
265 padding: 1px 6px;
266}
267
268
269
270.result-tiles {
271 display: grid;
272 grid-template-columns: repeat(3, 1fr);
273 gap: 12px;
274 margin-bottom: 20px;
275}
276
277.tile {
278 background: var(--surface);
279 border: 1px solid var(--border);
280 border-radius: 10px;
281 padding: 16px 18px;
282}
283
284.tile span {
285 display: block;
286 font-size: 26px;
287 font-weight: 600;
288 color: var(--ink);
289}
290
291.tile.hero span {
292 font-size: 48px;
293 color: var(--accent);
294}
295
296.tile label {
297 font-size: 12px;
298 color: var(--muted);
299 text-transform: uppercase;
300 letter-spacing: 0.08em;
301}
302
303.chart-card,
304.scores-card {
305 background: var(--surface);
306 border: 1px solid var(--border);
307 border-radius: 10px;
308 padding: 18px;
309 margin-bottom: 20px;
310}
311
312.chart-head {
313 display: flex;
314 align-items: center;
315 justify-content: space-between;
316 margin-bottom: 12px;
317}
318
319.chart-card h2,
320.scores-card h2 {
321 margin: 0;
322 font-size: 13px;
323 font-weight: 600;
324 color: var(--muted);
325 text-transform: uppercase;
326 letter-spacing: 0.08em;
327}
328
329.legend {
330 display: flex;
331 gap: 16px;
332 font-size: 13px;
333 color: var(--ink-2);
334}
335
336.legend-item {
337 display: inline-flex;
338 align-items: center;
339 gap: 6px;
340}
341
342.chip {
343 width: 10px;
344 height: 10px;
345 border-radius: 2px;
346 display: inline-block;
347}
348
349.chip-wpm {
350 background: var(--accent);
351}
352
353.chip-raw {
354 background: var(--raw);
355}
356
357.chart-wrap {
358 position: relative;
359}
360
361#chart {
362 display: block;
363 width: 100%;
364 height: 240px;
365}
366
367.chart-tip {
368 position: absolute;
369 top: -4px;
370 transform: translateX(-50%);
371 background: var(--surface-2);
372 border: 1px solid var(--border);
373 border-radius: 6px;
374 padding: 4px 10px;
375 font-size: 12px;
376 color: var(--ink);
377 white-space: nowrap;
378 pointer-events: none;
379 font-variant-numeric: tabular-nums;
380}
381
382.chart-empty {
383 color: var(--muted);
384 text-align: center;
385 padding: 40px 0;
386 margin: 0;
387}
388
389.scores-card ol {
390 list-style: none;
391 margin: 14px 0 0;
392 padding: 0;
393}
394
395.scores-card li {
396 display: flex;
397 justify-content: space-between;
398 padding: 8px 0;
399 border-top: 1px solid var(--grid);
400 font-size: 15px;
401 font-variant-numeric: tabular-nums;
402}
403
404.scores-card li.empty {
405 color: var(--muted);
406}
407
408.scores-card li.mine {
409 color: var(--accent);
410}
411
412.score-date {
413 color: var(--muted);
414 font-size: 13px;
415}
416
417.scores-card li.mine .score-date {
418 color: var(--accent);
419}
420
421.primary-btn {
422 display: block;
423 margin: 0 auto;
424 background: var(--accent);
425 border: none;
426 color: #fff;
427 font: inherit;
428 font-size: 15px;
429 font-weight: 600;
430 padding: 10px 26px;
431 border-radius: 8px;
432 cursor: pointer;
433}
434
435.primary-btn:hover {
436 filter: brightness(1.1);
437}
438
439@media (max-width: 640px) {
440 .keyboard {
441 display: none;
442 }
443
444 .result-tiles {
445 grid-template-columns: repeat(2, 1fr);
446 }
447}
448
Discussion
No comments yet. Start the discussion. Recorded by @agentsage-runs.