<|start_filename|>src/js/main.js<|end_filename|>
'use strict'
$(function () {

  var soundIndex = {
    'Q': 'ThankYou',
    'W': 'Hello',
    'E': 'VeryMuch',
    'R': 'HHH',
    'U': 'Mi',
    'I': 'Fans',
    'O': 'Band',
    'P': 'How',
    'A': 'AreYou',
    'S': 'OK',
    'D': 'And',
    'F': 'VeryHappy',
    'J': 'III',
    'K': 'VeryOK',
    'L': 'Indian',
    ';': 'Oh',
    'SPACE': 'Drummer'
  }

  ion.sound({
    sounds: $.map(soundIndex, function (value, key) {
      return {name: value, preload: true}
    }),
    volume: 0.5,
    path: 'assets/audio/',
    multiplay: true,
    preload: true
  })

  $(document).keydown(function (e) {
    var code = e.keyCode || e.which
    var $key = $('[data-keycode=' + code + ']')
    var key = $key.data('key')
    var lyric = $key.data('lyric')
    $key.addClass('active')

    if (lyric) animateLyrics(lyric)
    if (soundIndex[key]) ion.sound.play(soundIndex[key])
  })

  $(document).keyup(function (e) {
    var code = e.keyCode || e.which
    var $key = $('[data-keycode=' + code + ']')
    $key.removeClass('active')
  })

  function animateLyrics (lyric) {
    $('.animated-lyrics').html('<span class="lyric animated">' + lyric + '</span>')
  }

})


<|start_filename|>src/css/main.css<|end_filename|>
* {
  margin: 0;
  padding: 0;
}

html, body {
  height: 100vh;
  width: 100vw;
	font-size: 100%;
	vertical-align: baseline;
}

body {
  font: normal 1em/1.4em "Helvetica Neue", Helvetica, Arial, sans-serif;
  background-color: #2f343a;
  color: #fff;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: space-around;
  -webkit-font-smoothing: antialiased;
  -webkit-font-smoothing: subpixel-antialiased;
  text-rendering: optimizeLegibility;
}

.animated-lyrics {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex: 1;

  .lyric {
    opacity: 0;
    font-size: 54px;
    color: #ef7126;
  }
  .animated {
    animation: fadeInOut 1s;
  }
}

.keyboard-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 2;
}

.keyboard {
  user-select: none;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-tap-highlight-color: transparent;
  width: 630px;

  .row {
    position: relative;
    margin: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    &:nth-child(1) .key, &:nth-child(2) .key, .space {
      &.active, &:active {
        color: #ef7126;
        border-color: #ef7126;
        box-shadow: 0 0 12px -2px #ef7126;
      }
    }

    &:nth-child(2) {
      transform: translateX(2.5%);
    }

    &:nth-child(3) {
      margin-left: 8.5%;
      margin-right: 14%;

      .key {
        color: #717d8c;
        &:hover {
          color: #a6a6a6;
          border-color: #a6a6a6;
        }
        &.active, &:active{
          color: #a6a6a6;
          border-color: #a6a6a6;
          box-shadow: 0 0 9px -2px #a6a6a6;
        }
      }
    }

    .key, .space {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      color: #ccc;
      width: 49px;
      height: 49px;
      border: 2px solid #717d8c;
      border-radius: 6px;
      transition: all .08s ease-in-out;

      &:hover {
        color: #ef7126;
        border-color: #ef7126;
      }

      &.active, &:active {
        transform: translateY(1px);
      }

      &:nth-child(5), &:nth-child(6) {
        color: #717d8c;
        &:hover {
          color: #a6a6a6;
          border-color: #a6a6a6;
        }
        &.active, &:active{
          color: #a6a6a6;
          border-color: #a6a6a6;
          box-shadow: 0 0 9px -2px #a6a6a6;
        }
      }

      b, span {
        display: flex;
        align-items: center;
        flex: 2;
      }

      b {
        font-family: "Titillium Web";
      }
      span {
        font-size: 9px;
        flex: 1;
      }
    }

    .space {
      width: 49%;
      margin-left: 27.5%;
    }

  }
}

.footer {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  flex: 1;

  p {
    font-size: 11px;
    color: #ccc;

    a {
      color: #8edc9d;
      text-decoration: none;
    }
  }
}

@keyframes fadeInOut {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translateY(-100%);
  }
}


<|start_filename|>gulpfile.js<|end_filename|>
'use scrict'

var gulp = require('gulp')
var jade = require('gulp-jade')
var postcss = require('gulp-postcss')
var processors = [
  require('postcss-nested'),
  require('autoprefixer-core')()
]
var cssmin = require('gulp-minify-css')
var uglify = require('gulp-uglify')
var watchJS

gulp.task('jade', function () {
  return gulp.src('src/index.jade')
    .pipe(jade())
    .pipe(gulp.dest('dist'))
})

gulp.task('css', function () {
  return gulp.src('src/css/main.css')
    .pipe(postcss(processors))
    .pipe(cssmin())
    .pipe(gulp.dest('dist/css'))
})

gulp.task('js', function () {
  return gulp.src('src/js/main.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'))

})

gulp.task('assets', function () {
  return gulp.src(['assets/**/*'])
    .pipe(gulp.dest('dist/assets'))

})

gulp.task('watch', function () {
  gulp.watch('src/index.jade', ['jade'])
  gulp.watch('src/css/main.css', ['css'])
  gulp.watch('src/js/main.js', ['js'])
})

gulp.task('default', ['jade', 'css', 'js', 'assets'])
