@import "helpers"; @import "fonts/clear-sans.css"; $field-width: 500px; $grid-spacing: 15px; $grid-row-cells: 4; $tile-size: ($field-width - $grid-spacing * ($grid-row-cells + 1)) / $grid-row-cells; $tile-border-radius: 3px; $text-color: #776E65; $bright-text-color: #f9f6f2; $tile-color: #eee4da; $tile-gold-color: #edc22e; $tile-gold-glow-color: lighten($tile-gold-color, 15%); $game-container-background: #bbada0; $transition-speed: 100ms; html, body { margin: 0; padding: 0; background: #faf8ef; color: $text-color; font-family: "Clear Sans", "Helvetica Neue", Arial, sans-serif; font-size: 18px; } body { margin: 80px 0; } .heading:after { content: ""; display: block; clear: both; } h1.title { font-size: 80px; font-weight: bold; margin: 0; display: block; float: left; } @include keyframes(move-up) { 0% { top: 25px; opacity: 1; } 100% { top: -50px; opacity: 0; } } .score-container { $height: 25px; position: relative; float: right; background: $game-container-background; padding: 15px 25px; font-size: $height; height: $height; line-height: $height + 22px; font-weight: bold; border-radius: 3px; color: white; margin-top: 8px; &:after { position: absolute; width: 100%; top: 10px; left: 0; content: "Score"; text-transform: uppercase; font-size: 13px; line-height: 13px; text-align: center; color: $tile-color; } .score-addition { position: absolute; right: 30px; color: red; font-size: $height; line-height: $height; font-weight: bold; color: rgba($text-color, .9); z-index: 100; @include animation(move-up 600ms ease-in); @include animation-fill-mode(both); } } p { margin-top: 0; margin-bottom: 10px; line-height: 1.65; } a { color: $text-color; font-weight: bold; text-decoration: underline; } strong { &.important { text-transform: uppercase; } } hr { border: none; border-bottom: 1px solid lighten($text-color, 40%); margin-top: 20px; margin-bottom: 30px; } .container { width: $field-width; margin: 0 auto; } @include keyframes(fade-in) { 0% { opacity: 0; } 100% { opacity: 1; } } .game-container { margin-top: 40px; position: relative; padding: $grid-spacing; cursor: default; -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; background: $game-container-background; border-radius: $tile-border-radius * 2; width: $field-width; height: $field-width; box-sizing: border-box; &.game-over, &.game-won { &:after { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: block; background: rgba($tile-color, .5); text-align: center; height: $field-width; line-height: $field-width; z-index: 100; font-size: 60px; font-weight: bold; @include animation(fade-in 800ms ease $transition-speed * 12); @include animation-fill-mode(both); } } &.game-over:after { content: "Game over!"; } &.game-won:after { content: "You win!"; background: rgba($tile-gold-color, .5); color: $bright-text-color; } } .grid-container { position: absolute; z-index: 1; } .grid-row { margin-bottom: $grid-spacing; &:last-child { margin-bottom: 0; } &:after { content: ""; display: block; clear: both; } } .grid-cell { width: $tile-size; height: $tile-size; margin-right: $grid-spacing; float: left; border-radius: $tile-border-radius; background: rgba($tile-color, .35); &:last-child { margin-right: 0; } } .tile-container { position: absolute; z-index: 2; } .tile { background: red; width: $tile-size; height: $tile-size; border-radius: $tile-border-radius; background: $tile-color; text-align: center; line-height: $tile-size + 10px; font-size: 55px; font-weight: bold; z-index: 10; @include transition($transition-speed ease-in-out); @include transition-property(top, left); // Build position classes @for $x from 1 through $grid-row-cells { @for $y from 1 through $grid-row-cells { &.tile-position-#{$x}-#{$y} { position: absolute; left: round(($tile-size + $grid-spacing) * ($x - 1)); top: round(($tile-size + $grid-spacing) * ($y - 1)); } } } $base: 2; $exponent: 1; $limit: 11; // Colors for all 11 states, false = no special color $special-colors: false false, // 2 false false, // 4 #f78e48 true, // 8 #fc5e2e true, // 16 #ff3333 true, // 32 #ff0000 true, // 64 false true, // 128 false true, // 256 false true, // 512 false true, // 1024 false true; // 2048 // Build tile colors @while $exponent <= $limit { $power: pow($base, $exponent); &.tile-#{$power} { // Calculate base background color $gold-percent: ($exponent - 1) / ($limit - 1) * 100; $mixed-background: mix($tile-gold-color, $tile-color, $gold-percent); $nth-color: nth($special-colors, $exponent); $special-background: nth($nth-color, 1); $bright-color: nth($nth-color, 2); @if $special-background { $mixed-background: mix($special-background, $mixed-background, 55%); } @if $bright-color { color: $bright-text-color; } // Set background background: $mixed-background; // Add glow $glow-opacity: max($exponent - 4, 0) / ($limit - 4); @if not $special-background { box-shadow: 0 0 30px 10px rgba($tile-gold-glow-color, $glow-opacity / 1.8), inset 0 0 0 1px rgba(white, $glow-opacity / 3); } // Adjust font size for bigger numbers @if $power >= 100 and $power < 1000 { font-size: 45px; } @else if $power >= 1000 { font-size: 35px; } } $exponent: $exponent + 1; } } @include keyframes(appear) { 0% { // -webkit-transform: scale(1.5); opacity: 0; -webkit-transform: scale(0); } 100% { // -webkit-transform: scale(1); opacity: 1; -webkit-transform: scale(1); } } .tile-new { @include animation(appear 200ms ease $transition-speed); @include animation-fill-mode(both); } @include keyframes(pop) { 0% { -webkit-transform: scale(0); // opacity: 0; } 50% { -webkit-transform: scale(1.2); } 100% { -webkit-transform: scale(1); // opacity: 1; } } .tile-merged { z-index: 20; @include animation(pop 200ms ease $transition-speed); @include animation-fill-mode(both); } .game-intro { margin-bottom: 0; } .game-explanation { margin-top: 50px; }