diff --git a/.eslintrc.json b/.eslintrc.json index 258c29c2..031981dd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,7 +26,6 @@ "winston": true, "ws": true, "Mongoose": true, - "CORE_PATH": true, "ROOTPATH": true, "IS_DEBUG": true, "PROCNAME": true diff --git a/agent.js b/agent.js index f2461b7c..000e5cf8 100644 --- a/agent.js +++ b/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() diff --git a/client/scss/app.scss b/client/scss/app.scss index 7bba9aaa..d0f1e137 100644 --- a/client/scss/app.scss +++ b/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 "base/variables"; +@import "base/colors"; +@import "base/reset"; +@import "base/mixins"; +@import "base/fonts"; +@import "base/base"; -@import './libs/twemoji-awesome'; -@import './libs/jquery-contextmenu'; +@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'; diff --git a/client/scss/base/base.scss b/client/scss/base/base.scss new file mode 100644 index 00000000..5bb51ad1 --- /dev/null +++ b/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; + } +} diff --git a/client/scss/base/colors.scss b/client/scss/base/colors.scss new file mode 100644 index 00000000..b7ebf23a --- /dev/null +++ b/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); +} diff --git a/client/scss/base/fonts.scss b/client/scss/base/fonts.scss new file mode 100644 index 00000000..8be725b7 --- /dev/null +++ b/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; + } +} diff --git a/client/scss/base/mixins.scss b/client/scss/base/mixins.scss new file mode 100644 index 00000000..bbdbb5a5 --- /dev/null +++ b/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; + } +} diff --git a/client/scss/base/reset.scss b/client/scss/base/reset.scss new file mode 100644 index 00000000..39311d4e --- /dev/null +++ b/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; } diff --git a/client/scss/base/variables.scss b/client/scss/base/variables.scss new file mode 100644 index 00000000..0db6335c --- /dev/null +++ b/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; diff --git a/client/scss/components/alert.scss b/client/scss/components/alert.scss new file mode 100644 index 00000000..61336257 --- /dev/null +++ b/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'); + } + } + + } + + } + +} diff --git a/client/scss/components/button.scss b/client/scss/components/button.scss new file mode 100644 index 00000000..97338a0e --- /dev/null +++ b/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); + } +} diff --git a/client/scss/components/footer.scss b/client/scss/components/footer.scss new file mode 100644 index 00000000..63332902 --- /dev/null +++ b/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; + } + + } + +} diff --git a/client/scss/components/form.scss b/client/scss/components/form.scss new file mode 100644 index 00000000..d7dcbb25 --- /dev/null +++ b/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; + } + + } + } + + } + +} diff --git a/client/scss/components/grid.scss b/client/scss/components/grid.scss new file mode 100644 index 00000000..01830648 --- /dev/null +++ b/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; +} diff --git a/client/scss/components/hero.scss b/client/scss/components/hero.scss new file mode 100644 index 00000000..63460aa4 --- /dev/null +++ b/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'); + } + + } + } + + } + + } + + } + +} diff --git a/client/scss/components/list.scss b/client/scss/components/list.scss new file mode 100644 index 00000000..47a72ad2 --- /dev/null +++ b/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'); + } + + } + +} \ No newline at end of file diff --git a/client/scss/components/markdown-content.scss b/client/scss/components/markdown-content.scss new file mode 100644 index 00000000..cda53a10 --- /dev/null +++ b/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%); + } + } + + } + +} diff --git a/client/scss/components/modal.scss b/client/scss/components/modal.scss new file mode 100644 index 00000000..03986531 --- /dev/null +++ b/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; +} diff --git a/client/scss/components/nav.scss b/client/scss/components/nav.scss new file mode 100644 index 00000000..88c0f940 --- /dev/null +++ b/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'); + } + + } + + } + +} diff --git a/client/scss/components/panel.scss b/client/scss/components/panel.scss new file mode 100644 index 00000000..b6ce48fd --- /dev/null +++ b/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; + } + +} diff --git a/client/scss/components/search.scss b/client/scss/components/search.scss new file mode 100644 index 00000000..eafbef6d --- /dev/null +++ b/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; + } + + } + + } + +} diff --git a/client/scss/components/sidebar.scss b/client/scss/components/sidebar.scss new file mode 100644 index 00000000..bfb09b00 --- /dev/null +++ b/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'); + } + + } + + } + + } + + } + + } + +} diff --git a/client/scss/components/table.scss b/client/scss/components/table.scss new file mode 100644 index 00000000..0a444dde --- /dev/null +++ b/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; + } + +} diff --git a/client/scss/components/typography.scss b/client/scss/components/typography.scss new file mode 100644 index 00000000..53be5755 --- /dev/null +++ b/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'); + } +} \ No newline at end of file diff --git a/client/scss/libs/animate.scss b/client/scss/libs/animate.scss new file mode 100644 index 00000000..f8377f57 --- /dev/null +++ b/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; +} \ No newline at end of file diff --git a/client/scss/pages/_error.scss b/client/scss/pages/_error.scss new file mode 100644 index 00000000..5aa02851 --- /dev/null +++ b/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; + } + +} diff --git a/client/scss/pages/_login.scss b/client/scss/pages/_login.scss new file mode 100644 index 00000000..abfd9c93 --- /dev/null +++ b/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; + } +} diff --git a/libs/auth.js b/libs/auth.js new file mode 100644 index 00000000..19feb4f1 --- /dev/null +++ b/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 + }) +} diff --git a/libs/config.js b/libs/config.js new file mode 100644 index 00000000..4caa90c9 --- /dev/null +++ b/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 + } +} diff --git a/libs/rights.js b/libs/rights.js new file mode 100644 index 00000000..2c60f05e --- /dev/null +++ b/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} 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 + } + +} diff --git a/middlewares/auth.js b/middlewares/auth.js index d40f11be..8c84b8d9 100644 --- a/middlewares/auth.js +++ b/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 diff --git a/middlewares/security.js b/middlewares/security.js index dd20d88f..4a04056c 100644 --- a/middlewares/security.js +++ b/middlewares/security.js @@ -1,5 +1,7 @@ 'use strict' +/* global app */ + /** * Security Middleware * diff --git a/package.json b/package.json index 7ae5df8d..fbfe0344 100644 --- a/package.json +++ b/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", diff --git a/server.js b/server.js index 0076551f..ab7c64af 100644 --- a/server.js +++ b/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({