diff --git a/.gitignore b/.gitignore index 0d31019855..5633a2513c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,9 @@ .sass-cache/ +*.map + +# Eclipse project files +.project +.settings/ + +# Mac OS Finder folder data +.DS_Store diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a8c8cef1e..8b269ae253 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,11 +11,11 @@ Please follow the house rules to have a bigger chance of your contribution being - If you want to modify the CSS, please edit the SCSS files present in `style/`: `main.scss` and others. Don't edit the `main.css`, because it's supposed to be generated. In order to compile your SCSS modifications, you need to use the `sass` gem (install it by running `gem install sass` once Ruby is installed). To run SASS, simply use the following command: - `sass --watch style/main.scss` + `sass --unix-newlines --watch style/main.scss` SASS will automatically recompile your css when changed. - `Rakefile` contains some tasks that help during development. Feel free to add useful tasks if needed. - Please use 2-space indentation when editing the JavaScript. A `.jshintrc` file is present, which will help your code to follow the guidelines if you install and run `jshint`. - - Please test your modification thouroughly before submitting your Pull Request. + - Please test your modification thoroughly before submitting your Pull Request. ### Changes that might not be accepted We have to be conservative with the core game. This means that some modifications won't be merged, or will have to be evaluated carefully before being merged: diff --git a/README.md b/README.md index e475357b5d..7120611aa7 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,20 @@ The official app can also be found on the [Play Store](https://play.google.com/s ### Contributions +[Anna Harren](https://github.com/iirelu/) and [sigod](https://github.com/sigod) are maintainers for this repository. + +Other notable contributors: + - [TimPetricola](https://github.com/TimPetricola) added best score storage - [chrisprice](https://github.com/chrisprice) added custom code for swipe handling on mobile - - [elektryk](https://github.com/elektryk) made swipes work on Windows Phone + - [marcingajda](https://github.com/marcingajda) made swipes work on Windows Phone - [mgarciaisaia](https://github.com/mgarciaisaia) added support for Android 2.3 Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://github.com/Mechazawa), [grant](https://github.com/grant), [remram44](https://github.com/remram44) and [ghoullier](https://github.com/ghoullier) for the many other good contributions. ### Screenshot -

- Screenshot -

- -That screenshot is fake, by the way. I never reached 2048 :smile: +![](screenshots/screen01.png) ## Contributing Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into `master`! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process. diff --git a/index.html b/index.html index d698d25113..361a3cdca5 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,7 @@ +

2048

@@ -27,18 +28,23 @@

2048

-

Join the numbers and get to the 2048 tile!

- New Game +

+
+ +
+ +
@@ -86,5 +92,6 @@

2048

