diff --git a/BallColoron/TidePlus/index.html b/BallColoron/TidePlus/index.html
new file mode 100644
index 000000000..08854f4aa
--- /dev/null
+++ b/BallColoron/TidePlus/index.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+ C
+ o
+ l
+ o
+ r
+ o
+ n
+
+
Play
+
hint: red color always comes first
+
+
+
+
+
Bouncing ball
changes color
+
+
+
+
Tap on the bar to switch the colors
(Red, Yellow, Purple)
+
+
+
+
Always match the
ball and bar colors
+
+
+
+
+
+
+
+
+
+
+
Coloron
+
+
+
+
+
Tweet to challenge friends
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Click on the bars to change the color!
+
+
+
+
+
+
+
+
diff --git a/BallColoron/TidePlus/main.js b/BallColoron/TidePlus/main.js
new file mode 100644
index 000000000..d7f9708a5
--- /dev/null
+++ b/BallColoron/TidePlus/main.js
@@ -0,0 +1,588 @@
+class Game {
+
+ constructor() {
+ this.score = 0;
+ this.isRunning = 0; // game is not running
+
+ this.calculateScale();
+
+ this.timeline = new TimelineMax({smoothChildTiming: true});
+ this.time = 1.6; // initial speed
+ this.colors = ["#FF4571", "#FFD145", "#8260F6"]; // the 3 colors used in the game
+ this.colorsRGBA = ["rgba(255, 69, 113, 1)", "rgba(255, 69, 113, 1)", "rgba(255, 69, 113, 1)"];
+ this.color = this.colors[0]; // the intial color of the ball
+ this.prevColor = null; // used as a holder to prevent ball colors from repeating
+ }
+
+ /**
+ * The game screen is scalable. I took 1200x800px as the initial scale.
+ * In order to display the game an many screen sizes properly
+ * I have to compare the player's sreen size to the initial scale,
+ * then scale the game using CSS Transform to fit the screen properly
+ * The function is called in the controller and anywhere where I need
+ * to recalculate the scale on screen resize or device rotation
+ */
+ calculateScale() {
+ this.screen = $(window).width(); // screen width
+ this.screenHeight = $(window).height();
+ this.scale = (this.screen > this.screenHeight) ? this.screenHeight/800 : this.screen/1200;
+ this.stickWidth = 180*this.scale;
+ this.steps = this.screen/this.stickWidth; // how many steps (stick width + margin) it takes from one end to another
+ }
+
+ /**
+ * Creating as many sticks we need to fill the screen
+ * from start to end of the screen. The steps property is used for that
+ */
+ generateSticks() {
+ let numberOfSticks = Math.ceil(this.steps);
+ for(let i = 0; i <= numberOfSticks; i++)
+ new Stick();
+ }
+
+ generateBall() {
+ this.balltween = new TimelineMax({repeat: -1, paused: 1});
+ $('.scene .ball-holder').append('');
+ this.bounce();
+ }
+
+ generateTweet() {
+ let top = $(window).height() / 2 - 150;
+ let left = $(window).width() / 2 - 300;
+ window.open("https://twitter.com/intent/tweet?url=https://codepen.io/gregh/full/yVLOyO&text=I scored "+ this.score +" points on Coloron! Can you beat my score?&via=greghvns&hashtags=coloron", "TweetWindow", "width=600px,height=300px,top=" + top + ",left=" + left);
+ }
+
+ /**
+ * The greeting when the game begins
+ */
+ intro() {
+
+ TweenMax.killAll();
+
+ //TweenMax.to('.splash', 0.3, { opacity: 0, display: 'none', delay: 1 })
+
+ $('.stop-game').css('display', 'none');
+ $('.start-game').css('display', 'flex');
+
+ let introTl = new TimelineMax();
+ let ball = new TimelineMax({repeat: -1, delay: 3});
+ introTl
+ .fromTo('.start-game .logo-holder', 0.9, { opacity: 0 }, { opacity: 1 })
+ .staggerFromTo('.start-game .logo span', 0.5, { opacity: 0 }, { opacity: 1 }, 0.08)
+ .staggerFromTo('.start-game .bar', 1.6, { y: '+100%' }, { y: '0%', ease: Elastic.easeOut.config(1, 0.3) }, 0.08)
+ .staggerFromTo('.start-game .ball-demo', 1, { scale: 0 }, { scale: 1, ease: Elastic.easeOut.config(1, 0.3) }, 0.8, 2)
+
+
+ ball.fromTo('.start-game .section-1 .ball-demo', 0.5, { y: "0px" }, { y: "100px", scaleY: 1.1, transformOrigin: "bottom", ease: Power2.easeIn})
+ .to('.start-game .section-1 .ball-demo', 0.5, { y: "0px", scaleY: 1, transformOrigin: "bottom", ease: Power2.easeOut,
+ onStart: () => {
+ while(this.prevColor==this.color) {
+ this.color = (new Color).getRandomColor();
+ }
+ this.prevColor = this.color;
+ TweenMax.to('.start-game .section-1 .ball-demo', 0.5, {backgroundColor: this.color});
+ }
+ });
+ }
+
+ /**
+ * Display score
+ */
+ showResult() {
+ let score = this.score;
+ $('.stop-game').css('display', 'flex');
+ $('.stop-game .final-score').text(score + '!');
+ $('.stop-game .result').text(this.showGrade(score));
+ $('.nominee').show();
+
+ let resultTimeline = new TimelineMax();
+ resultTimeline
+ .fromTo('.stop-game .score-container', 0.7, { opacity: 0, scale: 0.3 }, { opacity: 1, scale: 1, ease: Elastic.easeOut.config(1.25, 0.5)})
+ .fromTo('.stop-game .final-score', 2, { scale: 0.5 }, { scale: 1, ease: Elastic.easeOut.config(2, 0.5)}, 0)
+ .fromTo('.stop-game .result', 1, { scale: 0.5 }, { scale: 1, ease: Elastic.easeOut.config(1.5, 0.5)}, 0.3)
+ ;
+
+ }
+
+ /**
+ * Takes players score and generates the cheering copy
+ * @param {int} score
+ * @return {string} grade
+ */
+ showGrade(score) {
+ if(score > 30) return "Chuck Norris?";
+ else if(score > 25) return "You're da man";
+ else if(score > 20) return "Awesome";
+ else if(score > 15) return "Great!";
+ else if(score > 13) return "Nice!";
+ else if(score > 10) return "Good Job!";
+ else if(score > 5) return "Really?";
+ else return "Poor...";
+ }
+
+ start() {
+
+ this.stop(); // stop the game
+
+ $('.start-game, .stop-game').css('display', 'none'); // hide all the popups
+ $('.nominee').hide();
+
+ new Game();
+ this.score = 0; // reset
+
+ this.isRunning = 1;
+
+ // Clean up the stick and ball holders
+ // and generate new ones
+ $('#sticks, .scene .ball-holder').html('');
+ $('#score').text(this.score);
+ this.generateSticks();
+ this.generateBall();
+
+ // disables scene animations for Phones
+ if( !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(window.navigator.userAgent) ) {
+ Animation.sceneAnimation();
+ }
+ this.moveToStart();
+ this.moveScene();
+
+ // reset timescale to normal as the game speeds up
+ this.timeline.timeScale(1);
+ this.balltween.timeScale(1);
+ }
+
+ stop() {
+
+ this.isRunning = 0;
+
+ $('.start-game, .stop-game').css('display', 'none');
+ $('#sticks, .scene .ball-holder, #score').html('');
+ TweenMax.killAll();
+
+ this.showResult();
+ }
+
+ scaleScreen() {
+
+ TweenMax.killAll(); // prevent multiple calls on resize
+
+ let height = $(window).height();
+ let width = $(window).width();
+
+ this.calculateScale();
+
+ $('.container')
+ .css('transform', 'scale(' + this.scale + ')')
+ .css('height', height/this.scale)
+ .css('width', width/this.scale)
+ .css('transformOrigin', 'left top');
+
+ $('#sticks').width(this.screen/this.scale + 3 * this.stickWidth/this.scale);
+
+ }
+
+ /**
+ * Calls the above function
+ * If the game is running it stops and shows the score
+ * If the game has stops it takes player to the main menu
+ */
+ scaleScreenAndRun() {
+
+ this.scaleScreen();
+
+ if(this.isRunning) {
+ this.stop();
+ } else {
+ this.intro();
+ }
+
+ }
+
+ /**
+ * This is the initial animation
+ * where the sticks come to the starting position
+ * and the ball appears and falls down
+ */
+ moveToStart() {
+
+ let tip = new TimelineMax({ delay: 2 });
+
+ tip
+ .fromTo('.learn-to-play', 1, { scale: 0 }, { scale: 1, opacity: 1, ease: Elastic.easeOut.config(1.25, 0.5) })
+ .to('.learn-to-play', 1, { scale: 0, opacity: 0, ease: Elastic.easeOut.config(1.25, 0.5) }, 3)
+
+ TweenMax.fromTo('#ball', this.time,
+ {
+ scale: 0
+ },
+ {
+ scale: 1,
+ delay: this.time * ((this.steps - 3) - 1.5),
+ onComplete: () => {
+ this.balltween.play();
+ }
+ });
+
+ this.timeline.add(
+ TweenMax.fromTo('#sticks', this.time * this.steps, { x: this.screen / this.scale }, { x: 0, ease: Power0.easeNone})
+ );
+ }
+
+ /**
+ * The animation that moves sticks
+ */
+ moveScene() {
+
+ this.timeline.add(
+ TweenMax.to('#sticks', this.time, { x: '-=180px', ease: Power0.easeNone, repeat: -1, onRepeat: () => { this.rearrange() } })
+ );
+
+ }
+
+ /**
+ * removes the first stick and adds one the the end
+ * this gives the sticks an infinite movement
+ */
+ rearrange() {
+
+ let scale = this.speedUp();
+
+ this.timeline.timeScale(scale);
+ this.balltween.timeScale(scale);
+
+ $('#sticks .stick').first().remove();
+ new Stick();
+
+ }
+
+ /**
+ * The game speeds up based on score
+ * The GSAP timeScale() function is called on the timeline to speed up the game
+ * This calculates how much shall the game speed up
+ */
+ speedUp() {
+ if(this.score > 30) {
+ return 1.8;
+ }
+ if(this.score > 20) {
+ return 1.7;
+ }
+ if(this.score > 15) {
+ return 1.5;
+ }
+ else if(this.score > 12) {
+ return 1.4;
+ }
+ else if(this.score > 10) {
+ return 1.3;
+ }
+ else if(this.score > 8) {
+ return 1.2;
+ }
+ else if(this.score > 5) {
+ return 1.1;
+ }
+ return 1;
+ }
+
+ /**
+ * Ball bouncing animation
+ * It checks if the ball and stick colors match
+ * And changes the ball color
+ */
+ bounce() {
+
+ this.balltween
+ .to('#ball', this.time/2, {y: '+=250px', scaleY: 0.7, transformOrigin: "bottom", ease: Power2.easeIn,
+ onComplete: () => {
+ this.checkColor();
+ }
+ }).to('#ball', this.time/2, {y: '-=250px', scaleY: 1.1, transformOrigin: "bottom", ease: Power2.easeOut,
+ onStart: () => {
+ while(this.prevColor==this.color) {
+ this.color = (new Color).getRandomColor();
+ }
+ this.prevColor = this.color;
+ TweenMax.to('#ball', 0.5, {backgroundColor: this.color});
+ $('#ball').removeClass('red')
+ .removeClass('yellow')
+ .removeClass('purple')
+ .addClass((new Color).colorcodeToName(this.color));
+ }
+ })
+ }
+
+ checkColor() {
+
+ let ballPos = $('#ball').offset().left + $('#ball').width()/2;
+ let stickWidth = $('.stick').width();
+ let score = this.score;
+
+ $('#sticks .stick').each(function(){
+ if($(this).offset().left < ballPos && $(this).offset().left > (ballPos - stickWidth)) {
+
+ if( Color.getColorFromClass($(this)) == Color.getColorFromClass('#ball') ) {
+ // if matches increase the score
+ score++;
+ $('#score').text(score);
+ TweenMax.fromTo('#score', 0.5, { scale: 1.5 }, { scale: 1, ease: Elastic.easeOut.config(1.5, 0.5) });
+ } else {
+
+ // you loose
+ game.stop();
+
+ }
+
+ }
+ })
+
+ this.score = score;
+ }
+
+}
+
+class Stick {
+
+ constructor() {
+ this.stick = this.addStick();
+ }
+
+ addStick() {
+ this.stick = $('#sticks').append('');
+ return this.stick;
+ }
+
+}
+
+class Color {
+
+ constructor() {
+ this.colors = ["#FF4571", "#FFD145", "#8260F6"];
+ this.effects = ["bubble", "triangle", "block"];
+ this.prevEffect = null;
+ }
+
+ getRandomColor() {
+ let colorIndex = Math.random()*3;
+ let color = this.colors[Math.floor(colorIndex)];
+ return color;
+ }
+
+ colorcodeToName(color) {
+ let colors = ["#FF4571", "#FFD145", "#8260F6"];
+ let names = ["red", "yellow", "purple"];
+ let index = colors.indexOf(color);
+ if(index == -1) return false;
+ return names[index];
+ }
+
+ /**
+ * Changes the color of an element
+ * As we as adds verbal name of the color
+ */
+ changeColor(el) {
+ let index = el.data("index");
+ if(index===undefined) { index = 0; }
+ else { index += 1; }
+ if(index==3) index = 0;
+ el
+ .css('background-color', this.colors[index])
+ .data('index', index);
+
+ el.removeClass('red')
+ .removeClass('yellow')
+ .removeClass('purple')
+ .addClass(this.colorcodeToName(this.colors[index]));
+
+ if(el.hasClass('inactive')) {
+ this.setEffect(el);
+ el.addClass('no-effect');
+ }
+
+ el.removeClass('inactive');
+ }
+
+ getRandomEffect() {
+ let effectIndex = null;
+
+ effectIndex = Math.floor(Math.random()*3);
+ while(effectIndex == this.prevEffect) {
+ effectIndex = Math.floor(Math.random()*3);
+ }
+
+ this.prevEffect = effectIndex;
+ return this.effects[effectIndex];
+ }
+
+ /**
+ * Adds the effect specific particles to the stick
+ */
+ setEffect(el) {
+ let effect = this.getRandomEffect();
+ el.addClass(effect + '-stick');
+ for(let i = 1; i <= 14; i++) {
+ if(effect=='block') {
+ el.append(``);
+ } else {
+ el.append(``);
+ }
+ }
+ }
+
+ /**
+ * Since the ball and sticks have several classes
+ * This method searches for the color class
+ * @param el [DOM element]
+ * @return {string} class name
+ */
+ static getColorFromClass(el) {
+ let classes = $(el).attr('class').split(/\s+/);
+ for (var i = 0, len = classes.length; i < len; i++) {
+ if(classes[i] == 'red' || classes[i] == 'yellow' || classes[i] == 'purple') {
+ return classes[i];
+ }
+ }
+ }
+}
+
+class Animation {
+
+ /**
+ * Creates and positions the small glow elements on the screen
+ */
+ static generateSmallGlows(number) {
+ let h = $(window).height();
+ let w = $(window).width();
+ let scale = (w > h) ? h/800 : w/1200;
+
+ h = h/scale;
+ w = w/scale;
+
+ for(let i = 0; i < number; i++) {
+ let left = Math.floor(Math.random()*w);
+ let top = Math.floor(Math.random()*(h/2));
+ let size = Math.floor(Math.random()*8) + 4;
+ $('.small-glows').prepend('');
+ let noise = $('.small-glows .small-glow').first();
+ noise.css({left: left, top: top, height: size, width: size});
+ }
+ }
+
+ /**
+ * Creates the animations for sticks
+ * The effects is chosen by random
+ * And one of the three functions is
+ * Called accordingly
+ */
+ playBubble(el) {
+ let bubble = new TimelineMax();
+ bubble.staggerFromTo(el.find('.bubble'), 0.3, {scale: 0.1}, {scale: 1}, 0.03)
+ bubble.staggerTo(el.find('.bubble'), 0.5, {y: '-=60px', yoyo: true, repeat: -1}, 0.03);
+ }
+
+ playTriangle(el) {
+ let triangle = new TimelineMax();
+ triangle.staggerFromTo(el.find('.triangle'), 0.3, {scale: 0.1}, {scale: 1}, 0.03)
+ .staggerTo(el.find('.triangle'), 1.5, {
+ cycle:{
+ rotationY: [0, 360],
+ rotationX: [360, 0],
+ },
+ repeat: -1,
+ repeatDelay: 0.1
+ }, 0.1);
+ }
+
+ playBlock(el) {
+ let block = new TimelineMax();
+ let block2 = new TimelineMax({delay: 0.69});
+
+ block.staggerFromTo(el.find('.block'), 0.3, {scale: 0.1}, {scale: 1}, 0.03)
+ .staggerTo(el.find('.block .inner:not(.inner-2)'), 1, {
+ cycle: {
+ x: ["+200%", "-200%"]
+ },
+ repeat: -1,
+ repeatDelay: 0.6,
+ }, 0.1);
+ block2.staggerTo(el.find('.block .inner-2'), 1, {
+ cycle: {
+ x: ["+200%", "-200%"]
+ },
+ repeat: -1,
+ repeatDelay: 0.6,
+ }, 0.1);
+ }
+
+ static sceneAnimation() {
+
+ const speed = 15; // uses it's local speed
+
+ // animates the small glows in a circular motion
+ $('.small-glow').each(function(){
+ let speedDelta = Math.floor(Math.random()*8);
+ let radius = Math.floor(Math.random()*20)+20;
+ TweenMax.to($(this), speed+speedDelta, {rotation: 360, transformOrigin: "-"+radius+"px -"+radius+"px", repeat: -1, ease: Power0.easeNone});
+ })
+
+ var wavet = TweenMax.to('.top_wave', speed*1.7/42, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
+ var wave1 = TweenMax.to('.wave1', speed*1.9/42, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
+ var wave2 = TweenMax.to('.wave2', speed*2/42, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
+ var wave3 = TweenMax.to('.wave3', speed*2.2/42, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
+ var wave4 = TweenMax.to('.wave4', speed*2.4/42, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
+
+ var mount1 = TweenMax.to('.mount1', speed*8, {backgroundPositionX: '-=1760px', repeat: -1, ease: Power0.easeNone});
+ var mount2 = TweenMax.to('.mount2', speed*10, {backgroundPositionX: '-=1782px', repeat: -1, ease: Power0.easeNone});
+
+ var clouds = TweenMax.to('.clouds', speed*3, {backgroundPositionX: '-=1001px', repeat: -1, ease: Power0.easeNone});
+
+ }
+
+}
+
+ var game = new Game();
+ var animation = new Animation();
+ var color = new Color();
+ var userAgent = window.navigator.userAgent;
+
+ Animation.generateSmallGlows(20);
+
+ $(document).ready(function(){
+ //game.showResult();
+ game.scaleScreen();
+ game.intro();
+ //game.start();
+ //game.bounce();
+
+ if($(window).height() < 480) {
+ $('.play-full-page').css('display', 'block');
+ }
+ })
+
+ $(document).on('click', '.stick', function(){
+ color.changeColor($(this));
+ if($(this).hasClass('no-effect')) {
+ if($(this).hasClass('bubble-stick')) {
+ animation.playBubble($(this));
+ } else if($(this).hasClass('triangle-stick')) {
+ animation.playTriangle($(this));
+ } else if($(this).hasClass('block-stick')) {
+ animation.playBlock($(this));
+ }
+ $(this).removeClass('no-effect');
+ }
+ });
+
+ $(document).on('click', '.section-2 .bar', function(){
+ color.changeColor($(this));
+ });
+
+ $(window).resize(function(){
+ if (!userAgent.match(/iPad/i) && !userAgent.match(/iPhone/i)) {
+ game.scaleScreenAndRun();
+ }
+ });
+
+ $(window).on("orientationchange",function(){
+ game.scaleScreenAndRun();
+ });
diff --git a/BallColoron/TidePlus/style.css b/BallColoron/TidePlus/style.css
new file mode 100644
index 000000000..54797d44b
--- /dev/null
+++ b/BallColoron/TidePlus/style.css
@@ -0,0 +1,738 @@
+@mixin bubble_shape ($width: 4px) {
+ border-radius: 50%;
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.12);
+ border-color: rgba(0, 0, 0, 0.12);
+ border-width: $width;
+}
+
+@mixin bubble ($size, $top, $left) {
+ height: $size;
+ width: $size;
+ top: $top;
+ left: $left;
+}
+
+@mixin bubble_hollow ($size, $top, $left) {
+ @include bubble ($size, $top, $left);
+ background-color: transparent;
+ border-style: solid;
+}
+
+@mixin triangle ($height, $width, $top, $left) {
+ border-left: ($height/2) solid transparent;
+ border-right: ($height/2) solid transparent;
+ border-bottom: $width solid rgba(0, 0, 0, 0.12);
+ background-color: transparent;
+ left: $left;
+ top: $top;
+}
+
+@mixin triangle_hollow ($height, $width, $top, $left) {
+ @include triangle( $height, $width, $top, $left );
+ &:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ border-left: ($height/4-1) solid transparent;
+ border-right: ($height/4-1) solid transparent;
+ border-bottom: ($height/2-3) solid transparent;
+ top: 6px;
+ left: -($width/4);
+ transition: border-bottom-color 0.4s ease;
+
+ .red & {
+ border-bottom-color: #fc5c82;
+ }
+ .yellow & {
+ border-bottom-color: #fcd45c;
+ }
+ .purple & {
+ border-bottom-color: #9174f5;
+ }
+ }
+}
+
+@mixin block ($height, $width, $top, $left) {
+ height: $height;
+ width: $width;
+ top: $top;
+ left: $left;
+}
+
+@mixin block_hollow ($height, $width, $top, $left) {
+ @include block ($height, $width, $top, $left);
+ & .inner {
+ background-color: transparent !important;
+ border-style: solid;
+ box-sizing: border-box;
+ }
+}
+
+.bubble {
+ @include bubble_shape;
+}
+.bubble-1 {
+ @include bubble(15px, 21px, 59px);
+}
+.bubble-2 {
+ @include bubble(27px, 36px, 16px);
+}
+.bubble-3 {
+ @include bubble(21px, 63px, 49px);
+}
+.bubble-4 {
+ @include bubble(15px, 98px, 37px);
+}
+.bubble-5 {
+ @include bubble_hollow(5px, 116px, 20px);
+}
+.bubble-6 {
+ @include bubble(6px, 128px, 63px);
+}
+.bubble-7 {
+ @include bubble(27px, 150px, 52px);
+}
+.bubble-8 {
+ @include bubble(19px, 154px, 18px);
+}
+.bubble-9 {
+ @include bubble(10px, 189px, 13px);
+}
+.bubble-10 {
+ @include bubble_hollow(5px, 199px, 52px);
+}
+.bubble-11 {
+ @include bubble(21px, 220px, 29px);
+}
+.bubble-12 {
+ @include bubble(21px, 263px, 48px);
+}
+.bubble-13 {
+ @include bubble_hollow(5px, 275px, 16px);
+}
+.bubble-14 {
+ @include bubble(15px, 296px, 34px);
+}
+.triangle {
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.12);
+ border-color: rgba(0, 0, 0, 0.12);
+}
+.triangle-1 {
+ @include bubble_shape;
+ @include bubble(10px, 22px, 55px);
+}
+.triangle-2 {
+ @include triangle_hollow(16px, 14px, 27px, 15px);
+}
+.triangle-3 {
+ @include triangle_hollow(24px, 19px, 60px, 43px);
+}
+.triangle-4 {
+ @include bubble_shape(3px);
+ @include bubble_hollow(8px, 61px, 17px);
+}
+.triangle-5 {
+ @include triangle(10px, 8px, 101px, 25px);
+ transform: rotate(180deg);
+}
+
+.triangle-6 {
+ @include triangle(8px, 6px, 103px, 60px);
+ transform: rotate(-90deg);
+}
+
+.triangle-7 {
+ @include triangle(25px, 19px, 126px, 17px);
+ transform: rotate(180deg);
+}
+
+.triangle-8 {
+ @include triangle(21px, 16px, 149px, 50px);
+}
+
+.triangle-9 {
+ @include triangle(11px, 8px, 177px, 21px);
+}
+
+.triangle-10 {
+ @include bubble_shape;
+ @include bubble(10px, 177px, 60px);
+}
+
+.triangle-11 {
+ @include triangle(18px, 13px, 213px, 33px);
+ transform: rotate(180deg);
+}
+
+.triangle-12 {
+ @include bubble_shape(2px);
+ @include bubble_hollow(10px, 233px, 65px);
+}
+
+.triangle-13 {
+ @include bubble_shape;
+ @include bubble(10px, 250px, 22px);
+}
+
+.triangle-14 {
+ @include triangle_hollow(16px, 14px, 270px, 45px);
+ transform: rotate(180deg);
+}
+
+.stick {
+ .block {
+ position: absolute;
+ overflow: hidden;
+ z-index: 999;
+ border-radius: 7px;
+ .inner {
+ border-radius: 7px;
+ background-color: rgba(0, 0, 0, 0.12);
+ border-color: rgba(0, 0, 0, 0.12);
+ border-width: 3px;
+ height: 100%;
+ width: 100%;
+ position: absolute;
+ }
+ &:nth-child(2n+1) .inner-2 {
+ left: -200%;
+ }
+ &:nth-child(2n+2) .inner-2 {
+ left: 200%;
+ }
+ }
+ .block-1 {
+ @include block_hollow(16px, 31px, 16px, 30px);
+ }
+ .block-2 {
+ @include block(14px, 42px, 50px, 15px);
+ }
+ .block-3 {
+ @include block(18px, 9px, 73px, 64px);
+ }
+ .block-4 {
+ @include block(9px, 14px, 84px, 26px);
+ }
+ .block-5 {
+ @include block(15px, 15px, 109px, 45px);
+ .inner {
+ border-radius: 50%;
+ }
+ }
+ .block-6 {
+ @include block(9px, 27px, 135px, 19px);
+ }
+ .block-7 {
+ @include block(12px, 12px, 144px, 60px);
+ .inner {
+ border-radius: 50%;
+ border-style: solid;
+ box-sizing: border-box;
+ background-color: transparent;
+ }
+ }
+ .block-8 {
+ @include block(27px, 14px, 164px, 24px);
+ }
+ .block-9 {
+ @include block(8px, 8px, 188px, 64px);
+ }
+ .block-10 {
+ @include block_hollow(12px, 22px, 219px, 11px);
+ }
+ .block-11 {
+ @include block(22px, 22px, 226px, 50px);
+ .inner {
+ border-radius: 50%;
+ }
+ }
+ .block-12 {
+ @include block(18px, 9px, 248px, 26px);
+ }
+ .block-13 {
+ @include block(8px, 8px, 278px, 50px);
+ .inner {
+ border-radius: 50%;
+ }
+ }
+ .block-14 {
+ @include block_hollow(12px, 22px, 297px, 18px);
+ }
+ .block-15 {
+ @include block(9px, 27px, 307px, 48px);
+ }
+}
+
+body {
+ background-color: #28DAD4;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ font-family: 'Roboto', sans-serif;
+}
+a {
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor.svg), pointer;
+ &:focus, &:active {
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor-tap.svg), pointer;
+ }
+}
+.container {
+ position: fixed;
+ left: 0;
+ top: 0;
+ height: 100%;
+ width: 100%;
+}
+.waves, .mounts {
+ position: absolute;
+ width: 100%;
+ left: 0;
+ bottom: 0;
+}
+.waves div, .mounts div {
+ position: absolute;
+ width: 100%;
+}
+.clouds {
+ position: absolute;
+ width: 100%;
+ left: 0;
+ top: 77px;
+ height: 151px;
+ background: url(https://greghub.github.io/coloron/public/svg/clouds.svg) repeat-x;
+ background-position-x: 170px;
+}
+.top_wave {
+ background: url(https://greghub.github.io/coloron/public/svg/top_wave.png) repeat-x 0 -1px;
+ height: 35px;
+ bottom: 0;
+ z-index: 10001;
+}
+.wave1 {
+ background: url(https://greghub.github.io/coloron/public/svg/wave1.svg) repeat-x;
+ height: 150px;
+ bottom: 0;
+ z-index: 23;
+}
+.wave2 {
+ background: url(https://greghub.github.io/coloron/public/svg/wave2.svg) repeat-x;
+ height: 180px;
+ bottom: 30px;
+ z-index: 22;
+}
+.wave3 {
+ background: url(https://greghub.github.io/coloron/public/svg/wave3.svg) repeat-x;
+ height: 180px;
+ bottom: 90px;
+ z-index: 21;
+}
+.wave4 {
+ background: url(https://greghub.github.io/coloron/public/svg/wave4.svg) repeat-x;
+ height: 180px;
+ bottom: 120px;
+ z-index: 20;
+}
+.mount1 {
+ background: url(https://greghub.github.io/coloron/public/svg/mount1.svg) repeat-x;
+ height: 150px;
+ bottom: 280px;
+ z-index: 11;
+}
+.mount2 {
+ background: url(https://greghub.github.io/coloron/public/svg/mount2.svg) repeat-x;
+ height: 150px;
+ bottom: 290px;
+ z-index: 10;
+}
+.noise {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ z-index: 1010;
+ background: url(https://greghub.github.io/coloron/public/svg/noise.png);
+}
+.glow {
+ position: absolute;
+ left: -350px;
+ top: -350px;
+ width: 800px;
+ height: 800px;
+ background-color: rgba(81, 237, 200, 0.34);
+ border-radius: 50%;
+ box-shadow: 0 0 100px 100px rgba(81, 237, 200, 0.34);
+ z-index: 1010;
+}
+.sun {
+ position: relative;
+ left: 50%;
+ top: 50%;
+ width: 1px;
+ height: 1px;
+ background-color: rgba(255, 227, 69, 1);
+ border-radius: 50%;
+ box-shadow: 0 0 32px 32px rgba(255, 227, 69, 1),
+ 0 0 150px 150px rgba(103, 244, 210, 0.4);
+}
+.small-glow {
+ z-index: 99;
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ position: absolute;
+ background-color: rgba(255, 255, 255, 0.34);
+ box-shadow: 0 0 1px 1px rgba(255, 255, 255, 0.34);
+}
+.small-glow.yellow {
+ background-color: rgba(255, 227, 69, 0.34);
+ box-shadow: 0 0 4px 4px rgba(255, 227, 69, 0.34);
+}
+.sticks {
+ z-index: 1011;
+ outline: none;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+}
+.stick {
+ height: 362px;
+ width: 90px;
+ border-radius: 14px;
+ background-image: url(https://greghub.github.io/coloron/public/svg/noise.png);
+ position: relative;
+ overflow: hidden;
+ float: left;
+ margin-right: 90px;
+ transition: background-color 0.4s ease;
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor.svg), pointer;
+ &:focus, &:active {
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor-tap.svg), pointer;
+ }
+}
+.stick.red {
+ background-color: #FF4571;
+}
+.stick.yellow {
+ background-color: #FFD145;
+}
+.stick.purple {
+ background-color: #8260F6;
+}
+.stick.inactive {
+ background-color: #4C4660;
+}
+.ball, .ball-demo {
+ background: url(https://greghub.github.io/coloron/public/svg/ball.svg) right bottom;
+ background-size: 64px 64px;
+ width: 53px;
+ height: 53px;
+ z-index: 1011;
+ background-color: #FF4571;
+ border-radius: 50%;
+}
+.ball {
+ margin-bottom: 250px;
+}
+.controls {
+ z-index: 999999;
+ position: relative
+}
+.game-full-flex {
+ position: fixed;
+ display: none; // gets updated to flex with JS
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ z-index: 9998;
+}
+.start-game {
+ .start-game-top {
+ min-height: 20%;
+ .play-full-page {
+ display: none;
+ border: 3px solid #fff;
+ border-radius: 100px;
+ color: #fff;
+ width: 260px;
+ height: 50px;
+ font-size: 28px;
+ text-align: center;
+ font-weight: 900;
+ letter-spacing: -1px;
+ line-height: 52px;
+ text-decoration: none;
+ text-transform: uppercase;
+ margin-top: 24px;
+ &:hover {
+ opacity: 0.7;
+ }
+ }
+ }
+ .logo-holder {
+ width: 513px;
+ height: 162px;
+ background-color: #4C4660;
+ border: 4px solid #FF4571;
+ border-radius: 68px;
+ text-align: center;
+ margin-top: -10%;
+ .logo {
+ color: #fff;
+ text-transform: uppercase;
+ font-weight: 900;
+ font-size: 100px;
+ letter-spacing: -0.1em;
+ margin-top: 10px;
+ margin-bottom: 4px;
+ text-align: center;
+ span {
+ margin-left: -8px;
+ margin-right: -8px;
+ }
+ }
+ .play-button {
+ display: inline-block;
+ background-color: #FF4571;
+ border: 4px solid #fff;
+ border-radius: 100px;
+ color: #fff;
+ width: 200px;
+ height: 56px;
+ font-size: 42px;
+ text-align: center;
+ font-weight: 900;
+ letter-spacing: -3px;
+ line-height: 56px;
+ text-decoration: none;
+ &:hover {
+ background-color: lighten(#FF4571, 5%);
+ }
+ }
+ .hint {
+ color: #fff;
+ font-size: 20px;
+ span {
+ color: #FF4571;
+ }
+ }
+ }
+ .how-to-play {
+ display: flex;
+ justify-content: space-around;
+ width: 100%;
+ .section-1, .section-3 {
+ flex: 1;
+ .content {
+ justify-content: center;
+ }
+ }
+ h4 {
+ color: #fff;
+ font-weight: 400;
+ font-size: 22px;
+ text-align: center;
+ }
+ .content {
+ height: 200px;
+ position: relative;
+ display: flex;
+ justify-content: space-around;
+ }
+ .bar {
+ width: 60px;
+ border-radius: 7px;
+ margin-top: auto;
+ transition: background-color 0.4s ease;
+ &.bar-1 {
+ height: 180px;
+ background: #FF4571;
+ }
+ &.bar-2 {
+ height: 120px;
+ background: #FFD145;
+ }
+ &.bar-3 {
+ height: 150px;
+ background: #4C4660;
+ }
+ }
+ .section-2 {
+ .bar {
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor.svg), pointer;
+ &:focus, &:active {
+ cursor: url(https://greghub.github.io/coloron/public/svg/cursor-tap.svg), pointer;
+ }
+ }
+ }
+ .section-3 {
+ .ball-demo {
+ background-color: #815FF8;
+ }
+ .bar-1 {
+ height: 120px;
+ background-color: #815FF8;
+ }
+ }
+ }
+}
+.stop-game {
+ justify-content: center;
+ .score-container {
+ background-color: #4C4660;
+ width: 433px;
+ height: 386px;
+ border-radius: 38px;
+ text-align: center;
+ h1 {
+ color: #fff;
+ text-transform: uppercase;
+ letter-spacing: -0.1em;
+ margin-top: 20px;
+ margin-bottom: 4px;
+ font-size: 64px;
+ }
+ .final-score {
+ color: #FFE345;
+ font-weight: 900;
+ font-size: 130px;
+ letter-spacing: -6px;
+ line-height: 110px;
+ }
+ .result {
+ color: #FF4571;
+ text-transform: uppercase;
+ font-weight: 700;
+ font-size: 30px;
+ }
+ h4 {
+ color: #fff;
+ margin-top: 12px;
+ }
+ .tweet {
+ background: #fff;
+ padding: 8px 20px;
+ border-radius: 4px;
+ color: #55ACEE;
+ text-decoration: none;
+ font-size: 18px;
+ line-height: 24px;
+ display: inline-block;
+ &:hover {
+ background-color: #55ACEE;
+ color: #fff;
+ }
+ i {
+ font-size: 24px;
+ top: 2px;
+ right: 2px;
+ position: relative;
+ }
+ }
+ .play-again {
+ background-color: #FF4571;
+ border: 2px solid #fff;
+ color: #fff;
+ text-decoration: none;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: -1px;
+ font-size: 26px;
+ padding: 6px 24px;
+ border-radius: 22px;
+ margin: 6px 4px;
+ display: inline-block;
+ &:hover {
+ background-color: lighten(#FF4571, 5%);
+ }
+ }
+ .main-menu {
+ background-color: #44BFA3;
+ border: 2px solid #fff;
+ color: #fff;
+ text-decoration: none;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: -1px;
+ font-size: 26px;
+ padding: 6px 24px;
+ border-radius: 22px;
+ margin: 6px 4px;
+ display: inline-block;
+ &:hover {
+ background-color: lighten(#44BFA3, 5%);
+ }
+ }
+ }
+}
+.scene {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ position: fixed;
+ z-index: 9997;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ .ball-holder {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ padding-left: 558px;
+ }
+ .score {
+ position: fixed;
+ right: 54px;
+ top: 20px;
+ color: #33485F;
+ font-size: 90px;
+ font-weight: 900;
+ letter-spacing: -0.1em;
+ }
+ .learn-to-play {
+ z-index: 9999;
+ display: inline-block;
+ text-align: center;
+ position: relative;
+ top: 20%;
+ font-size: 48px;
+ color: rgba(255,255,255,0.85);
+ font-weight: 700;
+ letter-spacing: -2px;
+ opacity: 0;
+ }
+}
+
+.splash {
+ display: none;
+}
+
+@media print {
+ .splash {
+ display: block;
+ position: fixed;
+ z-index: 99999;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #28DAD4;
+ background-image: url(https://greghub.github.io/coloron/public/images/coloron-image.png);
+ background-size: auto 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+}
+
+.nominee {
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 9999;
+}