瀏覽代碼

Merged core back into main project

NGPixel 8 年之前
父節點
當前提交
1ced194cd2

+ 0 - 1
.eslintrc.json

@@ -26,7 +26,6 @@
     "winston": true,
     "ws": true,
     "Mongoose": true,
-    "CORE_PATH": true,
     "ROOTPATH": true,
     "IS_DEBUG": true,
     "PROCNAME": true

+ 5 - 9
agent.js

@@ -7,17 +7,16 @@
 global.PROCNAME = 'AGENT'
 global.ROOTPATH = __dirname
 global.IS_DEBUG = process.env.NODE_ENV === 'development'
-if (IS_DEBUG) {
-  global.CORE_PATH = ROOTPATH + '/../core/'
-} else {
-  global.CORE_PATH = ROOTPATH + '/node_modules/requarks-core/'
-}
+
+let appconf = require('./libs/config')()
+global.appconfig = appconf.config
+global.appdata = appconf.data
 
 // ----------------------------------------
 // Load Winston
 // ----------------------------------------
 
-global.winston = require(CORE_PATH + 'core-libs/winston')(IS_DEBUG)
+global.winston = require('./libs/logger')(IS_DEBUG)
 
 // ----------------------------------------
 // Load global modules
@@ -25,9 +24,6 @@ global.winston = require(CORE_PATH + 'core-libs/winston')(IS_DEBUG)
 
 winston.info('[AGENT] Background Agent is initializing...')
 
-let appconf = require(CORE_PATH + 'core-libs/config')()
-global.appconfig = appconf.config
-global.appdata = appconf.data
 global.db = require('./libs/db').init()
 global.upl = require('./libs/uploads-agent').init()
 global.git = require('./libs/git').init()

+ 30 - 23
client/scss/app.scss

@@ -1,31 +1,38 @@
+@charset "utf-8";
 
 $primary: 'indigo';
 
-@import 'core-client/scss/core';
-@import 'core-client/scss/components/alert';
-@import 'core-client/scss/components/button';
-@import 'core-client/scss/components/footer';
-@import 'core-client/scss/components/form';
-@import 'core-client/scss/components/grid';
-@import 'core-client/scss/components/hero';
-@import 'core-client/scss/components/markdown-content';
-@import 'core-client/scss/components/modal';
-@import 'core-client/scss/components/nav';
-@import 'core-client/scss/components/panel';
-@import 'core-client/scss/components/search';
-@import 'core-client/scss/components/sidebar';
-@import 'core-client/scss/components/table';
-@import 'core-client/scss/components/typography';
-
-@import './libs/twemoji-awesome';
-@import './libs/jquery-contextmenu';
+@import "base/variables";
+@import "base/colors";
+@import "base/reset";
+@import "base/mixins";
+@import "base/fonts";
+@import "base/base";
+
+@import "libs/animate";
+
+@import 'components/alert';
+@import 'components/button';
+@import 'components/footer';
+@import 'components/form';
+@import 'components/grid';
+@import 'components/hero';
+@import 'components/markdown-content';
+@import 'components/modal';
+@import 'components/nav';
+@import 'components/panel';
+@import 'components/search';
+@import 'components/sidebar';
+@import 'components/table';
+@import 'components/typography';
+
+@import 'libs/twemoji-awesome';
+@import 'libs/jquery-contextmenu';
 @import 'node_modules/highlight.js/styles/tomorrow';
 @import 'node_modules/simplemde/dist/simplemde.min';
 
-@import './components/_editor';
+@import 'components/_editor';
 
-@import './layout/_header';
-//@import './layout/_content';
+@import 'layout/_header';
 
-//@import './pages/_account';
-@import './pages/_welcome';
+@import 'pages/_welcome';

+ 107 - 0
client/scss/base/base.scss

@@ -0,0 +1,107 @@
+html {
+  box-sizing: border-box;
+  font-family: $core-font-standard;
+}
+*, *:before, *:after {
+  box-sizing: inherit;
+}
+
+[v-cloak], .is-hidden {
+  display: none;
+}
+
+body {
+	background-color: mc('blue-grey','100');
+}
+
+main {
+	background-color: #FFF;
+}
+
+a {
+	color: mc('indigo', '600');
+	text-decoration: none;
+
+	&:hover {
+		color: mc('indigo', '700');
+		text-decoration: underline;
+	}
+}
+
+// Container
+
+.has-stickynav {
+	padding-top: 50px;
+}
+
+.container {
+  position: relative;
+
+  @include desktop {
+    margin: 0 auto;
+    max-width: 960px;
+
+    // Modifiers
+    &.is-fluid {
+      margin: 0;
+      max-width: none;
+    }
+  }
+
+
+  @include widescreen {
+    max-width: 1200px;
+  }
+}
+
+.content {
+	padding: 20px;
+}
+
+// Visibility
+
+.is-hidden {
+  display: none !important;
+}
+
+.is-hidden-mobile {
+  @include mobile {
+    display: none !important;
+  }
+}
+
+.is-hidden-tablet {
+  @include tablet {
+    display: none !important;
+  }
+}
+
+.is-hidden-tablet-only {
+  @include tablet-only {
+    display: none !important;
+  }
+}
+
+.is-hidden-touch {
+  @include touch {
+    display: none !important;
+  }
+}
+
+.is-hidden-desktop {
+  @include desktop {
+    display: none !important;
+  }
+}
+
+.is-hidden-desktop-only {
+  @include desktop-only {
+    display: none !important;
+  }
+}
+
+.is-hidden-widescreen {
+  @include widescreen {
+    display: none !important;
+  }
+}

+ 327 - 0
client/scss/base/colors.scss

@@ -0,0 +1,327 @@
+$material-colors: (
+  'red': (
+	'50': #ffebee,
+	'100': #ffcdd2,
+	'200': #ef9a9a,
+	'300': #e57373,
+	'400': #ef5350,
+	'500': #f44336,
+	'600': #e53935,
+	'700': #d32f2f,
+	'800': #c62828,
+	'900': #b71c1c,
+	'a100': #ff8a80,
+	'a200': #ff5252,
+	'a400': #ff1744,
+	'a700': #d50000
+  ),
+
+  'pink': (
+	'50': #fce4ec,
+	'100': #f8bbd0,
+	'200': #f48fb1,
+	'300': #f06292,
+	'400': #ec407a,
+	'500': #e91e63,
+	'600': #d81b60,
+	'700': #c2185b,
+	'800': #ad1457,
+	'900': #880e4f,
+	'a100': #ff80ab,
+	'a200': #ff4081,
+	'a400': #f50057,
+	'a700': #c51162
+  ),
+
+  'purple': (
+	'50': #f3e5f5,
+	'100': #e1bee7,
+	'200': #ce93d8,
+	'300': #ba68c8,
+	'400': #ab47bc,
+	'500': #9c27b0,
+	'600': #8e24aa,
+	'700': #7b1fa2,
+	'800': #6a1b9a,
+	'900': #4a148c,
+	'a100': #ea80fc,
+	'a200': #e040fb,
+	'a400': #d500f9,
+	'a700': #aa00ff
+  ),
+
+  'deep-purple': (
+	'50': #ede7f6,
+	'100': #d1c4e9,
+	'200': #b39ddb,
+	'300': #9575cd,
+	'400': #7e57c2,
+	'500': #673ab7,
+	'600': #5e35b1,
+	'700': #512da8,
+	'800': #4527a0,
+	'900': #311b92,
+	'a100': #b388ff,
+	'a200': #7c4dff,
+	'a400': #651fff,
+	'a700': #6200ea
+  ),
+
+  'indigo': (
+	'50': #e8eaf6,
+	'100': #c5cae9,
+	'200': #9fa8da,
+	'300': #7986cb,
+	'400': #5c6bc0,
+	'500': #3f51b5,
+	'600': #3949ab,
+	'700': #303f9f,
+	'800': #283593,
+	'900': #1a237e,
+	'a100': #8c9eff,
+	'a200': #536dfe,
+	'a400': #3d5afe,
+	'a700': #304ffe
+  ),
+
+  'blue': (
+	'50': #e3f2fd,
+	'100': #bbdefb,
+	'200': #90caf9,
+	'300': #64b5f6,
+	'400': #42a5f5,
+	'500': #2196f3,
+	'600': #1e88e5,
+	'700': #1976d2,
+	'800': #1565c0,
+	'900': #0d47a1,
+	'a100': #82b1ff,
+	'a200': #448aff,
+	'a400': #2979ff,
+	'a700': #2962ff
+  ),
+
+  'light-blue': (
+	'50': #e1f5fe,
+	'100': #b3e5fc,
+	'200': #81d4fa,
+	'300': #4fc3f7,
+	'400': #29b6f6,
+	'500': #03a9f4,
+	'600': #039be5,
+	'700': #0288d1,
+	'800': #0277bd,
+	'900': #01579b,
+	'a100': #80d8ff,
+	'a200': #40c4ff,
+	'a400': #00b0ff,
+	'a700': #0091ea
+  ),
+
+  'cyan': (
+	'50': #e0f7fa,
+	'100': #b2ebf2,
+	'200': #80deea,
+	'300': #4dd0e1,
+	'400': #26c6da,
+	'500': #00bcd4,
+	'600': #00acc1,
+	'700': #0097a7,
+	'800': #00838f,
+	'900': #006064,
+	'a100': #84ffff,
+	'a200': #18ffff,
+	'a400': #00e5ff,
+	'a700': #00b8d4
+  ),
+
+  'teal': (
+	'50': #e0f2f1,
+	'100': #b2dfdb,
+	'200': #80cbc4,
+	'300': #4db6ac,
+	'400': #26a69a,
+	'500': #009688,
+	'600': #00897b,
+	'700': #00796b,
+	'800': #00695c,
+	'900': #004d40,
+	'a100': #a7ffeb,
+	'a200': #64ffda,
+	'a400': #1de9b6,
+	'a700': #00bfa5
+  ),
+
+  'green': (
+	'50': #e8f5e9,
+	'100': #c8e6c9,
+	'200': #a5d6a7,
+	'300': #81c784,
+	'400': #66bb6a,
+	'500': #4caf50,
+	'600': #43a047,
+	'700': #388e3c,
+	'800': #2e7d32,
+	'900': #1b5e20,
+	'a100': #b9f6ca,
+	'a200': #69f0ae,
+	'a400': #00e676,
+	'a700': #00c853
+  ),
+
+  'light-green': (
+	'50': #f1f8e9,
+	'100': #dcedc8,
+	'200': #c5e1a5,
+	'300': #aed581,
+	'400': #9ccc65,
+	'500': #8bc34a,
+	'600': #7cb342,
+	'700': #689f38,
+	'800': #558b2f,
+	'900': #33691e,
+	'a100': #ccff90,
+	'a200': #b2ff59,
+	'a400': #76ff03,
+	'a700': #64dd17
+  ),
+
+  'lime': (
+	'50': #f9fbe7,
+	'100': #f0f4c3,
+	'200': #e6ee9c,
+	'300': #dce775,
+	'400': #d4e157,
+	'500': #cddc39,
+	'600': #c0ca33,
+	'700': #afb42b,
+	'800': #9e9d24,
+	'900': #827717,
+	'a100': #f4ff81,
+	'a200': #eeff41,
+	'a400': #c6ff00,
+	'a700': #aeea00
+  ),
+
+  'yellow': (
+	'50': #fffde7,
+	'100': #fff9c4,
+	'200': #fff59d,
+	'300': #fff176,
+	'400': #ffee58,
+	'500': #ffeb3b,
+	'600': #fdd835,
+	'700': #fbc02d,
+	'800': #f9a825,
+	'900': #f57f17,
+	'a100': #ffff8d,
+	'a200': #ffff00,
+	'a400': #ffea00,
+	'a700': #ffd600
+  ),
+
+  'amber': (
+	'50': #fff8e1,
+	'100': #ffecb3,
+	'200': #ffe082,
+	'300': #ffd54f,
+	'400': #ffca28,
+	'500': #ffc107,
+	'600': #ffb300,
+	'700': #ffa000,
+	'800': #ff8f00,
+	'900': #ff6f00,
+	'a100': #ffe57f,
+	'a200': #ffd740,
+	'a400': #ffc400,
+	'a700': #ffab00
+  ),
+
+  'orange': (
+	'50': #fff3e0,
+	'100': #ffe0b2,
+	'200': #ffcc80,
+	'300': #ffb74d,
+	'400': #ffa726,
+	'500': #ff9800,
+	'600': #fb8c00,
+	'700': #f57c00,
+	'800': #ef6c00,
+	'900': #e65100,
+	'a100': #ffd180,
+	'a200': #ffab40,
+	'a400': #ff9100,
+	'a700': #ff6d00
+  ),
+
+  'deep-orange': (
+	'50': #fbe9e7,
+	'100': #ffccbc,
+	'200': #ffab91,
+	'300': #ff8a65,
+	'400': #ff7043,
+	'500': #ff5722,
+	'600': #f4511e,
+	'700': #e64a19,
+	'800': #d84315,
+	'900': #bf360c,
+	'a100': #ff9e80,
+	'a200': #ff6e40,
+	'a400': #ff3d00,
+	'a700': #dd2c00
+  ),
+
+  'brown': (
+	'50': #efebe9,
+	'100': #d7ccc8,
+	'200': #bcaaa4,
+	'300': #a1887f,
+	'400': #8d6e63,
+	'500': #795548,
+	'600': #6d4c41,
+	'700': #5d4037,
+	'800': #4e342e,
+	'900': #3e2723
+  ),
+
+  'grey': (
+	'50': #fafafa,
+	'100': #f5f5f5,
+	'200': #eeeeee,
+	'300': #e0e0e0,
+	'400': #bdbdbd,
+	'500': #9e9e9e,
+	'600': #757575,
+	'700': #616161,
+	'800': #424242,
+	'900': #212121
+  ),
+
+  'blue-grey': (
+	'50': #eceff1,
+	'100': #cfd8dc,
+	'200': #b0bec5,
+	'300': #90a4ae,
+	'400': #78909c,
+	'500': #607d8b,
+	'600': #546e7a,
+	'700': #455a64,
+	'800': #37474f,
+	'900': #263238,
+	'1000': #11171a
+  )
+);
+
+@function material-color($color-name, $color-variant: '500') {
+  $color: map-get(map-get($material-colors, $color-name),$color-variant);
+  @if $color {
+	@return $color;
+  } @else {
+	// Libsass still doesn't seem to support @error
+	@warn "=> ERROR: COLOR NOT FOUND! <= | Your $color-name, $color-variant combination did not match any of the values in the $material-colors map.";
+  }
+}
+
+@function mc($color-name, $color-variant: '500') {
+	@return material-color($color-name, $color-variant);
+}

+ 2027 - 0
client/scss/base/fonts.scss

