├── .gitignore ├── img ├── themes.png ├── screenshot.png ├── icons │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── mstile-150x150.png │ ├── apple-touch-icon.png │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── browserconfig.xml │ └── safari-pinned-tab.svg ├── splash │ ├── ipad_splash.png │ ├── ipadpro1_splash.png │ ├── ipadpro2_splash.png │ ├── ipadpro3_splash.png │ ├── iphone5_splash.png │ ├── iphone6_splash.png │ ├── iphonex_splash.png │ ├── iphonexr_splash.png │ ├── iphoneplus_splash.png │ └── iphonexsmax_splash.png └── check.svg ├── README.md ├── manifest.json ├── LICENSE ├── sw.js ├── app.js ├── calculator.js ├── style.css ├── themes.css └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | -------------------------------------------------------------------------------- /img/themes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/themes.png -------------------------------------------------------------------------------- /img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/screenshot.png -------------------------------------------------------------------------------- /img/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/favicon.ico -------------------------------------------------------------------------------- /img/splash/ipad_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/ipad_splash.png -------------------------------------------------------------------------------- /img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /img/splash/ipadpro1_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/ipadpro1_splash.png -------------------------------------------------------------------------------- /img/splash/ipadpro2_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/ipadpro2_splash.png -------------------------------------------------------------------------------- /img/splash/ipadpro3_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/ipadpro3_splash.png -------------------------------------------------------------------------------- /img/splash/iphone5_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphone5_splash.png -------------------------------------------------------------------------------- /img/splash/iphone6_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphone6_splash.png -------------------------------------------------------------------------------- /img/splash/iphonex_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphonex_splash.png -------------------------------------------------------------------------------- /img/splash/iphonexr_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphonexr_splash.png -------------------------------------------------------------------------------- /img/splash/iphoneplus_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphoneplus_splash.png -------------------------------------------------------------------------------- /img/splash/iphonexsmax_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/splash/iphonexsmax_splash.png -------------------------------------------------------------------------------- /img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisdiana/pwa-calculator/HEAD/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /img/icons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #f5923e 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PWA Calculator 2 | 3 | > A Progressive Web App Calculator 4 | 5 | PWA Calculator Screenshot 6 | 7 | **[DEMO](https://chrisdiana.github.io/pwa-calculator/)** 8 | 9 | #### Why? 10 | For some reason iOS for iPad doesn't ship with a bundled native calculator. 11 | Most of the calculators in the Apple App Store have ads...and that's no fun. 12 | 13 | #### Features 14 | 15 | * Offline support 16 | * 8 Themes 17 | * Responsive 18 | 19 | #### Themes 20 | 21 | PWA Calculator Themes 22 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Calculator", 3 | "short_name": "Calculator", 4 | "description": "A calculator application", 5 | "categories": ["utilities", "tools"], 6 | "icons": [{ 7 | "src": "img/icons/icon-128x128.png", 8 | "sizes": "128x128", 9 | "type": "image/png" 10 | }, { 11 | "src": "img/icons/icon-144x144.png", 12 | "sizes": "144x144", 13 | "type": "image/png" 14 | }, { 15 | "src": "img/icons/icon-152x152.png", 16 | "sizes": "152x152", 17 | "type": "image/png" 18 | }, { 19 | "src": "img/icons/icon-192x192.png", 20 | "sizes": "192x192", 21 | "type": "image/png" 22 | }, { 23 | "src": "img/icons/icon-256x256.png", 24 | "sizes": "256x256", 25 | "type": "image/png" 26 | }, { 27 | "src": "img/icons/icon-512x512.png", 28 | "sizes": "512x512", 29 | "type": "image/png" 30 | }], 31 | "start_url": "index.html", 32 | "display": "standalone", 33 | "background_color": "#f5923e", 34 | "theme_color": "#f5923e" 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Chris Diana 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /img/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const CACHE_NAME = 'static-cache-v2'; 4 | const FILES_TO_CACHE = [ 5 | 'index.html', 6 | 'app.js', 7 | 'calculator.js', 8 | 'manifest.json', 9 | 'style.css', 10 | 'themes.css', 11 | 'img/check.svg', 12 | 'img/icons/android-chrome-192x192.png', 13 | 'img/icons/android-chrome-512x512.png', 14 | 'img/icons/apple-touch-icon.png', 15 | 'img/icons/browserconfig.xml', 16 | 'img/icons/favicon-16x16.png', 17 | 'img/icons/favicon-32x32.png', 18 | 'img/icons/favicon.ico', 19 | 'img/icons/mstile-150x150.png', 20 | 'img/icons/safari-pinned-tab.svg', 21 | 'img/splash/iphone5_splash.png', 22 | 'img/splash/iphone6_splash.png', 23 | 'img/splash/iphoneplus_splash.png', 24 | 'img/splash/iphonex_splash.png', 25 | 'img/splash/iphonexr_splash.png', 26 | 'img/splash/iphonexsmax_splash.png', 27 | 'img/splash/ipad_splash.png', 28 | 'img/splash/ipadpro1_splash.png', 29 | 'img/splash/ipadpro3_splash.png', 30 | 'img/splash/ipadpro2_splash.png', 31 | ]; 32 | 33 | // Install service worker and cache all content 34 | self.addEventListener('install', e => e.waitUntil( 35 | caches.open(CACHE_NAME).then(c => c.addAll(FILES_TO_CACHE)))); 36 | 37 | // Fetch content from cache if available for 38 | // offline support and cache new resources if available 39 | self.addEventListener('fetch', e => e.respondWith( 40 | caches.match(e.request).then((r) => { 41 | return r || fetch(e.request).then((res) => { 42 | return caches.open(CACHE_NAME).then((cache) => { 43 | cache.put(e.request, res.clone()); 44 | return res; 45 | }) 46 | }) 47 | }) 48 | )); 49 | 50 | // Clean up old caches 51 | self.addEventListener('activate', e => e.waitUntil( 52 | caches.keys().then((keyList) => { 53 | return Promise.all(keyList.map((key) => { 54 | if(CACHE_NAME.indexOf(key) === -1) { 55 | return caches.delete(key); 56 | } 57 | })); 58 | }) 59 | )); -------------------------------------------------------------------------------- /img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if ('serviceWorker' in navigator) { 4 | navigator.serviceWorker.register('sw.js'); 5 | } 6 | 7 | var previousTheme = null; 8 | 9 | function setTheme(theme) { 10 | var themeVars = { 11 | displayId: 'calculator-display', 12 | displayClass: 'calculator-display', 13 | keyClass: 'calculator-key' 14 | }; 15 | var displayEl = document.getElementById(themeVars.displayId); 16 | var keyEls = document.querySelectorAll('.' + themeVars.keyClass); 17 | 18 | displayEl.className = themeVars.displayClass + ' ' + theme; 19 | 20 | keyEls.forEach((key) => { 21 | if(previousTheme) { 22 | key.classList.replace(previousTheme, theme); 23 | } else { 24 | key.classList.add(theme); 25 | } 26 | }); 27 | 28 | previousTheme = theme; 29 | window.localStorage.setItem('theme', theme); 30 | } 31 | 32 | (function() { 33 | 34 | var iPhone = (navigator.userAgent.indexOf("iPhone OS") !== -1); 35 | var iPad = (navigator.userAgent.indexOf("iPad") !== -1); 36 | 37 | var mainContainer = document.getElementById('calculator'); 38 | var instructions = document.getElementById('screen-instructions'); 39 | var modal = document.getElementById('modal'); 40 | var modalClose = document.getElementById('close-modal'); 41 | var modalOpen = document.getElementById('calculator-set-theme'); 42 | 43 | function showInstructions() { 44 | instructions.classList.add('show'); 45 | mainContainer.classList.add('hide'); 46 | } 47 | 48 | function initEvents() { 49 | modalOpen.onclick = function(e) { 50 | modal.classList.add('show'); 51 | modal.classList.remove('hide'); 52 | } 53 | 54 | modalClose.onclick = function(e) { 55 | modal.classList.remove('show'); 56 | modal.classList.add('hide'); 57 | } 58 | 59 | window.onclick = function(e) { 60 | if (e.target == modal) { 61 | modal.classList.remove('show'); 62 | modal.classList.add('hide'); 63 | } 64 | } 65 | } 66 | 67 | function init() { 68 | initEvents(); 69 | 70 | var calc = new Calculator('.calculator-display', '.calculator-keys'); 71 | calc.initEvents(); 72 | 73 | var theme = window.localStorage.getItem('theme') || 'apple'; 74 | setTheme(theme); 75 | } 76 | 77 | if ((!window.navigator.standalone && (iPhone || iPad))) { 78 | showInstructions(); 79 | } else { 80 | init(); 81 | } 82 | 83 | })(); 84 | -------------------------------------------------------------------------------- /calculator.js: -------------------------------------------------------------------------------- 1 | var Calculator = function(displayClass, keysClass) { 2 | this.displayValue = '0'; 3 | this.firstOperand = null; 4 | this.waitingForSecondOperand = false; 5 | this.currentOperator = null; 6 | this.currentOperatorClass = 'op-active'; 7 | this.display = document.querySelector(displayClass); 8 | this.keys = document.querySelector(keysClass); 9 | this.calculate = { 10 | '/': (a, b) => (a / b), 11 | '*': (a, b) => (a * b), 12 | '+': (a, b) => (a + b), 13 | '-': (a, b) => (a - b), 14 | '=': (a, b) => b 15 | }; 16 | }; 17 | 18 | Calculator.prototype = { 19 | 20 | operator(nextOperator) { 21 | const inputValue = parseFloat(this.displayValue); 22 | 23 | if (this.currentOperator && this.waitingForSecondOperand) { 24 | this.currentOperator = nextOperator; 25 | return; 26 | } 27 | 28 | if (this.firstOperand == null) { 29 | this.firstOperand = inputValue; 30 | } else if (this.currentOperator) { 31 | const currentValue = this.firstOperand || 0; 32 | const result = this.calculate[this.currentOperator](currentValue, inputValue); 33 | this.displayValue = String(result); 34 | this.firstOperand = result; 35 | } 36 | 37 | this.waitingForSecondOperand = true; 38 | this.currentOperator = nextOperator; 39 | }, 40 | 41 | digit(digit) { 42 | if (this.waitingForSecondOperand === true) { 43 | this.displayValue = digit; 44 | this.waitingForSecondOperand = false; 45 | } else { 46 | this.displayValue = this.displayValue === '0' ? digit : this.displayValue + digit; 47 | } 48 | }, 49 | 50 | decimal(dot) { 51 | if (this.waitingForSecondOperand === true) return; 52 | // If the `displayValue` does not contain a decimal point 53 | if (!this.displayValue.includes(dot)) { 54 | // Append the decimal point 55 | this.displayValue += dot; 56 | } 57 | }, 58 | 59 | clear() { 60 | this.displayValue = '0'; 61 | }, 62 | 63 | allclear() { 64 | this.displayValue = '0'; 65 | this.firstOperand = null; 66 | this.waitingForSecondOperand = false; 67 | this.currentOperator = null; 68 | }, 69 | 70 | posneg() { 71 | if(Math.sign(parseFloat(this.displayValue)) === 1) { 72 | this.displayValue = '-' + this.displayValue; 73 | } else { 74 | this.displayValue = this.displayValue.replace('-', ''); 75 | } 76 | }, 77 | 78 | updateDisplay() { 79 | this.display.innerText = this.displayValue; 80 | }, 81 | 82 | isOperatorBtn(el) { 83 | var isOp = false; 84 | if(typeof(el) === "object") { 85 | if(el.getAttribute('data-type') == 'operator' && el.innerText !== '=') { 86 | isOp = true; 87 | } 88 | } 89 | return isOp; 90 | }, 91 | 92 | initEvents() { 93 | this.keys.addEventListener('click', (e) => { 94 | for(var i in this.keys.children) { 95 | var el = this.keys.children[i]; 96 | if(this.isOperatorBtn(el)) { 97 | el.classList.remove(this.currentOperatorClass); 98 | } 99 | } 100 | if(this.isOperatorBtn(e.target)) { 101 | e.target.classList.add(this.currentOperatorClass); 102 | } 103 | if(this[e.target.getAttribute('data-type')]) { 104 | this[e.target.getAttribute('data-type')](e.target.value); 105 | } 106 | this.updateDisplay(); 107 | }); 108 | this.updateDisplay(); 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html, 6 | body { 7 | color: #444; 8 | font-family: 'Helvetica', sans-serif; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | height: 100%; 12 | margin: 0; 13 | padding: 0; 14 | width: 100%; 15 | } 16 | 17 | html { 18 | overflow: hidden; 19 | } 20 | 21 | body { 22 | align-content: stretch; 23 | align-items: stretch; 24 | background: #282828; 25 | display: flex; 26 | flex-direction: column; 27 | flex-wrap: nowrap; 28 | justify-content: flex-start; 29 | color: #fff; 30 | -webkit-user-select: none; 31 | -moz-user-select: -moz-none; 32 | -ms-user-select: none; 33 | user-select: none; 34 | } 35 | 36 | .calculator-keys { 37 | position: fixed; 38 | top: 0; 39 | bottom: 0; 40 | width: 100%; 41 | } 42 | 43 | .calculator-display { 44 | float: left; 45 | text-align: right; 46 | width: 100%; 47 | height: 17%; 48 | font-size: 8vh; 49 | line-height: 17vh; 50 | font-weight: 300; 51 | padding: 0 1.5rem; 52 | color: #fafafa; 53 | font-weight: 100; 54 | overflow-x: scroll; 55 | } 56 | 57 | .calculator-key { 58 | float: left; 59 | text-align: center; 60 | width: 25%; 61 | height: 17%; 62 | font-size: 6vh; 63 | font-weight: 300; 64 | border: 0.5px solid #777; 65 | } 66 | 67 | button.calculator-key:focus { 68 | outline: none; 69 | } 70 | 71 | .calculator-key.wide { 72 | width: 50%; 73 | } 74 | 75 | .modal { 76 | display: none; 77 | position: fixed; 78 | z-index: 1; 79 | left: 0; 80 | top: 0; 81 | width: 100%; 82 | height: 100%; 83 | overflow: auto; 84 | background-color: rgb(0,0,0); 85 | background-color: rgba(0,0,0,0.4); 86 | } 87 | 88 | .modal-content { 89 | background-color: #fefefe; 90 | margin: 15% auto; 91 | padding: 20px 30px 40px 30px; 92 | border: 1px solid #888; 93 | max-width: 500px; 94 | text-align: center; 95 | } 96 | 97 | .modal-close { 98 | color: #aaa; 99 | float: right; 100 | font-size: 28px; 101 | font-weight: bold; 102 | } 103 | 104 | .modal-close:hover, 105 | .modal-close:focus { 106 | color: black; 107 | text-decoration: none; 108 | cursor: pointer; 109 | } 110 | 111 | .hide { 112 | display: none !important; 113 | } 114 | 115 | .show { 116 | display: block !important; 117 | } 118 | 119 | #calculator-set-theme { 120 | color: #909090; 121 | color: #fff; 122 | position: absolute; 123 | top: 5px; 124 | left: 10px; 125 | font-size: 24px; 126 | z-index: 9; 127 | text-decoration: none; 128 | } 129 | 130 | #calculator-set-theme:hover { 131 | color: #fafafa; 132 | } 133 | 134 | .theme-title { 135 | color: #777; 136 | } 137 | 138 | .radio div { 139 | display: inline-block; 140 | } 141 | .radio input[type="radio"] { 142 | display: none; 143 | } 144 | .radio input[type="radio"] + label { 145 | color: #333; 146 | font-family: Arial, sans-serif; 147 | font-size: 14px; 148 | } 149 | .radio input[type="radio"] + label span { 150 | display: inline-block; 151 | width: 40px; 152 | height: 40px; 153 | margin: -1px 4px 0 0; 154 | vertical-align: middle; 155 | cursor: pointer; 156 | border-radius: 50%; 157 | border: 2px solid #FFFFFF; 158 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.33); 159 | background-repeat: no-repeat; 160 | background-position: center; 161 | text-align: center; 162 | line-height: 44px; 163 | } 164 | .radio input[type="radio"] + label span img { 165 | opacity: 0; 166 | transition: all .3s ease; 167 | } 168 | .radio input[type="radio"]:checked + label span img { 169 | opacity: 1; 170 | } 171 | 172 | .radio-label { 173 | display: block; 174 | margin-top: 8px; 175 | color: #848484; 176 | font-size: 14px; 177 | } 178 | 179 | .theme { 180 | padding: 10px; 181 | width: 100px; 182 | white-space: nowrap; 183 | overflow: hidden; 184 | text-overflow: ellipsis; 185 | } 186 | 187 | .screen-instructions { 188 | display: none; 189 | text-align: center; 190 | max-width: 500px; 191 | margin: 2rem auto 0; 192 | } 193 | 194 | .install-instructions { 195 | text-align: left; 196 | line-height: 24px; 197 | font-size: 18px; 198 | } 199 | 200 | @media screen and (max-width: 480px) { 201 | .calculator-key { 202 | font-size: 4vh; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /themes.css: -------------------------------------------------------------------------------- 1 | /* THEMES */ 2 | 3 | /* Apple */ 4 | .apple { 5 | background: #f5923e; 6 | background: -moz-linear-gradient(45deg, #f5923e 0%, #333333 61%); 7 | background: -webkit-linear-gradient(45deg, #f5923e 0%,#333333 61%); 8 | background: linear-gradient(45deg, #f5923e 0%,#333333 61%); 9 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5923e', endColorstr='#333333',GradientType=1 ); 10 | } 11 | 12 | .calculator-display.apple { 13 | background: #333; 14 | } 15 | 16 | .calculator-key.nm.apple { 17 | background: rgb(192, 192, 192); 18 | color: #1c1c1c; 19 | border: 0.5px solid #777; 20 | } 21 | 22 | .calculator-key.op.apple { 23 | background: #f5923e; 24 | color: #fafafa; 25 | border: 0.5px solid #777; 26 | } 27 | 28 | .calculator-key.op.op-active.apple { 29 | border: 2px solid #4f4f4f; 30 | } 31 | 32 | .calculator-key.sp.apple { 33 | background: #949597; 34 | color: #fafafa; 35 | border: 0.5px solid #777; 36 | } 37 | 38 | /* Bubblegum */ 39 | .bubblegum { 40 | color: #fff; 41 | background: #ff48a5; 42 | background: -moz-linear-gradient(45deg, #ff48a5 0%, #ff77bc 45%, #ffcae5 100%); 43 | background: -webkit-linear-gradient(45deg, #ff48a5 0%,#ff77bc 45%,#ffcae5 100%); 44 | background: linear-gradient(45deg, #ff48a5 0%,#ff77bc 45%,#ffcae5 100%); 45 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff48a5', endColorstr='#ffcae5',GradientType=1 ); 46 | } 47 | 48 | .calculator-key.nm.bubblegum { 49 | background: #ffcae5; 50 | border: 0.5px solid #ff48a4; 51 | } 52 | 53 | .calculator-key.op.bubblegum { 54 | background: #ff77bc; 55 | border: 0.5px solid #ff48a4; 56 | } 57 | 58 | .calculator-key.op.op-active.bubblegum { 59 | border: 2px solid #ff2995; 60 | } 61 | 62 | .calculator-key.sp.bubblegum { 63 | background: #ffaed7; 64 | border: 0.5px solid #ff48a4; 65 | } 66 | 67 | /* Pink Pastel */ 68 | .pink-pastel { 69 | color: #fff; 70 | background: #f29fac; 71 | background: -moz-linear-gradient(45deg, #f29fac 0%, #f3b7c2 100%); 72 | background: -webkit-linear-gradient(45deg, #f29fac 0%,#f3b7c2 100%); 73 | background: linear-gradient(45deg, #f29fac 0%,#f3b7c2 100%); 74 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f29fac', endColorstr='#f3b7c2',GradientType=1 ); 75 | 76 | } 77 | 78 | .calculator-key.nm.pink-pastel { 79 | background: rgb(243,213,220); 80 | } 81 | 82 | .calculator-key.op.pink-pastel { 83 | background: rgb(237,201,210); 84 | } 85 | 86 | .calculator-key.op.op-active.pink-pastel { 87 | border: 2px solid #f29fac; 88 | } 89 | 90 | .calculator-key.sp.pink-pastel { 91 | background: rgb(243,183,194); 92 | } 93 | 94 | /* Unicorn */ 95 | .unicorn { 96 | color: #fff; 97 | background: #9994de; 98 | background: -moz-linear-gradient(left, #9994de 0%, #f39eeb 100%); 99 | background: -webkit-linear-gradient(left, #9994de 0%,#f39eeb 100%); 100 | background: linear-gradient(to right, #9994de 0%,#f39eeb 100%); 101 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9994de', endColorstr='#f39eeb',GradientType=1 ); 102 | } 103 | 104 | .calculator-key.nm.unicorn { 105 | background: rgb(201,156,226); 106 | border: 0.5px solid rgb(153,148,222); 107 | } 108 | 109 | .calculator-key.op.unicorn { 110 | background: rgb(153,148,222); 111 | border: 0.5px solid rgb(153,148,222); 112 | } 113 | 114 | .calculator-key.op.op-active.unicorn { 115 | border: 2px solid rgb(253,160,238); 116 | } 117 | 118 | .calculator-key.sp.unicorn { 119 | background: rgb(253,160,238); 120 | border: 0.5px solid rgb(153,148,222); 121 | } 122 | 123 | /* BMB */ 124 | 125 | .bmb { 126 | background: #1c1f24; 127 | background: -moz-linear-gradient(45deg, #1c1f24 0%, #37cc9f 100%); 128 | background: -webkit-linear-gradient(45deg, #1c1f24 0%,#37cc9f 100%); 129 | background: linear-gradient(45deg, #1c1f24 0%,#37cc9f 100%); 130 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1c1f24', endColorstr='#37cc9f',GradientType=1 ); 131 | } 132 | 133 | .calculator-display.bmb { 134 | background: rgb(28,31,36); 135 | color: rgb(55,204,159); 136 | } 137 | 138 | .calculator-key.nm.bmb { 139 | background: rgb(220, 225, 221); 140 | } 141 | 142 | .calculator-key.op.bmb { 143 | background: rgb(29,33,42); 144 | background: rgb(164,175,193); 145 | } 146 | 147 | .calculator-key.op.op-active.bmb { 148 | border: 2px solid rgb(28,31,36); 149 | } 150 | 151 | .calculator-key.sp.bmb { 152 | background: rgb(225,108,73); 153 | color: #fff; 154 | } 155 | 156 | 157 | /* TI */ 158 | 159 | .ti { 160 | background: #1d3f55; 161 | background: -moz-linear-gradient(45deg, #1d3f55 0%, #8b977c 100%); 162 | background: -webkit-linear-gradient(45deg, #1d3f55 0%,#8b977c 100%); 163 | background: linear-gradient(45deg, #1d3f55 0%,#8b977c 100%); 164 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1d3f55', endColorstr='#8b977c',GradientType=1 ); 165 | } 166 | 167 | .calculator-display.ti { 168 | background: rgb(140,152,124); 169 | color: rgb(7,12,6); 170 | } 171 | 172 | .calculator-key.nm.ti { 173 | background: rgb(205,205,205); 174 | } 175 | 176 | .calculator-key.op.op-active.ti { 177 | border: 2px solid rgb(204, 204, 204); 178 | } 179 | 180 | .calculator-key.op.ti { 181 | background: rgb(29,63,85); 182 | color: #fff; 183 | } 184 | 185 | .calculator-key.sp.ti { 186 | background: rgb(16,16,16); 187 | color: #fff; 188 | } 189 | 190 | 191 | /* Dark */ 192 | 193 | .dark { 194 | background: rgb(52,51,56); 195 | } 196 | 197 | .calculator-display.dark { 198 | background: rgb(219,230,226); 199 | color: rgb(104,132,147); 200 | } 201 | 202 | .calculator-key.nm.dark { 203 | background: rgb(52,51,56); 204 | color: #fff; 205 | } 206 | 207 | .calculator-key.op.dark { 208 | background: rgb(38, 37, 41); 209 | color: #fff; 210 | } 211 | 212 | .calculator-key.op.op-active.dark { 213 | border: 2px solid rgb(204, 204, 204); 214 | } 215 | 216 | .calculator-key.sp.dark { 217 | background: rgb(45, 44, 48); 218 | color: #fff; 219 | } 220 | 221 | /* Light */ 222 | 223 | .light { 224 | background: #ee5a62; 225 | background: -moz-linear-gradient(45deg, #ee5a62 0%, #3487be 100%); 226 | background: -webkit-linear-gradient(45deg, #ee5a62 0%,#3487be 100%); 227 | background: linear-gradient(45deg, #ee5a62 0%,#3487be 100%); 228 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ee5a62', endColorstr='#3487be',GradientType=1 ); 229 | } 230 | 231 | .calculator-display.light { 232 | background: rgb(37,37,37); 233 | color: rgb(171,171,171); 234 | } 235 | 236 | .calculator-key.nm.light { 237 | background: rgb(248,248,248); 238 | color: rgb(51,51,51); 239 | } 240 | 241 | .calculator-key.op.light { 242 | background: rgb(52,135,190); 243 | color: #fff; 244 | } 245 | 246 | .calculator-key.op.op-active.light { 247 | border: 2px solid rgb(204, 204, 204); 248 | } 249 | 250 | .calculator-key.sp.light { 251 | background: rgb(238,90,98); 252 | color: #fff; 253 | } 254 | 255 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Calculator 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 |
73 |
74 | 75 |
76 |
77 | 78 |

Calculator

79 |
    80 |
  1. Open in Mobile Safari on your iPhone or iPad
  2. 81 |
  3. Tap the 'Share' button
  4. 82 |
  5. Choose 'Add to Home Screen'
  6. 83 |
84 |
85 |
86 | 87 | 178 | 179 | 180 | 181 | 182 | 183 | --------------------------------------------------------------------------------