├── README.md ├── background.js ├── contentscripts ├── board.js ├── button.js ├── controls.js └── game.js ├── flappy-octocat.crx ├── icons ├── .DS_Store ├── icon-128.png ├── icon-16.png └── icon-48.png ├── manifest.json ├── screenshot.gif └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # Flappy Octocat 2 | 3 | > a chrome extension to play a flappy bird like game on github contributions board 4 | 5 | * Inspired by a really awesome chrome extension [Game Of Life](https://github.com/yuanchuan/game-of-life) ! 6 | 7 | ![screenshot](screenshot.gif) 8 | 9 | 10 | 1. Install the extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/flappy-octocat/jjjhhlomhbdmnfgaccmddhmjfeekjlbl?utm_source=chrome-ntp-icon) 11 | 2. Press 'Space' to jump. Have fun! 12 | 13 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | function getDomainFromUrl(url){ 2 | var host = "null"; 3 | if(typeof url == "undefined" || null == url) 4 | url = window.location.href; 5 | var regex = /.*\:\/\/([^\/]*).*/; 6 | var match = url.match(regex); 7 | if(typeof match != "undefined" && null != match) 8 | host = match[1]; 9 | return host; 10 | } 11 | 12 | function checkForValidUrl(tabId, changeInfo, tab) { 13 | if(getDomainFromUrl(tab.url).toLowerCase() == "github.com"){ 14 | chrome.pageAction.show(tabId); 15 | } 16 | }; 17 | 18 | chrome.tabs.onUpdated.addListener(checkForValidUrl); 19 | -------------------------------------------------------------------------------- /contentscripts/board.js: -------------------------------------------------------------------------------- 1 | var Board = { 2 | id: 'fo-board', 3 | row: 13, 4 | col: 61, 5 | color0: '#ebedf0', 6 | color1: '#239a3b', 7 | color2: '#c6e48b', 8 | catLoc: [], 9 | tubeLocs: [], 10 | treeLocs: [], 11 | catPoints: [], 12 | barrierPoints: [], 13 | element: null 14 | } 15 | 16 | Board.cat = [ 17 | [0, 0, 1, 0, 0, 0, 1], 18 | [0, 0, 1, 1, 1, 1, 1], 19 | [0, 0, 1, 2, 1, 2, 1], 20 | [1, 0, 1, 1, 1, 1, 1], 21 | [0, 1, 0, 0, 1, 0, 0], 22 | [0, 0, 1, 1, 1, 1, 1], 23 | [0, 0, 1, 0, 1, 0, 1], 24 | ] 25 | 26 | Board.tube = [ 27 | [1, 1, 1, 1, 1], 28 | [1, 1, 1, 1, 1], 29 | [1, 1, 1, 1, 1], 30 | [1, 1, 1, 1, 1], 31 | ] 32 | 33 | Board.tree = [ 34 | [0, 1, 1, 0, 1, 1, 0], 35 | [1, 1, 1, 1, 1, 1, 1], 36 | [1, 1, 1, 1, 1, 1, 1], 37 | ] 38 | 39 | Board.init = function() { 40 | Board.catLoc = [5, 3] 41 | Board.tubeLocs = [[20, 9], [58, 0]] 42 | Board.treeLocs = [[38, 10]] 43 | Board.catPoints = [] 44 | Board.barrierPoints = [] 45 | Board.timer = {} 46 | } 47 | 48 | Board.handleKeydown = function(e) { 49 | if (e.keyCode == 32 && e.target == document.body) { 50 | e.preventDefault(); 51 | Board.jump() 52 | } 53 | } 54 | 55 | Board.bindKeyPress = function() { 56 | window.addEventListener('keydown', Board.handleKeydown); 57 | } 58 | 59 | Board.unbindKeyPress = function() { 60 | window.removeEventListener('keydown', Board.handleKeydown); 61 | } 62 | 63 | Board.setUpInterval = function() { 64 | Board.setUpIntervalFall() 65 | Board.setUpIntervalMove() 66 | } 67 | 68 | Board.setUpIntervalFall = function() { 69 | if (!Game.running || Game.paused) { 70 | return false 71 | } 72 | Board.timer.fall = setTimeout(function() { 73 | Board.fall() 74 | Board.setUpIntervalFall() 75 | }, Game.intervalFall) 76 | } 77 | 78 | Board.setUpIntervalMove = function() { 79 | if (!Game.running || Game.paused) { 80 | return false 81 | } 82 | Board.timer.move = setTimeout(function() { 83 | Board.move() 84 | if (Game.score % 50 == 0) { 85 | Game.intervalMove = Math.ceil(Game.intervalMove * 0.8) 86 | } 87 | Board.setUpIntervalMove() 88 | }, Game.intervalMove) 89 | } 90 | 91 | Board.pointDebug = function(li) { 92 | li.addEventListener('click', function(e) { 93 | if(!Board.color(this) || Board.color(this) == Board.color0) { 94 | Board.fill(this, Board.color1); 95 | } else { 96 | Board.fill(this, Board.color0); 97 | } 98 | }) 99 | } 100 | 101 | Board.open = function() { 102 | var element = document.getElementById(Board.id) 103 | if (!element) { 104 | element = document.createElement('div') 105 | element.id = Board.id 106 | element.innerHTML = ('').repeat(Board.col) 107 | 108 | var i = 0 109 | element.querySelectorAll('ul').forEach(function(ul){ 110 | var j = 0 111 | ul.querySelectorAll('li').forEach(function(li) { 112 | li.setAttribute('id', 'p-' + j + '-' + i) 113 | // Board.pointDebug(li) 114 | j += 1 115 | }) 116 | i += 1 117 | }) 118 | 119 | Board.element = element 120 | Game.container.appendChild(element) 121 | 122 | Board.refresh() 123 | } 124 | } 125 | 126 | Board.start = function() { 127 | Board.refresh() 128 | Board.bindKeyPress() 129 | Board.setUpInterval() 130 | } 131 | 132 | Board.color = function(e) { 133 | return e.getAttribute('fill') 134 | } 135 | 136 | Board.fill = function(e, color) { 137 | e.style.backgroundColor = color 138 | e.setAttribute('fill', color) 139 | } 140 | 141 | Board.clear = function() { 142 | Board.element.querySelectorAll('li').forEach(function(li){ 143 | Board.fill(li, Board.color0) 144 | }) 145 | Board.catPoints = [] 146 | Board.barrierPoints = [] 147 | } 148 | 149 | Board.draw = function(matrix, loc, type) { 150 | var p 151 | var color 152 | for (r in matrix) { 153 | for (c in matrix[r]) { 154 | y = parseInt(loc[1]) + parseInt(r) 155 | x = parseInt(loc[0]) + parseInt(c) 156 | if (x >= Board.col || x < 0) { 157 | continue 158 | } 159 | if (y >= Board.row || y < 0) { 160 | continue 161 | } 162 | id = 'p-' + y + '-' + x 163 | p = document.getElementById(id) 164 | if (matrix[r][c] != 0) { 165 | if (type == 'cat') { 166 | Board.catPoints.push(id) 167 | } else { 168 | Board.barrierPoints.push(id) 169 | } 170 | } 171 | Board.fill(p, Board['color' + matrix[r][c]]) 172 | } 173 | } 174 | } 175 | 176 | Board.refresh = function() { 177 | Board.clear() 178 | Board.draw(Board.cat, Board.catLoc, 'cat') 179 | Board.tubeLocs.forEach(function(tubeLoc){ 180 | Board.draw(Board.tube, tubeLoc, 'tube') 181 | }) 182 | Board.treeLocs.forEach(function(treeLoc){ 183 | Board.draw(Board.tree, treeLoc, 'tree') 184 | }) 185 | Board.check() 186 | } 187 | 188 | Board.jump = function() { 189 | if (Game.running && !Game.paused) { 190 | var step = 2 191 | if (Board.catLoc[1] < 2) { 192 | step = Board.catLoc[1] 193 | } 194 | if (step > 0) { 195 | Board.catLoc = [Board.catLoc[0], Board.catLoc[1] - step] 196 | Board.refresh() 197 | } 198 | } 199 | } 200 | 201 | Board.fall = function() { 202 | if (Game.paused) return 203 | 204 | if (Board.catLoc[1] + Board.cat.length < Board.row) { 205 | Board.catLoc = [Board.catLoc[0], Board.catLoc[1] + 1] 206 | Board.refresh() 207 | } 208 | } 209 | 210 | Board.move = function() { 211 | if (Game.paused) return 212 | 213 | Game.addScore() 214 | var tubeLocs = Board.tubeLocs 215 | Board.tubeLocs = [] 216 | tubeLocs.forEach(function(loc) { 217 | if (loc[0] + Board.tube[0].length > 0) { 218 | Board.tubeLocs.push([loc[0] - 1, loc[1]]) 219 | } 220 | }) 221 | 222 | var treeLocs = Board.treeLocs 223 | Board.treeLocs = [] 224 | treeLocs.forEach(function(loc) { 225 | if (loc[0] + Board.tree[0].length > 0) { 226 | Board.treeLocs.push([loc[0] - 1, loc[1]]) 227 | } 228 | }) 229 | 230 | if ((Board.tubeLocs.length + Board.treeLocs.length) < 3 && Math.random() > 0.2) { 231 | Board.generateBarrier() 232 | } 233 | 234 | Board.refresh() 235 | } 236 | 237 | Board.generateBarrier = function() { 238 | var rand = Math.random() 239 | if (rand < 0.3) { 240 | Board.tubeLocs.push([Board.col - 1, 0]) 241 | } else if (rand < 0.7) { 242 | Board.tubeLocs.push([Board.col - 1, Board.row - Board.tube.length]) 243 | } else { 244 | Board.treeLocs.push([Board.col - 1, Board.row - Board.tree.length]) 245 | } 246 | } 247 | 248 | Board.check = function() { 249 | if (!Game.running) { 250 | return false 251 | } 252 | Board.catPoints.every(function(p) { 253 | if (Board.barrierPoints.indexOf(p) > -1) { 254 | Board.die() 255 | return false 256 | } 257 | return true 258 | }) 259 | } 260 | 261 | Board.die = function() { 262 | Game.die() 263 | Board.flash(6) 264 | } 265 | 266 | Board.flash = function(times) { 267 | if (times > 0) { 268 | Board.timer.flash = setTimeout(function(){ 269 | document.getElementById(Board.id).querySelectorAll('li').forEach(function(li){ 270 | if (Board.color(li) == Board.color0) { 271 | Board.fill(li, Board.color1) 272 | } else if (Board.color(li) == Board.color1) { 273 | Board.fill(li, Board.color0) 274 | } 275 | }) 276 | Board.flash(times - 1) 277 | }, 150) 278 | } 279 | } 280 | 281 | Board.close = function() { 282 | if (Board.element) { 283 | Board.element.parentNode.removeChild(Board.element) 284 | Board.element = null 285 | Board.unbindKeyPress() 286 | Object.keys(Board.timer).forEach(function(n) { 287 | clearTimeout(Board.timer[n]) 288 | }) 289 | } 290 | } 291 | 292 | Board.init(); 293 | -------------------------------------------------------------------------------- /contentscripts/button.js: -------------------------------------------------------------------------------- 1 | var Button = { 2 | id: 'fo-button', 3 | element: null 4 | } 5 | 6 | Button.init = function() { 7 | if (Game.graph){ 8 | Button.build() 9 | } 10 | } 11 | 12 | Button.build = function() { 13 | var element = document.getElementById(Button.id) 14 | if (!element){ 15 | element = document.createElement('a') 16 | element.id = Button.id 17 | element.innerHTML = 'Play' 18 | element.addEventListener('click', function(e) { 19 | Board.open() 20 | Controls.open() 21 | }) 22 | Game.legend.insertBefore(element, Game.legend.firstChild) 23 | 24 | Button.element = element 25 | } 26 | } 27 | 28 | Button.init() 29 | -------------------------------------------------------------------------------- /contentscripts/controls.js: -------------------------------------------------------------------------------- 1 | var Controls = { 2 | id: "fo-controls", 3 | actions: ['start', 'restart', 'pause', 'unpause', 'close'], 4 | buttons: {}, 5 | element: null 6 | } 7 | 8 | Controls.init = function() { 9 | } 10 | 11 | Controls.action = function (e) { 12 | var btn = e.target 13 | if (btn.hasAttribute('data-action') && !btn.hasAttribute('disabled')) { 14 | Controls.onclick && Controls.onclick(btn) 15 | } 16 | return false 17 | } 18 | 19 | Controls.onclick = function(btn) { 20 | var action = Game[btn.getAttribute('data-action')] 21 | action && action() 22 | Controls.refresh() 23 | } 24 | 25 | Controls.open = function() { 26 | if (!Controls.element) { 27 | var content = '0' + 28 | Controls.actions.map(function(name) { 29 | return '' 30 | }).join('') 31 | 32 | var element = document.createElement('div') 33 | element.id = Controls.id 34 | element.innerHTML = content 35 | 36 | Controls.actions.forEach(function(name) { 37 | Controls.buttons[name] = element.querySelector('[data-action="' + name + '"]') 38 | }) 39 | element.addEventListener('click', Controls.action) 40 | 41 | Controls.element = element 42 | Game.container.appendChild(element) 43 | Controls.refresh() 44 | } 45 | } 46 | 47 | Controls.apply = function(operation, names, value) { 48 | if (!Array.isArray(names)) names = [names] 49 | names.forEach(function(name) { 50 | var btn = Controls.buttons[name] 51 | switch (operation) { 52 | case 'disable': btn.setAttribute('disabled', true); break 53 | case 'enable': btn.removeAttribute('disabled'); break 54 | case 'show': btn.style.display = ''; break 55 | case 'hide': btn.style.display = 'none'; break 56 | case 'setTitle': btn.title = value; break 57 | case 'setShadow': btn.firstChild.style.boxShadow = value 58 | } 59 | }) 60 | return this 61 | } 62 | 63 | Controls.refreshScore = function() { 64 | var score = document.getElementById('fo-score') 65 | score.innerHTML = Game.score 66 | } 67 | 68 | Controls.refresh = function() { 69 | if (!Game.running && !Game.dead) { 70 | Controls.apply('show', ['start', 'close']).apply('hide', ['restart', 'pause', 'unpause']) 71 | } else if(!Game.running && Game.dead) { 72 | Controls.apply('show', ['restart', 'close']).apply('hide', ['start', 'pause', 'unpause']) 73 | } else if (Game.running && !Game.paused) { 74 | Controls.apply('show', ['pause', 'close']).apply('hide', ['unpause', 'start', 'restart']) 75 | } else if (Game.running && Game.paused) { 76 | Controls.apply('show', ['unpause', 'restart', 'close']).apply('hide', ['pause', 'start']) 77 | } 78 | } 79 | 80 | Controls.close = function() { 81 | if (Controls.element) { 82 | Controls.element.parentNode.removeChild(Controls.element) 83 | Controls.element = null 84 | } 85 | } 86 | 87 | Controls.init() 88 | -------------------------------------------------------------------------------- /contentscripts/game.js: -------------------------------------------------------------------------------- 1 | var Game = { 2 | running: false, 3 | paused: false, 4 | dead: false, 5 | intervalMove: 300, 6 | intervalFall: 250, 7 | score: 0 8 | } 9 | 10 | Game.graph = document.querySelector('.js-calendar-graph') 11 | Game.container = document.querySelector('.js-calendar-graph').parentNode 12 | Game.legend = document.querySelector('.contrib-legend') 13 | 14 | Game.init = function() { 15 | Game.container.setAttribute('fo-container', '') 16 | } 17 | 18 | Game.start = function() { 19 | Game.score = 0 20 | Game.intervalMove = 300 21 | Game.running = true 22 | Game.paused = false 23 | Game.dead = false 24 | Board.init() 25 | Board.start() 26 | } 27 | 28 | Game.restart = function() { 29 | Game.start() 30 | } 31 | 32 | Game.pause = function() { 33 | Game.running = true 34 | Game.paused = true 35 | Game.dead = false 36 | } 37 | 38 | Game.unpause = function() { 39 | Game.running = true 40 | Game.paused = false 41 | Game.dead = false 42 | Board.setUpInterval() 43 | } 44 | 45 | Game.close = function() { 46 | Game.running = false 47 | Game.paused = false 48 | Game.dead = false 49 | Board.close() 50 | Controls.close() 51 | } 52 | 53 | Game.addScore = function() { 54 | Game.score += 1 55 | Controls.refreshScore() 56 | } 57 | 58 | Game.die = function() { 59 | Game.running = false 60 | Game.dead = true 61 | 62 | Controls.refresh() 63 | } 64 | 65 | Game.init() 66 | -------------------------------------------------------------------------------- /flappy-octocat.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/flappy-octocat.crx -------------------------------------------------------------------------------- /icons/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/.DS_Store -------------------------------------------------------------------------------- /icons/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-128.png -------------------------------------------------------------------------------- /icons/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-16.png -------------------------------------------------------------------------------- /icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-48.png -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | 4 | "name": "Flappy Octocat", 5 | "description": "a chrome extension to play a flappy bird like game on github contributions board!", 6 | "version": "1.0.3", 7 | "icons": { 8 | "16": "icons/icon-16.png", 9 | "48": "icons/icon-48.png", 10 | "128": "icons/icon-128.png" 11 | }, 12 | "page_action": { 13 | "default_icon": "icons/icon-48.png" 14 | }, 15 | "background": { 16 | "scripts": ["background.js"] 17 | }, 18 | "content_scripts": [ 19 | { 20 | "matches": ["https://github.com/*"], 21 | "css": ["style.css"], 22 | "js": ["contentscripts/game.js", "contentscripts/board.js", "contentscripts/controls.js", "contentscripts/button.js"] 23 | } 24 | ], 25 | "permissions": [ 26 | "tabs", 27 | "https://github.com/*" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/screenshot.gif -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | [fo-container] { 2 | position: relative; 3 | } 4 | 5 | .border[fo-container] { 6 | border-color: transparent !important; 7 | } 8 | 9 | [fo-container] .flash-notice { 10 | display: none; 11 | } 12 | 13 | [fo-container="running"] li[style$="238);"] { 14 | opacity: .8; 15 | } 16 | 17 | [fo-container]:not([fo-container="running"]) 18 | 19 | #tetrix-board li:hover { 20 | cursor: pointer; 21 | z-index: 2; 22 | outline: 1px solid rgba(30, 104, 35, .55); 23 | } 24 | 25 | #fo-board { 26 | position: absolute; 27 | top: -4px; 28 | left: -7px; 29 | width: calc(100% + 8px); 30 | height: 100%; 31 | background: #fff; 32 | } 33 | 34 | #fo-board:after { 35 | content: ''; 36 | clear: both; 37 | display: block; 38 | visibility: hidden; 39 | } 40 | 41 | #fo-board ul { 42 | float: left; 43 | } 44 | 45 | #fo-board li { 46 | display: block; 47 | font-size: 0; 48 | width: 12px; 49 | height: 12px; 50 | background-color: #eee; 51 | transition: background-color .2s ease; 52 | position: relative; 53 | z-index: 1; 54 | box-sizing: border-box; 55 | border: 1px solid #fff; 56 | } 57 | 58 | #fo-button { 59 | float: left; 60 | margin-right: 1em; 61 | padding: 0 5px 0 13px; 62 | vertical-align: middle; 63 | transition: all .2s ease; 64 | color: #8cc665; 65 | box-shadow: rgba(140, 198, 101, .25) 0px 0px 0px 1px; 66 | border-radius: 2px; 67 | cursor: pointer; 68 | } 69 | 70 | #fo-button:hover { 71 | box-shadow: rgba(140, 198, 101, .69) 0px 0px 0px 1px; 72 | text-decoration: none; 73 | } 74 | 75 | #fo-button:before { 76 | content: ''; 77 | display: inline-block; 78 | width: 4px; 79 | height: 4px; 80 | margin: -5px 4px 0 0; 81 | vertical-align: middle; 82 | color: #8cc665; 83 | box-shadow: 84 | -4px 0px #8cc665, 85 | -8px 4px #8cc665, 86 | -4px 4px #8cc665, 87 | 0 4px #8cc665; 88 | } 89 | 90 | #fo-controls { 91 | position: absolute; 92 | text-align: center; 93 | width: 100%; 94 | bottom: -32px; 95 | padding-left: 40px; 96 | } 97 | #fo-controls a { 98 | display: inline-block; 99 | position: relative; 100 | width: 5em; 101 | padding: 2px 0; 102 | margin: 0 2px; 103 | transition: all .2s ease; 104 | font-size: .8em; 105 | color: rgba(140, 198, 101, .8); 106 | text-decoration: none; 107 | border: 1px solid rgba(140, 198, 101, .3); 108 | border-radius: 2px; 109 | cursor: pointer; 110 | } 111 | #fo-controls a:after { 112 | content: attr(data-action); 113 | } 114 | 115 | @keyframes rotating { 116 | from { transform: rotate(45deg); } 117 | to { transform: rotate(0) } 118 | } 119 | #fo-controls a[data-action="close"] { 120 | position: relative; 121 | width: 20px; 122 | height: 20px; 123 | line-height: 0; 124 | margin-left: 10px; 125 | vertical-align: text-top; 126 | border:none; 127 | background: none; 128 | color: #d6e685; 129 | font-size: 0; 130 | -webkit-animation: rotating .2s ease; 131 | animation: rotating .2s ease; 132 | -webkit-transfom-origin: 50% 50%; 133 | transfom-origin: 50% 50%; 134 | } 135 | #fo-controls a[data-action="close"]:before, 136 | #fo-controls a[data-action="close"]:after { 137 | content: ''; 138 | position: absolute; 139 | left: 50%; 140 | top: 50%; 141 | width: 61.8%; 142 | height: 1px; 143 | background: #bfd06b; 144 | -webkit-transfom-origin: 50% 50%; 145 | transfom-origin: 50% 50%; 146 | } 147 | #fo-controls a[data-action="close"]:before { 148 | -webkit-transform: translate(-50%, 0) rotate(-45deg); 149 | transform: translate(-50%, 0) rotate(-45deg); 150 | } 151 | #fo-controls a[data-action="close"]:after { 152 | -webkit-transform: translate(-50%, 0) rotate(45deg); 153 | transform: translate(-50%, 0) rotate(45deg); 154 | } 155 | #fo-controls a[data-action="close"]:hover:before, 156 | #fo-controls a[data-action="close"]:hover:after { 157 | background-color: #d0b96b; 158 | } 159 | 160 | #fo-controls a[data-action="start"] { 161 | border-color: rgba(140, 198, 101, 0.7); 162 | background-color: rgba(192, 247, 155, .13); 163 | } 164 | #fo-controls a[data-action="pause"] { 165 | background-color: rgba(214, 230, 133, .18); 166 | border-color: #d6e685; 167 | color: #9bb517; 168 | } 169 | #fo-controls a[disabled] { 170 | background: transparent; 171 | border-color: rgba(160, 165, 157, .69);; 172 | color: rgba(160, 165, 157, .69); 173 | opacity: .5; 174 | cursor: default; 175 | } 176 | #fo-controls a[data-action="start"]:not([disabled]):hover { 177 | background-color: rgba(237, 255, 200, .35); 178 | } 179 | 180 | #fo-score { 181 | position: absolute; 182 | left: 0px; 183 | top: -10px; 184 | font-size: 12px; 185 | color: #b6b6b6; 186 | } 187 | #fo-score:before { 188 | content: 'Score: '; 189 | margin-right: 2px; 190 | } 191 | --------------------------------------------------------------------------------