@@ -0,0 +1,2027 @@
+
+// ========================================
+// Core-Icons
+//
+// Contains selections from:
+// - Typicons, by Stephen Hutchings, licensed under CC BY-SA 3.0
+// - Feather, by Cole Bemis, licensed under MIT
+// - 60 Vicons, by Victor Erixon, licensed under WTFPL
+// - FontAwesome, by Dave Gandy, licensed under SIL OFL 1.1
+// ========================================
+
+@font-face {
+  font-family: 'core-icons';
+  src:
+    url('/fonts/core-icons.ttf?e6rn1i') format('truetype'),
+    url('/fonts/core-icons.woff?e6rn1i') format('woff'),
+    url('/fonts/core-icons.svg?e6rn1i#core-icons') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+
+[class^="icon-"], [class*=" icon-"] {
+  /* use !important to prevent issues with browser extensions that change fonts */
+  font-family: 'core-icons' !important;
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+// Core-Icons Reference
+
+$icon-minus2: "\f068";
+$icon-font: "\f031";
+$icon-bold: "\f032";
+$icon-italic: "\f033";
+$icon-align-left2: "\f036";
+$icon-align-center2: "\f037";
+$icon-align-right2: "\f038";
+$icon-align-justify2: "\f039";
+$icon-list: "\f03a";
+$icon-video-camera2: "\f03d";
+$icon-image3: "\f03e";
+$icon-photo: "\f03e";
+$icon-picture-o: "\f03e";
+$icon-twitter-square: "\f081";
+$icon-facebook-square: "\f082";
+$icon-linkedin-square: "\f08c";
+$icon-github-square: "\f092";
+$icon-twitter: "\f099";
+$icon-facebook: "\f09a";
+$icon-facebook-f: "\f09a";
+$icon-github: "\f09b";
+$icon-chain: "\f0c1";
+$icon-link3: "\f0c1";
+$icon-bars: "\f0c9";
+$icon-navicon: "\f0c9";
+$icon-reorder: "\f0c9";
+$icon-list-ul: "\f0ca";
+$icon-list-ol: "\f0cb";
+$icon-strikethrough: "\f0cc";
+$icon-underline: "\f0cd";
+$icon-table: "\f0ce";
+$icon-linkedin: "\f0e1";
+$icon-file-text-o: "\f0f6";
+$icon-quote-left: "\f10d";
+$icon-terminal: "\f120";
+$icon-code: "\f121";
+$icon-youtube-play: "\f16a";
+$icon-dropbox: "\f16b";
+$icon-stack-overflow: "\f16c";
+$icon-bitbucket: "\f171";
+$icon-apple: "\f179";
+$icon-windows2: "\f17a";
+$icon-android: "\f17b";
+$icon-linux: "\f17c";
+$icon-vimeo-square: "\f194";
+$icon-slack: "\f198";
+$icon-google: "\f1a0";
+$icon-git-square: "\f1d2";
+$icon-git: "\f1d3";
+$icon-header: "\f1dc";
+$icon-safari: "\f267";
+$icon-chrome: "\f268";
+$icon-firefox: "\f269";
+$icon-opera: "\f26a";
+$icon-internet-explorer: "\f26b";
+$icon-vimeo: "\f27d";
+$icon-edge: "\f282";
+$icon-gitlab: "\f296";
+$icon-th-small: "\e900";
+$icon-th-menu: "\e901";
+$icon-th-list: "\e902";
+$icon-th-large: "\e903";
+$icon-home: "\e904";
+$icon-location: "\e905";
+$icon-link: "\e906";
+$icon-starburst: "\e907";
+$icon-starburst-outline: "\e908";
+$icon-star: "\e909";
+$icon-flow-children: "\e90a";
+$icon-export: "\e90b";
+$icon-delete: "\e90c";
+$icon-delete-outline: "\e90d";
+$icon-cloud-storage: "\e90e";
+$icon-backspace: "\e90f";
+$icon-attachment: "\e910";
+$icon-arrow-move: "\e911";
+$icon-warning: "\e912";
+$icon-location-arrow: "\e913";
+$icon-point-of-interest: "\e914";
+$icon-infinity: "\e915";
+$icon-eye: "\e916";
+$icon-refresh: "\e917";
+$icon-pin: "\e918";
+$icon-eject: "\e919";
+$icon-arrow-sync: "\e91a";
+$icon-arrow-shuffle: "\e91b";
+$icon-arrow-repeat: "\e91c";
+$icon-arrow-minimise: "\e91d";
+$icon-arrow-maximise: "\e91e";
+$icon-arrow-loop: "\e91f";
+$icon-spanner: "\e920";
+$icon-power: "\e921";
+$icon-flag: "\e922";
+$icon-th-large-outline: "\e923";
+$icon-th-small-outline: "\e924";
+$icon-th-menu-outline: "\e925";
+$icon-th-list-outline: "\e926";
+$icon-home-outline: "\e927";
+$icon-trash: "\e928";
+$icon-star-outline: "\e929";
+$icon-mail: "\e92a";
+$icon-heart-outline: "\e92b";
+$icon-flash-outline: "\e92c";
+$icon-watch: "\e92d";
+$icon-warning-outline: "\e92e";
+$icon-location-arrow-outline: "\e92f";
+$icon-info-outline: "\e930";
+$icon-backspace-outline: "\e931";
+$icon-upload-outline: "\e932";
+$icon-tag: "\e933";
+$icon-tabs-outline: "\e934";
+$icon-pin-outline: "\e935";
+$icon-pipette: "\e936";
+$icon-pencil: "\e937";
+$icon-folder: "\e938";
+$icon-folder-delete: "\e939";
+$icon-folder-add: "\e93a";
+$icon-edit: "\e93b";
+$icon-document: "\e93c";
+$icon-document-delete: "\e93d";
+$icon-document-add: "\e93e";
+$icon-brush: "\e93f";
+$icon-thumbs-up: "\e940";
+$icon-thumbs-down: "\e941";
+$icon-pen: "\e942";
+$icon-bookmark: "\e943";
+$icon-arrow-up: "\e944";
+$icon-arrow-sync-outline: "\e945";
+$icon-arrow-right: "\e946";
+$icon-arrow-repeat-outline: "\e947";
+$icon-arrow-loop-outline: "\e948";
+$icon-arrow-left: "\e949";
+$icon-flow-switch: "\e94a";
+$icon-flow-parallel: "\e94b";
+$icon-flow-merge: "\e94c";
+$icon-document-text: "\e94d";
+$icon-arrow-down: "\e94e";
+$icon-bell: "\e94f";
+$icon-adjust-contrast: "\e950";
+$icon-lightbulb: "\e951";
+$icon-tags: "\e952";
+$icon-eye2: "\e000";
+$icon-paper-clip: "\e001";
+$icon-mail2: "\e002";
+$icon-toggle: "\e003";
+$icon-layout: "\e004";
+$icon-link2: "\e005";
+$icon-bell2: "\e006";
+$icon-lock: "\e007";
+$icon-unlock: "\e008";
+$icon-ribbon: "\e009";
+$icon-image: "\e010";
+$icon-signal: "\e011";
+$icon-target: "\e012";
+$icon-clipboard: "\e013";
+$icon-clock: "\e014";
+$icon-watch2: "\e015";
+$icon-air-play: "\e016";
+$icon-camera: "\e017";
+$icon-video: "\e018";
+$icon-disc: "\e019";
+$icon-printer: "\e020";
+$icon-monitor: "\e021";
+$icon-server: "\e022";
+$icon-cog: "\e023";
+$icon-heart: "\e024";
+$icon-paragraph: "\e025";
+$icon-align-justify: "\e026";
+$icon-align-left: "\e027";
+$icon-align-center: "\e028";
+$icon-align-right: "\e029";
+$icon-book: "\e030";
+$icon-layers: "\e031";
+$icon-stack: "\e032";
+$icon-stack-2: "\e033";
+$icon-paper: "\e034";
+$icon-paper-stack: "\e035";
+$icon-search: "\e036";
+$icon-zoom-in: "\e037";
+$icon-zoom-out: "\e038";
+$icon-reply: "\e039";
+$icon-circle-plus: "\e040";
+$icon-circle-minus: "\e041";
+$icon-circle-check: "\e042";
+$icon-circle-cross: "\e043";
+$icon-square-plus: "\e044";
+$icon-square-minus: "\e045";
+$icon-square-check: "\e046";
+$icon-square-cross: "\e047";
+$icon-microphone: "\e048";
+$icon-record: "\e049";
+$icon-skip-back: "\e050";
+$icon-rewind: "\e051";
+$icon-play: "\e052";
+$icon-pause: "\e053";
+$icon-stop: "\e054";
+$icon-fast-forward: "\e055";
+$icon-skip-forward: "\e056";
+$icon-shuffle: "\e057";
+$icon-repeat: "\e058";
+$icon-folder2: "\e059";
+$icon-umbrella: "\e060";
+$icon-moon: "\e061";
+$icon-thermometer: "\e062";
+$icon-drop: "\e063";
+$icon-sun: "\e064";
+$icon-cloud: "\e065";
+$icon-cloud-upload: "\e066";
+$icon-cloud-download: "\e067";
+$icon-upload: "\e068";
+$icon-download: "\e069";
+$icon-location2: "\e070";
+$icon-location-2: "\e071";
+$icon-map: "\e072";
+$icon-battery: "\e073";
+$icon-head: "\e074";
+$icon-briefcase: "\e075";
+$icon-speech-bubble: "\e076";
+$icon-anchor: "\e077";
+$icon-globe: "\e078";
+$icon-box: "\e079";
+$icon-reload: "\e080";
+$icon-share: "\e081";
+$icon-marquee: "\e082";
+$icon-marquee-plus: "\e083";
+$icon-marquee-minus: "\e084";
+$icon-tag2: "\e085";
+$icon-power2: "\e086";
+$icon-command: "\e087";
+$icon-alt: "\e088";
+$icon-esc: "\e089";
+$icon-bar-graph: "\e090";
+$icon-bar-graph-2: "\e091";
+$icon-pie-graph: "\e092";
+$icon-star2: "\e093";
+$icon-arrow-left2: "\e094";
+$icon-arrow-right2: "\e095";
+$icon-arrow-up2: "\e096";
+$icon-arrow-down2: "\e097";
+$icon-volume: "\e098";
+$icon-mute: "\e099";
+$icon-content-right: "\e100";
+$icon-content-left: "\e101";
+$icon-grid: "\e102";
+$icon-grid-2: "\e103";
+$icon-columns: "\e104";
+$icon-loader: "\e105";
+$icon-bag: "\e106";
+$icon-ban: "\e107";
+$icon-flag2: "\e108";
+$icon-trash2: "\e109";
+$icon-expand: "\e110";
+$icon-contract: "\e111";
+$icon-maximize: "\e112";
+$icon-minimize: "\e113";
+$icon-plus: "\e114";
+$icon-minus: "\e115";
+$icon-check: "\e116";
+$icon-cross: "\e117";
+$icon-move: "\e118";
+$icon-delete2: "\e119";
+$icon-menu: "\e120";
+$icon-archive: "\e121";
+$icon-inbox: "\e122";
+$icon-outbox: "\e123";
+$icon-file: "\e124";
+$icon-file-add: "\e125";
+$icon-file-subtract: "\e126";
+$icon-help: "\e127";
+$icon-open: "\e128";
+$icon-ellipsis: "\e129";
+$icon-box2: "\e953";
+$icon-write: "\e954";
+$icon-clock2: "\e955";
+$icon-reply2: "\e956";
+$icon-reply-all: "\e957";
+$icon-forward: "\e958";
+$icon-flag3: "\e959";
+$icon-search2: "\e95a";
+$icon-trash3: "\e95b";
+$icon-envelope: "\e95c";
+$icon-bubble: "\e95d";
+$icon-bubbles: "\e95e";
+$icon-user: "\e95f";
+$icon-users: "\e960";
+$icon-cloud2: "\e961";
+$icon-download2: "\e962";
+$icon-upload2: "\e963";
+$icon-rain: "\e964";
+$icon-sun2: "\e965";
+$icon-moon2: "\e966";
+$icon-bell3: "\e967";
+$icon-folder3: "\e968";
+$icon-pin2: "\e969";
+$icon-sound: "\e96a";
+$icon-microphone2: "\e96b";
+$icon-camera2: "\e96c";
+$icon-image2: "\e96d";
+$icon-cog2: "\e96e";
+$icon-calendar: "\e96f";
+$icon-book2: "\e970";
+$icon-map-marker: "\e971";
+$icon-store: "\e972";
+$icon-support: "\e973";
+$icon-tag3: "\e974";
+$icon-heart2: "\e975";
+$icon-video-camera: "\e976";
+$icon-trophy: "\e977";
+$icon-cart: "\e978";
+$icon-eye3: "\e979";
+$icon-cancel: "\e97a";
+$icon-chart: "\e97b";
+$icon-target2: "\e97c";
+$icon-printer2: "\e97d";
+$icon-location3: "\e97e";
+$icon-bookmark2: "\e97f";
+$icon-monitor2: "\e980";
+$icon-cross2: "\e981";
+$icon-plus2: "\e982";
+$icon-left: "\e983";
+$icon-up: "\e984";
+$icon-browser: "\e985";
+$icon-windows: "\e986";
+$icon-switch: "\e987";
+$icon-dashboard: "\e988";
+$icon-play2: "\e989";
+$icon-fast-forward2: "\e98a";
+$icon-next: "\e98b";
+$icon-refresh2: "\e98c";
+$icon-film: "\e98d";
+$icon-home2: "\e98e";
+
+// CSS Classes
+
+.icon-minus2 {
+  &:before {
+    content: $icon-minus2;
+  }
+}
+.icon-font {
+  &:before {
+    content: $icon-font;
+  }
+}
+.icon-bold {
+  &:before {
+    content: $icon-bold;
+  }
+}
+.icon-italic {
+  &:before {
+    content: $icon-italic;
+  }
+}
+.icon-align-left2 {
+  &:before {
+    content: $icon-align-left2;
+  }
+}
+.icon-align-center2 {
+  &:before {
+    content: $icon-align-center2;
+  }
+}
+.icon-align-right2 {
+  &:before {
+    content: $icon-align-right2;
+  }
+}
+.icon-align-justify2 {
+  &:before {
+    content: $icon-align-justify2;
+  }
+}
+.icon-list {
+  &:before {
+    content: $icon-list;
+  }
+}
+.icon-video-camera2 {
+  &:before {
+    content: $icon-video-camera2;
+  }
+}
+.icon-image3 {
+  &:before {
+    content: $icon-image3;
+  }
+}
+.icon-photo {
+  &:before {
+    content: $icon-photo;
+  }
+}
+.icon-picture-o {
+  &:before {
+    content: $icon-picture-o;
+  }
+}
+.icon-twitter-square {
+  &:before {
+    content: $icon-twitter-square;
+  }
+}
+.icon-facebook-square {
+  &:before {
+    content: $icon-facebook-square;
+  }
+}
+.icon-linkedin-square {
+  &:before {
+    content: $icon-linkedin-square;
+  }
+}
+.icon-github-square {
+  &:before {
+    content: $icon-github-square;
+  }
+}
+.icon-twitter {
+  &:before {
+    content: $icon-twitter;
+  }
+}
+.icon-facebook {
+  &:before {
+    content: $icon-facebook;
+  }
+}
+.icon-facebook-f {
+  &:before {
+    content: $icon-facebook-f;
+  }
+}
+.icon-github {
+  &:before {
+    content: $icon-github;
+  }
+}
+.icon-chain {
+  &:before {
+    content: $icon-chain;
+  }
+}
+.icon-link3 {
+  &:before {
+    content: $icon-link3;
+  }
+}
+.icon-bars {
+  &:before {
+    content: $icon-bars;
+  }
+}
+.icon-navicon {
+  &:before {
+    content: $icon-navicon;
+  }
+}
+.icon-reorder {
+  &:before {
+    content: $icon-reorder;
+  }
+}
+.icon-list-ul {
+  &:before {
+    content: $icon-list-ul;
+  }
+}
+.icon-list-ol {
+  &:before {
+    content: $icon-list-ol;
+  }
+}
+.icon-strikethrough {
+  &:before {
+    content: $icon-strikethrough;
+  }
+}
+.icon-underline {
+  &:before {
+    content: $icon-underline;
+  }
+}
+.icon-table {
+  &:before {
+    content: $icon-table;
+  }
+}
+.icon-linkedin {
+  &:before {
+    content: $icon-linkedin;
+  }
+}
+.icon-file-text-o {
+  &:before {
+    content: $icon-file-text-o;
+  }
+}
+.icon-quote-left {
+  &:before {
+    content: $icon-quote-left;
+  }
+}
+.icon-terminal {
+  &:before {
+    content: $icon-terminal;
+  }
+}
+.icon-code {
+  &:before {
+    content: $icon-code;
+  }
+}
+.icon-youtube-play {
+  &:before {
+    content: $icon-youtube-play;
+  }
+}
+.icon-dropbox {
+  &:before {
+    content: $icon-dropbox;
+  }
+}
+.icon-stack-overflow {
+  &:before {
+    content: $icon-stack-overflow;
+  }
+}
+.icon-bitbucket {
+  &:before {
+    content: $icon-bitbucket;
+  }
+}
+.icon-apple {
+  &:before {
+    content: $icon-apple;
+  }
+}
+.icon-windows2 {
+  &:before {
+    content: $icon-windows2;
+  }
+}
+.icon-android {
+  &:before {
+    content: $icon-android;
+  }
+}
+.icon-linux {
+  &:before {
+    content: $icon-linux;
+  }
+}
+.icon-vimeo-square {
+  &:before {
+    content: $icon-vimeo-square;
+  }
+}
+.icon-slack {
+  &:before {
+    content: $icon-slack;
+  }
+}
+.icon-google {
+  &:before {
+    content: $icon-google;
+  }
+}
+.icon-git-square {
+  &:before {
+    content: $icon-git-square;
+  }
+}
+.icon-git {
+  &:before {
+    content: $icon-git;
+  }
+}
+.icon-header {
+  &:before {
+    content: $icon-header;
+  }
+}
+.icon-safari {
+  &:before {
+    content: $icon-safari;
+  }
+}
+.icon-chrome {
+  &:before {
+    content: $icon-chrome;
+  }
+}
+.icon-firefox {
+  &:before {
+    content: $icon-firefox;
+  }
+}
+.icon-opera {
+  &:before {
+    content: $icon-opera;
+  }
+}
+.icon-internet-explorer {
+  &:before {
+    content: $icon-internet-explorer;
+  }
+}
+.icon-vimeo {
+  &:before {
+    content: $icon-vimeo;
+  }
+}
+.icon-edge {
+  &:before {
+    content: $icon-edge;
+  }
+}
+.icon-gitlab {
+  &:before {
+    content: $icon-gitlab;
+  }
+}
+.icon-th-small {
+  &:before {
+    content: $icon-th-small;
+  }
+}
+.icon-th-menu {
+  &:before {
+    content: $icon-th-menu;
+  }
+}
+.icon-th-list {
+  &:before {
+    content: $icon-th-list;
+  }
+}
+.icon-th-large {
+  &:before {
+    content: $icon-th-large;
+  }
+}
+.icon-home {
+  &:before {
+    content: $icon-home;
+  }
+}
+.icon-location {
+  &:before {
+    content: $icon-location;
+  }
+}
+.icon-link {
+  &:before {
+    content: $icon-link;
+  }
+}
+.icon-starburst {
+  &:before {
+    content: $icon-starburst;
+  }
+}
+.icon-starburst-outline {
+  &:before {
+    content: $icon-starburst-outline;
+  }
+}
+.icon-star {
+  &:before {
+    content: $icon-star;
+  }
+}
+.icon-flow-children {
+  &:before {
+    content: $icon-flow-children;
+  }
+}
+.icon-export {
+  &:before {
+    content: $icon-export;
+  }
+}
+.icon-delete {
+  &:before {
+    content: $icon-delete;
+  }
+}
+.icon-delete-outline {
+  &:before {
+    content: $icon-delete-outline;
+  }
+}
+.icon-cloud-storage {
+  &:before {
+    content: $icon-cloud-storage;
+  }
+}
+.icon-backspace {
+  &:before {
+    content: $icon-backspace;
+  }
+}
+.icon-attachment {
+  &:before {
+    content: $icon-attachment;
+  }
+}
+.icon-arrow-move {
+  &:before {
+    content: $icon-arrow-move;
+  }
+}
+.icon-warning {
+  &:before {
+    content: $icon-warning;
+  }
+}
+.icon-location-arrow {
+  &:before {
+    content: $icon-location-arrow;
+  }
+}
+.icon-point-of-interest {
+  &:before {
+    content: $icon-point-of-interest;
+  }
+}
+.icon-infinity {
+  &:before {
+    content: $icon-infinity;
+  }
+}
+.icon-eye {
+  &:before {
+    content: $icon-eye;
+  }
+}
+.icon-refresh {
+  &:before {
+    content: $icon-refresh;
+  }
+}
+.icon-pin {
+  &:before {
+    content: $icon-pin;
+  }
+}
+.icon-eject {
+  &:before {
+    content: $icon-eject;
+  }
+}
+.icon-arrow-sync {
+  &:before {
+    content: $icon-arrow-sync;
+  }
+}
+.icon-arrow-shuffle {
+  &:before {
+    content: $icon-arrow-shuffle;
+  }
+}
+.icon-arrow-repeat {
+  &:before {
+    content: $icon-arrow-repeat;
+  }
+}
+.icon-arrow-minimise {
+  &:before {
+    content: $icon-arrow-minimise;
+  }
+}
+.icon-arrow-maximise {
+  &:before {
+    content: $icon-arrow-maximise;
+  }
+}
+.icon-arrow-loop {
+  &:before {
+    content: $icon-arrow-loop;
+  }
+}
+.icon-spanner {
+  &:before {
+    content: $icon-spanner;
+  }
+}
+.icon-power {
+  &:before {
+    content: $icon-power;
+  }
+}
+.icon-flag {
+  &:before {
+    content: $icon-flag;
+  }
+}
+.icon-th-large-outline {
+  &:before {
+    content: $icon-th-large-outline;
+  }
+}
+.icon-th-small-outline {
+  &:before {
+    content: $icon-th-small-outline;
+  }
+}
+.icon-th-menu-outline {
+  &:before {
+    content: $icon-th-menu-outline;
+  }
+}
+.icon-th-list-outline {
+  &:before {
+    content: $icon-th-list-outline;
+  }
+}
+.icon-home-outline {
+  &:before {
+    content: $icon-home-outline;
+  }
+}
+.icon-trash {
+  &:before {
+    content: $icon-trash;
+  }
+}
+.icon-star-outline {
+  &:before {
+    content: $icon-star-outline;
+  }
+}
+.icon-mail {
+  &:before {
+    content: $icon-mail;
+  }
+}
+.icon-heart-outline {
+  &:before {
+    content: $icon-heart-outline;
+  }
+}
+.icon-flash-outline {
+  &:before {
+    content: $icon-flash-outline;
+  }
+}
+.icon-watch {
+  &:before {
+    content: $icon-watch;
+  }
+}
+.icon-warning-outline {
+  &:before {
+    content: $icon-warning-outline;
+  }
+}
+.icon-location-arrow-outline {
+  &:before {
+    content: $icon-location-arrow-outline;
+  }
+}
+.icon-info-outline {
+  &:before {
+    content: $icon-info-outline;
+  }
+}
+.icon-backspace-outline {
+  &:before {
+    content: $icon-backspace-outline;
+  }
+}
+.icon-upload-outline {
+  &:before {
+    content: $icon-upload-outline;
+  }
+}
+.icon-tag {
+  &:before {
+    content: $icon-tag;
+  }
+}
+.icon-tabs-outline {
+  &:before {
+    content: $icon-tabs-outline;
+  }
+}
+.icon-pin-outline {
+  &:before {
+    content: $icon-pin-outline;
+  }
+}
+.icon-pipette {
+  &:before {
+    content: $icon-pipette;
+  }
+}
+.icon-pencil {
+  &:before {
+    content: $icon-pencil;
+  }
+}
+.icon-folder {
+  &:before {
+    content: $icon-folder;
+  }
+}
+.icon-folder-delete {
+  &:before {
+    content: $icon-folder-delete;
+  }
+}
+.icon-folder-add {
+  &:before {
+    content: $icon-folder-add;
+  }
+}
+.icon-edit {
+  &:before {
+    content: $icon-edit;
+  }
+}
+.icon-document {
+  &:before {
+    content: $icon-document;
+  }
+}
+.icon-document-delete {
+  &:before {
+    content: $icon-document-delete;
+  }
+}
+.icon-document-add {
+  &:before {
+    content: $icon-document-add;
+  }
+}
+.icon-brush {
+  &:before {
+    content: $icon-brush;
+  }
+}
+.icon-thumbs-up {
+  &:before {
+    content: $icon-thumbs-up;
+  }
+}
+.icon-thumbs-down {
+  &:before {
+    content: $icon-thumbs-down;
+  }
+}
+.icon-pen {
+  &:before {
+    content: $icon-pen;
+  }
+}
+.icon-bookmark {
+  &:before {
+    content: $icon-bookmark;
+  }
+}
+.icon-arrow-up {
+  &:before {
+    content: $icon-arrow-up;
+  }
+}
+.icon-arrow-sync-outline {
+  &:before {
+    content: $icon-arrow-sync-outline;
+  }
+}
+.icon-arrow-right {
+  &:before {
+    content: $icon-arrow-right;
+  }
+}
+.icon-arrow-repeat-outline {
+  &:before {
+    content: $icon-arrow-repeat-outline;
+  }
+}
+.icon-arrow-loop-outline {
+  &:before {
+    content: $icon-arrow-loop-outline;
+  }
+}
+.icon-arrow-left {
+  &:before {
+    content: $icon-arrow-left;
+  }
+}
+.icon-flow-switch {
+  &:before {
+    content: $icon-flow-switch;
+  }
+}
+.icon-flow-parallel {
+  &:before {
+    content: $icon-flow-parallel;
+  }
+}
+.icon-flow-merge {
+  &:before {
+    content: $icon-flow-merge;
+  }
+}
+.icon-document-text {
+  &:before {
+    content: $icon-document-text;
+  }
+}
+.icon-arrow-down {
+  &:before {
+    content: $icon-arrow-down;
+  }
+}
+.icon-bell {
+  &:before {
+    content: $icon-bell;
+  }
+}
+.icon-adjust-contrast {
+  &:before {
+    content: $icon-adjust-contrast;
+  }
+}
+.icon-lightbulb {
+  &:before {
+    content: $icon-lightbulb;
+  }
+}
+.icon-tags {
+  &:before {
+    content: $icon-tags;
+  }
+}
+.icon-eye2 {
+  &:before {
+    content: $icon-eye2;
+  }
+}
+.icon-paper-clip {
+  &:before {
+    content: $icon-paper-clip;
+  }
+}
+.icon-mail2 {
+  &:before {
+    content: $icon-mail2;
+  }
+}
+.icon-toggle {
+  &:before {
+    content: $icon-toggle;
+  }
+}
+.icon-layout {
+  &:before {
+    content: $icon-layout;
+  }
+}
+.icon-link2 {
+  &:before {
+    content: $icon-link2;
+  }
+}
+.icon-bell2 {
+  &:before {
+    content: $icon-bell2;
+  }
+}
+.icon-lock {
+  &:before {
+    content: $icon-lock;
+  }
+}
+.icon-unlock {
+  &:before {
+    content: $icon-unlock;
+  }
+}
+.icon-ribbon {
+  &:before {
+    content: $icon-ribbon;
+  }
+}
+.icon-image {
+  &:before {
+    content: $icon-image;
+  }
+}
+.icon-signal {
+  &:before {
+    content: $icon-signal;
+  }
+}
+.icon-target {
+  &:before {
+    content: $icon-target;
+  }
+}
+.icon-clipboard {
+  &:before {
+    content: $icon-clipboard;
+  }
+}
+.icon-clock {
+  &:before {
+    content: $icon-clock;
+  }
+}
+.icon-watch2 {
+  &:before {
+    content: $icon-watch2;
+  }
+}
+.icon-air-play {
+  &:before {
+    content: $icon-air-play;
+  }
+}
+.icon-camera {
+  &:before {
+    content: $icon-camera;
+  }
+}
+.icon-video {
+  &:before {
+    content: $icon-video;
+  }
+}
+.icon-disc {
+  &:before {
+    content: $icon-disc;
+  }
+}
+.icon-printer {
+  &:before {
+    content: $icon-printer;
+  }
+}
+.icon-monitor {
+  &:before {
+    content: $icon-monitor;
+  }
+}
+.icon-server {
+  &:before {
+    content: $icon-server;
+  }
+}
+.icon-cog {
+  &:before {
+    content: $icon-cog;
+  }
+}
+.icon-heart {
+  &:before {
+    content: $icon-heart;
+  }
+}
+.icon-paragraph {
+  &:before {
+    content: $icon-paragraph;
+  }
+}
+.icon-align-justify {
+  &:before {
+    content: $icon-align-justify;
+  }
+}
+.icon-align-left {
+  &:before {
+    content: $icon-align-left;
+  }
+}
+.icon-align-center {
+  &:before {
+    content: $icon-align-center;
+  }
+}
+.icon-align-right {
+  &:before {
+    content: $icon-align-right;
+  }
+}
+.icon-book {
+  &:before {
+    content: $icon-book;
+  }
+}
+.icon-layers {
+  &:before {
+    content: $icon-layers;
+  }
+}
+.icon-stack {
+  &:before {
+    content: $icon-stack;
+  }
+}
+.icon-stack-2 {
+  &:before {
+    content: $icon-stack-2;
+  }
+}
+.icon-paper {
+  &:before {
+    content: $icon-paper;
+  }
+}
+.icon-paper-stack {
+  &:before {
+    content: $icon-paper-stack;
+  }
+}
+.icon-search {
+  &:before {
+    content: $icon-search;
+  }
+}
+.icon-zoom-in {
+  &:before {
+    content: $icon-zoom-in;
+  }
+}
+.icon-zoom-out {
+  &:before {
+    content: $icon-zoom-out;
+  }
+}
+.icon-reply {
+  &:before {
+    content: $icon-reply;
+  }
+}
+.icon-circle-plus {
+  &:before {
+    content: $icon-circle-plus;
+  }
+}
+.icon-circle-minus {
+  &:before {
+    content: $icon-circle-minus;
+  }
+}
+.icon-circle-check {
+  &:before {
+    content: $icon-circle-check;
+  }
+}
+.icon-circle-cross {
+  &:before {
+    content: $icon-circle-cross;
+  }
+}
+.icon-square-plus {
+  &:before {
+    content: $icon-square-plus;
+  }
+}
+.icon-square-minus {
+  &:before {
+    content: $icon-square-minus;
+  }
+}
+.icon-square-check {
+  &:before {
+    content: $icon-square-check;
+  }
+}
+.icon-square-cross {
+  &:before {
+    content: $icon-square-cross;
+  }
+}
+.icon-microphone {
+  &:before {
+    content: $icon-microphone;
+  }
+}
+.icon-record {
+  &:before {
+    content: $icon-record;
+  }
+}
+.icon-skip-back {
+  &:before {
+    content: $icon-skip-back;
+  }
+}
+.icon-rewind {
+  &:before {
+    content: $icon-rewind;
+  }
+}
+.icon-play {
+  &:before {
+    content: $icon-play;
+  }
+}
+.icon-pause {
+  &:before {
+    content: $icon-pause;
+  }
+}
+.icon-stop {
+  &:before {
+    content: $icon-stop;
+  }
+}
+.icon-fast-forward {
+  &:before {
+    content: $icon-fast-forward;
+  }
+}
+.icon-skip-forward {
+  &:before {
+    content: $icon-skip-forward;
+  }
+}
+.icon-shuffle {
+  &:before {
+    content: $icon-shuffle;
+  }
+}
+.icon-repeat {
+  &:before {
+    content: $icon-repeat;
+  }
+}
+.icon-folder2 {
+  &:before {
+    content: $icon-folder2;
+  }
+}
+.icon-umbrella {
+  &:before {
+    content: $icon-umbrella;
+  }
+}
+.icon-moon {
+  &:before {
+    content: $icon-moon;
+  }
+}
+.icon-thermometer {
+  &:before {
+    content: $icon-thermometer;
+  }
+}
+.icon-drop {
+  &:before {
+    content: $icon-drop;
+  }
+}
+.icon-sun {
+  &:before {
+    content: $icon-sun;
+  }
+}
+.icon-cloud {
+  &:before {
+    content: $icon-cloud;
+  }
+}
+.icon-cloud-upload {
+  &:before {
+    content: $icon-cloud-upload;
+  }
+}
+.icon-cloud-download {
+  &:before {
+    content: $icon-cloud-download;
+  }
+}
+.icon-upload {
+  &:before {
+    content: $icon-upload;
+  }
+}
+.icon-download {
+  &:before {
+    content: $icon-download;
+  }
+}
+.icon-location2 {
+  &:before {
+    content: $icon-location2;
+  }
+}
+.icon-location-2 {
+  &:before {
+    content: $icon-location-2;
+  }
+}
+.icon-map {
+  &:before {
+    content: $icon-map;
+  }
+}
+.icon-battery {
+  &:before {
+    content: $icon-battery;
+  }
+}
+.icon-head {
+  &:before {
+    content: $icon-head;
+  }
+}
+.icon-briefcase {
+  &:before {
+    content: $icon-briefcase;
+  }
+}
+.icon-speech-bubble {
+  &:before {
+    content: $icon-speech-bubble;
+  }
+}
+.icon-anchor {
+  &:before {
+    content: $icon-anchor;
+  }
+}
+.icon-globe {
+  &:before {
+    content: $icon-globe;
+  }
+}
+.icon-box {
+  &:before {
+    content: $icon-box;
+  }
+}
+.icon-reload {
+  &:before {
+    content: $icon-reload;
+  }
+}
+.icon-share {
+  &:before {
+    content: $icon-share;
+  }
+}
+.icon-marquee {
+  &:before {
+    content: $icon-marquee;
+  }
+}
+.icon-marquee-plus {
+  &:before {
+    content: $icon-marquee-plus;
+  }
+}
+.icon-marquee-minus {
+  &:before {
+    content: $icon-marquee-minus;
+  }
+}
+.icon-tag2 {
+  &:before {
+    content: $icon-tag2;
+  }
+}
+.icon-power2 {
+  &:before {
+    content: $icon-power2;
+  }
+}
+.icon-command {
+  &:before {
+    content: $icon-command;
+  }
+}
+.icon-alt {
+  &:before {
+    content: $icon-alt;
+  }
+}
+.icon-esc {
+  &:before {
+    content: $icon-esc;
+  }
+}
+.icon-bar-graph {
+  &:before {
+    content: $icon-bar-graph;
+  }
+}
+.icon-bar-graph-2 {
+  &:before {
+    content: $icon-bar-graph-2;
+  }
+}
+.icon-pie-graph {
+  &:before {
+    content: $icon-pie-graph;
+  }
+}
+.icon-star2 {
+  &:before {
+    content: $icon-star2;
+  }
+}
+.icon-arrow-left2 {
+  &:before {
+    content: $icon-arrow-left2;
+  }
+}
+.icon-arrow-right2 {
+  &:before {
+    content: $icon-arrow-right2;
+  }
+}
+.icon-arrow-up2 {
+  &:before {
+    content: $icon-arrow-up2;
+  }
+}
+.icon-arrow-down2 {
+  &:before {
+    content: $icon-arrow-down2;
+  }
+}
+.icon-volume {
+  &:before {
+    content: $icon-volume;
+  }
+}
+.icon-mute {
+  &:before {
+    content: $icon-mute;
+  }
+}
+.icon-content-right {
+  &:before {
+    content: $icon-content-right;
+  }
+}
+.icon-content-left {
+  &:before {
+    content: $icon-content-left;
+  }
+}
+.icon-grid {
+  &:before {
+    content: $icon-grid;
+  }
+}
+.icon-grid-2 {
+  &:before {
+    content: $icon-grid-2;
+  }
+}
+.icon-columns {
+  &:before {
+    content: $icon-columns;
+  }
+}
+.icon-loader {
+  &:before {
+    content: $icon-loader;
+  }
+}
+.icon-bag {
+  &:before {
+    content: $icon-bag;
+  }
+}
+.icon-ban {
+  &:before {
+    content: $icon-ban;
+  }
+}
+.icon-flag2 {
+  &:before {
+    content: $icon-flag2;
+  }
+}
+.icon-trash2 {
+  &:before {
+    content: $icon-trash2;
+  }
+}
+.icon-expand {
+  &:before {
+    content: $icon-expand;
+  }
+}
+.icon-contract {
+  &:before {
+    content: $icon-contract;
+  }
+}
+.icon-maximize {
+  &:before {
+    content: $icon-maximize;
+  }
+}
+.icon-minimize {
+  &:before {
+    content: $icon-minimize;
+  }
+}
+.icon-plus {
+  &:before {
+    content: $icon-plus;
+  }
+}
+.icon-minus {
+  &:before {
+    content: $icon-minus;
+  }
+}
+.icon-check {
+  &:before {
+    content: $icon-check;
+  }
+}
+.icon-cross {
+  &:before {
+    content: $icon-cross;
+  }
+}
+.icon-move {
+  &:before {
+    content: $icon-move;
+  }
+}
+.icon-delete2 {
+  &:before {
+    content: $icon-delete2;
+  }
+}
+.icon-menu {
+  &:before {
+    content: $icon-menu;
+  }
+}
+.icon-archive {
+  &:before {
+    content: $icon-archive;
+  }
+}
+.icon-inbox {
+  &:before {
+    content: $icon-inbox;
+  }
+}
+.icon-outbox {
+  &:before {
+    content: $icon-outbox;
+  }
+}
+.icon-file {
+  &:before {
+    content: $icon-file;
+  }
+}
+.icon-file-add {
+  &:before {
+    content: $icon-file-add;
+  }
+}
+.icon-file-subtract {
+  &:before {
+    content: $icon-file-subtract;
+  }
+}
+.icon-help {
+  &:before {
+    content: $icon-help;
+  }
+}
+.icon-open {
+  &:before {
+    content: $icon-open;
+  }
+}
+.icon-ellipsis {
+  &:before {
+    content: $icon-ellipsis;
+  }
+}
+.icon-box2 {
+  &:before {
+    content: $icon-box2;
+  }
+}
+.icon-write {
+  &:before {
+    content: $icon-write;
+  }
+}
+.icon-clock2 {
+  &:before {
+    content: $icon-clock2;
+  }
+}
+.icon-reply2 {
+  &:before {
+    content: $icon-reply2;
+  }
+}
+.icon-reply-all {
+  &:before {
+    content: $icon-reply-all;
+  }
+}
+.icon-forward {
+  &:before {
+    content: $icon-forward;
+  }
+}
+.icon-flag3 {
+  &:before {
+    content: $icon-flag3;
+  }
+}
+.icon-search2 {
+  &:before {
+    content: $icon-search2;
+  }
+}
+.icon-trash3 {
+  &:before {
+    content: $icon-trash3;
+  }
+}
+.icon-envelope {
+  &:before {
+    content: $icon-envelope;
+  }
+}
+.icon-bubble {
+  &:before {
+    content: $icon-bubble;
+  }
+}
+.icon-bubbles {
+  &:before {
+    content: $icon-bubbles;
+  }
+}
+.icon-user {
+  &:before {
+    content: $icon-user;
+  }
+}
+.icon-users {
+  &:before {
+    content: $icon-users;
+  }
+}
+.icon-cloud2 {
+  &:before {
+    content: $icon-cloud2;
+  }
+}
+.icon-download2 {
+  &:before {
+    content: $icon-download2;
+  }
+}
+.icon-upload2 {
+  &:before {
+    content: $icon-upload2;
+  }
+}
+.icon-rain {
+  &:before {
+    content: $icon-rain;
+  }
+}
+.icon-sun2 {
+  &:before {
+    content: $icon-sun2;
+  }
+}
+.icon-moon2 {
+  &:before {
+    content: $icon-moon2;
+  }
+}
+.icon-bell3 {
+  &:before {
+    content: $icon-bell3;
+  }
+}
+.icon-folder3 {
+  &:before {
+    content: $icon-folder3;
+  }
+}
+.icon-pin2 {
+  &:before {
+    content: $icon-pin2;
+  }
+}
+.icon-sound {
+  &:before {
+    content: $icon-sound;
+  }
+}
+.icon-microphone2 {
+  &:before {
+    content: $icon-microphone2;
+  }
+}
+.icon-camera2 {
+  &:before {
+    content: $icon-camera2;
+  }
+}
+.icon-image2 {
+  &:before {
+    content: $icon-image2;
+  }
+}
+.icon-cog2 {
+  &:before {
+    content: $icon-cog2;
+  }
+}
+.icon-calendar {
+  &:before {
+    content: $icon-calendar;
+  }
+}
+.icon-book2 {
+  &:before {
+    content: $icon-book2;
+  }
+}
+.icon-map-marker {
+  &:before {
+    content: $icon-map-marker;
+  }
+}
+.icon-store {
+  &:before {
+    content: $icon-store;
+  }
+}
+.icon-support {
+  &:before {
+    content: $icon-support;
+  }
+}
+.icon-tag3 {
+  &:before {
+    content: $icon-tag3;
+  }
+}
+.icon-heart2 {
+  &:before {
+    content: $icon-heart2;
+  }
+}
+.icon-video-camera {
+  &:before {
+    content: $icon-video-camera;
+  }
+}
+.icon-trophy {
+  &:before {
+    content: $icon-trophy;
+  }
+}
+.icon-cart {
+  &:before {
+    content: $icon-cart;
+  }
+}
+.icon-eye3 {
+  &:before {
+    content: $icon-eye3;
+  }
+}
+.icon-cancel {
+  &:before {
+    content: $icon-cancel;
+  }
+}
+.icon-chart {
+  &:before {
+    content: $icon-chart;
+  }
+}
+.icon-target2 {
+  &:before {
+    content: $icon-target2;
+  }
+}
+.icon-printer2 {
+  &:before {
+    content: $icon-printer2;
+  }
+}
+.icon-location3 {
+  &:before {
+    content: $icon-location3;
+  }
+}
+.icon-bookmark2 {
+  &:before {
+    content: $icon-bookmark2;
+  }
+}
+.icon-monitor2 {
+  &:before {
+    content: $icon-monitor2;
+  }
+}
+.icon-cross2 {
+  &:before {
+    content: $icon-cross2;
+  }
+}
+.icon-plus2 {
+  &:before {
+    content: $icon-plus2;
+  }
+}
+.icon-left {
+  &:before {
+    content: $icon-left;
+  }
+}
+.icon-up {
+  &:before {
+    content: $icon-up;
+  }
+}
+.icon-browser {
+  &:before {
+    content: $icon-browser;
+  }
+}
+.icon-windows {
+  &:before {
+    content: $icon-windows;
+  }
+}
+.icon-switch {
+  &:before {
+    content: $icon-switch;
+  }
+}
+.icon-dashboard {
+  &:before {
+    content: $icon-dashboard;
+  }
+}
+.icon-play2 {
+  &:before {
+    content: $icon-play2;
+  }
+}
+.icon-fast-forward2 {
+  &:before {
+    content: $icon-fast-forward2;
+  }
+}
+.icon-next {
+  &:before {
+    content: $icon-next;
+  }
+}
+.icon-refresh2 {
+  &:before {
+    content: $icon-refresh2;
+  }
+}
+.icon-film {
+  &:before {
+    content: $icon-film;
+  }
+}
+.icon-home2 {
+  &:before {
+    content: $icon-home2;
+  }
+}

+ 142 - 0
client/scss/base/mixins.scss

@@ -0,0 +1,142 @@
+/**
+ * Clearfix
+ *
+ * @return     {string}  Clearfix attribute
+ */
+@mixin clearfix {
+	&:after {
+		content: "";
+		display: table;
+		clear: both;
+	}
+}
+
+/**
+ * Placeholder attribute for inputs
+ *
+ * @return     {string}  Placeholder attributes
+ */
+@mixin placeholder {
+	&::-webkit-input-placeholder {@content};
+	&::-moz-placeholder {@content}
+	&:-ms-input-placeholder {@content}
+	&:placeholder-shown {@content};
+}
+
+/**
+ * Spinner element
+ *
+ * @param      {string}  $color             - Color
+ * @param      {string}  $dur               - Animation Duration
+ * @param      {int}     $width             - Width
+ * @param      {int}     $height  [$width]  - height
+ *
+ * @return     {string}  Spinner element
+ */
+@mixin spinner($color,$dur,$width,$height:$width) {
+	width: $width;
+	height: $height;
+	border-radius: 50%;
+	box-shadow:0 0 0 1px rgba(0,0,0,0.1), 2px 1px 0 $color;
+	@include prefix(animation, spin $dur linear infinite);
+	@include keyframes(spin) {
+		100%{
+		 @include prefix(transform, rotate(360deg));
+		}
+	};
+}
+
+/**
+ * Prefixes for keyframes
+ *
+ * @param      {string}  $animation-name          - The animation name
+ *
+ * @return     {string}  Prefixed keyframes attributes
+ */
+@mixin keyframes($animation-name) {
+		@-webkit-keyframes #{$animation-name} {
+				@content;
+		}
+		@-moz-keyframes #{$animation-name} {
+				@content;
+		}
+		@-o-keyframes #{$animation-name} {
+				@content;
+		}
+		@keyframes #{$animation-name} {
+				@content;
+		}
+}
+
+/**
+ * Prefix function for browser compatibility
+ *
+ * @param      {string}  $property          - Property name
+ * @param      {any}     $value             - Property value
+ *
+ * @return     {string}  Prefixed attributes
+ */
+@mixin prefix($property, $value) {
+	-webkit-#{$property}: #{$value};
+		 -moz-#{$property}: #{$value};
+			-ms-#{$property}: #{$value};
+			 -o-#{$property}: #{$value};
+					#{$property}: #{$value};
+}
+
+/**
+ * Layout Mixins
+ */
+@mixin from($device) {
+  @media screen and (min-width: $device) {
+    @content;
+  }
+}
+
+@mixin until($device) {
+  @media screen and (max-width: $device - 1px) {
+    @content;
+  }
+}
+
+@mixin mobile {
+  @media screen and (max-width: $tablet - 1px) {
+    @content;
+  }
+}
+
+@mixin tablet {
+  @media screen and (min-width: $tablet) {
+    @content;
+  }
+}
+
+@mixin tablet-only {
+  @media screen and (min-width: $tablet) and (max-width: $desktop - 1px) {
+    @content;
+  }
+}
+
+@mixin touch {
+  @media screen and (max-width: $desktop - 1px) {
+    @content;
+  }
+}
+
+@mixin desktop {
+  @media screen and (min-width: $desktop) {
+    @content;
+  }
+}
+
+@mixin desktop-only {
+  @media screen and (min-width: $desktop) and (max-width: $widescreen - 1px) {
+    @content;
+  }
+}
+
+@mixin widescreen {
+  @media screen and (min-width: $widescreen) {
+    @content;
+  }
+}