+ diff --git a/js/game_manager.js b/js/game_manager.js index 912d2d71e8..91894c3764 100644 --- a/js/game_manager.js +++ b/js/game_manager.js @@ -8,7 +8,9 @@ function GameManager(size, InputManager, Actuator, StorageManager) { this.inputManager.on("move", this.move.bind(this)); this.inputManager.on("restart", this.restart.bind(this)); + this.inputManager.on("undoMove", this.undoMove.bind(this)); this.inputManager.on("restartWithConfirmation", this.restartWithConfirmation.bind(this)); + this.inputManager.on("undoWithConfirmation", this.undoWithConfirmation.bind(this)); this.inputManager.on("keepPlaying", this.keepPlaying.bind(this)); this.setup(); @@ -21,17 +23,51 @@ GameManager.prototype.restart = function () { this.setup(); }; -// Restart the game after user confirmation +// Undo the current move +GameManager.prototype.undoMove = function () { + this.actuator.continueGame(); // Clear the game won/lost message + + if (this.storageManager.getLengthOfGameStatesStack() > 0) { + var previousState = this.storageManager.popGameState(); + + // Reload the game from a previous game if present + if (previousState) { + this.grid = new Grid(previousState.grid.size, + previousState.grid.cells); // Reload grid + this.score = previousState.score; + this.over = previousState.over; + this.won = previousState.won; + this.keepPlaying = previousState.keepPlaying; + } + + // Manually Update the actuator + this.actuator.actuate(this.grid, { + score: this.score, + over: this.over, + won: this.won, + bestScore: this.storageManager.getBestScore(), + terminated: this.isGameTerminated(), + keepPlaying: this.keepPlaying + }); + } +}; +// Restart the game after user confirmation GameManager.prototype.restartWithConfirmation = function () { // Open confirm message this.actuator.promptRestart(); }; +GameManager.prototype.undoWithConfirmation = function () { + // Open confirm message + this.actuator.promptUndo(); +}; + // Keep playing after winning (allows going over 2048) GameManager.prototype.keepPlaying = function () { this.keepPlaying = true; this.actuator.continueGame(); // Clear the game won/lost message + this.actuate(); }; // Return true if the game is lost, or has won and the user hasn't kept playing @@ -94,6 +130,7 @@ GameManager.prototype.actuate = function () { this.storageManager.clearGameState(); } else { this.storageManager.setGameState(this.serialize()); + this.storageManager.pushGameState(this.serialize()); } this.actuator.actuate(this.grid, { @@ -101,7 +138,8 @@ GameManager.prototype.actuate = function () { over: this.over, won: this.won, bestScore: this.storageManager.getBestScore(), - terminated: this.isGameTerminated() + terminated: this.isGameTerminated(), + keepPlaying: this.keepPlaying }); }; @@ -258,7 +296,7 @@ GameManager.prototype.tileMatchesAvailable = function () { tile = this.grid.cellContent({ x: x, y: y }); if (tile) { - for (var direction = 0; direction < 4; direction++) { + for (var direction = 0; direction < 2; direction++) { var vector = self.getVector(direction); var cell = { x: x + vector.x, y: y + vector.y }; diff --git a/js/html_actuator.js b/js/html_actuator.js index 9e4bfad306..29e9c3c527 100644 --- a/js/html_actuator.js +++ b/js/html_actuator.js @@ -25,7 +25,15 @@ HTMLActuator.prototype.actuate = function (grid, metadata) { self.updateBestScore(metadata.bestScore); if (metadata.terminated) { + // when last move create a 2048 tile and couldn't find next move, + // metadata.over and metadata.won are both set to true if (metadata.over) { + //edge case ; + if (metadata.won && !metadata.keepPlaying){ + // last move won , and no more move ; + self.message(true); + return; + } self.message(false); // You lose } else if (metadata.won) { self.message(true); // You win! @@ -66,10 +74,13 @@ HTMLActuator.prototype.addTile = function (tile) { if (tile.previousPosition) { // Make sure that the tile gets rendered in the previous position first - window.requestAnimationFrame(function () { - classes[2] = self.positionClass({ x: tile.x, y: tile.y }); - self.applyClasses(wrapper, classes); // Update the position - }); + var newPosClass = self.positionClass({ x: tile.x, y: tile.y }); + if (newPosClass !== classes[2]) { + window.requestAnimationFrame(function () { + classes[2] = newPosClass; + self.applyClasses(wrapper, classes); // Update the position + }); + } } else if (tile.mergedFrom) { classes.push("tile-merged"); this.applyClasses(wrapper, classes); @@ -126,14 +137,15 @@ HTMLActuator.prototype.updateBestScore = function (bestScore) { HTMLActuator.prototype.message = function (won) { var type = won ? "game-won" : "game-over"; - var message = won ? "You win!" : "Game over!"; + var message = won ? i18n.get('you_win') : i18n.get('game_over'); this.messageContainer.classList.add(type); this.messageContainer.getElementsByTagName("p")[0].textContent = message; }; HTMLActuator.prototype.promptRestart = function () { - var message = "Start a new game?"; + this.clearMessage(); + var message = i18n.get('start_a_new_game'); this.messageContainer.classList.add("restart-game"); this.messageContainer.getElementsByTagName("p")[0].textContent = message; }; @@ -143,4 +155,12 @@ HTMLActuator.prototype.clearMessage = function () { this.messageContainer.classList.remove("game-won"); this.messageContainer.classList.remove("game-over"); this.messageContainer.classList.remove("restart-game"); + this.messageContainer.classList.remove("undo-move"); +}; + +HTMLActuator.prototype.promptUndo = function () { + this.clearMessage(); + var message = i18n.get('undo_the_current_move'); + this.messageContainer.classList.add("undo-move"); + this.messageContainer.getElementsByTagName("p")[0].textContent = message; }; diff --git a/js/i18n.js b/js/i18n.js new file mode 100644 index 0000000000..2b21bb51f7 --- /dev/null +++ b/js/i18n.js @@ -0,0 +1,123 @@ +/** + * Internationalization methods for '2048' game. + * + * @author Igor A. + */ + +'use strict'; + +var Localizer = (function(lang) { + var defaultMsgs = { + intro : 'Join the numbers and get to the 2048 tile!', + new_game : 'New Game', + undo : 'Undo', + keep_going : 'Keep going', + try_again : 'Try again', + ok : 'OK', + cancel : 'Cancel', + start_a_new_game : 'Start a new game?', + undo_the_current_move : 'Undo the current move?', + you_win : 'You win!', + game_over : 'Game over!' + }; + + var localizedMsgs = {}; + + this.lang = lang || navigator.language || 'en'; + + switch (this.lang) { + case 'ru': + localizedMsgs = { + intro : 'Объединяйте числа и получите 2048!', + new_game : 'Новая игра', + undo : 'Отменить ход', + keep_going : 'Продолжайте', + try_again : 'Попробовать ещё раз', + ok : 'ОК', + cancel : 'Отмена', + start_a_new_game : 'Начать новую игру?', + undo_the_current_move : 'Отменить текущий ход?', + you_win : 'Вы победили!', + game_over : 'Игра закончена!' + }; + break; + case 'uk': + localizedMsgs = { + intro : 'Об\'єднуйте числа і отримаєте 2048!', + new_game : 'Нова гра', + undo : 'Скасувати хід', + keep_going : 'Продовжуйте', + try_again : 'Спробувати ще раз', + ok : 'ОК', + cancel : 'Відміна', + start_a_new_game : 'Почати нову гру?', + undo_the_current_move : 'Скасувати поточний хід?', + you_win : 'Ви виграли!', + game_over : 'Гра завершена!' + }; + break; + case 'de': + localizedMsgs = { + intro : 'Verbinde Zahlen & schaffe die 2048 Kachel!', + new_game : 'Neues Spiel', + undo : 'Rück.', + keep_going : 'Weitermachen', + try_again : 'Erneut versuchen', + ok : 'OK', + cancel : 'Abbrechen', + start_a_new_game : 'Neues Spiel beginnen?', + undo_the_current_move : 'Zug rückgängig machen?', + you_win : 'Sieg!', + game_over : 'Game over!' + }; + break; + } + + // In Android (ES5 and earlier) we can not use Object.assign method + this.messages = mergeObjects(defaultMsgs, localizedMsgs); + + /** + * Return localized string by key or default english string if key not + * found. + */ + this.get = function(key) { + if (typeof this.messages[key] === 'string') { + return this.messages[key]; + } + return ''; + }; + + return this; +}); + +/** + * Overwrites o1's values with o2's and adds o2's if non existent in o1. + */ +function mergeObjects(o1, o2) { + var r = {}; + for ( var attrname in o1) { + r[attrname] = o1[attrname]; + } + for ( var attrname in o2) { + r[attrname] = o2[attrname]; + } + return r; +} + +/** + * Retrieve GET parameter's value from query. + */ +function findGetParameter(name) { + var r = null, tmp = []; + var items = location.search.substr(1).split('&'); + for (var index = 0; index < items.length; index++) { + tmp = items[index].split('='); + if (tmp[0] === name) { + r = decodeURIComponent(tmp[1]); + } + } + return r; +} + +// Usage: i18n.get('key') +var i18n = new Localizer(findGetParameter('lang')); diff --git a/js/keyboard_input_manager.js b/js/keyboard_input_manager.js index 8ce791518a..a514c4deab 100644 --- a/js/keyboard_input_manager.js +++ b/js/keyboard_input_manager.js @@ -71,8 +71,10 @@ KeyboardInputManager.prototype.listen = function () { // Respond to button presses this.bindButtonPress(".retry-button", this.restart); this.bindButtonPress(".restart-button", this.restartWithConfirmation); + this.bindButtonPress(".undo-button", this.undoWithConfirmation); this.bindButtonPress(".keep-playing-button", this.keepPlaying); - this.bindButtonPress(".confirm-button", this.restart); + this.bindButtonPress(".undo-move-button", this.undoMove); + this.bindButtonPress(".confirm-button", this.restart); this.bindButtonPress(".cancel-button", this.keepPlaying); // Respond to swipe events @@ -81,7 +83,7 @@ KeyboardInputManager.prototype.listen = function () { gameContainer.addEventListener(this.eventTouchstart, function (event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 1) || - event.targetTouches > 1) { + event.targetTouches.length > 1) { return; // Ignore if touching with more than 1 finger } @@ -102,7 +104,7 @@ KeyboardInputManager.prototype.listen = function () { gameContainer.addEventListener(this.eventTouchend, function (event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 0) || - event.targetTouches > 0) { + event.targetTouches.length > 0) { return; // Ignore if still touching with one or more fingers } @@ -129,6 +131,11 @@ KeyboardInputManager.prototype.listen = function () { }); }; +KeyboardInputManager.prototype.undoMove = function (event) { + event.preventDefault(); + this.emit("undoMove"); +}; + KeyboardInputManager.prototype.restart = function (event) { event.preventDefault(); this.emit("restart"); @@ -139,6 +146,11 @@ KeyboardInputManager.prototype.restartWithConfirmation = function (event) { this.emit("restartWithConfirmation"); }; +KeyboardInputManager.prototype.undoWithConfirmation = function (event) { + event.preventDefault(); + this.emit("undoWithConfirmation"); +}; + KeyboardInputManager.prototype.keepPlaying = function (event) { event.preventDefault(); this.emit("keepPlaying"); diff --git a/js/local_storage_manager.js b/js/local_storage_manager.js index 776e94b1ab..c06f5a7b6e 100644 --- a/js/local_storage_manager.js +++ b/js/local_storage_manager.js @@ -19,8 +19,9 @@ window.fakeStorage = { }; function LocalStorageManager() { - this.bestScoreKey = "bestScore"; - this.gameStateKey = "gameState"; + this.bestScoreKey = "bestScore"; + this.gameStateKey = "gameState"; + this.gameStatesStackKey = "gameStatesStack"; var supported = this.localStorageSupported(); this.storage = supported ? window.localStorage : window.fakeStorage; @@ -28,9 +29,9 @@ function LocalStorageManager() { LocalStorageManager.prototype.localStorageSupported = function () { var testKey = "test"; - var storage = window.localStorage; try { + var storage = window.localStorage; storage.setItem(testKey, "1"); storage.removeItem(testKey); return true; @@ -60,4 +61,53 @@ LocalStorageManager.prototype.setGameState = function (gameState) { LocalStorageManager.prototype.clearGameState = function () { this.storage.removeItem(this.gameStateKey); + this.storage.removeItem(this.gameStatesStackKey); +}; + +// Game states stack push and pop operations and stack length +LocalStorageManager.prototype.popGameState = function () { + var gameStatesStackJSON = this.storage.getItem(this.gameStatesStackKey); + var gameStatesStack = gameStatesStackJSON ? JSON.parse(gameStatesStackJSON) : [ ]; + var previousGameState = null; + var currentGameState = this.storage.getItem(this.gameStateKey); + + // Do not allow the stack to underflow + if(gameStatesStack.length > 0) { + previousGameState = gameStatesStack.pop(); + // The current state will be first item popped + // So you pop once more to get the previous state + if(currentGameState.indexOf(previousGameState) >= 0) { + previousGameState = gameStatesStack.pop(); + } + } + + // Always keep one item on the stack the current state + if(gameStatesStack.length == 0) { + gameStatesStack.push(previousGameState); + } + + this.storage.setItem(this.gameStatesStackKey, JSON.stringify(gameStatesStack)); + return previousGameState ? JSON.parse(previousGameState) : null; +}; + +LocalStorageManager.prototype.pushGameState = function (gameState) { + var gameStatesStackJSON = this.storage.getItem(this.gameStatesStackKey); + var gameStatesStack = gameStatesStackJSON ? JSON.parse(gameStatesStackJSON) : [ ]; + + if(typeof gameStatesStack !== 'undefined') { + if(gameStatesStack.length > 50) { + gameStatesStack.shift(); + } + } + + gameStatesStack.push(JSON.stringify(gameState)); + + this.storage.setItem(this.gameStatesStackKey, JSON.stringify(gameStatesStack)); +}; + +LocalStorageManager.prototype.getLengthOfGameStatesStack = function () { + var gameStatesStackJSON = this.storage.getItem(this.gameStatesStackKey); + var gameStatesStack = gameStatesStackJSON ? JSON.parse(gameStatesStackJSON) : [ ]; + + return gameStatesStack.length; }; diff --git a/js/nightmode.js b/js/nightmode.js new file mode 100644 index 0000000000..fed6b2c937 --- /dev/null +++ b/js/nightmode.js @@ -0,0 +1,26 @@ +function toggleNightMode() { + if (document.getElementsByTagName("html")[0].style.backgroundColor === "rgb(45, 48, 44)") { + document.getElementsByTagName("html")[0].style.backgroundColor = "#faf8ef"; + document.getElementsByTagName("body")[0].style.backgroundColor = "#faf8ef"; + if (typeof(Storage) !== "undefined") { + localStorage['nightmode'] = "0"; + } + return false; + } else { + document.getElementsByTagName("html")[0].style.backgroundColor = "#2D302C"; + document.getElementsByTagName("body")[0].style.backgroundColor = "#2D302C"; + if (typeof(Storage) !== "undefined") { + localStorage['nightmode'] = "1"; + } + return false; + } +} + +window.onload = function() { + var a = document.getElementById("night"); + a.onclick = toggleNightMode; + + if (typeof(Storage) !== "undefined" && localStorage['nightmode'] == "1") { + toggleNightMode(); + } +} diff --git a/screenshots/screen01.png b/screenshots/screen01.png new file mode 100644 index 0000000000..80f356de4f Binary files /dev/null and b/screenshots/screen01.png differ diff --git a/style/fonts/ClearSans-Bold-webfont.eot b/style/fonts/ClearSans-Bold-webfont.eot index 3678ef2a44..8a75af5bfd 100755 Binary files a/style/fonts/ClearSans-Bold-webfont.eot and b/style/fonts/ClearSans-Bold-webfont.eot differ diff --git a/style/fonts/ClearSans-Bold-webfont.svg b/style/fonts/ClearSans-Bold-webfont.svg index aa985aebfd..4464a061ef 100755 --- a/style/fonts/ClearSans-Bold-webfont.svg +++ b/style/fonts/ClearSans-Bold-webfont.svg @@ -3,15 +3,14 @@ - + - - - - - - + + + + + @@ -80,28 +79,28 @@ - + - + - + - - + + - + - - + + - + @@ -118,23 +117,23 @@ - + - + - + - + @@ -173,7 +172,7 @@ - + @@ -191,7 +190,7 @@ - + @@ -199,50 +198,760 @@ - - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -252,15 +961,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -268,31 +1017,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -310,331 +1136,1611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/style/fonts/ClearSans-Bold-webfont.woff b/style/fonts/ClearSans-Bold-webfont.woff index 184a945da4..742fb60699 100755 Binary files a/style/fonts/ClearSans-Bold-webfont.woff and b/style/fonts/ClearSans-Bold-webfont.woff differ diff --git a/style/fonts/ClearSans-Light-webfont.eot b/style/fonts/ClearSans-Light-webfont.eot index 0dc609d138..30cac5a773 100755 Binary files a/style/fonts/ClearSans-Light-webfont.eot and b/style/fonts/ClearSans-Light-webfont.eot differ diff --git a/style/fonts/ClearSans-Light-webfont.svg b/style/fonts/ClearSans-Light-webfont.svg index 1d5d2ecebb..82cd2df559 100755 --- a/style/fonts/ClearSans-Light-webfont.svg +++ b/style/fonts/ClearSans-Light-webfont.svg @@ -3,21 +3,20 @@ - + - - - - - - + + + + + - + @@ -28,9 +27,9 @@ - + - + @@ -42,8 +41,8 @@ - - + + @@ -111,7 +110,7 @@ - + @@ -133,7 +132,7 @@ - + @@ -206,43 +205,756 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -253,15 +965,34 @@ + + + + + + + + + + + + + + + + + + + @@ -269,32 +1000,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -312,359 +1105,1372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + + + - - - - - + + + + + - - - - + + + + + + + + + + + - - - + + + - + \ No newline at end of file diff --git a/style/fonts/ClearSans-Light-webfont.woff b/style/fonts/ClearSans-Light-webfont.woff index 44555e04e9..46157f949e 100755 Binary files a/style/fonts/ClearSans-Light-webfont.woff and b/style/fonts/ClearSans-Light-webfont.woff differ diff --git a/style/fonts/ClearSans-Regular-webfont.eot b/style/fonts/ClearSans-Regular-webfont.eot index b020e058cb..9df1d1bc3d 100755 Binary files a/style/fonts/ClearSans-Regular-webfont.eot and b/style/fonts/ClearSans-Regular-webfont.eot differ diff --git a/style/fonts/ClearSans-Regular-webfont.svg b/style/fonts/ClearSans-Regular-webfont.svg index 1e2cffdc2f..e1f76a38a0 100755 --- a/style/fonts/ClearSans-Regular-webfont.svg +++ b/style/fonts/ClearSans-Regular-webfont.svg @@ -3,21 +3,20 @@ - + - - - - - - + + + + + - + @@ -28,9 +27,9 @@ - + - + @@ -42,8 +41,8 @@ - - + + @@ -80,7 +79,7 @@ - + @@ -111,30 +110,30 @@ - + - + - + - + - - + + @@ -206,43 +205,757 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -253,15 +966,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,32 +1022,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -312,358 +1143,1729 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + + + - - - - - + + + + + - - - - + + + + + + + + + + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/style/fonts/ClearSans-Regular-webfont.woff b/style/fonts/ClearSans-Regular-webfont.woff index 9d58858d80..03bd4a3375 100755 Binary files a/style/fonts/ClearSans-Regular-webfont.woff and b/style/fonts/ClearSans-Regular-webfont.woff differ diff --git a/style/helpers.scss b/style/helpers.scss index 7b4445b37b..a2933d3687 100644 --- a/style/helpers.scss +++ b/style/helpers.scss @@ -48,18 +48,19 @@ @mixin transform($args...) { -webkit-transform: $args; -moz-transform: $args; + -ms-transform: $args; transform: $args; } // Keyframe animations @mixin keyframes($animation-name) { - @-webkit-keyframes $animation-name { + @-webkit-keyframes #{$animation-name} { @content; } - @-moz-keyframes $animation-name { + @-moz-keyframes #{$animation-name} { @content; } - @keyframes $animation-name { + @keyframes #{$animation-name} { @content; } } diff --git a/style/main.css b/style/main.css index cae6a45a2c..b7b3fe4692 100644 --- a/style/main.css +++ b/style/main.css @@ -23,7 +23,6 @@ h1.title { 0% { top: 25px; opacity: 1; } - 100% { top: -50px; opacity: 0; } } @@ -31,7 +30,6 @@ h1.title { 0% { top: 25px; opacity: 1; } - 100% { top: -50px; opacity: 0; } } @@ -39,7 +37,6 @@ h1.title { 0% { top: 25px; opacity: 1; } - 100% { top: -50px; opacity: 0; } } @@ -101,7 +98,8 @@ a { color: #776e65; font-weight: bold; text-decoration: underline; - cursor: pointer; } + cursor: pointer; + -webkit-tap-highlight-color: transparent; } strong.important { text-transform: uppercase; } @@ -119,21 +117,23 @@ hr { @-webkit-keyframes fade-in { 0% { opacity: 0; } - 100% { opacity: 1; } } @-moz-keyframes fade-in { 0% { opacity: 0; } - 100% { opacity: 1; } } @keyframes fade-in { 0% { opacity: 0; } - 100% { opacity: 1; } } +#night { + float: left; + padding: 7px; + margin-top: 10px; } + .game-container { margin-top: 10px; position: relative; @@ -188,29 +188,41 @@ hr { height: 40px; line-height: 42px; margin-left: 9px; } - .game-container .game-message a.keep-playing-button, .game-container .game-message a.confirm-button, .game-container .game-message a.cancel-button { + .game-container .game-message a.keep-playing-button, .game-container .game-message a.confirm-button, .game-container .game-message a.cancel-button, .game-container .game-message a.undo-move-button { display: none; } .game-container .game-message.game-won { background: rgba(237, 194, 46, 0.5); color: #f9f6f2; } .game-container .game-message.game-won a.keep-playing-button { display: inline-block; } - .game-container .game-message.game-won, .game-container .game-message.game-over, .game-container .game-message.restart-game { + .game-container .game-message.game-won, .game-container .game-message.game-over, .game-container .game-message.restart-game, .game-container .game-message.undo-move { display: block; } - -.game-container .game-message.restart-game { - -webkit-animation: fade-in 400ms ease 100ms; - -moz-animation: fade-in 400ms ease 100ms; - animation: fade-in 400ms ease 100ms; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - animation-fill-mode: both; } -.game-container .game-message.restart-game .lower { - margin-top: 85px; } -.game-container .game-message.restart-game .lower a.confirm-button, .game-container .game-message.restart-game .lower a.cancel-button { - display: inline-block; } -.game-container .game-message.restart-game .lower a.retry-button { - display: none; } + .game-container .game-message.restart-game { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-container .game-message.restart-game .lower { + margin-top: 85px; } + .game-container .game-message.restart-game .lower a.confirm-button, .game-container .game-message.restart-game .lower a.cancel-button { + display: inline-block; } + .game-container .game-message.restart-game .lower a.retry-button { + display: none; } + .game-container .game-message.undo-move { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-container .game-message.undo-move .lower { + margin-top: 85px; } + .game-container .game-message.undo-move .lower a.undo-move-button, .game-container .game-message.undo-move .lower a.cancel-button { + display: inline-block; } + .game-container .game-message.undo-move .lower a.retry-button { + display: none; } .grid-container { position: absolute; @@ -242,70 +254,90 @@ hr { .tile, .tile .tile-inner { width: 107px; height: 107px; - line-height: 116.25px; } + line-height: 107px; + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); } .tile.tile-position-1-1 { -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); + -ms-transform: translate(0px, 0px); transform: translate(0px, 0px); } .tile.tile-position-1-2 { -webkit-transform: translate(0px, 121px); -moz-transform: translate(0px, 121px); + -ms-transform: translate(0px, 121px); transform: translate(0px, 121px); } .tile.tile-position-1-3 { -webkit-transform: translate(0px, 242px); -moz-transform: translate(0px, 242px); + -ms-transform: translate(0px, 242px); transform: translate(0px, 242px); } .tile.tile-position-1-4 { -webkit-transform: translate(0px, 363px); -moz-transform: translate(0px, 363px); + -ms-transform: translate(0px, 363px); transform: translate(0px, 363px); } .tile.tile-position-2-1 { -webkit-transform: translate(121px, 0px); -moz-transform: translate(121px, 0px); + -ms-transform: translate(121px, 0px); transform: translate(121px, 0px); } .tile.tile-position-2-2 { -webkit-transform: translate(121px, 121px); -moz-transform: translate(121px, 121px); + -ms-transform: translate(121px, 121px); transform: translate(121px, 121px); } .tile.tile-position-2-3 { -webkit-transform: translate(121px, 242px); -moz-transform: translate(121px, 242px); + -ms-transform: translate(121px, 242px); transform: translate(121px, 242px); } .tile.tile-position-2-4 { -webkit-transform: translate(121px, 363px); -moz-transform: translate(121px, 363px); + -ms-transform: translate(121px, 363px); transform: translate(121px, 363px); } .tile.tile-position-3-1 { -webkit-transform: translate(242px, 0px); -moz-transform: translate(242px, 0px); + -ms-transform: translate(242px, 0px); transform: translate(242px, 0px); } .tile.tile-position-3-2 { -webkit-transform: translate(242px, 121px); -moz-transform: translate(242px, 121px); + -ms-transform: translate(242px, 121px); transform: translate(242px, 121px); } .tile.tile-position-3-3 { -webkit-transform: translate(242px, 242px); -moz-transform: translate(242px, 242px); + -ms-transform: translate(242px, 242px); transform: translate(242px, 242px); } .tile.tile-position-3-4 { -webkit-transform: translate(242px, 363px); -moz-transform: translate(242px, 363px); + -ms-transform: translate(242px, 363px); transform: translate(242px, 363px); } .tile.tile-position-4-1 { -webkit-transform: translate(363px, 0px); -moz-transform: translate(363px, 0px); + -ms-transform: translate(363px, 0px); transform: translate(363px, 0px); } .tile.tile-position-4-2 { -webkit-transform: translate(363px, 121px); -moz-transform: translate(363px, 121px); + -ms-transform: translate(363px, 121px); transform: translate(363px, 121px); } .tile.tile-position-4-3 { -webkit-transform: translate(363px, 242px); -moz-transform: translate(363px, 242px); + -ms-transform: translate(363px, 242px); transform: translate(363px, 242px); } .tile.tile-position-4-4 { -webkit-transform: translate(363px, 363px); -moz-transform: translate(363px, 363px); + -ms-transform: translate(363px, 363px); transform: translate(363px, 363px); } .tile { @@ -327,23 +359,23 @@ hr { background: #eee4da; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-4 .tile-inner { - background: #ede0c8; + background: #eee1c9; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-8 .tile-inner { color: #f9f6f2; - background: #f2b179; } + background: #f3b27a; } .tile.tile-16 .tile-inner { color: #f9f6f2; - background: #f59563; } + background: #f69664; } .tile.tile-32 .tile-inner { color: #f9f6f2; - background: #f67c5f; } + background: #f77c5f; } .tile.tile-64 .tile-inner { color: #f9f6f2; - background: #f65e3b; } + background: #f75f3b; } .tile.tile-128 .tile-inner { color: #f9f6f2; - background: #edcf72; + background: #edd073; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.2381), inset 0 0 0 1px rgba(255, 255, 255, 0.14286); font-size: 45px; } @media screen and (max-width: 520px) { @@ -351,7 +383,7 @@ hr { font-size: 25px; } } .tile.tile-256 .tile-inner { color: #f9f6f2; - background: #edcc61; + background: #edcc62; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.31746), inset 0 0 0 1px rgba(255, 255, 255, 0.19048); font-size: 45px; } @media screen and (max-width: 520px) { @@ -359,7 +391,7 @@ hr { font-size: 25px; } } .tile.tile-512 .tile-inner { color: #f9f6f2; - background: #edc850; + background: #edc950; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.39683), inset 0 0 0 1px rgba(255, 255, 255, 0.2381); font-size: 45px; } @media screen and (max-width: 520px) { @@ -383,7 +415,7 @@ hr { font-size: 15px; } } .tile.tile-super .tile-inner { color: #f9f6f2; - background: #3c3a32; + background: #3c3a33; font-size: 30px; } @media screen and (max-width: 520px) { .tile.tile-super .tile-inner { @@ -394,36 +426,39 @@ hr { opacity: 0; -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 100% { opacity: 1; -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } @-moz-keyframes appear { 0% { opacity: 0; -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 100% { opacity: 1; -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } @keyframes appear { 0% { opacity: 0; -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 100% { opacity: 1; -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } .tile-new .tile-inner { -webkit-animation: appear 200ms ease 100ms; @@ -437,46 +472,49 @@ hr { 0% { -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 50% { -webkit-transform: scale(1.2); -moz-transform: scale(1.2); + -ms-transform: scale(1.2); transform: scale(1.2); } - 100% { -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } @-moz-keyframes pop { 0% { -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 50% { -webkit-transform: scale(1.2); -moz-transform: scale(1.2); + -ms-transform: scale(1.2); transform: scale(1.2); } - 100% { -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } @keyframes pop { 0% { -webkit-transform: scale(0); -moz-transform: scale(0); + -ms-transform: scale(0); transform: scale(0); } - 50% { -webkit-transform: scale(1.2); -moz-transform: scale(1.2); + -ms-transform: scale(1.2); transform: scale(1.2); } - 100% { -webkit-transform: scale(1); -moz-transform: scale(1); + -ms-transform: scale(1); transform: scale(1); } } .tile-merged .tile-inner { z-index: 20; @@ -493,11 +531,13 @@ hr { clear: both; } .game-intro { - float: left; line-height: 42px; - margin-bottom: 0; } + margin-top: 5px; + margin-bottom: 0; + width: 285px; + font-size: 14px; } -.restart-button { +.restart-button, .undo-button { display: inline-block; background: #8f7a66; border-radius: 3px; @@ -508,7 +548,10 @@ hr { line-height: 42px; display: block; text-align: center; - float: right; } + float: right; + margin-left: 5px; + margin-top: 10px; + font-size: 16px; } .game-explanation { margin-top: 10px; } @@ -532,13 +575,14 @@ hr { .score-container, .best-container { margin-top: 0; padding: 15px 10px; - min-width: 40px; } + min-width: 40px; + font-size: 16px; } .heading { - margin-bottom: 10px; } + margin-bottom: 5px; } .game-intro { - width: 55%; + width: 100%; display: block; box-sizing: border-box; line-height: 1.65; } @@ -547,11 +591,10 @@ hr { width: 42%; padding: 0; display: block; - box-sizing: border-box; - margin-top: 2px; } + box-sizing: border-box; } .game-container { - margin-top: 17px; + margin-top: 15px; position: relative; padding: 10px; cursor: default; @@ -604,28 +647,41 @@ hr { height: 40px; line-height: 42px; margin-left: 9px; } - .game-container .game-message a.keep-playing-button, .game-container .game-message a.confirm-button, .game-container .game-message a.cancel-button { + .game-container .game-message a.keep-playing-button, .game-container .game-message a.confirm-button, .game-container .game-message a.cancel-button, .game-container .game-message a.undo-move-button { display: none; } .game-container .game-message.game-won { background: rgba(237, 194, 46, 0.5); color: #f9f6f2; } .game-container .game-message.game-won a.keep-playing-button { display: inline-block; } - .game-container .game-message.game-won, .game-container .game-message.game-over, .game-container .game-message.restart-game { + .game-container .game-message.game-won, .game-container .game-message.game-over, .game-container .game-message.restart-game, .game-container .game-message.undo-move { display: block; } -.game-container .game-message.restart-game { - -webkit-animation: fade-in 400ms ease 100ms; - -moz-animation: fade-in 400ms ease 100ms; - animation: fade-in 400ms ease 100ms; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - animation-fill-mode: both; } -.game-container .game-message.restart-game .lower { - margin-top: 85px; } - .game-container .game-message.restart-game .lower a.confirm-button, .game-container .game-message.restart-game .lower a.cancel-button { - display: inline-block; } -.game-container .game-message.restart-game .lower a.retry-button { - display: none; } + .game-container .game-message.restart-game { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-container .game-message.restart-game .lower { + margin-top: 85px; } + .game-container .game-message.restart-game .lower a.confirm-button, .game-container .game-message.restart-game .lower a.cancel-button { + display: inline-block; } + .game-container .game-message.restart-game .lower a.retry-button { + display: none; } + .game-container .game-message.undo-move { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-container .game-message.undo-move .lower { + margin-top: 85px; } + .game-container .game-message.undo-move .lower a.undo-move-button, .game-container .game-message.undo-move .lower a.cancel-button { + display: inline-block; } + .game-container .game-message.undo-move .lower a.retry-button { + display: none; } .grid-container { position: absolute; @@ -657,70 +713,90 @@ hr { .tile, .tile .tile-inner { width: 58px; height: 58px; - line-height: 67.5px; } + line-height: 58px; + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); } .tile.tile-position-1-1 { -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); + -ms-transform: translate(0px, 0px); transform: translate(0px, 0px); } .tile.tile-position-1-2 { -webkit-transform: translate(0px, 67px); -moz-transform: translate(0px, 67px); + -ms-transform: translate(0px, 67px); transform: translate(0px, 67px); } .tile.tile-position-1-3 { -webkit-transform: translate(0px, 135px); -moz-transform: translate(0px, 135px); + -ms-transform: translate(0px, 135px); transform: translate(0px, 135px); } .tile.tile-position-1-4 { -webkit-transform: translate(0px, 202px); -moz-transform: translate(0px, 202px); + -ms-transform: translate(0px, 202px); transform: translate(0px, 202px); } .tile.tile-position-2-1 { -webkit-transform: translate(67px, 0px); -moz-transform: translate(67px, 0px); + -ms-transform: translate(67px, 0px); transform: translate(67px, 0px); } .tile.tile-position-2-2 { -webkit-transform: translate(67px, 67px); -moz-transform: translate(67px, 67px); + -ms-transform: translate(67px, 67px); transform: translate(67px, 67px); } .tile.tile-position-2-3 { -webkit-transform: translate(67px, 135px); -moz-transform: translate(67px, 135px); + -ms-transform: translate(67px, 135px); transform: translate(67px, 135px); } .tile.tile-position-2-4 { -webkit-transform: translate(67px, 202px); -moz-transform: translate(67px, 202px); + -ms-transform: translate(67px, 202px); transform: translate(67px, 202px); } .tile.tile-position-3-1 { -webkit-transform: translate(135px, 0px); -moz-transform: translate(135px, 0px); + -ms-transform: translate(135px, 0px); transform: translate(135px, 0px); } .tile.tile-position-3-2 { -webkit-transform: translate(135px, 67px); -moz-transform: translate(135px, 67px); + -ms-transform: translate(135px, 67px); transform: translate(135px, 67px); } .tile.tile-position-3-3 { -webkit-transform: translate(135px, 135px); -moz-transform: translate(135px, 135px); + -ms-transform: translate(135px, 135px); transform: translate(135px, 135px); } .tile.tile-position-3-4 { -webkit-transform: translate(135px, 202px); -moz-transform: translate(135px, 202px); + -ms-transform: translate(135px, 202px); transform: translate(135px, 202px); } .tile.tile-position-4-1 { -webkit-transform: translate(202px, 0px); -moz-transform: translate(202px, 0px); + -ms-transform: translate(202px, 0px); transform: translate(202px, 0px); } .tile.tile-position-4-2 { -webkit-transform: translate(202px, 67px); -moz-transform: translate(202px, 67px); + -ms-transform: translate(202px, 67px); transform: translate(202px, 67px); } .tile.tile-position-4-3 { -webkit-transform: translate(202px, 135px); -moz-transform: translate(202px, 135px); + -ms-transform: translate(202px, 135px); transform: translate(202px, 135px); } .tile.tile-position-4-4 { -webkit-transform: translate(202px, 202px); -moz-transform: translate(202px, 202px); + -ms-transform: translate(202px, 202px); transform: translate(202px, 202px); } .tile .tile-inner { @@ -733,3 +809,5 @@ hr { margin-top: 90px !important; } .game-message .lower { margin-top: 30px !important; } } + +/*# sourceMappingURL=main.css.map */ diff --git a/style/main.scss b/style/main.scss index cce393fa78..9da823dd13 100644 --- a/style/main.scss +++ b/style/main.scss @@ -9,14 +9,14 @@ $tile-border-radius: 3px; $mobile-threshold: $field-width + 20px; -$text-color: #776E65; +$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-margin-top: 40px; +$game-container-margin-top: 10px; $game-container-background: #bbada0; $transition-speed: 100ms; @@ -31,16 +31,12 @@ html, body { font-size: 18px; } -body { - margin: 80px 0; -} - .heading { @include clearfix; } h1.title { - font-size: 80px; + font-size: 72px; font-weight: bold; margin: 0; display: block; @@ -70,7 +66,7 @@ h1.title { position: relative; display: inline-block; background: $game-container-background; - padding: 15px 25px; + padding: 12px 20px; font-size: $height; height: $height; line-height: $height + 22px; @@ -111,12 +107,12 @@ h1.title { } .best-container:after { - content: "Best" + content: "Best"; } p { margin-top: 0; - margin-bottom: 10px; + margin-bottom: 5px; line-height: 1.65; } @@ -125,6 +121,7 @@ a { font-weight: bold; text-decoration: underline; cursor: pointer; + -webkit-tap-highlight-color: transparent; } strong { @@ -136,8 +133,8 @@ strong { hr { border: none; border-bottom: 1px solid lighten($text-color, 40%); - margin-top: 20px; - margin-bottom: 30px; + margin-top: 10px; + margin-bottom: 10px; } .container { @@ -167,6 +164,12 @@ hr { line-height: 42px; } +#night { + float: left; + padding: 7px; + margin-top: 10px; +} + // Game field mixin used to render CSS at different width @mixin game-field { .game-container { @@ -226,9 +229,9 @@ hr { margin-left: 9px; // margin-top: 59px; - &.keep-playing-button { - display: none; - } + &.keep-playing-button, &.confirm-button, &.cancel-button, &.undo-move-button { + display: none; + } } @include animation(fade-in 800ms ease $transition-speed * 12); @@ -238,14 +241,42 @@ hr { background: rgba($tile-gold-color, .5); color: $bright-text-color; - a.keep-playing-button { - display: inline-block; - } + a.keep-playing-button { + display: inline-block; + } } - &.game-won, &.game-over { + &.game-won, &.game-over, &.restart-game, &.undo-move { display: block; } + + &.restart-game { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + &.restart-game .lower { + margin-top: 85px; } + &.restart-game .lower a.confirm-button, &.restart-game .lower a.cancel-button { + display: inline-block; } + &.restart-game .lower a.retry-button { + display: none; } + + &.undo-move { + -webkit-animation: fade-in 400ms ease 100ms; + -moz-animation: fade-in 400ms ease 100ms; + animation: fade-in 400ms ease 100ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + &.undo-move .lower { + margin-top: 85px; } + &.undo-move .lower a.undo-move-button, &.undo-move .lower a.cancel-button { + display: inline-block; } + &.undo-move .lower a.retry-button { + display: none; } } } @@ -292,7 +323,8 @@ hr { &, .tile-inner { width: ceil($tile-size); height: ceil($tile-size); - line-height: $tile-size + 10px; + line-height: ceil($tile-size); + @include transform(translateZ(0)); } // Build position classes @@ -456,30 +488,34 @@ hr { } .game-intro { - float: left; line-height: 42px; + margin-top: 5px; margin-bottom: 0; + width: 285px; + font-size: 14px; } -.restart-button { +.restart-button, .undo-button { @include button; display: block; text-align: center; float: right; + margin-left: 5px; + margin-top: 10px; + font-size: 16px; } .game-explanation { - margin-top: 50px; + margin-top: 10px; } @include smaller($mobile-threshold) { // Redefine variables for smaller screens - $field-width: 280px; - $grid-spacing: 10px; - $grid-row-cells: 4; - $tile-size: ($field-width - $grid-spacing * ($grid-row-cells + 1)) / $grid-row-cells; - $tile-border-radius: 3px; - $game-container-margin-top: 17px; + $field-width: 280px !global; + $grid-spacing: 10px !global; + $tile-size: ($field-width - $grid-spacing * ($grid-row-cells + 1)) / $grid-row-cells !global; + $tile-border-radius: 3px !global; + $game-container-margin-top: 15px !global; html, body { font-size: 15px; @@ -504,15 +540,16 @@ hr { margin-top: 0; padding: 15px 10px; min-width: 40px; + font-size: 16px; } .heading { - margin-bottom: 10px; + margin-bottom: 5px; } // Show intro and restart button side by side .game-intro { - width: 55%; + width: 100%; display: block; box-sizing: border-box; line-height: 1.65; @@ -523,7 +560,6 @@ hr { padding: 0; display: block; box-sizing: border-box; - margin-top: 2px; } // Render the game field at the right width diff --git a/style/night.png b/style/night.png new file mode 100644 index 0000000000..bb83110f77 Binary files /dev/null and b/style/night.png differ