diff --git a/learn/typing-game/index.html b/learn/typing-game/index.html
new file mode 100644
index 00000000..c55f5c57
--- /dev/null
+++ b/learn/typing-game/index.html
@@ -0,0 +1,17 @@
+
+
+ Typing game
+
+
+
+
Typing game!
+
Practive you typing skills with a quote from Sherlock Holmes. Click **start** to begin!
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/learn/typing-game/script.js b/learn/typing-game/script.js
new file mode 100644
index 00000000..35faf563
--- /dev/null
+++ b/learn/typing-game/script.js
@@ -0,0 +1,92 @@
+// all of our quotes
+const quotes = [
+ 'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
+ 'There is nothing more deceptive than an obvious fact.',
+ 'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
+ 'I never make exceptions. An exception disproves the rule.',
+ 'What one man can invent another can discover.',
+ 'Nothing clears up a case so much as stating it to another person.',
+ 'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
+];
+// store the list of words and the index of the word the player is currently typing
+let words = [];
+let wordIndex = 0;
+// the starting time
+let startTime = Date.now();
+// page elements
+const quoteElement = document.getElementById('quote');
+const messageElement = document.getElementById('message');
+const typedValueElement = document.getElementById('typed-value');
+
+function quoteCompleted() {
+ typedValueElement.value = '';
+ typedValueElement.removeEventListener('input', typedValueEventHandler);
+ typedValueElement.disabled = true;
+ alert('Finished!')
+}
+
+function typedValueEventHandler(event) {
+ //get the current word
+ const currentWord = words[wordIndex];
+ // get the current value
+ const typedValue = typedValueElement.value;
+
+ if (typedValue === currentWord && wordIndex === words.length - 1) {
+ // end of sentense
+ // display success
+ const elapsedTime = new Date().getTime() - startTime;
+ const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
+ messageElement.innerText = message;
+ quoteCompleted();
+ } else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {
+ // end of word
+ // clear the typedValueElement for the new word
+ typedValueElement.value = '';
+ // move to the next word
+ wordIndex++;
+ // reset the class name for all elements in quote
+ for (const wordElement of quoteElement.childNodes) {
+ wordElement.className = '';
+ }
+ // highlight the new word
+ quoteElement.childNodes[wordIndex].className = 'highlight';
+ } else if (currentWord.startsWith(typedValue)) {
+ // currently correct
+ // highlight the next word
+ typedValueElement.className = '';
+ } else {
+ // error state
+ typedValueElement.className = 'error';
+ }
+}
+
+document.getElementById('start').addEventListener('click', () => {
+ // get a quote
+ const quoteIndex = Math.floor(Math.random() * quotes.length);
+ const quote = quotes[quoteIndex];
+ // put the quote into an array of words
+ words = quote.split(' ');
+ // reset the word index for tracking
+ wordIndex = 0;
+
+ // UI updates
+ // Create an array of span elements so we can set a class
+ const spanWords = words.map(function(word) { return `${word} `});
+ // convert into string and set as innerHTML on quote display
+ quoteElement.innerHTML = spanWords.join('');
+ // hilight the first word
+ quoteElement.childNodes[0].className = 'highlight';
+ // clear any prior messages
+ messageElement.innerText = '';
+
+ // setup the textbox
+ // clear the textbox
+ typedValueElement.value = '';
+ // set focus
+ typedValueElement.focus();
+ //set the event handler
+ typedValueElement.addEventListener('input', typedValueEventHandler);
+ typedValueElement.disabled = false;
+ // start the timer
+ startTime = new Date().getTime();
+});
\ No newline at end of file
diff --git a/learn/typing-game/style.css b/learn/typing-game/style.css
new file mode 100644
index 00000000..36f8c06f
--- /dev/null
+++ b/learn/typing-game/style.css
@@ -0,0 +1,8 @@
+.highlight {
+ background-color: yellow;
+}
+
+.error {
+ background-color: lightcoral;
+ border: red;
+}
\ No newline at end of file