+ 138 - 0
client/scss/base/reset.scss

@@ -0,0 +1,138 @@
+/*
+	HTML5 Reset :: style.css
+	----------------------------------------------------------
+	We have learned much from/been inspired by/taken code where offered from:
+	Eric Meyer					:: http://meyerweb.com
+	HTML5 Doctor				:: http://html5doctor.com
+	and the HTML5 Boilerplate	:: http://html5boilerplate.com
+-------------------------------------------------------------------------------*/
+
+/* Let's default this puppy out
+-------------------------------------------------------------------------------*/
+
+html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, menu, nav, section, time, mark, audio, video, details, summary {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font-weight: normal;
+	vertical-align: baseline;
+	background: transparent;
+}
+
+main, article, aside, figure, footer, header, nav, section, details, summary {display: block;}
+
+/* Handle box-sizing while better addressing child elements:
+   http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
+html {
+	box-sizing: border-box;
+}
+
+*,
+*:before,
+*:after {
+	box-sizing: inherit;
+}
+
+/* consider resetting the default cursor: https://gist.github.com/murtaugh/5247154 */
+
+/* Responsive images and other embedded objects */
+/* if you don't have full control over `img` tags (if you have to overcome attributes), consider adding height: auto */
+img,
+object,
+embed {max-width: 100%;}
+
+/*
+   Note: keeping IMG here will cause problems if you're using foreground images as sprites.
+	In fact, it *will* cause problems with Google Maps' controls at small size.
+	If this is the case for you, try uncommenting the following:
+#map img {
+		max-width: none;
+}
+*/
+
+/* force a vertical scrollbar to prevent a jumpy page */
+html {overflow-y: scroll;}
+
+/* we use a lot of ULs that aren't bulleted.
+	you'll have to restore the bullets within content,
+	which is fine because they're probably customized anyway */
+ul {list-style: none;}
+
+blockquote, q {quotes: none;}
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {content: ''; content: none;}
+
+a {margin: 0; padding: 0; font-size: 100%; vertical-align: baseline; background: transparent;}
+
+del {text-decoration: line-through;}
+
+abbr[title], dfn[title] {border-bottom: 1px dotted #000; cursor: help;}
+
+/* tables still need cellspacing="0" in the markup */
+table {border-collapse: separate; border-spacing: 0;}
+th {font-weight: bold; vertical-align: bottom;}
+td {font-weight: normal; vertical-align: top;}
+
+hr {display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0;}
+
+input, select {vertical-align: middle;}
+
+pre {
+    white-space: pre; /* CSS2 */
+    white-space: pre-wrap; /* CSS 2.1 */
+    white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
+    word-wrap: break-word; /* IE */
+}
+
+input[type="radio"] {vertical-align: text-bottom;}
+input[type="checkbox"] {vertical-align: bottom;}
+.ie7 input[type="checkbox"] {vertical-align: baseline;}
+.ie6 input {vertical-align: text-bottom;}
+
+select, input, textarea {font: 99% sans-serif;}
+
+table {font-size: inherit; font: 100%;}
+
+small {font-size: 85%;}
+
+strong {font-weight: bold;}
+
+td, td img {vertical-align: top;}
+
+/* Make sure sup and sub don't mess with your line-heights http://gist.github.com/413930 */
+sub, sup {font-size: 75%; line-height: 0; position: relative;}
+sup {top: -0.5em;}
+sub {bottom: -0.25em;}
+
+/* standardize any monospaced elements */
+pre, code, kbd, samp {font-family: monospace, sans-serif;}
+
+/* hand cursor on clickable elements */
+.clickable,
+label,
+input[type=button],
+input[type=submit],
+input[type=file],
+button {cursor: pointer;}
+
+/* Webkit browsers add a 2px margin outside the chrome of form elements */
+button, input, select, textarea {margin: 0;}
+
+/* make buttons play nice in IE */
+button,
+input[type=button] {width: auto; overflow: visible;}
+
+/* scale images in IE7 more attractively */
+.ie7 img {-ms-interpolation-mode: bicubic;}
+
+/* prevent BG image flicker upon hover
+   (commented out as usage is rare, and the filter syntax messes with some pre-processors)
+.ie6 html {filter: expression(document.execCommand("BackgroundImageCache", false, true));}
+*/
+
+/* let's clear some floats */
+.clearfix:after { content: " "; display: block; clear: both; }

+ 25 - 0
client/scss/base/variables.scss

@@ -0,0 +1,25 @@
+
+// --------------------------------------
+// FONTS
+// --------------------------------------
+
+$core-font-standard: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+$core-font-monospace: Consolas, "Liberation Mono", Menlo, Courier, monospace;
+
+// --------------------------------------
+// LAYOUT
+// --------------------------------------
+
+$tablet: 769px !default;
+$desktop: 980px !default;
+$widescreen: 1180px !default;
+
+// --------------------------------------
+// COLORS
+// --------------------------------------
+
+$color-text: mc('grey', '800');
+$color-link: mc('blue', '500');
+$color-link-hover: mc('blue', '700');
+$color-link-active: mc('purple', '500');
+$color-bg: #F4F5F9;

+ 114 - 0
client/scss/components/alert.scss

@@ -0,0 +1,114 @@
+/*#alerts {
+	position: fixed;
+	top: 60px;
+	right: 10px;
+	width: 350px;
+	z-index: 10;
+	text-shadow: 1px 1px 0 rgba(0,0,0,0.1);
+
+	.notification {
+		animation: 0.5s ease slideInRight;
+		margin-top: 5px;
+
+		&.exit {
+			animation: 0.5s ease fadeOutRight;
+		}
+
+	}
+
+	h3 {
+		font-size: 16px;
+		font-size: 500;
+	}
+
+}*/
+
+#alerts {
+	position: fixed;
+	top: 55px;
+	right: 10px;
+	width: 350px;
+	z-index: 100;
+
+	> ul {
+		margin: 0;
+		padding: 0;
+		list-style-type: none;
+
+		> li {
+			background-color: material-color('blue-grey', '800');
+			box-shadow: 5px 5px 0 transparentize(material-color('blue-grey', '900'), 0.7);
+			border: 1px solid material-color('blue-grey', '500');
+			border-left-width: 5px;
+			margin-top: 5px;
+			padding: 8px 12px;
+			animation-name: slideFromRight;
+			animation-duration: 1s;
+			cursor: pointer;
+			position: relative;
+
+			&:hover {
+				background-color: material-color('blue-grey', '900');
+			}
+
+			&.exit {
+				animation-name: zoomOut;
+				animation-duration: 1s;
+				transform-origin: top center;
+			}
+
+			> button {
+        background-color: transparent;
+        border: none;
+        color: #FFF;
+        width: 15px;
+        height: 15px;
+        padding: 0;
+        position: absolute;
+        top: 10px;
+        right: 10px;
+
+        &:before {
+          content: 'X';
+        }
+
+      }
+
+			> strong {
+				display: block;
+				font-size: 13px;
+				font-weight: 500;
+				color: #FFF;
+
+				> i {
+					margin-right: 5px;
+				}
+
+			}
+
+			> span {
+				font-size: 12px;
+				font-weight: 500;
+				color: material-color('blue-grey', '100');
+			}
+
+			&.error {
+				border-color: material-color('red', '400');
+				background-color: material-color('red', '600');
+				> span {
+					color: material-color('red', '50');
+				}
+			}
+			&.success {
+				border-color: material-color('green', '400');
+				background-color: material-color('green', '700');
+				> span {
+					color: material-color('green', '50');
+				}
+			}
+
+		}
+
+	}
+
+}

