diff --git a/01 - JavaScript Drum Kit/index-START.html b/01 - JavaScript Drum Kit/index-START.html
deleted file mode 100644
index 4070d32767..0000000000
--- a/01 - JavaScript Drum Kit/index-START.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
- JS Drum Kit
-
-
-
-
-
-
-
- A
- clap
-
-
- S
- hihat
-
-
- D
- kick
-
-
- F
- openhat
-
-
- G
- boom
-
-
- H
- ride
-
-
- J
- snare
-
-
- K
- tom
-
-
- L
- tink
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/01 - JavaScript Drum Kit/index.html b/01 - JavaScript Drum Kit/index.html
deleted file mode 100644
index a18f2bc2ca..0000000000
--- a/01 - JavaScript Drum Kit/index.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
- JS Drum Kit
-
-
-
-
-
-
-
- A
- clap
-
-
- S
- hihat
-
-
- D
- kick
-
-
- F
- openhat
-
-
- G
- boom
-
-
- H
- ride
-
-
- J
- snare
-
-
- K
- tom
-
-
- L
- tink
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/01 - JavaScript Drum Kit/style.css b/01 - JavaScript Drum Kit/style.css
deleted file mode 100644
index 3e0a320b37..0000000000
--- a/01 - JavaScript Drum Kit/style.css
+++ /dev/null
@@ -1,50 +0,0 @@
-html {
- font-size: 10px;
- background:url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
- background-size: cover;
-}
-body,html {
- margin: 0;
- padding: 0;
- font-family: sans-serif;
-}
-
-.keys {
- display:flex;
- flex:1;
- min-height:100vh;
- align-items: center;
- justify-content: center;
-}
-
-.key {
- border:4px solid black;
- border-radius:5px;
- margin:1rem;
- font-size: 1.5rem;
- padding:1rem .5rem;
- transition:all .07s;
- width:100px;
- text-align: center;
- color:white;
- background:rgba(0,0,0,0.4);
- text-shadow:0 0 5px black;
-}
-
-.playing {
- transform:scale(1.1);
- border-color:#ffc600;
- box-shadow: 0 0 10px #ffc600;
-}
-
-kbd {
- display: block;
- font-size: 40px;
-}
-
-.sound {
- font-size: 1.2rem;
- text-transform: uppercase;
- letter-spacing: 1px;
- color:#ffc600;
-}
diff --git a/03 - CSS Variables/index-START.html b/03 - CSS Variables/index-START.html
deleted file mode 100644
index bf0f33e3ba..0000000000
--- a/03 - CSS Variables/index-START.html
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
- Scoped CSS Variables and JS
-
-
- Update CSS Variables with JS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/06 - Type Ahead/index-START.html b/06 - Type Ahead/index-START.html
deleted file mode 100644
index 1436886918..0000000000
--- a/06 - Type Ahead/index-START.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- Type Ahead 👀
-
-
-
-
-
-
-
-
diff --git a/06 - Type Ahead/style.css b/06 - Type Ahead/style.css
deleted file mode 100644
index 155164bae9..0000000000
--- a/06 - Type Ahead/style.css
+++ /dev/null
@@ -1,88 +0,0 @@
- html {
- box-sizing: border-box;
- background:#ffc600;
- font-family:'helvetica neue';
- font-size: 20px;
- font-weight: 200;
- }
- *, *:before, *:after {
- box-sizing: inherit;
- }
- input {
- width: 100%;
- padding:20px;
- }
-
- .search-form {
- max-width:400px;
- margin:50px auto;
- }
-
- input.search {
- margin: 0;
- text-align: center;
- outline:0;
- border:0;
- border: 10px solid #F7F7F7;
- width: 120%;
- left: -10%;
- position: relative;
- top: 10px;
- z-index: 2;
- border-radius: 5px;
- font-size: 40px;
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
- }
-
-
- .suggestions {
- margin: 0;
- padding: 0;
- position: relative;
- /*perspective:20px;*/
- }
- .suggestions li {
- background:white;
- list-style: none;
- border-bottom: 1px solid #D8D8D8;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);
- margin:0;
- padding:20px;
- transition:background 0.2s;
- display:flex;
- justify-content:space-between;
- text-transform: capitalize;
- }
-
- .suggestions li:nth-child(even) {
- transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);
- background: linear-gradient(to bottom, #ffffff 0%,#EFEFEF 100%);
- }
- .suggestions li:nth-child(odd) {
- transform: perspective(100px) rotateX(-3deg) translateY(3px);
- background: linear-gradient(to top, #ffffff 0%,#EFEFEF 100%);
- }
-
- span.population {
- font-size: 15px;
- }
-
-
- .details {
- text-align: center;
- font-size: 15px;
- }
-
- .hl {
- background:#ffc600;
- }
-
- .love {
- text-align: center;
- }
-
- a {
- color:black;
- background:rgba(0,0,0,0.1);
- text-decoration: none;
- }
diff --git a/08 - Fun with HTML5 Canvas/index-START.html b/08 - Fun with HTML5 Canvas/index-START.html
deleted file mode 100644
index 37c148df07..0000000000
--- a/08 - Fun with HTML5 Canvas/index-START.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- HTML5 Canvas
-
-
-
-
-
-
-
-
-
diff --git a/10 - Hold Shift and Check Checkboxes/index-START.html b/10 - Hold Shift and Check Checkboxes/index-START.html
deleted file mode 100644
index eb7ed310bb..0000000000
--- a/10 - Hold Shift and Check Checkboxes/index-START.html
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
- Document
-
-
-
-
-
-
-
-
This is an inbox layout.
-
-
-
-
-
Hold down your Shift key
-
-
-
-
-
Everything inbetween should also be set to checked
-
-
-
-
Try do it with out any libraries
-
-
-
-
Just regular JavaScript
-
-
-
-
-
Don't forget to tweet your result!
-
-
-
-
-
-
diff --git a/readme.md b/README.md
similarity index 74%
rename from readme.md
rename to README.md
index 873f3242f4..0ac3d055aa 100644
--- a/readme.md
+++ b/README.md
@@ -2,6 +2,11 @@
# JavaScript30
+```sh
+npm start
+# open http://localhost:3000/ OR http://localhost:3001/
+```
+
Starter Files + Completed solutions for the JavaScript 30 Day Challenge.
Grab the course at [https://JavaScript30.com](https://JavaScript30.com)
diff --git a/bs-config.js b/bs-config.js
new file mode 100644
index 0000000000..2a3f9c415e
--- /dev/null
+++ b/bs-config.js
@@ -0,0 +1,104 @@
+
+/*
+ |--------------------------------------------------------------------------
+ | Browser-sync config file
+ |--------------------------------------------------------------------------
+ |
+ | For up-to-date information about the options:
+ | http://www.browsersync.io/docs/options/
+ |
+ | There are more options than you see here, these are just the ones that are
+ | set internally. See the website for more info.
+ |
+ |
+ */
+module.exports = {
+ 'ui': {
+ 'port': 3001,
+ 'weinre': {
+ 'port': 8080
+ }
+ },
+ 'files': ['src/**/*.js', 'src/**/*.html', 'src/**/*.css'],
+ 'watchOptions': {},
+ server: {
+ baseDir: 'src',
+ directory: true
+ },
+ 'proxy': false,
+ 'port': 3000,
+ 'middleware': false,
+ 'serveStatic': [],
+ 'ghostMode': {
+ 'clicks': true,
+ 'scroll': true,
+ 'forms': {
+ 'submit': true,
+ 'inputs': true,
+ 'toggles': true
+ }
+ },
+ 'logLevel': 'info',
+ 'logPrefix': 'BS',
+ 'logConnections': false,
+ 'logFileChanges': true,
+ 'logSnippet': true,
+ 'rewriteRules': [],
+ 'open': false,
+ 'browser': 'default',
+ 'cors': false,
+ 'xip': false,
+ 'hostnameSuffix': false,
+ 'reloadOnRestart': false,
+ 'notify': true,
+ 'scrollProportionally': true,
+ 'scrollThrottle': 0,
+ 'scrollRestoreTechnique': 'window.name',
+ 'scrollElements': [],
+ 'scrollElementMapping': [],
+ 'reloadDelay': 0,
+ 'reloadDebounce': 0,
+ 'reloadThrottle': 0,
+ 'plugins': [],
+ 'injectChanges': true,
+ 'startPath': null,
+ 'minify': true,
+ 'host': null,
+ 'localOnly': false,
+ 'codeSync': true,
+ 'timestamps': true,
+ 'clientEvents': [
+ 'scroll',
+ 'scroll:element',
+ 'input:text',
+ 'input:toggles',
+ 'form:submit',
+ 'form:reset',
+ 'click'
+ ],
+ 'socket': {
+ 'socketIoOptions': {
+ 'log': false
+ },
+ 'socketIoClientConfig': {
+ 'reconnectionAttempts': 50
+ },
+ 'path': '/browser-sync/socket.io',
+ 'clientPath': '/browser-sync',
+ 'namespace': '/browser-sync',
+ 'clients': {
+ 'heartbeatTimeout': 5000
+ }
+ },
+ 'tagNames': {
+ 'less': 'link',
+ 'scss': 'link',
+ 'css': 'link',
+ 'jpg': 'img',
+ 'jpeg': 'img',
+ 'png': 'img',
+ 'svg': 'img',
+ 'gif': 'img',
+ 'js': 'script'
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000..5db079e5e8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "JavaScript30",
+ "version": "1.0.0",
+ "main": "index.js",
+ "repository": "https://github.com/saitodisse/JavaScript30.git",
+ "author": "Julio Makdisse Saito ",
+ "license": "MIT",
+ "scripts": {
+ "start": "browser-sync start --config bs-config.js"
+ },
+ "devDependencies": {
+ "browser-sync": "^2.18.2",
+ "eslint": "^3.12.0",
+ "eslint-config-standard": "^6.2.1",
+ "eslint-config-standard-jsx": "^3.2.0",
+ "eslint-plugin-promise": "^3.4.0",
+ "eslint-plugin-react": "^6.8.0",
+ "eslint-plugin-standard": "^2.0.1"
+ }
+}
diff --git a/01 - JavaScript Drum Kit/index-FINISHED.html b/src/01 - JavaScript Drum Kit/index-FINISHED.html
similarity index 100%
rename from 01 - JavaScript Drum Kit/index-FINISHED.html
rename to src/01 - JavaScript Drum Kit/index-FINISHED.html
diff --git a/src/01 - JavaScript Drum Kit/index-START.html b/src/01 - JavaScript Drum Kit/index-START.html
new file mode 100644
index 0000000000..fd090e9a95
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/index-START.html
@@ -0,0 +1,53 @@
+
+
+
+
+ JS Drum Kit
+
+
+
+
+
+
+
+ A
+ clap
+
+
+ S
+ hihat
+
+
+ D
+ kick
+
+
+ F
+ openhat
+
+
+ G
+ boom
+
+
+ H
+ ride
+
+
+ J
+ snare
+
+
+ K
+ tom
+
+
+ L
+ tink
+
+
+
+
+
+
+
diff --git a/src/01 - JavaScript Drum Kit/index.html b/src/01 - JavaScript Drum Kit/index.html
new file mode 100644
index 0000000000..9d0f030f1d
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/index.html
@@ -0,0 +1,68 @@
+
+
+
+
+ JS Drum Kit
+
+
+
+
+
+
+
+ A
+ clap
+
+
+ S
+ hihat
+
+
+ D
+ kick
+
+
+ F
+ openhat
+
+
+ G
+ boom
+
+
+ H
+ ride
+
+
+ J
+ snare
+
+
+ K
+ tom
+
+
+ L
+ tink
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/01 - JavaScript Drum Kit/scripts.js b/src/01 - JavaScript Drum Kit/scripts.js
new file mode 100644
index 0000000000..08933376f0
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/scripts.js
@@ -0,0 +1,24 @@
+/* global Audio */
+function removeTransition (e) {
+ if (e.propertyName !== 'transform') return
+ e.target.classList.remove('playing')
+}
+
+function handlekey (e) {
+ playSoundByKey(e.keyCode)
+}
+
+function playSoundByKey (keyCode) {
+ const keyElement = document.querySelector(`div[data-key="${keyCode}"]`)
+ if (!keyElement) {
+ return
+ }
+ keyElement.classList.add('playing')
+ const audioPath = keyElement.getAttribute('data-audioPath')
+ const audio = new Audio(audioPath)
+ audio.play()
+}
+
+const keys = Array.from(document.querySelectorAll('.key'))
+keys.forEach(key => key.addEventListener('transitionend', removeTransition))
+window.addEventListener('keydown', handlekey)
diff --git a/src/01 - JavaScript Drum Kit/sequence-01.html b/src/01 - JavaScript Drum Kit/sequence-01.html
new file mode 100644
index 0000000000..20becf373f
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-01.html
@@ -0,0 +1,20 @@
+
+
+
+
+ JS Drum Kit
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/01 - JavaScript Drum Kit/sequence-01.js b/src/01 - JavaScript Drum Kit/sequence-01.js
new file mode 100644
index 0000000000..730493dcbc
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-01.js
@@ -0,0 +1,49 @@
+/* global Audio, requestAnimationFrame */
+
+const initialTime = (new Date()).getTime()
+let lastTime
+let timeDiff = 0
+const fps = 60
+
+let seqIndex = 0
+let currentStatePlaying = false
+
+const HIHAT = new Audio('sounds/hihat.wav')
+const KICK = new Audio('sounds/kick.wav')
+
+function startOrStop (e) {
+ if (e.keyCode === 13) {
+ currentStatePlaying = !currentStatePlaying
+ }
+ draw()
+}
+
+function draw () {
+ const sequence = [
+ [KICK, HIHAT],
+ [HIHAT],
+ [HIHAT],
+ [KICK, HIHAT]
+ ]
+
+ setTimeout(function () {
+ if (currentStatePlaying) {
+ requestAnimationFrame(draw)
+ }
+
+ const now = (new Date()).getTime()
+
+ if (lastTime) {
+ timeDiff = (now - initialTime) % 300
+ if (timeDiff < 20) {
+ sequence[seqIndex % sequence.length].forEach((audio) => {
+ audio.play()
+ })
+ seqIndex++
+ }
+ }
+ lastTime = now
+ }, 1000 / fps)
+}
+
+window.addEventListener('keydown', startOrStop)
diff --git a/src/01 - JavaScript Drum Kit/sequence-02.html b/src/01 - JavaScript Drum Kit/sequence-02.html
new file mode 100644
index 0000000000..f02895845a
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-02.html
@@ -0,0 +1,14 @@
+
+
+
+
+ JS Drum Kit
+
+
+
+
+
Sequence
+
+
+
+
diff --git a/src/01 - JavaScript Drum Kit/sequence-02.js b/src/01 - JavaScript Drum Kit/sequence-02.js
new file mode 100644
index 0000000000..ac333d61e0
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-02.js
@@ -0,0 +1,93 @@
+/* global AudioContext, XMLHttpRequest, requestAnimationFrame */
+
+function start () {
+ window.AudioContext = window.AudioContext || window.webkitAudioContext
+ const context = new AudioContext()
+
+ function loadAudio (url) {
+ return new Promise((resolve, reject) => {
+ const request = new XMLHttpRequest()
+ request.open('GET', url, true)
+ request.responseType = 'arraybuffer'
+
+ // Decode asynchronously
+ request.onload = function () {
+ context.decodeAudioData(request.response, function (buffer) {
+ resolve(buffer)
+ }, reject)
+ }
+ request.send()
+ })
+ }
+
+ function playSound (buffer) {
+ const source = context.createBufferSource() // creates a sound source
+ source.buffer = buffer // tell the source which sound to play
+ source.connect(context.destination) // connect the source to the context's destination (the speakers)
+ source.start(0) // play the source now
+ // note: on older systems, may have to use deprecated noteOn(time);
+ }
+
+ let hithatBuffer
+ let kickBuffer
+ let tinkBuffer
+
+ loadAudio('sounds/hihat.wav').then((buffer) => {
+ hithatBuffer = buffer
+ })
+ .then(() => {
+ return loadAudio('sounds/kick.wav').then((buffer) => {
+ kickBuffer = buffer
+ })
+ })
+ .then(() => {
+ return loadAudio('sounds/tink.wav').then((buffer) => {
+ tinkBuffer = buffer
+ })
+ })
+ .then(() => {
+ const beatsPerSecond = 5
+ let seqIndex = 0
+
+ function draw () {
+ setTimeout(() => {
+ requestAnimationFrame(draw)
+
+ if (seqIndex % 8 === 0) {
+ playSound(hithatBuffer)
+ playSound(kickBuffer)
+ }
+ if (seqIndex % 8 === 1) {
+ playSound(hithatBuffer)
+ }
+ if (seqIndex % 8 === 2) {
+ playSound(hithatBuffer)
+ playSound(tinkBuffer)
+ }
+ if (seqIndex % 8 === 3) {
+ playSound(hithatBuffer)
+ playSound(kickBuffer)
+ }
+ if (seqIndex % 8 === 4) {
+ playSound(hithatBuffer)
+ playSound(kickBuffer)
+ }
+ if (seqIndex % 8 === 5) {
+ playSound(hithatBuffer)
+ playSound(tinkBuffer)
+ }
+ if (seqIndex % 8 === 6) {
+ playSound(hithatBuffer)
+ }
+ if (seqIndex % 8 === 7) {
+ playSound(hithatBuffer)
+ playSound(kickBuffer)
+ }
+ seqIndex++
+ }, 1000 / beatsPerSecond)
+ }
+ draw()
+ })
+}
+
+window.onload = start
diff --git a/src/01 - JavaScript Drum Kit/sequence-03.html b/src/01 - JavaScript Drum Kit/sequence-03.html
new file mode 100644
index 0000000000..089b2bf26d
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-03.html
@@ -0,0 +1,14 @@
+
+
+
+
+ JS Drum Kit
+
+
+
+
+
Sequence
+
+
+
+
diff --git a/src/01 - JavaScript Drum Kit/sequence-03.js b/src/01 - JavaScript Drum Kit/sequence-03.js
new file mode 100644
index 0000000000..c9f3018241
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/sequence-03.js
@@ -0,0 +1,72 @@
+/* global AudioContext, XMLHttpRequest */
+
+function start () {
+ window.AudioContext = window.AudioContext || window.webkitAudioContext
+ const context = new AudioContext()
+
+ function loadAudio (url) {
+ return new Promise((resolve, reject) => {
+ const request = new XMLHttpRequest()
+ request.open('GET', url, true)
+ request.responseType = 'arraybuffer'
+
+ // Decode asynchronously
+ request.onload = function () {
+ context.decodeAudioData(request.response, function (buffer) {
+ resolve(buffer)
+ }, reject)
+ }
+ request.send()
+ })
+ }
+
+ function playSound (buffer, time) {
+ const source = context.createBufferSource()
+ source.buffer = buffer
+ source.connect(context.destination)
+ if (!source.start) {
+ source.start = source.noteOn
+ }
+ source.start(time)
+ }
+
+ let hithatBuffer
+ let kickBuffer
+ let snareBuffer
+
+ function load () {
+ return Promise.all([
+ loadAudio('sounds/hihat.wav').then((buffer) => { hithatBuffer = buffer }),
+ loadAudio('sounds/kick.wav').then((buffer) => { kickBuffer = buffer }),
+ loadAudio('sounds/snare.wav').then((buffer) => { snareBuffer = buffer })
+ ])
+ }
+
+ let play = () => {
+ // We'll start playing the rhythm 100 milliseconds from "now"
+ const startTime = context.currentTime
+ const tempo = 120 // BPM (beats per minute)
+ const eighthNoteTime = (60 / tempo) / 2
+
+ // Play 2 bars of the following:
+ for (let bar = 0; bar < 2; bar++) {
+ const time = startTime + bar * 8 * eighthNoteTime
+ // Play the bass (kick) drum on beats 1, 5
+ playSound(kickBuffer, time)
+ playSound(kickBuffer, time + 4 * eighthNoteTime)
+
+ // Play the snare drum on beats 3, 7
+ playSound(snareBuffer, time + 2 * eighthNoteTime)
+ playSound(snareBuffer, time + 6 * eighthNoteTime)
+
+ // Play the hi-hat every eighthh note.
+ for (let i = 0; i < 8; ++i) {
+ playSound(hithatBuffer, time + i * eighthNoteTime)
+ }
+ }
+ }
+
+ load().then(play)
+}
+
+window.onload = start
diff --git a/01 - JavaScript Drum Kit/sounds/boom.wav b/src/01 - JavaScript Drum Kit/sounds/boom.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/boom.wav
rename to src/01 - JavaScript Drum Kit/sounds/boom.wav
diff --git a/01 - JavaScript Drum Kit/sounds/clap.wav b/src/01 - JavaScript Drum Kit/sounds/clap.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/clap.wav
rename to src/01 - JavaScript Drum Kit/sounds/clap.wav
diff --git a/01 - JavaScript Drum Kit/sounds/hihat.wav b/src/01 - JavaScript Drum Kit/sounds/hihat.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/hihat.wav
rename to src/01 - JavaScript Drum Kit/sounds/hihat.wav
diff --git a/01 - JavaScript Drum Kit/sounds/kick.wav b/src/01 - JavaScript Drum Kit/sounds/kick.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/kick.wav
rename to src/01 - JavaScript Drum Kit/sounds/kick.wav
diff --git a/01 - JavaScript Drum Kit/sounds/openhat.wav b/src/01 - JavaScript Drum Kit/sounds/openhat.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/openhat.wav
rename to src/01 - JavaScript Drum Kit/sounds/openhat.wav
diff --git a/01 - JavaScript Drum Kit/sounds/ride.wav b/src/01 - JavaScript Drum Kit/sounds/ride.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/ride.wav
rename to src/01 - JavaScript Drum Kit/sounds/ride.wav
diff --git a/01 - JavaScript Drum Kit/sounds/snare.wav b/src/01 - JavaScript Drum Kit/sounds/snare.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/snare.wav
rename to src/01 - JavaScript Drum Kit/sounds/snare.wav
diff --git a/01 - JavaScript Drum Kit/sounds/tink.wav b/src/01 - JavaScript Drum Kit/sounds/tink.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/tink.wav
rename to src/01 - JavaScript Drum Kit/sounds/tink.wav
diff --git a/01 - JavaScript Drum Kit/sounds/tom.wav b/src/01 - JavaScript Drum Kit/sounds/tom.wav
similarity index 100%
rename from 01 - JavaScript Drum Kit/sounds/tom.wav
rename to src/01 - JavaScript Drum Kit/sounds/tom.wav
diff --git a/src/01 - JavaScript Drum Kit/style.css b/src/01 - JavaScript Drum Kit/style.css
new file mode 100644
index 0000000000..c19733e7e7
--- /dev/null
+++ b/src/01 - JavaScript Drum Kit/style.css
@@ -0,0 +1,73 @@
+html {
+ font-size: 10px;
+ background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
+ background-size: cover;
+}
+
+body, html {
+ margin: 0;
+ padding: 0;
+ font-family: sans-serif;
+}
+
+.keys {
+ display: flex;
+ flex: 1;
+ min-height: 100vh;
+ align-items: center;
+ justify-content: center;
+}
+
+.key {
+ border: 4px solid black;
+ border-radius: 5px;
+ margin: 1rem;
+ font-size: 1.5rem;
+ padding: 1rem .5rem;
+ transition: all .07s;
+ width: 100px;
+ text-align: center;
+ color: white;
+ background: rgba(0, 0, 0, 0.4);
+ text-shadow: 0 0 5px black;
+}
+
+.playing {
+ transform: scale(1.1);
+ border-color: #ffc600;
+ box-shadow: 0 0 10px #ffc600;
+}
+
+kbd {
+ display: block;
+ font-size: 40px;
+}
+
+.sound {
+ font-size: 1.2rem;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ color: #ffc600;
+}
+
+.titleContainer {
+ display: flex;
+ flex: 1;
+ min-height: 100vh;
+ align-items: center;
+ justify-content: center;
+}
+
+.title {
+ border: 4px solid black;
+ border-radius: 5px;
+ margin: 1rem;
+ font-size: 3.5rem;
+ padding: 1rem .5rem;
+ transition: all .07s;
+ width: 270px;
+ text-align: center;
+ color: white;
+ background: rgba(0, 0, 0, 0.4);
+ text-shadow: 0 0 5px black;
+}
diff --git a/02 - JS + CSS Clock/index-FINISHED.html b/src/02 - JS + CSS Clock/index-FINISHED.html
similarity index 100%
rename from 02 - JS + CSS Clock/index-FINISHED.html
rename to src/02 - JS + CSS Clock/index-FINISHED.html
diff --git a/02 - JS + CSS Clock/index-START.html b/src/02 - JS + CSS Clock/index-START.html
similarity index 57%
rename from 02 - JS + CSS Clock/index-START.html
rename to src/02 - JS + CSS Clock/index-START.html
index 259280d228..e948ba99df 100644
--- a/02 - JS + CSS Clock/index-START.html
+++ b/src/02 - JS + CSS Clock/index-START.html
@@ -3,24 +3,11 @@
Document
-
-
-
-
-
-
-
-
+