+ 122 - 0
client/scss/components/button.scss

@@ -0,0 +1,122 @@
+.button {
+	background-color: mc('orange','600');
+	color: #FFF;
+	border: 1px solid mc('orange','700');
+	border-radius: 3px;
+	display: inline-flex;
+	height: 30px;
+	align-items: center;
+	padding: 0 15px;
+	font-size: 13px;
+	font-weight: 600;
+	font-family: $core-font-standard;
+	margin: 0;
+	transition: all .4s ease;
+	cursor: pointer;
+	text-decoration: none;
+	text-transform: uppercase;
+
+	span {
+		font-weight: 600;
+		display: inline-flex;
+		align-items: center;
+		line-height: 14px;
+		height: 14px;
+	}
+
+	i {
+		margin-right: 8px;
+		font-size: 14px;
+		line-height: 14px;
+		height: 14px;
+	}
+
+	&:focus {
+		outline: none;
+		border-color: #FFF;
+	}
+
+	&:hover {
+		background-color: mc('orange','800');
+		text-decoration: none;
+	}
+
+	@each $color, $colorvalue in $material-colors {
+		&.is-#{$color} {
+			background-color: mc($color, '600');
+			border-color: mc($color,'700');
+			color: #FFF;
+
+			&.is-outlined {
+				background-color: #FFF;
+				color: mc($color,'700');
+			}
+
+			&.is-inverted {
+				background-color: rgba(mc($color, '800'), 0);
+				border-color: mc($color, '500');
+			}
+
+			&:hover {
+				background-color: mc($color,'800');
+				color: #FFF;
+				animation: none;
+			}
+		}
+
+	}
+
+	&.is-icon-only {
+		i {
+			margin-right: 0;
+		}
+	}
+
+	&.is-featured {
+		animation: btnInvertedPulse .6s ease alternate infinite;
+	}
+
+	&.is-disabled, &:disabled {
+		background-color: mc('grey', '300');
+		border: 1px solid mc('grey','400');
+		color: mc('grey', '500');
+		cursor: default;
+    transition: none;
+
+    &:hover {
+      background-color: mc('grey', '300') !important;
+      color: mc('grey', '500') !important;
+    }
+	}
+
+}
+
+.button-group {
+
+	.button {
+		border-radius: 0;
+		margin-left: 1px;
+
+		&:first-child {
+			margin-left: 0;
+			border-top-left-radius: 4px;
+			border-bottom-left-radius: 4px;
+		}
+
+		&:last-child {
+			border-top-right-radius: 4px;
+			border-bottom-right-radius: 4px;
+		}
+
+	}
+
+}
+
+@include keyframes(btnInvertedPulse) {
+	0% {
+		background-color: rgba(mc('grey', '500'), 0);
+	}
+	100% {
+		background-color: rgba(mc('grey', '500'), 0.25);
+	}
+}

+ 26 - 0
client/scss/components/footer.scss

@@ -0,0 +1,26 @@
+.footer {
+	background-color: mc('blue-grey','50');
+	border-bottom: 5px solid mc('blue-grey','100');
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 25px;
+	font-size: 13px;
+	font-weight: 500;
+	color: mc('blue-grey','500');
+
+	ul {
+		padding: 0;
+		margin: 0;
+		list-style-type: none;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+
+		li {
+			padding: 0 15px;
+		}
+
+	}
+
+}

+ 213 - 0
client/scss/components/form.scss

@@ -0,0 +1,213 @@
+
+.control {
+
+  & + .control {
+    margin-top: 15px;
+  }
+
+	// ===============================================================
+	// TEXTBOX
+	// ===============================================================
+
+	input[type=text], input[type=password] {
+		background-color: #FFF;
+		display: flex;
+		height: 30px;
+		align-items: center;
+		padding: 0 12px;
+		border: 1px solid mc('grey', '400');
+		border-radius: 3px;
+		font-family: $core-font-standard;
+		font-size: 14px;
+		color: mc('grey', '700');
+		transition: all .4s ease;
+		box-shadow: inset 0 0 5px 0 rgba(0,0,0,0.1);
+
+		&:focus {
+			outline: none;
+			border-color: mc('light-blue', '500');
+			box-shadow: inset 0 0 5px 0 rgba(mc('light-blue', '500'), 0.3);
+		}
+
+		&:disabled {
+			background-color: mc('grey', '100');
+		}
+
+    &.is-dirty.is-invalid {
+      border-color: mc('red', '500');
+      box-shadow: inset 0 0 5px 0 mc('red', '100');
+    }
+
+	}
+
+	&.is-fullwidth {
+
+		input[type=text], input[type=password], select, textarea {
+			width: 100%;
+		}
+
+	}
+
+	// ===============================================================
+	// DROPDOWN
+	// ===============================================================
+
+	select {
+		background-color: #FFF;
+		display: flex;
+		height: 30px;
+		align-items: center;
+		padding: 0 12px;
+		border: 1px solid mc('grey', '400');
+		border-radius: 3px;
+		font-family: $core-font-standard;
+		font-size: 14px;
+		color: mc('grey', '700');
+		transition: all .4s ease;
+		box-shadow: inset 0 0 5px 0 rgba(0,0,0,0.1);
+		cursor: pointer;
+
+		&:focus {
+			outline: none;
+			border-color: mc('light-blue', '500');
+			box-shadow: inset 0 0 5px 0 rgba(mc('light-blue', '500'), 0.3);
+		}
+
+		&:disabled {
+			background-color: mc('grey', '100');
+		}
+
+	}
+
+	// ===============================================================
+	// CHECKBOX / RADIO BUTTONS
+	// ===============================================================
+
+	input[type=radio], input[type=checkbox] {
+		position: absolute;
+	  left: -9999px;
+	  opacity: 0;
+
+	  & + label {
+			position: relative;
+			padding: 0 15px 0 25px;
+			cursor: pointer;
+			display: inline-block;
+			height: 25px;
+			line-height: 25px;
+			font-size: 14px;
+			transition: .28s ease;
+			@include prefix('user-select', none);
+
+			&:before, &:after {
+				content: '';
+				position: absolute;
+				left: 0;
+				top: 0;
+				margin: 4px;
+				border: 2px solid mc($primary, '600');
+				margin: 4px;
+		    width: 16px;
+		    height: 16px;
+		    border-radius: 50%;
+				z-index: 0;
+				transition: .28s ease;
+			}
+
+	  }
+
+	  &:checked + label {
+
+	  	&:before, &:after {
+				border-color: mc($primary, '600');
+			}
+
+			&:after {
+				@include prefix('transform', scale(0.5));
+				background-color: mc($primary, '600');
+			}
+
+	  }
+
+	}
+
+	input[type=checkbox] + label {
+		&:before, &:after {
+	    border-radius: 0;
+		}
+	}
+
+	.help {
+		font-size: 12px;
+
+		&.is-red {
+			color: mc('red','600');
+		}
+
+	}
+
+	& + label {
+		margin-top: 20px;
+	}
+
+	> i:first-child {
+		margin-right: 8px;
+	}
+
+}
+
+.label {
+	margin-bottom: 5px;
+	font-size: 14px;
+	font-weight: 500;
+	display: block;
+}
+
+.form-sections {
+
+	section {
+		border-top: 1px solid mc('grey', '200');
+		padding: 20px;
+		@include prefix(animation-duration, .6s);
+
+		&:first-child {
+			border-top: none;
+		}
+
+		.button + .button {
+			margin-left: 10px;
+		}
+
+    .desc {
+      display: inline-block;
+      padding: 10px 0 0 0px;
+      font-size: 12px;
+      color: mc('grey', '500');
+    }
+
+		.section-block {
+			padding-left: 20px;
+			font-size: 14px;
+			color: mc('blue-grey', '800');
+
+			h6 {
+				font-size: 14px;
+				font-weight: 500;
+				color: mc('blue-grey', '600');
+				margin-top: 15px;
+				border-bottom: 1px dotted mc('blue-grey', '200');
+			}
+
+			p {
+				padding: 5px 0;
+
+				&.is-small {
+					font-size: 13px;
+				}
+
+			}
+		}
+
+	}
+
+}

+ 501 - 0
client/scss/components/grid.scss

@@ -0,0 +1,501 @@
+.column {
+	flex-basis: 0;
+	flex-grow: 1;
+	flex-shrink: 1;
+	padding: 10px;
+
+	.columns.is-mobile > &.is-narrow {
+		flex: none;
+	}
+
+	.columns.is-mobile > &.is-full {
+		flex: none;
+		width: 100%;
+	}
+
+	.columns.is-mobile > &.is-three-quarters {
+		flex: none;
+		width: 75%;
+	}
+
+	.columns.is-mobile > &.is-two-thirds {
+		flex: none;
+		width: 66.6666%;
+	}
+
+	.columns.is-mobile > &.is-half {
+		flex: none;
+		width: 50%;
+	}
+
+	.columns.is-mobile > &.is-one-third {
+		flex: none;
+		width: 33.3333%;
+	}
+
+	.columns.is-mobile > &.is-one-quarter {
+		flex: none;
+		width: 25%;
+	}
+
+	.columns.is-mobile > &.is-offset-three-quarters {
+		margin-left: 75%;
+	}
+
+	.columns.is-mobile > &.is-offset-two-thirds {
+		margin-left: 66.6666%;
+	}
+
+	.columns.is-mobile > &.is-offset-half {
+		margin-left: 50%;
+	}
+
+	.columns.is-mobile > &.is-offset-one-third {
+		margin-left: 33.3333%;
+	}
+
+	.columns.is-mobile > &.is-offset-one-quarter {
+		margin-left: 25%;
+	}
+
+	@for $i from 1 through 12 {
+		.columns.is-mobile > &.is-#{$i} {
+			flex: none;
+			width: $i / 12 * 100%;
+		}
+
+		.columns.is-mobile > &.is-offset-#{$i} {
+			margin-left: $i / 12 * 100%;
+		}
+	}
+
+	@include mobile {
+		&.is-narrow-mobile {
+			flex: none;
+		}
+
+		&.is-full-mobile {
+			flex: none;
+			width: 100%;
+		}
+
+		&.is-three-quarters-mobile {
+			flex: none;
+			width: 75%;
+		}
+
+		&.is-two-thirds-mobile {
+			flex: none;
+			width: 66.6666%;
+		}
+
+		&.is-half-mobile {
+			flex: none;
+			width: 50%;
+		}
+
+		&.is-one-third-mobile {
+			flex: none;
+			width: 33.3333%;
+		}
+
+		&.is-one-quarter-mobile {
+			flex: none;
+			width: 25%;
+		}
+
+		&.is-offset-three-quarters-mobile {
+			margin-left: 75%;
+		}
+
+		&.is-offset-two-thirds-mobile {
+			margin-left: 66.6666%;
+		}
+
+		&.is-offset-half-mobile {
+			margin-left: 50%;
+		}
+
+		&.is-offset-one-third-mobile {
+			margin-left: 33.3333%;
+		}
+
+		&.is-offset-one-quarter-mobile {
+			margin-left: 25%;
+		}
+
+		@for $i from 1 through 12 {
+			&.is-#{$i}-mobile {
+				flex: none;
+				width: $i / 12 * 100%;
+			}
+
+			&.is-offset-#{$i}-mobile {
+				margin-left: $i / 12 * 100%;
+			}
+		}
+	}
+
+
+	@include tablet {
+		&.is-narrow,
+		&.is-narrow-tablet {
+			flex: none;
+		}
+
+		&.is-full,
+		&.is-full-tablet {
+			flex: none;
+			width: 100%;
+		}
+
+		&.is-three-quarters,
+		&.is-three-quarters-tablet {
+			flex: none;
+			width: 75%;
+		}
+
+		&.is-two-thirds,
+		&.is-two-thirds-tablet {
+			flex: none;
+			width: 66.6666%;
+		}
+
+		&.is-half,
+		&.is-half-tablet {
+			flex: none;
+			width: 50%;
+		}
+
+		&.is-one-third,
+		&.is-one-third-tablet {
+			flex: none;
+			width: 33.3333%;
+		}
+
+		&.is-one-quarter,
+		&.is-one-quarter-tablet {
+			flex: none;
+			width: 25%;
+		}
+
+		&.is-offset-three-quarters,
+		&.is-offset-three-quarters-tablet {
+			margin-left: 75%;
+		}
+
+		&.is-offset-two-thirds,
+		&.is-offset-two-thirds-tablet {
+			margin-left: 66.6666%;
+		}
+
+		&.is-offset-half,
+		&.is-offset-half-tablet {
+			margin-left: 50%;
+		}
+
+		&.is-offset-one-third,
+		&.is-offset-one-third-tablet {
+			margin-left: 33.3333%;
+		}
+
+		&.is-offset-one-quarter,
+		&.is-offset-one-quarter-tablet {
+			margin-left: 25%;
+		}
+
+		@for $i from 1 through 12 {
+			&.is-#{$i},
+			&.is-#{$i}-tablet {
+				flex: none;
+				width: $i / 12 * 100%;
+			}
+
+			&.is-offset-#{$i},
+			&.is-offset-#{$i}-tablet {
+				margin-left: $i / 12 * 100%;
+			}
+		}
+	}
+
+
+	@include desktop {
+		&.is-narrow-desktop {
+			flex: none;
+		}
+
+		&.is-full-desktop {
+			flex: none;
+			width: 100%;
+		}
+
+		&.is-three-quarters-desktop {
+			flex: none;
+			width: 75%;
+		}
+
+		&.is-two-thirds-desktop {
+			flex: none;
+			width: 66.6666%;
+		}
+
+		&.is-half-desktop {
+			flex: none;
+			width: 50%;
+		}
+
+		&.is-one-third-desktop {
+			flex: none;
+			width: 33.3333%;
+		}
+
+		&.is-one-quarter-desktop {
+			flex: none;
+			width: 25%;
+		}
+
+		&.is-offset-three-quarters-desktop {
+			margin-left: 75%;
+		}
+
+		&.is-offset-two-thirds-desktop {
+			margin-left: 66.6666%;
+		}
+
+		&.is-offset-half-desktop {
+			margin-left: 50%;
+		}
+
+		&.is-offset-one-third-desktop {
+			margin-left: 33.3333%;
+		}
+
+		&.is-offset-one-quarter-desktop {
+			margin-left: 25%;
+		}
+
+		@for $i from 1 through 12 {
+			&.is-#{$i}-desktop {
+				flex: none;
+				width: $i / 12 * 100%;
+			}
+
+			&.is-offset-#{$i}-desktop {
+				margin-left: $i / 12 * 100%;
+			}
+		}
+	}
+
+
+	@include widescreen {
+		&.is-narrow-widescreen {
+			flex: none;
+		}
+
+		&.is-full-widescreen {
+			flex: none;
+			width: 100%;
+		}
+
+		&.is-three-quarters-widescreen {
+			flex: none;
+			width: 75%;
+		}
+
+		&.is-two-thirds-widescreen {
+			flex: none;
+			width: 66.6666%;
+		}
+
+		&.is-half-widescreen {
+			flex: none;
+			width: 50%;
+		}
+
+		&.is-one-third-widescreen {
+			flex: none;
+			width: 33.3333%;
+		}
+
+		&.is-one-quarter-widescreen {
+			flex: none;
+			width: 25%;
+		}
+
+		&.is-offset-three-quarters-widescreen {
+			margin-left: 75%;
+		}
+
+		&.is-offset-two-thirds-widescreen {
+			margin-left: 66.6666%;
+		}
+
+		&.is-offset-half-widescreen {
+			margin-left: 50%;
+		}
+
+		&.is-offset-one-third-widescreen {
+			margin-left: 33.3333%;
+		}
+
+		&.is-offset-one-quarter-widescreen {
+			margin-left: 25%;
+		}
+
+		@for $i from 1 through 12 {
+			&.is-#{$i}-widescreen {
+				flex: none;
+				width: $i / 12 * 100%;
+			}
+
+			&.is-offset-#{$i}-widescreen {
+				margin-left: $i / 12 * 100%;
+			}
+		}
+	}
+}
+
+.columns {
+	margin-left: -10px;
+	margin-right: -10px;
+	margin-top: -10px;
+
+	&:last-child {
+		margin-bottom: -10px;
+	}
+
+	&:not(:last-child) {
+		margin-bottom: 10px;
+	}
+
+	// Modifiers
+	&.is-centered {
+		justify-content: center;
+	}
+
+	&.is-gapless {
+		margin-left: 0;
+		margin-right: 0;
+		margin-top: 0;
+
+		&:last-child {
+			margin-bottom: 0;
+		}
+
+		&:not(:last-child) {
+			margin-bottom: 20px;
+		}
+
+		& > .column {
+			margin: 0;
+			padding: 0;
+		}
+	}
+
+	&.is-stretched {
+		flex-grow: 1;
+		align-items: stretch;
+		align-self: stretch;
+	}
+
+	&.is-grid {
+		// Responsiveness
+		@include tablet {
+			flex-wrap: wrap;
+
+			& > .column {
+				max-width: 33.3333%;
+				padding: 10px;
+				width: 33.3333%;
+
+				& + .column {
+					margin-left: 0;
+				}
+			}
+		}
+	}
+
+	&.is-mobile {
+		display: flex;
+	}
+
+	&.is-multiline {
+		flex-wrap: wrap;
+	}
+
+	&.is-vcentered {
+		align-items: center;
+	}
+
+	// Responsiveness
+	@include tablet {
+		&:not(.is-desktop) {
+			display: flex;
+		}
+	}
+
+
+	@include desktop {
+		// Modifiers
+		&.is-desktop {
+			display: flex;
+		}
+	}
+}
+
+.tile {
+	align-items: stretch;
+	flex-basis: auto;
+	flex-grow: 1;
+	flex-shrink: 1;
+	min-height: min-content;
+
+	// Modifiers
+	&.is-ancestor {
+		margin-left: -10px;
+		margin-right: -10px;
+		margin-top: -10px;
+
+		&:last-child {
+			margin-bottom: -10px;
+		}
+
+		&:not(:last-child) {
+			margin-bottom: 10px;
+		}
+	}
+
+	&.is-child {
+		margin: 0 !important;
+	}
+
+	&.is-parent {
+		padding: 10px;
+	}
+
+	&.is-vertical {
+		flex-direction: column;
+
+		& > .tile.is-child:not(:last-child) {
+			margin-bottom: 20px !important;
+		}
+	}
+
+	// Responsiveness
+	@include tablet {
+		&:not(.is-child) {
+			display: flex;
+		}
+
+		@for $i from 1 through 12 {
+			&.is-#{$i} {
+				flex: none;
+				width: $i / 12 * 100%;
+			}
+		}
+	}
+}
+
+.column.is-white {
+	background-color: #FFF;
+}

+ 68 - 0
client/scss/components/hero.scss

@@ -0,0 +1,68 @@
+.hero {
+	padding: 20px;
+	background-color: mc('grey', '50');
+	border-bottom: 1px solid mc('grey', '200');
+	position: relative;
+
+	h1 {
+		font-size: 28px;
+		color: mc($primary, '500');
+		font-weight: 300;
+	}
+
+	h2 {
+		font-size: 18px;
+		color: mc('grey', '500');
+		font-weight: 400;
+	}
+
+	.hero-menu {
+		position: absolute;
+		right: 20px;
+		bottom: -1px;
+		z-index: 1;
+		display: flex;
+
+		li {
+			display: flex;
+			margin-left: 1px;
+
+			a, button {
+				background-color: mc('light-blue', '500');
+				color: #FFF;
+				display: inline-flex;
+				align-items: center;
+				justify-items: center;
+				padding: 0 15px;
+				height: 32px;
+				border: 1px solid mc('light-blue', '600');
+				font-family: $core-font-standard;
+				font-size: 13px;
+				transition: all 0.4s ease;
+				cursor: pointer;
+				text-decoration: none;
+				text-transform: uppercase;
+
+				i {
+					margin-right: 10px;
+				}
+
+				@each $color, $colorvalue in $material-colors {
+					&.is-#{$color} {
+						background-color: mc($color, '600');
+						border-color: mc($color, '600');
+
+						&:hover {
+							background-color: mc($color, '800');
+						}
+
+					}
+				}
+
+			}
+
+		}
+
+	}
+
+}

+ 62 - 0
client/scss/components/list.scss

@@ -0,0 +1,62 @@
+.list {
+	background-color: #FFF;
+	min-height: 25px;
+
+	.list-header {
+		background-color: mc('grey','100');
+		height: 30px;
+		display: flex;
+		align-items: center;
+		padding: 0 20px;
+		text-transform: uppercase;
+		font-size: 13px;
+		color: mc($primary,'500');
+		text-shadow: 1px 1px 0 #FFF;
+		
+		span {
+			font-weight: 500;
+		}
+	
+		i {
+			margin-right: 10px;
+		}
+
+	}
+
+	.list-row {
+		border-top: 1px solid mc('grey','100');
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 10px 20px;
+
+		&:first-child {
+			border-top: none;
+		}
+
+	}
+
+	.list-item {
+		display: flex;
+		justify-content: flex-start;
+		align-items: center;
+	}
+
+	.list-icon {
+		margin-right: 15px;
+		color: mc('grey','500');
+	}
+	.list-content {
+		display: flex;
+		flex-direction: column;
+
+		strong {
+			color: mc('grey','700');
+		}
+		span {
+			color: mc('grey','600');	
+		}
+
+	}
+
+}

+ 355 - 0
client/scss/components/markdown-content.scss

@@ -0,0 +1,355 @@
+.mkcontent {
+	font-size: 14px;
+	color: mc('grey', '700');
+	padding: 0 0 20px 0;
+
+	h1, h2, h3 {
+		font-weight: 400;
+		margin: 10px 0 0;
+		padding: 7px 20px;
+		font-weight: 500;
+	}
+
+	h1 {
+		background-color: mc('indigo', '50');
+		border-bottom: 2px solid mc('indigo', '100');
+		font-size: 18px;
+		color: mc('indigo', '500');
+
+		&:first-child {
+			margin-top: 1px;
+		}
+
+		/*& + h2 {
+			margin-top: 1px;
+			border-top: none;
+		}*/
+
+		& + p {
+			padding-top: 20px;
+		}
+
+	}
+
+	h2 {
+		background-color: lighten(mc('teal', '50'), 5%);
+		border: 1px solid mc('teal', '100');
+		border-right-width: 5px;
+		border-top-left-radius: 3px;
+		border-bottom-left-radius: 3px;
+		font-size: 16px;
+		color: mc('teal', '900');
+		margin-left: 20px;
+	}
+
+	.indent-h2 {
+		border-right: 5px solid mc('teal', '100');
+		margin-left: 20px;
+		padding-top: 1px;
+		padding-bottom: 20px;
+		overflow: hidden;
+
+		& + h1, & + h2 {
+			margin-top: 1px;
+		}
+
+		&:last-child {
+			padding-bottom: 5px;
+		}
+
+		h3:first-child {
+			margin-top: 0;
+			border-top: none;
+		}
+
+	}
+
+	h3 {
+		background-color: lighten(mc('blue', '50'), 3%);
+		border: 1px solid mc('blue', '100');
+		border-right-width: 5px;
+		border-top-left-radius: 3px;
+		border-bottom-left-radius: 3px;
+		font-size: 14px;
+		color: mc('blue', '700');
+		margin-left: 20px;
+		margin-right: 1px;
+		padding: 5px 20px;
+	}
+
+	.indent-h3 {
+		border-right: 5px solid mc('teal', '100');
+		margin-left: 20px;
+		margin-right: 1px;
+		padding-bottom: 10px;
+
+		& + h1, & + h2, & + h3 {
+			margin-top: 1px;
+		}
+
+		&:last-child {
+			padding-bottom: 0;
+		}
+
+	}
+
+	a {
+		text-decoration: underline;
+		font-weight: 400;
+
+		&:hover {
+			color: mc('blue', '700');
+		}
+
+		&.toc-anchor {
+			font-size: 80%;
+			color: mc('indigo', '300');
+			border-bottom: none;
+			text-decoration: none;
+
+			&:visited {
+				color: mc('indigo', '300') !important;
+			}
+
+		}
+
+		&.external-link {
+			position: relative;
+			padding-left: 5px;
+			//display: inline-flex;
+			//align-items: center;
+
+			&:before {
+				content: $icon-open;
+				display: inline-block;
+				font-family: 'core-icons';
+				font-style: normal;
+				font-weight: normal;
+				text-decoration: none;
+				color: mc('grey', '500');
+				font-size: 14px;
+				margin-right: 5px;
+			}
+
+			&:hover:before {
+				text-decoration: none;
+			}
+
+		}
+
+	}
+
+	ul {
+		padding: 10px 0 10px 40px;
+		list-style-type: square;
+
+		li {
+			padding: 1px 0;
+
+			> ul {
+				padding: 5px 0 5px 15px;
+				list-style-type: disc;
+			}
+
+			p {
+				padding: 0;
+
+				&:first-child {
+					padding: 0;
+				}
+
+			}
+
+		}
+
+	}
+
+	ol {
+		padding: 10px 40px;
+		list-style-type: decimal;
+
+		li {
+			padding: 1px 0;
+		}
+
+	}
+
+	p {
+		padding: 10px 20px;
+
+		&:first-child {
+			padding-top: 20px;
+		}
+
+		&.is-gapless {
+			padding: 0 20px;
+
+			& + p {
+				padding-top: 20px;
+			}
+
+			& + h1 {
+				margin-top: 1px;
+			}
+
+		}
+
+	}
+
+	table {
+		width: auto;
+		border-collapse: collapse;
+		margin: 10px 20px;
+		font-size: 14px;
+
+		th {
+			background-color: mc('blue', '500');
+			color: #FFF;
+			border: 1px solid mc('blue', '500');
+			padding: 5px 15px;
+
+			&:first-child {
+				border-left-color: mc('blue', '500');
+			}
+
+			&:last-child {
+				border-right-color: mc('blue', '500');
+			}
+
+		}
+
+		td {
+			border: 1px solid mc('grey', '500');
+			padding: 5px 15px;
+		}
+
+		tr:nth-child(even) {
+			background-color: mc('grey', '100');
+		}
+
+	}
+
+	code {
+		font-weight: 500;
+		color: mc('purple', '500');
+		background-color: lighten(mc('purple', '50'), 5%);
+		padding: 0 5px;
+		border-radius: 4px;
+	}
+
+	pre {
+		background-color: mc('grey', '50');
+		border-top: 1px solid mc('grey', '100');
+		box-shadow: inset 0 0 5px 0 rgba(mc('grey', '500'), 0.3);
+		padding: 20px;
+		font-family: $core-font-monospace;
+		white-space: pre;
+
+		> code {
+			box-shadow: inset 0 0 5px 0 mc('grey', '100');
+			border-radius: 5px;
+			font-weight: 400;
+			background-color: none;
+			color: mc('grey', '700');
+			padding: 0;
+		}
+
+		& + p {
+			padding-top: 1em;
+		}
+
+		& + h1, & + h2, & + h3 {
+			margin-top: 1px;
+		}
+
+	}
+
+	.align-right {
+		float:right;
+    margin: 0 0 10px 10px;
+    max-width: 30vw;
+	}
+  .align-center {
+		text-align: center;
+	}
+
+	img.pagelogo {
+		position: absolute;
+		right: 20px;
+		top: 20px;
+		max-width: 200px;
+		max-height: 100px;
+		z-index: 3;
+	}
+
+	strong {
+		color: mc('grey', '700');
+	}
+
+	.twa {
+		font-size: 120%;
+	}
+
+	hr {
+		margin: 20px;
+		border-top: 1px dotted mc('grey', '500');
+	}
+
+	blockquote {
+		background-color: mc('teal', '50');
+		border: 1px solid mc('teal', '100');
+		border-bottom-width: 2px;
+		box-shadow: inset 0px 0px 0px 1px rgba(255,255,255,1);
+		border-radius: 5px;
+		padding: 0 10px;
+		margin: 10px 20px;
+
+		p {
+			padding: 10px 0;
+			color: mc('teal', '800');
+
+			&:first-child {
+				padding: 10px 0;
+			}
+
+			strong {
+				color: inherit;
+			}
+
+		}
+
+		&.is-danger {
+			background-color: mc('red', '100');
+			border-color: mc('red', '200');
+			p {
+				color: mc('red', '900');
+			}
+		}
+
+		&.is-warning {
+			background-color: mc('amber', '50');
+			border-color: mc('amber', '200');
+			p {
+				color: darken(mc('amber', '900'), 10%);
+			}
+		}
+
+		&.is-success {
+			background-color: mc('green', '50');
+			border-color: mc('green', '200');
+			p {
+				color: darken(mc('green', '900'), 10%);
+			}
+		}
+
+		&.is-info {
+			background-color: mc('blue', '50');
+			border-color: mc('blue', '200');
+			p {
+				color: darken(mc('blue', '900'), 10%);
+			}
+		}
+
+	}
+
+}

+ 356 - 0
client/scss/components/modal.scss

@@ -0,0 +1,356 @@
+.modal {
+	align-items: flex-start;
+	display: none;
+
+	&.is-active {
+		display: block;
+	}
+
+	&.is-superimposed {
+		.modal-background {
+			z-index: 20;
+		}
+		.modal-container {
+			z-index: 21;
+		}
+	}
+
+}
+.modal-background {
+	top: 0;
+	left: 0;
+	width: 100vw;
+	height: 100vh;
+	position: fixed;
+	background-color: rgba(0,0,0,0.85);
+	animation: .4s ease fadeIn;
+	z-index: 10;
+}
+.modal-container {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	z-index: 11;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+.modal-content {
+	animation: .3s ease zoomIn;
+	width: 600px;
+	background-color: #FFF;
+
+	&.is-expanded {
+		align-self: stretch;
+		width: 100%;
+		margin: 20px;
+		display: flex;
+		flex-direction: column;
+
+		> section {
+			flex-grow: 1;
+		}
+
+	}
+
+	header {
+		background-color: mc('teal', '600');
+		color: #FFF;
+		display: flex;
+		flex-shrink: 0;
+		height: 40px;
+		align-items: center;
+		font-weight: 400;
+		font-size: 16px;
+		padding: 0 20px;
+		position: relative;
+
+		@each $color, $colorvalue in $material-colors {
+			&.is-#{$color} {
+				background-color: mc($color, '600');
+			}
+		}
+
+		.modal-notify {
+			position: absolute;
+			display: none;
+			align-items: center;
+			height: 40px;
+			right: 20px;
+			top: 0;
+
+			&.is-active {
+				display: flex;
+			}
+
+			span {
+				font-size: 12px;
+				letter-spacing: 1px;
+				text-transform: uppercase;
+			}
+
+			i {
+				margin-left: 15px;
+				display: inline-block;
+				@include spinner(#FFF, .5s, 20px);
+			}
+
+		}
+
+	}
+
+	section {
+		padding: 20px;
+		border-top: 1px dotted mc('grey', '300');
+
+		&:first-of-type {
+			border-top: none;
+			padding-top: 20px;
+		}
+		&:last-of-type {
+			padding-bottom: 20px;
+		}
+
+		&.is-gapless {
+			padding: 10px;
+			display: flex;
+		}
+
+		&.modal-loading {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+
+			> i {
+				display: block;
+				@include spinner(mc('blue','500'), .4s, 32px);
+				margin-bottom: 10px;
+			}
+
+			> span {
+				color: mc('grey', '600');
+			}
+
+			> em {
+				font-size: 12px;
+				color: mc('grey', '500');
+				font-style: normal;
+			}
+
+		}
+
+		&.modal-instructions {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			color: mc('grey', '800');
+
+			img {
+				height: 100px;
+
+				& + * {
+					margin-top: 10px;
+				}
+
+			}
+
+			i.is-huge {
+				font-size: 72px;
+				margin-bottom: 10px;
+			}
+
+			> span {
+				color: mc('grey', '800');
+			}
+
+			> em {
+				font-size: 12px;
+				color: mc('grey', '600');
+				font-style: normal;
+				margin-top: 10px;
+				display: block;
+			}
+
+		}
+
+		.bullets {
+			list-style-type: square;
+			padding: 5px 0 0 30px;
+			font-size: 14px;
+			color: mc('grey', '800');
+		}
+
+		.note {
+			display: block;
+			margin-top: 10px;
+			font-size: 14px;
+			color: mc('grey', '800');
+
+			&:first-child {
+				margin-top: 0;
+			}
+
+			ul {
+				color: mc('grey', '800');
+				padding-left: 10px;
+
+				li {
+					margin-top: 5px;
+					display: flex;
+					align-items: center;
+
+					> i {
+						margin-right: 8px;
+						font-size: 18px;
+					}
+
+				}
+			}
+
+		}
+
+	}
+
+	footer {
+		padding: 20px;
+		text-align: right;
+
+		.button {
+			margin-left: 10px;
+		}
+
+	}
+
+}
+
+.modal-toolbar {
+	background-color: mc('teal', '700');
+	padding: 7px 20px;
+	display: flex;
+	flex-shrink: 0;
+	justify-content: center;
+
+	@each $color, $colorvalue in $material-colors {
+		&.is-#{$color} {
+			background-color: mc($color, '700');
+
+			.button {
+				border-color: mc($color, '900');
+				background-color: mc($color, '900');
+
+				&:hover {
+					border-color: mc($color, '900');
+					background-color: mc($color, '800');
+				}
+
+			}
+
+		}
+	}
+
+	// BUTTONS
+
+	.button {
+		border: 1px solid mc('teal', '900');
+		background-color: mc('teal', '900');
+		transition: all .4s ease;
+		color: #FFF;
+		border-radius: 0;
+
+		&:first-child {
+			border-top-left-radius: 4px;
+			border-bottom-left-radius: 4px;
+		}
+
+		&:last-child {
+			border-top-right-radius: 4px;
+			border-bottom-right-radius: 4px;
+		}
+
+		&:hover {
+			border-color: mc('teal', '900');
+			background-color: mc('teal', '800');
+			color: #FFF;
+		}
+
+	}
+
+	.button + .button {
+		margin-left: 1px;
+	}
+
+}
+
+.modal-sidebar {
+
+	background-color: mc('teal', '50');
+	padding: 0;
+	//padding: 7px 20px;
+
+	@each $color, $colorvalue in $material-colors {
+		&.is-#{$color} {
+			background-color: mc($color, '50');
+
+			.model-sidebar-header {
+				background-color: mc($color, '100');
+				color: mc($color, '800');
+			}
+
+			.model-sidebar-list > li a {
+				&:hover {
+					background-color: mc($color, '200');
+				}
+				&.is-active {
+					background-color: mc($color, '500');
+				}
+			}
+
+		}
+	}
+
+	.model-sidebar-header {
+		padding: 7px 20px;
+	}
+
+	.model-sidebar-content {
+		padding: 7px 20px;
+	}
+
+	.model-sidebar-list {
+
+		> li {
+			padding: 0;
+
+			a {
+				display: flex;
+				align-items: center;
+				height: 34px;
+				padding: 0 20px;
+				cursor: pointer;
+				color: mc('grey', '800');
+
+				&:hover {
+					background-color: mc('teal', '200');
+				}
+
+				&.is-active {
+					color: #FFF;
+				}
+
+				i {
+					margin-right: 7px;
+				}
+
+			}
+
+		}
+
+	}
+
+}
+
+.modal-content .card-footer-item.featured {
+	animation: flash 4s ease 0 infinite;
+}

+ 182 - 0
client/scss/components/nav.scss

@@ -0,0 +1,182 @@
+
+.nav {
+	align-items: stretch;
+	background-color: mc($primary, '500');
+	display: flex;
+	min-height: 50px;
+	position: relative;
+	text-align: center;
+	box-shadow: 0 2px 3px rgba(mc($primary, '500'), 0.2);
+	z-index: 2;
+	color: #FFF;
+
+	@each $color, $colorvalue in $material-colors {
+		&.is-#{$color} {
+			background-color: mc($color, '500');
+			box-shadow: 0 2px 3px rgba(mc($color, '500'), 0.2);
+
+			.nav-item {
+
+				.button {
+					border: 1px solid mc($color, '900');
+					background-color: mc($color, '800');
+
+					&.is-outlined {
+						background-color: mc($color, '600');
+						border-color: mc($color, '800');
+						color: mc($color, '100');
+					}
+
+					&:hover {
+						border-color: mc($color, '900');
+						background-color: mc($color, '900');
+					}
+
+				}
+
+			}
+
+		}
+	}
+
+}
+
+.nav-left {
+	align-items: stretch;
+	display: flex;
+	flex-basis: 0;
+	flex-grow: 1;
+	justify-content: flex-start;
+	overflow: hidden;
+	overflow-x: auto;
+	white-space: nowrap;
+}
+
+.nav-center {
+	align-items: stretch;
+	display: flex;
+	justify-content: center;
+	margin-left: auto;
+	margin-right: auto;
+}
+
+.nav-right {
+	@include tablet {
+		align-items: stretch;
+		display: flex;
+		flex-basis: 0;
+		flex-grow: 1;
+		justify-content: flex-end;
+	}
+}
+
+.nav-item {
+	align-items: center;
+	display: flex;
+	justify-content: center;
+	padding: 0 10px;
+
+	// LINKS
+
+	@at-root .nav-item a, a.nav-item {
+		color: mc($primary, '50');
+		transition: color .4s ease;
+		cursor: pointer;
+
+		&:hover {
+			color: mc($primary, '200');
+			text-decoration: none;
+		}
+
+	}
+
+	// LOGO
+
+	img {
+		max-height: 34px;
+	}
+
+	// HEADERS
+
+	h1 {
+		font-size: 16px;
+		font-weight: 400;
+		letter-spacing: 0.5px;
+		text-transform: uppercase;
+		transition: color .4s ease;
+		color: #FFF;
+		padding-left: 10px;
+
+		i {
+			margin-right: 8px;
+		}
+
+		&:hover {
+			color: mc('indigo', '100');
+		}
+	}
+
+	@at-root h2.nav-item, .nav-item h2 {
+		color: mc($primary, '50');
+	}
+
+	// BUTTONS
+
+	.button {
+		border: 1px solid mc($primary, '900');
+		background-color: mc($primary, '800');
+		transition: all .4s ease;
+		color: #FFF;
+		border-radius: 0;
+
+		&:first-child {
+			border-top-left-radius: 4px;
+			border-bottom-left-radius: 4px;
+		}
+
+		&:last-child {
+			border-top-right-radius: 4px;
+			border-bottom-right-radius: 4px;
+		}
+
+		&.is-outlined {
+			background-color: mc($primary, '600');
+			border-color: mc($primary, '800');
+			color: mc($primary, '100');
+		}
+
+		&:hover {
+			border-color: mc($primary, '900');
+			background-color: mc($primary, '900');
+			color: #FFF;
+		}
+
+	}
+
+	.button + .button {
+		margin-left: 1px;
+	}
+
+	// INPUTS
+
+	.control {
+
+		input[type=text] {
+			background-color: mc($primary, '800');
+			border-color: mc($primary, '400');
+			color: mc($primary, '50');
+
+			&:focus {
+				border-color: mc($primary, '200');
+				box-shadow: inset 0 0 5px 0 rgba(mc($primary, '900'), 0.5);
+			}
+
+			@include placeholder {
+				color: mc($primary, '200');
+			}
+
+		}
+
+	}
+
+}

+ 112 - 0
client/scss/components/panel.scss

@@ -0,0 +1,112 @@
+
+.panel-aside {
+	background-color: mc('blue-grey', '800');
+	border: 1px solid mc('blue-grey', '800');
+	border-bottom-left-radius: 8px;
+	padding: 20px;
+	color: mc('blue-grey','100');
+
+	label {
+		color: #FFF;
+	}
+
+}
+
+.panel {
+  background-color: #FFF;
+  box-shadow: 0 0 12px 0 rgba(mc('grey','800'), .10), 1px 6px 8px 0 rgba(mc('grey','800'), .10);
+  padding: 0 0 1px 0;
+  border-radius: 4px;
+
+  .panel-title {
+    border-bottom: 1px solid darken($color-bg, 5%);
+    padding: 0 15px;
+    color: $color-text;
+    font-size: 16px;
+    font-weight: 500;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 40px;
+
+    &.is-featured {
+      border-top-left-radius: 4px;
+      border-top-right-radius: 4px;
+      background-color: mc('indigo', '300');
+      border-bottom-color: mc('indigo', '400');
+      color: #FFF;
+
+      > i::before {
+        @include spinner(#FFF, 0.4s, 18px);
+      }
+
+    }
+
+    > span {
+      font-weight: 500;
+    }
+
+    > i {
+      display: flex;
+      width: 18px;
+      align-items: center;
+
+      &::before {
+        content: " ";
+        @include spinner(mc($primary,'500'), 0.4s, 18px);
+      }
+    }
+
+  }
+
+  .panel-content {
+    padding: 0 15px;
+
+    &.is-text {
+      padding: 25px;
+
+      p + p, p + h3 {
+        margin-top: 25px;
+      }
+
+      h3 {
+        margin-bottom: 15px;
+        font-weight: 500;
+      }
+
+      ul li {
+        color: mc('grey', '700');
+      }
+
+      strong {
+        font-weight: 500;
+        color: mc($primary,'800');
+      }
+
+    }
+
+  }
+
+  .panel-footer {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    height: 50px;
+    background-color: $color-bg;
+    padding: 0 15px;
+    margin: 0 1px;
+    border-bottom-left-radius: 4px;
+    border-bottom-right-radius: 4px;
+    position: relative;
+
+    .button + .button {
+      margin-left: 10px;
+    }
+
+  }
+
+  + .panel {
+    margin-top: 25px;
+  }
+
+}

+ 57 - 0
client/scss/components/search.scss

@@ -0,0 +1,57 @@
+.searchresults {
+	position: fixed;
+	top: 45px;
+	left: 0;
+	right: 0;
+	margin: 0 auto;
+	width: 500px;
+	z-index: 1;
+	background-color: mc($primary, '700');
+	border-bottom: 5px solid mc($primary, '800');
+	box-shadow: 0 0 5px mc($primary, '500');
+	color: #FFF;
+
+	&.slideInDown {
+		@include prefix(animation-duration, .6s);
+	}
+
+	.searchresults-label {
+		color: mc($primary, '200');
+		padding: 15px 10px 10px;
+		font-size: 13px;
+		text-transform: uppercase;
+		border-bottom: 1px dotted mc($primary, '400');
+	}
+
+	.searchresults-list {
+
+		> li {
+			display: flex;
+			font-size: 14px;
+			transition: background-color .3s linear;
+
+			&:nth-child(odd) {
+				background-color: mc($primary, '600');
+			}
+
+			&.is-active, &:hover {
+				background-color: mc($primary, '400');
+				color: #FFF;
+				border-left: 5px solid mc($primary, '200');
+			}
+
+			a {
+				color: mc($primary, '50');
+				display: flex;
+				align-items: center;
+				height: 30px;
+				padding: 0 20px;
+				width: 100%;
+				cursor: pointer;
+			}
+
+		}
+
+	}
+
+}

+ 83 - 0
client/scss/components/sidebar.scss

@@ -0,0 +1,83 @@
+
+.sidebar {
+	background-color: mc('blue-grey', '900');
+	color: mc('blue-grey', '50');
+	width: 250px;
+	max-width: 250px;
+	min-height: 80vh;
+
+	aside {
+
+		&:last-child {
+			padding-bottom: 20px;
+		}
+
+		.sidebar-label {
+			padding: 0 0 5px 0;
+			color: mc('blue-grey', '400');
+			font-size: 13px;
+			letter-spacing: 1px;
+			text-transform: uppercase;
+			border-bottom: 1px solid mc('blue-grey', '700');
+			margin: 25px 10px 15px 10px;
+
+			i {
+				margin-right: 5px;
+			}
+
+		}
+
+		.sidebar-menu {
+
+			li {
+				display: block;
+
+				a {
+					display: flex;
+					min-height: 30px;
+					align-items: center;
+					padding: 5px 20px;
+					color: mc('blue-grey', '50');
+					font-size: 14px;
+					transition: all .4s ease;
+					line-height: 14px;
+
+					i {
+						margin-right: 7px;
+						color: mc('blue-grey', '300');
+					}
+
+					&:hover {
+						color: mc('blue-grey', '400');
+						text-decoration: none;
+					}
+
+				}
+
+				> ul {
+					border-top: 1px solid lighten(mc('blue-grey', '900'), 3%);
+					border-bottom: 1px solid lighten(mc('blue-grey', '900'), 2%);
+					background-color: darken(mc('blue-grey', '900'), 2%);
+					margin-bottom: 10px;
+					padding: 10px 0;
+
+					li {
+						padding-left: 10px;
+						//border-left: 5px solid mc('blue-grey', '800');
+
+						a {
+							min-height: 24px;
+							color: mc('blue-grey', '100');
+						}
+
+					}
+
+				}
+
+			}
+
+		}
+
+	}
+
+}

+ 90 - 0
client/scss/components/table.scss

@@ -0,0 +1,90 @@
+.table {
+	border-spacing: collapse;
+	padding: 1px;
+	width: 100%;
+	font-size: 14px;
+
+	thead {
+		background-color: mc('blue-grey', '500');
+		color: #FFF;
+
+		th {
+			padding: 5px 10px;
+			font-weight: 500;
+			text-align: center;
+			border-left: 1px solid mc('blue-grey', '200');
+
+			&:first-child {
+				border-left: none;
+			}
+
+		}
+
+		@each $color, $colorvalue in $material-colors {
+			&.is-#{$color} {
+				background-color: mc($color, '500');
+
+				th {
+					border-left-color: mc($color, '200');
+				}
+
+			}
+		}
+
+	}
+
+	tbody {
+
+		tr {
+			background-color: mc('blue-grey', '100');
+
+			&:nth-child(odd) {
+				background-color: mc('blue-grey', '50');
+			}
+
+			td {
+				padding: 5px 10px;
+				border-left: 1px solid #FFF;
+				vertical-align: middle;
+
+				&:first-child {
+					border-left: none;
+				}
+
+			}
+
+		}
+
+	}
+
+	.is-centered {
+		text-align: center;
+	}
+
+	.has-icons i {
+		margin-right: 8px;
+	}
+
+	.is-icon {
+		font-size: 14px;
+		width: 20px;
+	}
+
+	.has-action-icons {
+		i {
+			cursor: pointer;
+			font-size: 20px;
+		}
+	}
+
+}
+
+.table-actions {
+	text-align: right;
+
+	.button {
+		border-top-left-radius: 0;
+		border-top-right-radius: 0;
+	}
+
+}

+ 16 - 0
client/scss/components/typography.scss

@@ -0,0 +1,16 @@
+
+h1 {
+	font-size: 28px;
+}
+h2 {
+	font-size: 18px;
+}
+h3 {
+	font-size: 16px;
+}
+
+@each $color, $colorvalue in $material-colors {
+	i.is-#{$color} {
+		color: mc($color, '600');
+	}
+}

+ 3486 - 0
client/scss/libs/animate.scss

@@ -0,0 +1,3486 @@
+@charset "UTF-8";
+
+/*!
+ * animate.css -http://daneden.me/animate
+ * Version - 3.5.1
+ * Licensed under the MIT license - http://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016 Daniel Eden
+ */
+
+.animated {
+  -webkit-animation-duration: 1s;
+  animation-duration: 1s;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+  &.infinite {
+    -webkit-animation-iteration-count: infinite;
+    animation-iteration-count: infinite;
+  }
+  &.hinge {
+    -webkit-animation-duration: 2s;
+    animation-duration: 2s;
+  }
+  &.flipOutX, &.flipOutY, &.bounceIn, &.bounceOut {
+    -webkit-animation-duration: .75s;
+    animation-duration: .75s;
+  }
+}
+
+@-webkit-keyframes bounce {
+  from, 20%, 53%, 80%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  40%, 43% {
+    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    -webkit-transform: translate3d(0, -30px, 0);
+    transform: translate3d(0, -30px, 0);
+  }
+
+  70% {
+    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    -webkit-transform: translate3d(0, -15px, 0);
+    transform: translate3d(0, -15px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, -4px, 0);
+    transform: translate3d(0, -4px, 0);
+  }
+}
+
+
+@keyframes bounce {
+  from, 20%, 53%, 80%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  40%, 43% {
+    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    -webkit-transform: translate3d(0, -30px, 0);
+    transform: translate3d(0, -30px, 0);
+  }
+
+  70% {
+    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+    -webkit-transform: translate3d(0, -15px, 0);
+    transform: translate3d(0, -15px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, -4px, 0);
+    transform: translate3d(0, -4px, 0);
+  }
+}
+
+
+.bounce {
+  -webkit-animation-name: bounce;
+  animation-name: bounce;
+  -webkit-transform-origin: center bottom;
+  transform-origin: center bottom;
+}
+
+@-webkit-keyframes flash {
+  from, 50%, to {
+    opacity: 1;
+  }
+
+  25%, 75% {
+    opacity: 0;
+  }
+}
+
+
+@keyframes flash {
+  from, 50%, to {
+    opacity: 1;
+  }
+
+  25%, 75% {
+    opacity: 0;
+  }
+}
+
+
+.flash {
+  -webkit-animation-name: flash;
+  animation-name: flash;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes pulse {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  50% {
+    -webkit-transform: scale3d(1.05, 1.05, 1.05);
+    transform: scale3d(1.05, 1.05, 1.05);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+@keyframes pulse {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  50% {
+    -webkit-transform: scale3d(1.05, 1.05, 1.05);
+    transform: scale3d(1.05, 1.05, 1.05);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+.pulse {
+  -webkit-animation-name: pulse;
+  animation-name: pulse;
+}
+
+@-webkit-keyframes rubberBand {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  30% {
+    -webkit-transform: scale3d(1.25, 0.75, 1);
+    transform: scale3d(1.25, 0.75, 1);
+  }
+
+  40% {
+    -webkit-transform: scale3d(0.75, 1.25, 1);
+    transform: scale3d(0.75, 1.25, 1);
+  }
+
+  50% {
+    -webkit-transform: scale3d(1.15, 0.85, 1);
+    transform: scale3d(1.15, 0.85, 1);
+  }
+
+  65% {
+    -webkit-transform: scale3d(0.95, 1.05, 1);
+    transform: scale3d(0.95, 1.05, 1);
+  }
+
+  75% {
+    -webkit-transform: scale3d(1.05, 0.95, 1);
+    transform: scale3d(1.05, 0.95, 1);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+@keyframes rubberBand {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  30% {
+    -webkit-transform: scale3d(1.25, 0.75, 1);
+    transform: scale3d(1.25, 0.75, 1);
+  }
+
+  40% {
+    -webkit-transform: scale3d(0.75, 1.25, 1);
+    transform: scale3d(0.75, 1.25, 1);
+  }
+
+  50% {
+    -webkit-transform: scale3d(1.15, 0.85, 1);
+    transform: scale3d(1.15, 0.85, 1);
+  }
+
+  65% {
+    -webkit-transform: scale3d(0.95, 1.05, 1);
+    transform: scale3d(0.95, 1.05, 1);
+  }
+
+  75% {
+    -webkit-transform: scale3d(1.05, 0.95, 1);
+    transform: scale3d(1.05, 0.95, 1);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+.rubberBand {
+  -webkit-animation-name: rubberBand;
+  animation-name: rubberBand;
+}
+
+@-webkit-keyframes shake {
+  from, to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  10%, 30%, 50%, 70%, 90% {
+    -webkit-transform: translate3d(-10px, 0, 0);
+    transform: translate3d(-10px, 0, 0);
+  }
+
+  20%, 40%, 60%, 80% {
+    -webkit-transform: translate3d(10px, 0, 0);
+    transform: translate3d(10px, 0, 0);
+  }
+}
+
+
+@keyframes shake {
+  from, to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  10%, 30%, 50%, 70%, 90% {
+    -webkit-transform: translate3d(-10px, 0, 0);
+    transform: translate3d(-10px, 0, 0);
+  }
+
+  20%, 40%, 60%, 80% {
+    -webkit-transform: translate3d(10px, 0, 0);
+    transform: translate3d(10px, 0, 0);
+  }
+}
+
+
+.shake {
+  -webkit-animation-name: shake;
+  animation-name: shake;
+}
+
+@-webkit-keyframes headShake {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  6.5% {
+    -webkit-transform: translateX(-6px) rotateY(-9deg);
+    transform: translateX(-6px) rotateY(-9deg);
+  }
+
+  18.5% {
+    -webkit-transform: translateX(5px) rotateY(7deg);
+    transform: translateX(5px) rotateY(7deg);
+  }
+
+  31.5% {
+    -webkit-transform: translateX(-3px) rotateY(-5deg);
+    transform: translateX(-3px) rotateY(-5deg);
+  }
+
+  43.5% {
+    -webkit-transform: translateX(2px) rotateY(3deg);
+    transform: translateX(2px) rotateY(3deg);
+  }
+
+  50% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+
+@keyframes headShake {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  6.5% {
+    -webkit-transform: translateX(-6px) rotateY(-9deg);
+    transform: translateX(-6px) rotateY(-9deg);
+  }
+
+  18.5% {
+    -webkit-transform: translateX(5px) rotateY(7deg);
+    transform: translateX(5px) rotateY(7deg);
+  }
+
+  31.5% {
+    -webkit-transform: translateX(-3px) rotateY(-5deg);
+    transform: translateX(-3px) rotateY(-5deg);
+  }
+
+  43.5% {
+    -webkit-transform: translateX(2px) rotateY(3deg);
+    transform: translateX(2px) rotateY(3deg);
+  }
+
+  50% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+
+.headShake {
+  -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-name: headShake;
+  animation-name: headShake;
+}
+
+@-webkit-keyframes swing {
+  20% {
+    -webkit-transform: rotate3d(0, 0, 1, 15deg);
+    transform: rotate3d(0, 0, 1, 15deg);
+  }
+
+  40% {
+    -webkit-transform: rotate3d(0, 0, 1, -10deg);
+    transform: rotate3d(0, 0, 1, -10deg);
+  }
+
+  60% {
+    -webkit-transform: rotate3d(0, 0, 1, 5deg);
+    transform: rotate3d(0, 0, 1, 5deg);
+  }
+
+  80% {
+    -webkit-transform: rotate3d(0, 0, 1, -5deg);
+    transform: rotate3d(0, 0, 1, -5deg);
+  }
+
+  to {
+    -webkit-transform: rotate3d(0, 0, 1, 0deg);
+    transform: rotate3d(0, 0, 1, 0deg);
+  }
+}
+
+
+@keyframes swing {
+  20% {
+    -webkit-transform: rotate3d(0, 0, 1, 15deg);
+    transform: rotate3d(0, 0, 1, 15deg);
+  }
+
+  40% {
+    -webkit-transform: rotate3d(0, 0, 1, -10deg);
+    transform: rotate3d(0, 0, 1, -10deg);
+  }
+
+  60% {
+    -webkit-transform: rotate3d(0, 0, 1, 5deg);
+    transform: rotate3d(0, 0, 1, 5deg);
+  }
+
+  80% {
+    -webkit-transform: rotate3d(0, 0, 1, -5deg);
+    transform: rotate3d(0, 0, 1, -5deg);
+  }
+
+  to {
+    -webkit-transform: rotate3d(0, 0, 1, 0deg);
+    transform: rotate3d(0, 0, 1, 0deg);
+  }
+}
+
+
+.swing {
+  -webkit-transform-origin: top center;
+  transform-origin: top center;
+  -webkit-animation-name: swing;
+  animation-name: swing;
+}
+
+@-webkit-keyframes tada {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  10%, 20% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
+    transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
+  }
+
+  30%, 50%, 70%, 90% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+  }
+
+  40%, 60%, 80% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+@keyframes tada {
+  from {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+
+  10%, 20% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
+    transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
+  }
+
+  30%, 50%, 70%, 90% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+  }
+
+  40%, 60%, 80% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+  }
+
+  to {
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+.tada {
+  -webkit-animation-name: tada;
+  animation-name: tada;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes wobble {
+  from {
+    -webkit-transform: none;
+    transform: none;
+  }
+
+  15% {
+    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+  }
+
+  30% {
+    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+  }
+
+  45% {
+    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+  }
+
+  60% {
+    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+  }
+
+  75% {
+    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes wobble {
+  from {
+    -webkit-transform: none;
+    transform: none;
+  }
+
+  15% {
+    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+  }
+
+  30% {
+    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+  }
+
+  45% {
+    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+  }
+
+  60% {
+    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+  }
+
+  75% {
+    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.wobble {
+  -webkit-animation-name: wobble;
+  animation-name: wobble;
+}
+
+@-webkit-keyframes jello {
+  from, 11.1%, to {
+    -webkit-transform: none;
+    transform: none;
+  }
+
+  22.2% {
+    -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);
+    transform: skewX(-12.5deg) skewY(-12.5deg);
+  }
+
+  33.3% {
+    -webkit-transform: skewX(6.25deg) skewY(6.25deg);
+    transform: skewX(6.25deg) skewY(6.25deg);
+  }
+
+  44.4% {
+    -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);
+    transform: skewX(-3.125deg) skewY(-3.125deg);
+  }
+
+  55.5% {
+    -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);
+    transform: skewX(1.5625deg) skewY(1.5625deg);
+  }
+
+  66.6% {
+    -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);
+    transform: skewX(-0.78125deg) skewY(-0.78125deg);
+  }
+
+  77.7% {
+    -webkit-transform: skewX(0.39063deg) skewY(0.39063deg);
+    transform: skewX(0.39063deg) skewY(0.39063deg);
+  }
+
+  88.8% {
+    -webkit-transform: skewX(-0.19531deg) skewY(-0.19531deg);
+    transform: skewX(-0.19531deg) skewY(-0.19531deg);
+  }
+}
+
+
+@keyframes jello {
+  from, 11.1%, to {
+    -webkit-transform: none;
+    transform: none;
+  }
+
+  22.2% {
+    -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);
+    transform: skewX(-12.5deg) skewY(-12.5deg);
+  }
+
+  33.3% {
+    -webkit-transform: skewX(6.25deg) skewY(6.25deg);
+    transform: skewX(6.25deg) skewY(6.25deg);
+  }
+
+  44.4% {
+    -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);
+    transform: skewX(-3.125deg) skewY(-3.125deg);
+  }
+
+  55.5% {
+    -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);
+    transform: skewX(1.5625deg) skewY(1.5625deg);
+  }
+
+  66.6% {
+    -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);
+    transform: skewX(-0.78125deg) skewY(-0.78125deg);
+  }
+
+  77.7% {
+    -webkit-transform: skewX(0.39063deg) skewY(0.39063deg);
+    transform: skewX(0.39063deg) skewY(0.39063deg);
+  }
+
+  88.8% {
+    -webkit-transform: skewX(-0.19531deg) skewY(-0.19531deg);
+    transform: skewX(-0.19531deg) skewY(-0.19531deg);
+  }
+}
+
+
+.jello {
+  -webkit-animation-name: jello;
+  animation-name: jello;
+  -webkit-transform-origin: center;
+  transform-origin: center;
+}
+
+@-webkit-keyframes bounceIn {
+  from, 20%, 40%, 60%, 80%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  20% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1);
+    transform: scale3d(1.1, 1.1, 1.1);
+  }
+
+  40% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9);
+    transform: scale3d(0.9, 0.9, 0.9);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(1.03, 1.03, 1.03);
+    transform: scale3d(1.03, 1.03, 1.03);
+  }
+
+  80% {
+    -webkit-transform: scale3d(0.97, 0.97, 0.97);
+    transform: scale3d(0.97, 0.97, 0.97);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+@keyframes bounceIn {
+  from, 20%, 40%, 60%, 80%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  20% {
+    -webkit-transform: scale3d(1.1, 1.1, 1.1);
+    transform: scale3d(1.1, 1.1, 1.1);
+  }
+
+  40% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9);
+    transform: scale3d(0.9, 0.9, 0.9);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(1.03, 1.03, 1.03);
+    transform: scale3d(1.03, 1.03, 1.03);
+  }
+
+  80% {
+    -webkit-transform: scale3d(0.97, 0.97, 0.97);
+    transform: scale3d(0.97, 0.97, 0.97);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: scale3d(1, 1, 1);
+    transform: scale3d(1, 1, 1);
+  }
+}
+
+
+.bounceIn {
+  -webkit-animation-name: bounceIn;
+  animation-name: bounceIn;
+}
+
+@-webkit-keyframes bounceInDown {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -3000px, 0);
+    transform: translate3d(0, -3000px, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 25px, 0);
+    transform: translate3d(0, 25px, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(0, -10px, 0);
+    transform: translate3d(0, -10px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, 5px, 0);
+    transform: translate3d(0, 5px, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes bounceInDown {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -3000px, 0);
+    transform: translate3d(0, -3000px, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 25px, 0);
+    transform: translate3d(0, 25px, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(0, -10px, 0);
+    transform: translate3d(0, -10px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, 5px, 0);
+    transform: translate3d(0, 5px, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.bounceInDown {
+  -webkit-animation-name: bounceInDown;
+  animation-name: bounceInDown;
+}
+
+@-webkit-keyframes bounceInLeft {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: translate3d(-3000px, 0, 0);
+    transform: translate3d(-3000px, 0, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(25px, 0, 0);
+    transform: translate3d(25px, 0, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(-10px, 0, 0);
+    transform: translate3d(-10px, 0, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(5px, 0, 0);
+    transform: translate3d(5px, 0, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes bounceInLeft {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  0% {
+    opacity: 0;
+    -webkit-transform: translate3d(-3000px, 0, 0);
+    transform: translate3d(-3000px, 0, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(25px, 0, 0);
+    transform: translate3d(25px, 0, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(-10px, 0, 0);
+    transform: translate3d(-10px, 0, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(5px, 0, 0);
+    transform: translate3d(5px, 0, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.bounceInLeft {
+  -webkit-animation-name: bounceInLeft;
+  animation-name: bounceInLeft;
+}
+
+@-webkit-keyframes bounceInRight {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(3000px, 0, 0);
+    transform: translate3d(3000px, 0, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(-25px, 0, 0);
+    transform: translate3d(-25px, 0, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(10px, 0, 0);
+    transform: translate3d(10px, 0, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(-5px, 0, 0);
+    transform: translate3d(-5px, 0, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes bounceInRight {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(3000px, 0, 0);
+    transform: translate3d(3000px, 0, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(-25px, 0, 0);
+    transform: translate3d(-25px, 0, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(10px, 0, 0);
+    transform: translate3d(10px, 0, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(-5px, 0, 0);
+    transform: translate3d(-5px, 0, 0);
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.bounceInRight {
+  -webkit-animation-name: bounceInRight;
+  animation-name: bounceInRight;
+}
+
+@-webkit-keyframes bounceInUp {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 3000px, 0);
+    transform: translate3d(0, 3000px, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, -20px, 0);
+    transform: translate3d(0, -20px, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(0, 10px, 0);
+    transform: translate3d(0, 10px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, -5px, 0);
+    transform: translate3d(0, -5px, 0);
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+@keyframes bounceInUp {
+  from, 60%, 75%, 90%, to {
+    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+  }
+
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 3000px, 0);
+    transform: translate3d(0, 3000px, 0);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, -20px, 0);
+    transform: translate3d(0, -20px, 0);
+  }
+
+  75% {
+    -webkit-transform: translate3d(0, 10px, 0);
+    transform: translate3d(0, 10px, 0);
+  }
+
+  90% {
+    -webkit-transform: translate3d(0, -5px, 0);
+    transform: translate3d(0, -5px, 0);
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+.bounceInUp {
+  -webkit-animation-name: bounceInUp;
+  animation-name: bounceInUp;
+}
+
+@-webkit-keyframes bounceOut {
+  20% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9);
+    transform: scale3d(0.9, 0.9, 0.9);
+  }
+
+  50%, 55% {
+    opacity: 1;
+    -webkit-transform: scale3d(1.1, 1.1, 1.1);
+    transform: scale3d(1.1, 1.1, 1.1);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+}
+
+
+@keyframes bounceOut {
+  20% {
+    -webkit-transform: scale3d(0.9, 0.9, 0.9);
+    transform: scale3d(0.9, 0.9, 0.9);
+  }
+
+  50%, 55% {
+    opacity: 1;
+    -webkit-transform: scale3d(1.1, 1.1, 1.1);
+    transform: scale3d(1.1, 1.1, 1.1);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+}
+
+
+.bounceOut {
+  -webkit-animation-name: bounceOut;
+  animation-name: bounceOut;
+}
+
+@-webkit-keyframes bounceOutDown {
+  20% {
+    -webkit-transform: translate3d(0, 10px, 0);
+    transform: translate3d(0, 10px, 0);
+  }
+
+  40%, 45% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, -20px, 0);
+    transform: translate3d(0, -20px, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+}
+
+
+@keyframes bounceOutDown {
+  20% {
+    -webkit-transform: translate3d(0, 10px, 0);
+    transform: translate3d(0, 10px, 0);
+  }
+
+  40%, 45% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, -20px, 0);
+    transform: translate3d(0, -20px, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+}
+
+
+.bounceOutDown {
+  -webkit-animation-name: bounceOutDown;
+  animation-name: bounceOutDown;
+}
+
+@-webkit-keyframes bounceOutLeft {
+  20% {
+    opacity: 1;
+    -webkit-transform: translate3d(20px, 0, 0);
+    transform: translate3d(20px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+}
+
+
+@keyframes bounceOutLeft {
+  20% {
+    opacity: 1;
+    -webkit-transform: translate3d(20px, 0, 0);
+    transform: translate3d(20px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+}
+
+
+.bounceOutLeft {
+  -webkit-animation-name: bounceOutLeft;
+  animation-name: bounceOutLeft;
+}
+
+@-webkit-keyframes bounceOutRight {
+  20% {
+    opacity: 1;
+    -webkit-transform: translate3d(-20px, 0, 0);
+    transform: translate3d(-20px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+}
+
+
+@keyframes bounceOutRight {
+  20% {
+    opacity: 1;
+    -webkit-transform: translate3d(-20px, 0, 0);
+    transform: translate3d(-20px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+}
+
+
+.bounceOutRight {
+  -webkit-animation-name: bounceOutRight;
+  animation-name: bounceOutRight;
+}
+
+@-webkit-keyframes bounceOutUp {
+  20% {
+    -webkit-transform: translate3d(0, -10px, 0);
+    transform: translate3d(0, -10px, 0);
+  }
+
+  40%, 45% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 20px, 0);
+    transform: translate3d(0, 20px, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+}
+
+
+@keyframes bounceOutUp {
+  20% {
+    -webkit-transform: translate3d(0, -10px, 0);
+    transform: translate3d(0, -10px, 0);
+  }
+
+  40%, 45% {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 20px, 0);
+    transform: translate3d(0, 20px, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+}
+
+
+.bounceOutUp {
+  -webkit-animation-name: bounceOutUp;
+  animation-name: bounceOutUp;
+}
+
+@-webkit-keyframes fadeIn {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+
+.fadeIn {
+  -webkit-animation-name: fadeIn;
+  animation-name: fadeIn;
+}
+
+@-webkit-keyframes fadeInDown {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInDown {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInDown {
+  -webkit-animation-name: fadeInDown;
+  animation-name: fadeInDown;
+}
+
+@-webkit-keyframes fadeInDownBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInDownBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInDownBig {
+  -webkit-animation-name: fadeInDownBig;
+  animation-name: fadeInDownBig;
+}
+
+@-webkit-keyframes fadeInLeft {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInLeft {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInLeft {
+  -webkit-animation-name: fadeInLeft;
+  animation-name: fadeInLeft;
+}
+
+@-webkit-keyframes fadeInLeftBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInLeftBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInLeftBig {
+  -webkit-animation-name: fadeInLeftBig;
+  animation-name: fadeInLeftBig;
+}
+
+@-webkit-keyframes fadeInRight {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInRight {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInRight {
+  -webkit-animation-name: fadeInRight;
+  animation-name: fadeInRight;
+}
+
+@-webkit-keyframes fadeInRightBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInRightBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInRightBig {
+  -webkit-animation-name: fadeInRightBig;
+  animation-name: fadeInRightBig;
+}
+
+@-webkit-keyframes fadeInUp {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInUp {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInUp {
+  -webkit-animation-name: fadeInUp;
+  animation-name: fadeInUp;
+}
+
+@-webkit-keyframes fadeInUpBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes fadeInUpBig {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.fadeInUpBig {
+  -webkit-animation-name: fadeInUpBig;
+  animation-name: fadeInUpBig;
+}
+
+@-webkit-keyframes fadeOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
+
+@keyframes fadeOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
+
+.fadeOut {
+  -webkit-animation-name: fadeOut;
+  animation-name: fadeOut;
+}
+
+@-webkit-keyframes fadeOutDown {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+
+
+@keyframes fadeOutDown {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+
+
+.fadeOutDown {
+  -webkit-animation-name: fadeOutDown;
+  animation-name: fadeOutDown;
+}
+
+@-webkit-keyframes fadeOutDownBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+}
+
+
+@keyframes fadeOutDownBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 2000px, 0);
+    transform: translate3d(0, 2000px, 0);
+  }
+}
+
+
+.fadeOutDownBig {
+  -webkit-animation-name: fadeOutDownBig;
+  animation-name: fadeOutDownBig;
+}
+
+@-webkit-keyframes fadeOutLeft {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+
+
+@keyframes fadeOutLeft {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+
+
+.fadeOutLeft {
+  -webkit-animation-name: fadeOutLeft;
+  animation-name: fadeOutLeft;
+}
+
+@-webkit-keyframes fadeOutLeftBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+}
+
+
+@keyframes fadeOutLeftBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(-2000px, 0, 0);
+    transform: translate3d(-2000px, 0, 0);
+  }
+}
+
+
+.fadeOutLeftBig {
+  -webkit-animation-name: fadeOutLeftBig;
+  animation-name: fadeOutLeftBig;
+}
+
+@-webkit-keyframes fadeOutRight {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+
+
+@keyframes fadeOutRight {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+
+
+.fadeOutRight {
+  -webkit-animation-name: fadeOutRight;
+  animation-name: fadeOutRight;
+}
+
+@-webkit-keyframes fadeOutRightBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+}
+
+
+@keyframes fadeOutRightBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(2000px, 0, 0);
+    transform: translate3d(2000px, 0, 0);
+  }
+}
+
+
+.fadeOutRightBig {
+  -webkit-animation-name: fadeOutRightBig;
+  animation-name: fadeOutRightBig;
+}
+
+@-webkit-keyframes fadeOutUp {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+
+
+@keyframes fadeOutUp {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+
+
+.fadeOutUp {
+  -webkit-animation-name: fadeOutUp;
+  animation-name: fadeOutUp;
+}
+
+@-webkit-keyframes fadeOutUpBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+}
+
+
+@keyframes fadeOutUpBig {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -2000px, 0);
+    transform: translate3d(0, -2000px, 0);
+  }
+}
+
+
+.fadeOutUpBig {
+  -webkit-animation-name: fadeOutUpBig;
+  animation-name: fadeOutUpBig;
+}
+
+@-webkit-keyframes flip {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  50% {
+    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95);
+    transform: perspective(400px) scale3d(0.95, 0.95, 0.95);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+}
+
+
+@keyframes flip {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  50% {
+    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95);
+    transform: perspective(400px) scale3d(0.95, 0.95, 0.95);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+}
+
+
+.animated.flip {
+  -webkit-backface-visibility: visible;
+  backface-visibility: visible;
+  -webkit-animation-name: flip;
+  animation-name: flip;
+}
+
+@-webkit-keyframes flipInX {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  60% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+}
+
+
+@keyframes flipInX {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  60% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+}
+
+
+.flipInX {
+  -webkit-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipInX;
+  animation-name: flipInX;
+}
+
+@-webkit-keyframes flipInY {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  60% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+}
+
+
+@keyframes flipInY {
+  from {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  60% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+  }
+
+  to {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+}
+
+
+.flipInY {
+  -webkit-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipInY;
+  animation-name: flipInY;
+}
+
+@-webkit-keyframes flipOutX {
+  from {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+
+  30% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes flipOutX {
+  from {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+
+  30% {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    opacity: 0;
+  }
+}
+
+
+.flipOutX {
+  -webkit-animation-name: flipOutX;
+  animation-name: flipOutX;
+  -webkit-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+}
+
+@-webkit-keyframes flipOutY {
+  from {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+
+  30% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes flipOutY {
+  from {
+    -webkit-transform: perspective(400px);
+    transform: perspective(400px);
+  }
+
+  30% {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+    opacity: 0;
+  }
+}
+
+
+.flipOutY {
+  -webkit-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipOutY;
+  animation-name: flipOutY;
+}
+
+@-webkit-keyframes lightSpeedIn {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+    transform: translate3d(100%, 0, 0) skewX(-30deg);
+    opacity: 0;
+  }
+
+  60% {
+    -webkit-transform: skewX(20deg);
+    transform: skewX(20deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: skewX(-5deg);
+    transform: skewX(-5deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes lightSpeedIn {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+    transform: translate3d(100%, 0, 0) skewX(-30deg);
+    opacity: 0;
+  }
+
+  60% {
+    -webkit-transform: skewX(20deg);
+    transform: skewX(20deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: skewX(-5deg);
+    transform: skewX(-5deg);
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.lightSpeedIn {
+  -webkit-animation-name: lightSpeedIn;
+  animation-name: lightSpeedIn;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+}
+
+@-webkit-keyframes lightSpeedOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+    transform: translate3d(100%, 0, 0) skewX(30deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes lightSpeedOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+    transform: translate3d(100%, 0, 0) skewX(30deg);
+    opacity: 0;
+  }
+}
+
+
+.lightSpeedOut {
+  -webkit-animation-name: lightSpeedOut;
+  animation-name: lightSpeedOut;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
+}
+
+@-webkit-keyframes rotateIn {
+  from {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: rotate3d(0, 0, 1, -200deg);
+    transform: rotate3d(0, 0, 1, -200deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes rotateIn {
+  from {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: rotate3d(0, 0, 1, -200deg);
+    transform: rotate3d(0, 0, 1, -200deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.rotateIn {
+  -webkit-animation-name: rotateIn;
+  animation-name: rotateIn;
+}
+
+@-webkit-keyframes rotateInDownLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes rotateInDownLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.rotateInDownLeft {
+  -webkit-animation-name: rotateInDownLeft;
+  animation-name: rotateInDownLeft;
+}
+
+@-webkit-keyframes rotateInDownRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes rotateInDownRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.rotateInDownRight {
+  -webkit-animation-name: rotateInDownRight;
+  animation-name: rotateInDownRight;
+}
+
+@-webkit-keyframes rotateInUpLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes rotateInUpLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.rotateInUpLeft {
+  -webkit-animation-name: rotateInUpLeft;
+  animation-name: rotateInUpLeft;
+}
+
+@-webkit-keyframes rotateInUpRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -90deg);
+    transform: rotate3d(0, 0, 1, -90deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+@keyframes rotateInUpRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -90deg);
+    transform: rotate3d(0, 0, 1, -90deg);
+    opacity: 0;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: none;
+    transform: none;
+    opacity: 1;
+  }
+}
+
+
+.rotateInUpRight {
+  -webkit-animation-name: rotateInUpRight;
+  animation-name: rotateInUpRight;
+}
+
+@-webkit-keyframes rotateOut {
+  from {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: rotate3d(0, 0, 1, 200deg);
+    transform: rotate3d(0, 0, 1, 200deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes rotateOut {
+  from {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: center;
+    transform-origin: center;
+    -webkit-transform: rotate3d(0, 0, 1, 200deg);
+    transform: rotate3d(0, 0, 1, 200deg);
+    opacity: 0;
+  }
+}
+
+
+.rotateOut {
+  -webkit-animation-name: rotateOut;
+  animation-name: rotateOut;
+}
+
+@-webkit-keyframes rotateOutDownLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes rotateOutDownLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    transform: rotate3d(0, 0, 1, 45deg);
+    opacity: 0;
+  }
+}
+
+
+.rotateOutDownLeft {
+  -webkit-animation-name: rotateOutDownLeft;
+  animation-name: rotateOutDownLeft;
+}
+
+@-webkit-keyframes rotateOutDownRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes rotateOutDownRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+}
+
+
+.rotateOutDownRight {
+  -webkit-animation-name: rotateOutDownRight;
+  animation-name: rotateOutDownRight;
+}
+
+@-webkit-keyframes rotateOutUpLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes rotateOutUpLeft {
+  from {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate3d(0, 0, 1, -45deg);
+    transform: rotate3d(0, 0, 1, -45deg);
+    opacity: 0;
+  }
+}
+
+
+.rotateOutUpLeft {
+  -webkit-animation-name: rotateOutUpLeft;
+  animation-name: rotateOutUpLeft;
+}
+
+@-webkit-keyframes rotateOutUpRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 90deg);
+    transform: rotate3d(0, 0, 1, 90deg);
+    opacity: 0;
+  }
+}
+
+
+@keyframes rotateOutUpRight {
+  from {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate3d(0, 0, 1, 90deg);
+    transform: rotate3d(0, 0, 1, 90deg);
+    opacity: 0;
+  }
+}
+
+
+.rotateOutUpRight {
+  -webkit-animation-name: rotateOutUpRight;
+  animation-name: rotateOutUpRight;
+}
+
+@-webkit-keyframes hinge {
+  0% {
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  20%, 60% {
+    -webkit-transform: rotate3d(0, 0, 1, 80deg);
+    transform: rotate3d(0, 0, 1, 80deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  40%, 80% {
+    -webkit-transform: rotate3d(0, 0, 1, 60deg);
+    transform: rotate3d(0, 0, 1, 60deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 700px, 0);
+    transform: translate3d(0, 700px, 0);
+    opacity: 0;
+  }
+}
+
+
+@keyframes hinge {
+  0% {
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  20%, 60% {
+    -webkit-transform: rotate3d(0, 0, 1, 80deg);
+    transform: rotate3d(0, 0, 1, 80deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  40%, 80% {
+    -webkit-transform: rotate3d(0, 0, 1, 60deg);
+    transform: rotate3d(0, 0, 1, 60deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+    opacity: 1;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 700px, 0);
+    transform: translate3d(0, 700px, 0);
+    opacity: 0;
+  }
+}
+
+
+.hinge {
+  -webkit-animation-name: hinge;
+  animation-name: hinge;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes rollIn {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+    transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+@keyframes rollIn {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+    transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+  }
+
+  to {
+    opacity: 1;
+    -webkit-transform: none;
+    transform: none;
+  }
+}
+
+
+.rollIn {
+  -webkit-animation-name: rollIn;
+  animation-name: rollIn;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes rollOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+    transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+  }
+}
+
+
+@keyframes rollOut {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+    transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+  }
+}
+
+
+.rollOut {
+  -webkit-animation-name: rollOut;
+  animation-name: rollOut;
+}
+
+@-webkit-keyframes zoomIn {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  50% {
+    opacity: 1;
+  }
+}
+
+
+@keyframes zoomIn {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  50% {
+    opacity: 1;
+  }
+}
+
+
+.zoomIn {
+  -webkit-animation-name: zoomIn;
+  animation-name: zoomIn;
+}
+
+@-webkit-keyframes zoomInDown {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomInDown {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomInDown {
+  -webkit-animation-name: zoomInDown;
+  animation-name: zoomInDown;
+}
+
+@-webkit-keyframes zoomInLeft {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomInLeft {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomInLeft {
+  -webkit-animation-name: zoomInLeft;
+  animation-name: zoomInLeft;
+}
+
+@-webkit-keyframes zoomInRight {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomInRight {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomInRight {
+  -webkit-animation-name: zoomInRight;
+  animation-name: zoomInRight;
+}
+
+@-webkit-keyframes zoomInUp {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomInUp {
+  from {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomInUp {
+  -webkit-animation-name: zoomInUp;
+  animation-name: zoomInUp;
+}
+
+@-webkit-keyframes zoomOut {
+  from {
+    opacity: 1;
+  }
+
+  50% {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
+
+@keyframes zoomOut {
+  from {
+    opacity: 1;
+  }
+
+  50% {
+    opacity: 0;
+    -webkit-transform: scale3d(0.3, 0.3, 0.3);
+    transform: scale3d(0.3, 0.3, 0.3);
+  }
+
+  to {
+    opacity: 0;
+  }
+}
+
+
+.zoomOut {
+  -webkit-animation-name: zoomOut;
+  animation-name: zoomOut;
+}
+
+@-webkit-keyframes zoomOutDown {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+    -webkit-transform-origin: center bottom;
+    transform-origin: center bottom;
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomOutDown {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+    -webkit-transform-origin: center bottom;
+    transform-origin: center bottom;
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomOutDown {
+  -webkit-animation-name: zoomOutDown;
+  animation-name: zoomOutDown;
+}
+
+@-webkit-keyframes zoomOutLeft {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0);
+    transform: scale(0.1) translate3d(-2000px, 0, 0);
+    -webkit-transform-origin: left center;
+    transform-origin: left center;
+  }
+}
+
+
+@keyframes zoomOutLeft {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0);
+    transform: scale(0.1) translate3d(-2000px, 0, 0);
+    -webkit-transform-origin: left center;
+    transform-origin: left center;
+  }
+}
+
+
+.zoomOutLeft {
+  -webkit-animation-name: zoomOutLeft;
+  animation-name: zoomOutLeft;
+}
+
+@-webkit-keyframes zoomOutRight {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale(0.1) translate3d(2000px, 0, 0);
+    transform: scale(0.1) translate3d(2000px, 0, 0);
+    -webkit-transform-origin: right center;
+    transform-origin: right center;
+  }
+}
+
+
+@keyframes zoomOutRight {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale(0.1) translate3d(2000px, 0, 0);
+    transform: scale(0.1) translate3d(2000px, 0, 0);
+    -webkit-transform-origin: right center;
+    transform-origin: right center;
+  }
+}
+
+
+.zoomOutRight {
+  -webkit-animation-name: zoomOutRight;
+  animation-name: zoomOutRight;
+}
+
+@-webkit-keyframes zoomOutUp {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+    -webkit-transform-origin: center bottom;
+    transform-origin: center bottom;
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+@keyframes zoomOutUp {
+  40% {
+    opacity: 1;
+    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+  }
+
+  to {
+    opacity: 0;
+    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+    -webkit-transform-origin: center bottom;
+    transform-origin: center bottom;
+    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+  }
+}
+
+
+.zoomOutUp {
+  -webkit-animation-name: zoomOutUp;
+  animation-name: zoomOutUp;
+}
+
+@-webkit-keyframes slideInDown {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+@keyframes slideInDown {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+.slideInDown {
+  -webkit-animation-name: slideInDown;
+  animation-name: slideInDown;
+}
+
+@-webkit-keyframes slideInLeft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+@keyframes slideInLeft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+.slideInLeft {
+  -webkit-animation-name: slideInLeft;
+  animation-name: slideInLeft;
+}
+
+@-webkit-keyframes slideInRight {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+@keyframes slideInRight {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+.slideInRight {
+  -webkit-animation-name: slideInRight;
+  animation-name: slideInRight;
+}
+
+@-webkit-keyframes slideInUp {
+  from {
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+@keyframes slideInUp {
+  from {
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+    visibility: visible;
+  }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+
+.slideInUp {
+  -webkit-animation-name: slideInUp;
+  animation-name: slideInUp;
+}
+
+@-webkit-keyframes slideOutDown {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+
+
+@keyframes slideOutDown {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+
+
+.slideOutDown {
+  -webkit-animation-name: slideOutDown;
+  animation-name: slideOutDown;
+}
+
+@-webkit-keyframes slideOutLeft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+
+
+@keyframes slideOutLeft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+
+
+.slideOutLeft {
+  -webkit-animation-name: slideOutLeft;
+  animation-name: slideOutLeft;
+}
+
+@-webkit-keyframes slideOutRight {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+
+
+@keyframes slideOutRight {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+
+
+.slideOutRight {
+  -webkit-animation-name: slideOutRight;
+  animation-name: slideOutRight;
+}
+
+@-webkit-keyframes slideOutUp {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+
+
+@keyframes slideOutUp {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+
+  to {
+    visibility: hidden;
+    -webkit-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+
+
+.slideOutUp {
+  -webkit-animation-name: slideOutUp;
+  animation-name: slideOutUp;
+}

+ 52 - 0
client/scss/pages/_error.scss

@@ -0,0 +1,52 @@
+
+body {
+	display: flex;
+	align-items: center;
+	min-height: 100vh;
+	width: 100vw;
+	padding: 25px 0;
+	margin: 0;
+	color: #FFF;
+
+	&.is-notexist {
+		background-color: mc('blue-grey', '900');
+	}
+
+	&.is-forbidden {
+		background-color: darken(mc('blue-grey', '900'), 5%);
+	}
+
+	&.is-error {
+		background-color: darken(mc('blue-grey', '900'), 10%);
+	}
+
+}
+
+.container {
+	text-align: center;
+
+	h1 {
+		margin-top: 30px;
+	}
+
+	h2 {
+		margin-bottom: 50px;
+	}
+
+	a.button {
+		margin: 0 5px;
+	}
+
+	h3 {
+		text-align: left;
+		margin-top: 50px;
+	}
+
+	pre {
+		margin-top: 10px;
+		text-align: left;
+		color: mc('blue-grey', '200');
+		font-size: 12px;
+	}
+
+}

+ 306 - 0
client/scss/pages/_login.scss

@@ -0,0 +1,306 @@
+
+body {
+	padding: 0;
+	margin: 0;
+	font-family: $core-font-standard;
+	font-size: 14px;
+}
+
+a {
+	color: #FFF;
+	transition: color 0.4s ease;
+	text-decoration: none;
+
+	&:hover {
+		color: mc('orange','600');
+		text-decoration: underline;
+	}
+
+}
+
+#bg {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	z-index: 1;
+	background-color: #000;
+
+	> div {
+		background-size: cover;
+		background-position: center center;
+		width: 100%;
+		height: 100%;
+		position: absolute;
+		top: 0;
+		left: 0;
+		opacity: 0;
+		visibility: hidden;
+		transition: opacity 3s ease, visibility 3s;
+		animation: bg 30s linear infinite;
+
+		&:nth-child(1) {
+			animation-delay: 10s;
+		}
+
+		&:nth-child(2) {
+			animation-delay: 20s;
+		}
+
+	}
+
+}
+
+#root {
+	position: fixed;
+	top: 15vh;
+	left: 10vw;
+	z-index: 2;
+	color: #FFF;
+	display: flex;
+	flex-direction: column;
+
+	h1 {
+		font-size: 4rem;
+		font-weight: bold;
+		color: #FFF;
+		padding: 0;
+		margin: 0;
+		animation: headerIntro 3s ease;
+	}
+
+	h2 {
+		font-size: 1.5rem;
+		font-weight: normal;
+		color: rgba(255,255,255,0.7);
+		padding: 0;
+		margin: 0 0 25px 0;
+		animation: headerIntro 3s ease;
+	}
+
+	h3 {
+		font-size: 1.25rem;
+		font-weight: normal;
+		color: #FB8C00;
+		padding: 0;
+		margin: 0;
+		animation: shake 1s ease;
+
+		> .fa {
+			margin-right: 7px;
+		}
+
+	}
+
+	h4 {
+		font-size: 0.8rem;
+		font-weight: normal;
+		color: rgba(255,255,255,0.7);
+		padding: 0;
+		margin: 0 0 15px 0;
+		animation: fadeIn 3s ease;
+	}
+
+	form {
+		display: flex;
+		flex-direction: column;
+	}
+
+	input[type=text], input[type=password] {
+		width: 350px;
+		max-width: 80vw;
+		border: 1px solid rgba(255,255,255,0.3);
+		border-radius: 3px;
+		background-color: rgba(0,0,0,0.2);
+		padding: 0 15px;
+		height: 40px;
+		margin: 0 0 10px 0;
+		color: #FFF;
+		font-weight: bold;
+		font-size: 14px;
+		transition: all 0.4s ease;
+
+		&:focus {
+			outline: none;
+			border-color: mc('orange','600');
+		}
+
+	}
+
+	button {
+		background-color: mc('orange','600');
+		color: #FFF;
+		border: 1px solid lighten(mc('orange','600'), 10%);
+		border-radius: 3px;
+		height: 40px;
+		width: 125px;
+		padding: 0;
+		font-weight: bold;
+		margin: 15px 0 0 0;
+		transition: all 0.4s ease;
+		cursor: pointer;
+
+		span {
+			font-weight: bold;
+		}
+
+		&:focus {
+			outline: none;
+			border-color: #FFF;
+		}
+
+		&:hover {
+			background-color: darken(mc('orange','600'), 10%);
+		}
+
+	}
+
+	#social {
+		margin-top: 25px;
+
+		> span {
+			display: block;
+			font-weight: bold;
+			color: rgba(255,255,255,0.7);
+		}
+
+		button {
+			margin-right: 5px;
+			width: auto;
+			padding: 0 15px;
+
+			> i {
+				margin-right: 10px;
+				font-size: 16px;
+			}
+
+			&.ms {
+				background-color: mc('blue','600');
+				border-color: lighten(mc('blue','600'), 10%);
+
+				&:focus {
+					border-color: #FFF;
+				}
+
+				&:hover {
+					background-color: darken(mc('blue','600'), 10%);
+				}
+
+			}
+
+			&.google {
+				background-color: mc('light-blue','600');
+				border-color: lighten(mc('light-blue','600'), 10%);
+
+				&:focus {
+					border-color: #FFF;
+				}
+
+				&:hover {
+					background-color: darken(mc('light-blue','600'), 10%);
+				}
+
+			}
+
+			&.facebook {
+				background-color: mc('indigo','600');
+				border-color: lighten(mc('indigo','600'), 10%);
+
+				&:focus {
+					border-color: #FFF;
+				}
+
+				&:hover {
+					background-color: darken(mc('indigo','600'), 10%);
+				}
+
+			}
+
+      &.github {
+				background-color: mc('blue-grey','700');
+				border-color: lighten(mc('blue-grey','700'), 10%);
+
+				&:focus {
+					border-color: #FFF;
+				}
+
+				&:hover {
+					background-color: darken(mc('blue-grey','700'), 10%);
+				}
+			}
+
+      &.slack {
+				background-color: mc('purple','700');
+				border-color: lighten(mc('purple','700'), 10%);
+
+				&:focus {
+					border-color: #FFF;
+				}
+
+				&:hover {
+					background-color: darken(mc('purple','700'), 10%);
+				}
+			}
+
+		}
+
+	}
+
+}
+
+#copyright {
+	display: flex;
+	align-items: center;
+	justify-content: flex-start;
+	position: absolute;
+	left: 10vw;
+	bottom: 10vh;
+	z-index: 2;
+	color: rgba(255,255,255,0.5);
+	font-weight: bold;
+
+	.icon {
+		font-size: 1.2rem;
+		margin: 0 8px;
+	}
+
+	a {
+		opacity: 0.75;
+	}
+
+}
+
+@include keyframes(bg) {
+	0% {
+		@include prefix(transform, scale(1,1));
+		visibility: visible;
+		opacity: 0;
+	},
+	5% {
+		opacity: 0.5;
+	},
+	33% {
+		opacity: 0.5;
+	},
+	38% {
+		@include prefix(transform, scale(1.2, 1.2));
+		opacity: 0;
+	},
+	39% {
+		visibility: hidden;
+	}
+	100% {
+		visibility: hidden;
+		opacity: 0;
+	}
+}
+
+@include keyframes(headerIntro) {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}

+ 243 - 0
libs/auth.js

@@ -0,0 +1,243 @@
+'use strict'
+
+/* global appconfig, appdata, db, winston */
+
+const LocalStrategy = require('passport-local').Strategy
+const GoogleStrategy = require('passport-google-oauth20').Strategy
+const WindowsLiveStrategy = require('passport-windowslive').Strategy
+const FacebookStrategy = require('passport-facebook').Strategy
+const GitHubStrategy = require('passport-github2').Strategy
+const SlackStrategy = require('passport-slack').Strategy
+const LdapStrategy = require('passport-ldapauth').Strategy
+const fs = require('fs')
+
+module.exports = function (passport) {
+  // Serialization user methods
+
+  passport.serializeUser(function (user, done) {
+    done(null, user._id)
+  })
+
+  passport.deserializeUser(function (id, done) {
+    db.User.findById(id).then((user) => {
+      if (user) {
+        done(null, user)
+      } else {
+        done(new Error('User not found.'), null)
+      }
+      return true
+    }).catch((err) => {
+      done(err, null)
+    })
+  })
+
+  // Local Account
+
+  if (!appdata.capabilities.manyAuthProviders || (appconfig.auth.local && appconfig.auth.local.enabled)) {
+    passport.use('local',
+      new LocalStrategy({
+        usernameField: 'email',
+        passwordField: 'password'
+      },
+      (uEmail, uPassword, done) => {
+        db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
+          if (user) {
+            return user.validatePassword(uPassword).then(() => {
+              return done(null, user) || true
+            }).catch((err) => {
+              return done(err, null)
+            })
+          } else {
+            return done(new Error('INVALID_LOGIN'), null)
+          }
+        }).catch((err) => {
+          done(err, null)
+        })
+      }
+    ))
+  }
+
+  // Google ID
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.google && appconfig.auth.google.enabled) {
+    passport.use('google',
+      new GoogleStrategy({
+        clientID: appconfig.auth.google.clientId,
+        clientSecret: appconfig.auth.google.clientSecret,
+        callbackURL: appconfig.host + '/login/google/callback'
+      },
+      (accessToken, refreshToken, profile, cb) => {
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // Microsoft Accounts
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
+    passport.use('windowslive',
+      new WindowsLiveStrategy({
+        clientID: appconfig.auth.microsoft.clientId,
+        clientSecret: appconfig.auth.microsoft.clientSecret,
+        callbackURL: appconfig.host + '/login/ms/callback'
+      },
+      function (accessToken, refreshToken, profile, cb) {
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // Facebook
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
+    passport.use('facebook',
+      new FacebookStrategy({
+        clientID: appconfig.auth.facebook.clientId,
+        clientSecret: appconfig.auth.facebook.clientSecret,
+        callbackURL: appconfig.host + '/login/facebook/callback',
+        profileFields: ['id', 'displayName', 'email']
+      },
+      function (accessToken, refreshToken, profile, cb) {
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // GitHub
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.github && appconfig.auth.github.enabled) {
+    passport.use('github',
+      new GitHubStrategy({
+        clientID: appconfig.auth.github.clientId,
+        clientSecret: appconfig.auth.github.clientSecret,
+        callbackURL: appconfig.host + '/login/github/callback',
+        scope: [ 'user:email' ]
+      },
+      (accessToken, refreshToken, profile, cb) => {
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // Slack
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.slack && appconfig.auth.slack.enabled) {
+    passport.use('slack',
+      new SlackStrategy({
+        clientID: appconfig.auth.slack.clientId,
+        clientSecret: appconfig.auth.slack.clientSecret,
+        callbackURL: appconfig.host + '/login/slack/callback'
+      },
+      (accessToken, refreshToken, profile, cb) => {
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // LDAP
+
+  if (appdata.capabilities.manyAuthProviders && appconfig.auth.ldap && appconfig.auth.ldap.enabled) {
+    passport.use('ldapauth',
+      new LdapStrategy({
+        server: {
+          url: appconfig.auth.ldap.url,
+          bindDn: appconfig.auth.ldap.bindDn,
+          bindCredentials: appconfig.auth.ldap.bindCredentials,
+          searchBase: appconfig.auth.ldap.searchBase,
+          searchFilter: appconfig.auth.ldap.searchFilter,
+          searchAttributes: ['displayName', 'name', 'cn', 'mail'],
+          tlsOptions: (appconfig.auth.ldap.tlsEnabled) ? {
+            ca: [
+              fs.readFileSync(appconfig.auth.ldap.tlsCertPath)
+            ]
+          } : {}
+        },
+        usernameField: 'email',
+        passReqToCallback: false
+      },
+      (profile, cb) => {
+        profile.provider = 'ldap'
+        profile.id = profile.dn
+        db.User.processProfile(profile).then((user) => {
+          return cb(null, user) || true
+        }).catch((err) => {
+          return cb(err, null) || true
+        })
+      }
+    ))
+  }
+
+  // Create users for first-time
+
+  db.onReady.then(() => {
+    db.User.findOne({ provider: 'local', email: 'guest' }).then((c) => {
+      if (c < 1) {
+        // Create root admin account
+
+        winston.info('[AUTH] No administrator account found. Creating a new one...')
+        db.User.hashPassword('admin123').then((pwd) => {
+          return db.User.create({
+            provider: 'local',
+            email: appconfig.admin,
+            name: 'Administrator',
+            password: pwd,
+            rights: [{
+              role: 'admin',
+              path: '/',
+              exact: false,
+              deny: false
+            }]
+          })
+        }).then(() => {
+          winston.info('[AUTH] Administrator account created successfully!')
+        }).then(() => {
+          if (appdata.capabilities.guest) {
+            // Create guest account
+
+            return db.User.create({
+              provider: 'local',
+              email: 'guest',
+              name: 'Guest',
+              password: '',
+              rights: [{
+                role: 'read',
+                path: '/',
+                exact: false,
+                deny: !appconfig.public
+              }]
+            }).then(() => {
+              winston.info('[AUTH] Guest account created successfully!')
+            })
+          } else {
+            return true
+          }
+        }).catch((err) => {
+          winston.error('[AUTH] An error occured while creating administrator/guest account:')
+          winston.error(err)
+        })
+      }
+    })
+
+    return true
+  })
+}

+ 58 - 0
libs/config.js

@@ -0,0 +1,58 @@
+'use strict'
+
+/* global winston */
+
+const fs = require('fs')
+const yaml = require('js-yaml')
+const _ = require('lodash')
+
+/**
+ * Load Application Configuration
+ *
+ * @param      {Object}  confPaths  Path to the configuration files
+ * @return     {Object}  Application Configuration
+ */
+module.exports = (confPaths) => {
+  confPaths = _.defaults(confPaths, {
+    config: './config.yml',
+    data: './app/data.yml'
+  })
+
+  let appconfig = {}
+  let appdata = {}
+
+  try {
+    appconfig = yaml.safeLoad(fs.readFileSync(confPaths.config, 'utf8'))
+    appdata = yaml.safeLoad(fs.readFileSync(confPaths.data, 'utf8'))
+  } catch (ex) {
+    winston.error(ex)
+    process.exit(1)
+  }
+
+  // Merge with defaults
+
+  appconfig = _.defaultsDeep(appconfig, appdata.defaults.config)
+
+  // List authentication strategies
+
+  if (appdata.capabilities.manyAuthProviders) {
+    appconfig.authStrategies = {
+      list: _.filter(appconfig.auth, ['enabled', true]),
+      socialEnabled: (_.chain(appconfig.auth).omit('local').reject({ enabled: false }).value().length > 0)
+    }
+    if (appconfig.authStrategies.list.length < 1) {
+      winston.error(new Error('You must enable at least 1 authentication strategy!'))
+      process.exit(1)
+    }
+  } else {
+    appconfig.authStrategies = {
+      list: { local: { enabled: true } },
+      socialEnabled: false
+    }
+  }
+
+  return {
+    config: appconfig,
+    data: appdata
+  }
+}

+ 120 - 0
libs/rights.js

@@ -0,0 +1,120 @@
+'use strict'
+
+/* global db */
+
+const _ = require('lodash')
+
+/**
+ * Rights
+ */
+module.exports = {
+
+  guest: {
+    provider: 'local',
+    email: 'guest',
+    name: 'Guest',
+    password: '',
+    rights: [
+      {
+        role: 'read',
+        path: '/',
+        deny: false,
+        exact: false
+      }
+    ]
+  },
+
+  /**
+   * Initialize Rights module
+   *
+   * @return     {void}  Void
+   */
+  init () {
+    let self = this
+
+    db.onReady.then(() => {
+      db.User.findOne({ provider: 'local', email: 'guest' }).then((u) => {
+        if (u) {
+          self.guest = u
+        }
+      })
+    })
+  },
+
+  /**
+   * Check user permissions for this request
+   *
+   * @param      {object}  req     The request object
+   * @return     {object}  List of permissions for this request
+   */
+  check (req) {
+    let self = this
+
+    let perm = {
+      read: false,
+      write: false,
+      manage: false
+    }
+    let rt = []
+    let p = _.chain(req.originalUrl).toLower().trim().value()
+
+    // Load User Rights
+
+    if (_.isArray(req.user.rights)) {
+      rt = req.user.rights
+    }
+
+    // Is admin?
+
+    if (_.find(rt, { role: 'admin' })) {
+      perm.read = true
+      perm.write = true
+      perm.manage = true
+    } else if (self.checkRole(p, rt, 'write')) {
+      perm.read = true
+      perm.write = true
+    } else if (self.checkRole(p, rt, 'read')) {
+      perm.read = true
+    }
+
+    return perm
+  },
+
+  /**
+   * Check for a specific role based on list of user rights
+   *
+   * @param      {String}         p       Base path
+   * @param      {array<object>}  rt      The user rights
+   * @param      {string}         role    The minimum role required
+   * @return     {boolean}        True if authorized
+   */
+  checkRole (p, rt, role) {
+    // Check specific role on path
+
+    let filteredRights = _.filter(rt, (r) => {
+      if (r.role === role || (r.role === 'write' && role === 'read')) {
+        if ((!r.exact && _.startsWith(p, r.path)) || (r.exact && p === r.path)) {
+          return true
+        }
+      }
+      return false
+    })
+
+    // Check for deny scenario
+
+    let isValid = false
+
+    if (filteredRights.length > 1) {
+      isValid = !_.chain(filteredRights).sortBy((r) => {
+        return r.path.length + ((r.deny) ? 0.5 : 0)
+      }).last().get('deny').value()
+    } else if (filteredRights.length === 1 && filteredRights[0].deny === false) {
+      isValid = true
+    }
+
+    // Deny by default
+
+    return isValid
+  }
+
+}

+ 16 - 3
middlewares/auth.js

@@ -1,5 +1,7 @@
 'use strict'
 
+/* global appdata, rights */
+
 const moment = require('moment-timezone')
 
 /**
@@ -14,13 +16,24 @@ module.exports = (req, res, next) => {
   // Is user authenticated ?
 
   if (!req.isAuthenticated()) {
-    return res.redirect('/login')
+    if (!appdata.capabilities.guest || req.app.locals.appconfig.public !== true) {
+      return res.redirect('/login')
+    } else {
+      req.user = rights.guest
+      res.locals.isGuest = true
+    }
+  } else if (appdata.capabilities.guest) {
+    res.locals.isGuest = false
   }
 
   // Check permissions
 
-  if (!rights.check(req, 'read')) {
-    return res.render('error-forbidden')
+  if (appdata.capabilities.rights) {
+    res.locals.rights = rights.check(req)
+
+    if (!res.locals.rights.read) {
+      return res.render('error-forbidden')
+    }
   }
 
   // Set i18n locale

+ 2 - 0
middlewares/security.js

@@ -1,5 +1,7 @@
 'use strict'
 
+/* global app */
+
 /**
  * Security Middleware
  *

+ 8 - 4
package.json

@@ -73,7 +73,7 @@
     "i18next-node-fs-backend": "^0.1.3",
     "image-size": "^0.5.1",
     "jimp": "github:ngpixel/jimp",
-    "js-yaml": "^3.8.1",
+    "js-yaml": "^3.8.2",
     "klaw": "^1.3.1",
     "levelup": "^1.3.5",
     "lodash": "^4.17.3",
@@ -95,13 +95,18 @@
     "multer": "^1.2.1",
     "ora": "^1.2.0",
     "passport": "^0.3.2",
+    "passport-facebook": "^2.1.1",
+    "passport-github2": "^0.1.10",
+    "passport-google-oauth20": "^1.0.0",
+    "passport-ldapauth": "^1.0.0",
     "passport-local": "^1.0.0",
+    "passport-slack": "0.0.7",
+    "passport-windowslive": "^1.0.2",
     "passport.socketio": "^3.7.0",
     "pm2": "^2.4.3",
     "pug": "^2.0.0-beta11",
     "read-chunk": "^2.0.0",
     "remove-markdown": "^0.1.0",
-    "requarks-core": "^0.2.2",
     "request": "^2.81.0",
     "search-index-adder": "github:ngpixel/search-index-adder",
     "search-index-searcher": "github:ngpixel/search-index-searcher",
@@ -116,7 +121,7 @@
     "through2": "^2.0.3",
     "validator": "^7.0.0",
     "validator-as-promised": "^1.0.2",
-    "winston": "^2.3.0"
+    "winston": "^2.3.1"
   },
   "devDependencies": {
     "babel-cli": "latest",
@@ -165,7 +170,6 @@
       "winston",
       "ws",
       "Mongoose",
-      "CORE_PATH",
       "ROOTPATH",
       "IS_DEBUG",
       "PROCNAME",

+ 4 - 5
server.js

@@ -9,7 +9,6 @@
 global.PROCNAME = 'SERVER'
 global.ROOTPATH = __dirname
 global.IS_DEBUG = process.env.NODE_ENV === 'development'
-global.CORE_PATH = (IS_DEBUG) ? ROOTPATH + '/../core/' : ROOTPATH + '/node_modules/requarks-core/'
 
 if (IS_DEBUG) {
   try { require('newrelic') } catch (err) {}
@@ -17,7 +16,7 @@ if (IS_DEBUG) {
 
 process.env.VIPS_WARNING = false
 
-let appconf = require(CORE_PATH + 'core-libs/config')()
+let appconf = require('./libs/config')()
 global.appconfig = appconf.config
 global.appdata = appconf.data
 
@@ -63,7 +62,7 @@ const session = require('express-session')
 const SessionMongoStore = require('connect-mongo')(session)
 const socketio = require('socket.io')
 
-var mw = autoload(CORE_PATH + '/core-middlewares')
+var mw = autoload(path.join(ROOTPATH, '/middlewares'))
 var ctrl = autoload(path.join(ROOTPATH, '/controllers'))
 
 // ----------------------------------------
@@ -90,8 +89,8 @@ app.use(express.static(path.join(ROOTPATH, 'assets')))
 // Passport Authentication
 // ----------------------------------------
 
-require(CORE_PATH + 'core-libs/auth')(passport)
-global.rights = require(CORE_PATH + 'core-libs/rights')
+require('./libs/auth')(passport)
+global.rights = require('./libs/rights')
 rights.init()
 
 var sessionStore = new SessionMongoStore({