├── .gitignore ├── LICENSE ├── Procfile ├── README.md ├── forms ├── __init__.py ├── app.py ├── log.py ├── settings.py ├── static │ ├── css │ │ └── main.css │ ├── fonts │ │ ├── ionicons.eot │ │ ├── ionicons.svg │ │ ├── ionicons.ttf │ │ └── ionicons.woff │ ├── img │ │ ├── favicon.ico │ │ └── logo.png │ └── scss │ │ ├── formspree.scss │ │ ├── grid.scss │ │ ├── hint │ │ ├── hint-always.scss │ │ ├── hint-color-types.scss │ │ ├── hint-core.scss │ │ ├── hint-effects.scss │ │ ├── hint-mixins.scss │ │ ├── hint-position.scss │ │ ├── hint-rounded.scss │ │ ├── hint-variables.scss │ │ └── hint.scss │ │ ├── ionicons.min.scss │ │ ├── main.scss │ │ ├── normalize.scss │ │ ├── reset.scss │ │ └── typography.scss ├── templates │ ├── 404.html │ ├── 500.html │ ├── confirmation_sent.html │ ├── email │ │ ├── confirm.html │ │ ├── confirm.txt │ │ ├── form.html │ │ └── form.txt │ ├── email_confirmed.html │ ├── error.html │ ├── index.html │ ├── info.html │ ├── layouts │ │ ├── base.html │ │ └── progress.html │ ├── loaderio-d7b004d89a8ac03ebe643374fab3a57b.html │ └── thanks.html └── utils.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | development.env 2 | *.py[cod] 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | parts 14 | bin 15 | var 16 | sdist 17 | develop-eggs 18 | .installed.cfg 19 | lib 20 | lib64 21 | env 22 | test_form/ 23 | __pycache__ 24 | 25 | # Installer logs 26 | pip-log.txt 27 | 28 | # Unit test / coverage reports 29 | .coverage 30 | .tox 31 | nosetests.xml 32 | 33 | # Translations 34 | *.mo 35 | 36 | # Mr Developer 37 | .mr.developer.cfg 38 | .project 39 | .pydevproject 40 | 41 | # Other 42 | .sass-cache/ 43 | 44 | .DS_Store 45 | codekit-config.json 46 | 47 | .env 48 | 49 | aliases.json 50 | 51 | dev.env 52 | sta.env 53 | pro.env 54 | 55 | celerybeat-schedule.db 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Sendspree Inc. 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn forms:forms_app -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | **NOTE:** This project is not being actively maintained. Please see the fork at [github.com/asm-products/formspree](http://github.com/asm-products/formspree) for further development, and join the discussion at [assembly.com/formspree](http://assembly.com/formspree). 3 | 4 | 5 | FORMS by Brace 6 | -------------- 7 | 8 | Functional HTML forms 9 | 10 | Just send your form to our URL and we'll forward it to your email. No PHP, Javascript or sign up required — perfect for static sites! 11 | Example: 12 | 13 |
14 | 15 | 16 | 17 |
18 | 19 | Setting it up is easy and free. Here's how: 20 | 21 | You don't even have to register. 22 | 23 | ## 1. Setup the HTML form 24 | 25 | Change your form's action-attribute to this and replace your@email.com with your own email. 26 | 27 | If you don't have an HTML form, create one using Brace.io. 28 | 29 | ## 2. Submit the form and confirm your email address 30 | 31 | Go to your website and submit the form once. This will send you an email asking to confirm your email address, so that no one can start sending you spam from random websites. 32 | 33 | ## 3. All set, receive emails 34 | 35 | From now on, when someone submits that form, we'll forward you the data as email. 36 | 37 | 38 | ## Advanced features: 39 | 40 | Form inputs can have specially named name-attributes, which alter functionality. They are all prefixed with an underscore. 41 | 42 | ### _replyto 43 | 44 | This value is used for the email's Reply-To field. This way you can directly "Reply" to the email to respond to the person who originally submitted the form. 45 | 46 | ### _next 47 | 48 | By default, after submitting a form the user is shown the Formspree "Thank You" page. You can provide an alternative URL for that page. 49 | 50 | ### _subject 51 | 52 | This value is used for the email's subject, so that you can quickly reply to submissions without having to edit the subject line each time. 53 | 54 | ### _cc 55 | 56 | This value is used for the email's CC Field. This lets you send a copy of each submission to another email address. 57 | 58 | ### _gotcha 59 | 60 | Add this "honeypot" field to avoid spam by fooling scrapers. If a value is provided, the submission will be silently ignored. The input should be hidden with CSS. 61 | 62 | ### Using AJAX 63 | 64 | You can use Formspree via AJAX. This even works cross-origin. The trick is to set the Accept header to application/json. If you're using jQuery this can be done like so: 65 | 66 | $.ajax({ 67 | url: "//forms.brace.io/you@email.com", 68 | method: "POST", 69 | data: {message: "hello!"}, 70 | dataType: "json" 71 | }); 72 | 73 | -------- 74 | 75 | 76 | Running your own copy of Brace Forms 77 | ------------------------------------ 78 | 79 | ### Running on localhost 80 | 81 | You'll need python 2.7 and should [install pip](https://pip.pypa.io/en/latest/installing.html), and create a [virtual environment](http://docs.python-guide.org/en/latest/dev/virtualenvs/) for the server. 82 | 83 | Once your environment is setup, clone the source and cd into the root of the Brace Forms repository. Then run: 84 | 85 | pip install -r requirements.txt 86 | 87 | then 88 | 89 | python manage.py runserver 90 | 91 | 92 | ### Running on heroku 93 | 94 | You will need to install the [heroku toolbelt](https://toolbelt.heroku.com/). 95 | 96 | Once your environment is setup, clone the source and cd into the root of the Brace Forms repository. Then run: 97 | 98 | heroku apps:create [your project name] 99 | 100 | then 101 | 102 | git push heroku 103 | 104 | Your new project will be running at [your project name].herokuapp.com. 105 | 106 | 107 | ### Dependencies 108 | 109 | Brace Forms requires Redis. If you're deploying to heroku you can get an addon, such as redistogo. To install redistogo into your project just run the command: 110 | 111 | heroku addons:add redistogo 112 | 113 | 114 | Brace Forms also requires a mailgun account to send the emails. You'll need to add the api keys to your environment variables. See the configuration settings below. 115 | 116 | 117 | ### Configuring Brace Forms 118 | 119 | Take a look at the `forms/settings.py` file for a list of environment variables that should be set in order for Forms to work correctly. 120 | 121 | -------------------------------------------------------------------------------- /forms/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from app import create_app 4 | forms_app = create_app() -------------------------------------------------------------------------------- /forms/app.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urlparse 3 | import hashlib 4 | import redis 5 | import re 6 | 7 | import flask 8 | from flask import request, url_for, render_template, redirect, jsonify 9 | 10 | import werkzeug.datastructures 11 | 12 | from paste.util.multidict import MultiDict 13 | 14 | from utils import crossdomain, request_wants_json, jsonerror 15 | import settings 16 | import log 17 | 18 | 19 | ''' 20 | constants 21 | 22 | ''' 23 | 24 | REDIS = redis.Redis.from_url(settings.REDIS_URL) 25 | 26 | DEFAULT_SENDER = settings.DEFAULT_SENDER 27 | 28 | HASH = lambda x, y: hashlib.md5(x+y+settings.NONCE_SECRET).hexdigest() 29 | COUNTER_KEY = lambda x, y: 'forms_counter_%s' % HASH(x, y) 30 | 31 | NONCE_KEY = lambda x, y: 'forms_nonce_%s' % HASH(x, y) 32 | VALID_NONCE = lambda x: REDIS.get('forms_nonce_%s' % x) 33 | 34 | EMAIL_CONFIRMED_KEY = lambda x: 'forms_email_%s' % x 35 | EMAIL_CONFIRMED = lambda x: REDIS.get('forms_email_%s' % x) 36 | 37 | HASH_EMAIL_KEY = lambda x: 'forms_hash_email_%s' % x 38 | HASH_EMAIL = lambda x: REDIS.get('forms_hash_email_%s' % x) 39 | HASH_HOST_KEY = lambda x: 'forms_hash_host_%s' % x 40 | HASH_HOST = lambda x: REDIS.get('forms_hash_host_%s' % x) 41 | 42 | IS_VALID_EMAIL = lambda x: re.match(r"[^@]+@[^@]+\.[^@]+", x) 43 | 44 | EXCLUDE_KEYS = ['_gotcha', '_next', '_subject', '_cc'] 45 | 46 | ''' 47 | helpers 48 | 49 | ''' 50 | 51 | 52 | def ordered_storage(f): 53 | ''' 54 | By default Flask doesn't maintain order of form arguments, pretty crazy 55 | From: https://gist.github.com/cbsmith/5069769 56 | ''' 57 | 58 | def decorator(*args, **kwargs): 59 | flask.request.parameter_storage_class = werkzeug.datastructures.ImmutableOrderedMultiDict 60 | return f(*args, **kwargs) 61 | return decorator 62 | 63 | 64 | def _send_email(to=None, subject=None, text=None, html=None, sender=None, cc=None, reply_to=None): 65 | ''' 66 | Sends email using Mailgun's REST-api 67 | ''' 68 | 69 | if None in [to, subject, text, sender]: 70 | raise ValueError('to, subject text and sender are required to send email') 71 | 72 | data = {'from': sender, 73 | 'to': to, 74 | 'subject': subject, 75 | 'text': text, 76 | 'html': html} 77 | 78 | if reply_to and IS_VALID_EMAIL(reply_to): 79 | data.update({'h:Reply-To': reply_to}) 80 | 81 | if cc and IS_VALID_EMAIL(cc): 82 | data.update({'cc': cc}) 83 | 84 | log.info('Queuing message to %s' % str(to)) 85 | 86 | result = requests.post( 87 | 'https://api.mailgun.net/v2/%s/messages' % setting.MAILGUN_DOMAIN, 88 | auth=('api', settings.MAILGUN_API_KEY), 89 | data=data 90 | ) 91 | 92 | log.info('Queued message to %s' % str(to)) 93 | errmsg = "" 94 | if result.status_code / 100 != 2: 95 | try: 96 | errmsg = result.json().get("message") 97 | except ValueError: 98 | errmsg = result.text 99 | log.warning(errmsg) 100 | 101 | return result.status_code / 100 == 2, errmsg 102 | 103 | 104 | def _get_values_for_hash(h): 105 | ''' 106 | We store email and host cleartext for each hash, returns those 107 | ''' 108 | 109 | return HASH_EMAIL(h), HASH_HOST(h) 110 | 111 | 112 | def _referrer_to_path(r): 113 | log.debug('Referrer was %s' % str(r)) 114 | if not r: 115 | return '' 116 | parsed = urlparse.urlparse(r) 117 | return parsed.netloc + parsed.path 118 | 119 | 120 | def _form_to_dict(data): 121 | ''' 122 | Forms are ImmutableMultiDicts, 123 | convert to json-serializable version 124 | ''' 125 | 126 | ret = {} 127 | ordered_keys = [] 128 | 129 | for elem in data.iteritems(multi=True): 130 | if not elem[0] in ret.keys(): 131 | ret[elem[0]] = [] 132 | 133 | if not elem[0] in EXCLUDE_KEYS: 134 | ordered_keys.append(elem[0]) 135 | 136 | ret[elem[0]].append(elem[1]) 137 | 138 | for r in ret.keys(): 139 | ret[r] = ', '.join(ret[r]) 140 | 141 | return ret, ordered_keys 142 | 143 | 144 | def _send_form(email, host): 145 | ''' 146 | Sends request.form to user's email. 147 | Assumes email has been verified. 148 | ''' 149 | 150 | data, keys = _form_to_dict(request.form) 151 | 152 | subject = data.get('_subject', 'New submission from %s' % _referrer_to_path(request.referrer)) 153 | reply_to = data.get('_replyto', None) 154 | cc = data.get('_cc', None) 155 | next = data.get('_next', url_for('thanks', next=request.referrer)) 156 | spam = data.get('_gotcha', None) 157 | 158 | # prevent submitting empty form 159 | if not any(data.values()): 160 | if request_wants_json(): 161 | return k(400, {'error': "Can't send an empty form"}) 162 | else: 163 | return render_template('error.html', 164 | title='Can\'t send an empty form', 165 | text=str('Return to form' % request.referrer)), 400 166 | 167 | if not spam: 168 | text = render_template('email/form.txt', data=data, host=host, keys=keys) 169 | html = render_template('email/form.html', data=data, host=host, keys=keys) 170 | result = _send_email(to=email, 171 | subject=subject, 172 | text=text, 173 | html=html, 174 | sender=DEFAULT_SENDER, 175 | reply_to=reply_to, 176 | cc=cc) 177 | 178 | if not result[0]: 179 | if request_wants_json(): 180 | return jsonerror(500, {'error': "Unable to send email"}) 181 | else: 182 | return render_template('error.html', 183 | title='Unable to send email', 184 | text=result[1]), 500 185 | 186 | REDIS.incr(COUNTER_KEY(email, host)) 187 | 188 | if request_wants_json(): 189 | return jsonify({'success': "Email sent"}) 190 | else: 191 | return redirect(next, code=302) 192 | 193 | 194 | def _send_confirmation(email, host): 195 | ''' 196 | Helper that actually creates confirmation nonce 197 | and sends the email to associated email. Renders 198 | different templates depending on the result 199 | ''' 200 | log.debug('Sending confirmation') 201 | if VALID_NONCE(HASH(email, host)): 202 | log.debug('Confirmation already sent') 203 | if request_wants_json(): 204 | return jsonify({'success': "confirmation email sent"}) 205 | else: 206 | return render_template('confirmation_sent.html', email=email, host=host) 207 | 208 | link = url_for('confirm_email', nonce=HASH(email, host), _external=True) 209 | 210 | def render_content(type): 211 | return render_template('email/confirm.%s' % type, 212 | email=email, 213 | host=host, 214 | nonce_link=link) 215 | 216 | log.debug('Sending email') 217 | 218 | result = _send_email(to=email, 219 | subject='Confirm email for %s' % settings.SERVICE_NAME, 220 | text=render_content('txt'), 221 | html=render_content('html'), 222 | sender=DEFAULT_SENDER) 223 | 224 | log.debug('Sent') 225 | 226 | if not result[0]: 227 | if request_wants_json(): 228 | return jsonerror(500, {'error': "Unable to send email"}) 229 | else: 230 | return render_template('error.html', 231 | title='Unable to send email', 232 | text=result[1]), 500 233 | 234 | 235 | REDIS.set(NONCE_KEY(email, host), None) 236 | REDIS.set(HASH_EMAIL_KEY(HASH(email, host)), email) 237 | REDIS.set(HASH_HOST_KEY(HASH(email, host)), host) 238 | 239 | if request_wants_json(): 240 | return jsonify({'success': "confirmation email sent"}) 241 | else: 242 | return render_template('confirmation_sent.html', email=email, host=host) 243 | 244 | 245 | def nl2br(value): 246 | return value.replace('\n','
\n') 247 | 248 | 249 | ''' 250 | views 251 | 252 | ''' 253 | 254 | 255 | def thanks(): 256 | return render_template('thanks.html') 257 | 258 | 259 | @crossdomain(origin='*') 260 | @ordered_storage 261 | def send(email): 262 | ''' 263 | Main endpoint, checks if email+host is valid and sends 264 | either form data or verification to email 265 | ''' 266 | 267 | if request.method == 'GET': 268 | if request_wants_json(): 269 | return jsonerror(405, {'error': "Please submit POST request."}) 270 | else: 271 | return render_template('info.html', 272 | title='Form should POST', 273 | text='Make sure your form has the method="POST" attribute'), 405 274 | 275 | if not IS_VALID_EMAIL(email): 276 | if request_wants_json(): 277 | return jsonerror(400, {'error': "Invalid email address"}) 278 | else: 279 | return render_template('error.html', 280 | title='Check email address', 281 | text='Email address %s is not formatted correctly' % str(email)), 400 282 | 283 | # Earlier we used referrer, which is problematic as it includes also URL 284 | # parameters. To maintain backwards compatability and to avoid doing migrations 285 | # check also if email is confirmed for the entire referrer 286 | host = flask.request.referrer 287 | new_host = _referrer_to_path(host) 288 | 289 | if not host: 290 | if request_wants_json(): 291 | return jsonerror(400, {'error': "Invalid \"Referrer\" header"}) 292 | else: 293 | return render_template('error.html', 294 | title='Unable to submit form', 295 | text='Make sure your form is running on a proper server. For geeks: could not find the "Referrer" header.'), 400 296 | 297 | if not EMAIL_CONFIRMED(HASH(email, host)) and not EMAIL_CONFIRMED(HASH(email, new_host)): 298 | return _send_confirmation(email, new_host) 299 | 300 | return _send_form(email, new_host) 301 | 302 | 303 | def confirm_email(nonce): 304 | ''' 305 | Confirmation emails point to this endpoint 306 | It either rejects the confirmation or 307 | flags associated email+host to be confirmed 308 | ''' 309 | 310 | # these are used just for email_confirmed.html template 311 | email, host = _get_values_for_hash(nonce) 312 | 313 | if not VALID_NONCE(nonce): 314 | return render_template('error.html', 315 | title='Not a valid link', 316 | text='Confirmation token not found.
Please check the link and try again.'), 400 317 | 318 | else: 319 | REDIS.set(EMAIL_CONFIRMED_KEY(nonce), 'confirmed') 320 | return render_template('email_confirmed.html', email=email, host=host) 321 | 322 | 323 | def default(template='index'): 324 | template = template if template.endswith('.html') else template+'.html' 325 | return render_template(template, is_redirect = request.args.get('redirected')) 326 | 327 | 328 | def favicon(): 329 | return flask.redirect(url_for('static', filename='img/favicon.ico')) 330 | 331 | ''' 332 | Add routes and create app (create_app is called in __init__.py) 333 | 334 | ''' 335 | 336 | def configure_routes(app): 337 | app.add_url_rule('/', 'index', view_func=default, methods=['GET']) 338 | app.add_url_rule('/favicon.ico', view_func=favicon) 339 | app.add_url_rule('/', 'send', view_func=send, methods=['GET', 'POST']) 340 | app.add_url_rule('/confirm/', 'confirm_email', view_func=confirm_email, methods=['GET']) 341 | app.add_url_rule('/thanks', 'thanks', view_func=thanks, methods=['GET']) 342 | app.add_url_rule('/', 'default', view_func=default, methods=['GET']) 343 | 344 | 345 | def create_app(): 346 | app = flask.Flask('forms') 347 | app.config.from_object(settings) 348 | configure_routes(app) 349 | 350 | @app.errorhandler(500) 351 | def internal_error(e): 352 | return render_template('500.html'), 500 353 | 354 | @app.errorhandler(404) 355 | def page_not_found(e): 356 | return render_template('error.html', title='Oops, page not found'), 404 357 | 358 | app.jinja_env.filters['nl2br'] = nl2br 359 | 360 | return app -------------------------------------------------------------------------------- /forms/log.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import datetime 4 | 5 | import settings 6 | 7 | _LEVEL_MAP = { 8 | 'debug': 4, 9 | 'info': 3, 10 | 'warning': 2, 11 | 'error': 1 12 | } 13 | 14 | def _header(level): 15 | return settings.SERVICE_NAME+":"+level+' '+datetime.datetime.now().isoformat()+" |" 16 | 17 | def _handler_stats(handler): 18 | stats = handler.request.method+" "+\ 19 | handler.request.path+\ 20 | " |" 21 | return stats 22 | 23 | def _should_display(msg_level): 24 | env_level = getattr(settings, 'LOG_LEVEL', 'debug') 25 | return _LEVEL_MAP[msg_level.lower()] <= _LEVEL_MAP[env_level] 26 | 27 | def _display_msg(msg, level, handler=None): 28 | if not _should_display(level): return 29 | if handler: msg = _handler_stats(handler)+msg 30 | msg = _header(level.upper())+msg 31 | print msg 32 | sys.stdout.flush() 33 | 34 | def error(msg, handler=None): 35 | if handler: msg = _handler_stats(handler)+msg 36 | msg = _header("ERROR")+msg 37 | print >> sys.stderr, msg 38 | 39 | def warning(msg, handler=None): 40 | _display_msg(msg, 'warning', handler) 41 | 42 | def info(msg, handler=None): 43 | _display_msg(msg, 'info', handler) 44 | 45 | def debug(msg, handler=None): 46 | _display_msg(msg, 'debug', handler) 47 | -------------------------------------------------------------------------------- /forms/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # load a bunch of environment 4 | 5 | DEBUG = os.getenv('DEBUG') in ['True', 'true', '1', 'yes'] 6 | 7 | NONCE_SECRET = os.getenv('NONCE_SECRET') 8 | REDIS_URL = os.getenv('REDISTOGO_URL') or os.getenv('REDISGREEN_URL') or 'http://localhost:6379' 9 | MAILGUN_API_KEY = os.getenv('MAILGUN_API_KEY') 10 | MAILGUN_DOMAIN = os.getenv('MAILGUN_DOMAIN') 11 | 12 | SERVICE_NAME = os.getenv('SERVICE_NAME') or 'Forms' 13 | SERVICE_URL = os.getenv('SERVICE_URL') or 'http://example.com' 14 | CONTACT_EMAIL = os.getenv('CONTACT_EMAIL') or 'team@example.com' 15 | DEFAULT_SENDER = os.getenv('DEFAULT_SENDER') or 'Forms Team ' 16 | API_ROOT = os.getenv('API_ROOT') or '//example.com' 17 | -------------------------------------------------------------------------------- /forms/static/css/main.css: -------------------------------------------------------------------------------- 1 | article, 2 | aside, 3 | details, 4 | figcaption, 5 | figure, 6 | footer, 7 | header, 8 | hgroup, 9 | nav, 10 | section, 11 | summary { 12 | display: block; } 13 | 14 | audio, 15 | canvas, 16 | video { 17 | display: inline-block; } 18 | 19 | audio:not([controls]) { 20 | display: none; 21 | height: 0; } 22 | 23 | [hidden], template { 24 | display: none; } 25 | 26 | html { 27 | background: white; 28 | color: black; 29 | -webkit-text-size-adjust: 100%; 30 | -ms-text-size-adjust: 100%; } 31 | 32 | html, 33 | button, 34 | input, 35 | select, 36 | textarea { 37 | font-family: sans-serif; } 38 | 39 | body { 40 | margin: 0; } 41 | 42 | a { 43 | background: transparent; } 44 | a:focus { 45 | outline: thin dotted; } 46 | a:hover, a:active { 47 | outline: 0; } 48 | 49 | h1 { 50 | font-size: 2em; 51 | margin: 0.67em 0; } 52 | 53 | h2 { 54 | font-size: 1.5em; 55 | margin: 0.83em 0; } 56 | 57 | h3 { 58 | font-size: 1.17em; 59 | margin: 1em 0; } 60 | 61 | h4 { 62 | font-size: 1em; 63 | margin: 1.33em 0; } 64 | 65 | h5 { 66 | font-size: 0.83em; 67 | margin: 1.67em 0; } 68 | 69 | h6 { 70 | font-size: 0.75em; 71 | margin: 2.33em 0; } 72 | 73 | abbr[title] { 74 | border-bottom: 1px dotted; } 75 | 76 | b, 77 | strong { 78 | font-weight: bold; } 79 | 80 | dfn { 81 | font-style: italic; } 82 | 83 | mark { 84 | background: #ff0; 85 | color: #000; } 86 | 87 | code, 88 | kbd, 89 | pre, 90 | samp { 91 | font-family: monospace, serif; 92 | font-size: 1em; } 93 | 94 | pre { 95 | white-space: pre; 96 | white-space: pre-wrap; 97 | word-wrap: break-word; } 98 | 99 | q { 100 | quotes: "\201C" "\201D" "\2018" "\2019"; } 101 | 102 | q:before, 103 | q:after { 104 | content: ''; 105 | content: none; } 106 | 107 | small { 108 | font-size: 80%; } 109 | 110 | sub, 111 | sup { 112 | font-size: 75%; 113 | line-height: 0; 114 | position: relative; 115 | vertical-align: baseline; } 116 | 117 | sup { 118 | top: -0.5em; } 119 | 120 | sub { 121 | bottom: -0.25em; } 122 | 123 | img { 124 | border: 0; } 125 | 126 | svg:not(:root) { 127 | overflow: hidden; } 128 | 129 | figure { 130 | margin: 0; } 131 | 132 | fieldset { 133 | border: 1px solid #c0c0c0; 134 | margin: 0 2px; 135 | padding: 0.35em 0.625em 0.75em; } 136 | 137 | legend { 138 | border: 0; 139 | padding: 0; 140 | white-space: normal; } 141 | 142 | button, 143 | input, 144 | select, 145 | textarea { 146 | font-family: inherit; 147 | font-size: 100%; 148 | margin: 0; 149 | vertical-align: baseline; } 150 | 151 | button, 152 | input { 153 | line-height: normal; } 154 | 155 | button, 156 | select { 157 | text-transform: none; } 158 | 159 | button, 160 | html input[type="button"], 161 | input[type="reset"], 162 | input[type="submit"] { 163 | -webkit-appearance: button; 164 | cursor: pointer; } 165 | 166 | button[disabled], 167 | input[disabled] { 168 | cursor: default; } 169 | 170 | input[type="checkbox"], 171 | input[type="radio"] { 172 | box-sizing: border-box; 173 | padding: 0; } 174 | 175 | input[type="search"] { 176 | -webkit-appearance: textfield; 177 | -moz-box-sizing: content-box; 178 | -webkit-box-sizing: content-box; 179 | box-sizing: content-box; } 180 | 181 | input[type="search"]::-webkit-search-cancel-button, 182 | input[type="search"]::-webkit-search-decoration { 183 | -webkit-appearance: none; } 184 | 185 | button::-moz-focus-inner, input::-moz-focus-inner { 186 | border: 0; 187 | padding: 0; } 188 | 189 | textarea { 190 | overflow: auto; 191 | vertical-align: top; } 192 | 193 | table { 194 | border-collapse: collapse; 195 | border-spacing: 0; } 196 | 197 | * { 198 | box-sizing: border-box; 199 | -moz-box-sizing: border-box; 200 | -webkit-box-sizing: border-box; } 201 | 202 | .row { 203 | width: 100%; } 204 | .row:after { 205 | content: "."; 206 | display: block; 207 | clear: both; 208 | visibility: hidden; 209 | line-height: 0; 210 | height: 0; } 211 | 212 | .container { 213 | width: 100%; 214 | max-width: 950px; 215 | margin: 0 auto; } 216 | .container:after { 217 | content: "."; 218 | display: block; 219 | clear: both; 220 | visibility: hidden; 221 | line-height: 0; 222 | height: 0; } 223 | .container.narrow { 224 | max-width: 600px; } 225 | @media (max-width: 760px) { 226 | .container { 227 | max-width: 100% !important; } } 228 | 229 | .col-1-1 { 230 | float: left; 231 | padding: 0 20px; 232 | width: 100%; } 233 | @media (max-width: 760px) { 234 | .col-1-1 { 235 | width: 100% !important; 236 | margin-bottom: 20px !important; } } 237 | 238 | .col-1-2 { 239 | float: left; 240 | padding: 0 20px; 241 | width: 50%; } 242 | @media (max-width: 760px) { 243 | .col-1-2 { 244 | width: 100% !important; 245 | margin-bottom: 20px !important; } } 246 | 247 | .col-1-3 { 248 | float: left; 249 | padding: 0 20px; 250 | width: 33.33%; } 251 | @media (max-width: 760px) { 252 | .col-1-3 { 253 | width: 100% !important; 254 | margin-bottom: 20px !important; } } 255 | 256 | .col-2-3 { 257 | float: left; 258 | padding: 0 20px; 259 | width: 66.66%; } 260 | @media (max-width: 760px) { 261 | .col-2-3 { 262 | width: 100% !important; 263 | margin-bottom: 20px !important; } } 264 | 265 | .col-1-4 { 266 | float: left; 267 | padding: 0 20px; 268 | width: 25%; } 269 | @media (max-width: 760px) { 270 | .col-1-4 { 271 | width: 100% !important; 272 | margin-bottom: 20px !important; } } 273 | 274 | .col-3-4 { 275 | float: left; 276 | padding: 0 20px; 277 | width: 75%; } 278 | @media (max-width: 760px) { 279 | .col-3-4 { 280 | width: 100% !important; 281 | margin-bottom: 20px !important; } } 282 | 283 | .col-2-5 { 284 | float: left; 285 | padding: 0 20px; 286 | width: 40%; } 287 | @media (max-width: 760px) { 288 | .col-2-5 { 289 | width: 100% !important; 290 | margin-bottom: 20px !important; } } 291 | 292 | .col-3-5 { 293 | float: left; 294 | padding: 0 20px; 295 | width: 60%; } 296 | @media (max-width: 760px) { 297 | .col-3-5 { 298 | width: 100% !important; 299 | margin-bottom: 20px !important; } } 300 | 301 | body { 302 | font-size: 18px; 303 | line-height: 1.5em; 304 | font-family: 'proxima-nova-soft', sans-serif; } 305 | 306 | h1, h2, h3, h4, h5, h6, p { 307 | font-family: 'proxima-nova-soft', sans-serif; 308 | -webkit-font-smoothing: antialiased; } 309 | h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child, h6:first-child, p:first-child { 310 | margin-top: 0; } 311 | h1:last-child, h2:last-child, h3:last-child, h4:last-child, h5:last-child, h6:last-child, p:last-child { 312 | margin-bottom: 0; } 313 | h1 > small, h2 > small, h3 > small, h4 > small, h5 > small, h6 > small, p > small { 314 | font-size: 0.65em; 315 | color: #aaa; } 316 | 317 | h1, h2, h3, h4, h5, h6 { 318 | font-weight: 600; 319 | line-height: 1.3em; 320 | color: #1b3544; } 321 | h1.light, h2.light, h3.light, h4.light, h5.light, h6.light { 322 | font-weight: 400; 323 | color: #444; } 324 | 325 | p { 326 | line-height: 1.5em; 327 | color: #444; } 328 | 329 | a { 330 | color: #359173; 331 | text-decoration: none; 332 | transition: color 0.3s ease-in-out; } 333 | a:hover { 334 | color: #359173; } 335 | 336 | .center { 337 | text-align: center; } 338 | 339 | .right { 340 | text-align: right; } 341 | 342 | .caps { 343 | text-transform: uppercase; } 344 | 345 | /*-------------------------------------*\ 346 | HINT.css - A CSS tooltip library 347 | \*-------------------------------------*/ 348 | /** 349 | * HINT.css is a tooltip library made in pure CSS. 350 | * 351 | * Source: https://github.com/chinchang/hint.css 352 | * Demo: http://kushagragour.in/lab/hint/ 353 | * 354 | * Release under The MIT License 355 | * 356 | */ 357 | /** 358 | * source: hint-core.scss 359 | * 360 | * Defines the basic styling for the tooltip. 361 | * Each tooltip is made of 2 parts: 362 | * 1) body (:after) 363 | * 2) arrow (:before) 364 | * 365 | * Classes added: 366 | * 1) hint 367 | */ 368 | .hint, [data-hint] { 369 | position: relative; 370 | display: inline-block; 371 | /** 372 | * tooltip arrow 373 | */ 374 | /** 375 | * tooltip body 376 | */ } 377 | .hint:before, .hint:after, [data-hint]:before, [data-hint]:after { 378 | position: absolute; 379 | -webkit-transform: translate3d(0, 0, 0); 380 | -moz-transform: translate3d(0, 0, 0); 381 | transform: translate3d(0, 0, 0); 382 | visibility: hidden; 383 | opacity: 0; 384 | z-index: 1000000; 385 | pointer-events: none; 386 | -webkit-transition: 0.3s ease; 387 | -moz-transition: 0.3s ease; 388 | transition: 0.3s ease; } 389 | .hint:hover:before, .hint:hover:after, .hint:focus:before, .hint:focus:after, [data-hint]:hover:before, [data-hint]:hover:after, [data-hint]:focus:before, [data-hint]:focus:after { 390 | visibility: visible; 391 | opacity: 1; } 392 | .hint:before, [data-hint]:before { 393 | content: ''; 394 | position: absolute; 395 | background: transparent; 396 | border: 6px solid transparent; 397 | z-index: 1000001; } 398 | .hint:after, [data-hint]:after { 399 | font-family: 'myriad-pro', sans-serif; 400 | font-weight: 400; 401 | content: attr(data-hint); 402 | background: #1b3544; 403 | color: white; 404 | padding: 12px 15px; 405 | font-size: 16px; 406 | line-height: 16px; 407 | white-space: nowrap; } 408 | 409 | /** 410 | * source: hint-position.scss 411 | * 412 | * Defines the positoning logic for the tooltips. 413 | * 414 | * Classes added: 415 | * 1) hint--top 416 | * 2) hint--bottom 417 | * 3) hint--left 418 | * 4) hint--right 419 | */ 420 | /** 421 | * set default color for tooltip arrows 422 | */ 423 | .hint--top:before { 424 | border-top-color: #1b3544; } 425 | 426 | .hint--bottom:before { 427 | border-bottom-color: #1b3544; } 428 | 429 | .hint--left:before { 430 | border-left-color: #1b3544; } 431 | 432 | .hint--right:before { 433 | border-right-color: #1b3544; } 434 | 435 | /** 436 | * top tooltip 437 | */ 438 | .hint--top:before { 439 | margin-bottom: -12px; } 440 | .hint--top:after { 441 | margin-left: -18px; } 442 | .hint--top:before, .hint--top:after { 443 | bottom: 100%; 444 | left: 18px; } 445 | .hint--top:hover:after, .hint--top:hover:before, .hint--top:focus:after, .hint--top:focus:before { 446 | -webkit-transform: translateY(-8px); 447 | -moz-transform: translateY(-8px); 448 | transform: translateY(-8px); } 449 | 450 | /** 451 | * bottom tooltip 452 | */ 453 | .hint--bottom:before { 454 | margin-top: -12px; } 455 | .hint--bottom:after { 456 | margin-left: -18px; } 457 | .hint--bottom:before, .hint--bottom:after { 458 | top: 100%; 459 | left: 18px; } 460 | .hint--bottom:hover:after, .hint--bottom:hover:before, .hint--bottom:focus:after, .hint--bottom:focus:before { 461 | -webkit-transform: translateY(8px); 462 | -moz-transform: translateY(8px); 463 | transform: translateY(8px); } 464 | 465 | /** 466 | * right tooltip 467 | */ 468 | .hint--right:before { 469 | margin-left: -12px; 470 | margin-bottom: -6px; } 471 | .hint--right:after { 472 | margin-bottom: -20px; } 473 | .hint--right:before, .hint--right:after { 474 | left: 100%; 475 | bottom: 50%; } 476 | .hint--right:hover:after, .hint--right:hover:before, .hint--right:focus:after, .hint--right:focus:before { 477 | -webkit-transform: translateX(8px); 478 | -moz-transform: translateX(8px); 479 | transform: translateX(8px); } 480 | 481 | /** 482 | * left tooltip 483 | */ 484 | .hint--left:before { 485 | margin-right: -12px; 486 | margin-bottom: -6px; } 487 | .hint--left:after { 488 | margin-bottom: -20px; } 489 | .hint--left:before, .hint--left:after { 490 | right: 100%; 491 | bottom: 50%; } 492 | .hint--left:hover:after, .hint--left:hover:before, .hint--left:focus:after, .hint--left:focus:before { 493 | -webkit-transform: translateX(-8px); 494 | -moz-transform: translateX(-8px); 495 | transform: translateX(-8px); } 496 | 497 | /** 498 | * source: hint-color-types.scss 499 | * 500 | * Contains tooltips of various types based on color differences. 501 | * 502 | * Classes added: 503 | * 1) hint--error 504 | * 2) hint--warning 505 | * 3) hint--info 506 | * 4) hint--success 507 | * 508 | */ 509 | /** 510 | * Error 511 | */ 512 | .hint--error:after { 513 | background-color: #b34e4d; } 514 | .hint--error.hint--top:before { 515 | border-top-color: #b34e4d; } 516 | .hint--error.hint--bottom:before { 517 | border-bottom-color: #b34e4d; } 518 | .hint--error.hint--left:before { 519 | border-left-color: #b34e4d; } 520 | .hint--error.hint--right:before { 521 | border-right-color: #b34e4d; } 522 | 523 | /** 524 | * Warning 525 | */ 526 | .hint--warning:after { 527 | background-color: #c09854; } 528 | .hint--warning.hint--top:before { 529 | border-top-color: #c09854; } 530 | .hint--warning.hint--bottom:before { 531 | border-bottom-color: #c09854; } 532 | .hint--warning.hint--left:before { 533 | border-left-color: #c09854; } 534 | .hint--warning.hint--right:before { 535 | border-right-color: #c09854; } 536 | 537 | /** 538 | * Info 539 | */ 540 | .hint--info:after { 541 | background-color: #3986ac; } 542 | .hint--info.hint--top:before { 543 | border-top-color: #3986ac; } 544 | .hint--info.hint--bottom:before { 545 | border-bottom-color: #3986ac; } 546 | .hint--info.hint--left:before { 547 | border-left-color: #3986ac; } 548 | .hint--info.hint--right:before { 549 | border-right-color: #3986ac; } 550 | 551 | /** 552 | * Success 553 | */ 554 | .hint--success:after { 555 | background-color: #458746; } 556 | .hint--success.hint--top:before { 557 | border-top-color: #458746; } 558 | .hint--success.hint--bottom:before { 559 | border-bottom-color: #458746; } 560 | .hint--success.hint--left:before { 561 | border-left-color: #458746; } 562 | .hint--success.hint--right:before { 563 | border-right-color: #458746; } 564 | 565 | /** 566 | * source: hint-always.scss 567 | * 568 | * Defines a persisted tooltip which shows always. 569 | * 570 | * Classes added: 571 | * 1) hint--always 572 | * 573 | */ 574 | .hint--always:after, .hint--always:before { 575 | opacity: 1; 576 | visibility: visible; } 577 | .hint--always.hint--top:after, .hint--always.hint--top:before { 578 | -webkit-transform: translateY(-8px); 579 | -moz-transform: translateY(-8px); 580 | transform: translateY(-8px); } 581 | .hint--always.hint--bottom:after, .hint--always.hint--bottom:before { 582 | -webkit-transform: translateY(8px); 583 | -moz-transform: translateY(8px); 584 | transform: translateY(8px); } 585 | .hint--always.hint--left:after, .hint--always.hint--left:before { 586 | -webkit-transform: translateX(-8px); 587 | -moz-transform: translateX(-8px); 588 | transform: translateX(-8px); } 589 | .hint--always.hint--right:after, .hint--always.hint--right:before { 590 | -webkit-transform: translateX(8px); 591 | -moz-transform: translateX(8px); 592 | transform: translateX(8px); } 593 | 594 | /** 595 | * source: hint-rounded.scss 596 | * 597 | * Defines rounded corner tooltips. 598 | * 599 | * Classes added: 600 | * 1) hint--rounded 601 | * 602 | */ 603 | .hint--rounded:after { 604 | border-radius: 4px; } 605 | 606 | /** 607 | * source: hint-effects.scss 608 | * 609 | * Defines various transition effects for the tooltips. 610 | * 611 | * Classes added: 612 | * 1) hint--bounce 613 | * 614 | */ 615 | .hint--bounce:before, .hint--bounce:after { 616 | -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24); 617 | -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24); 618 | transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24); } 619 | 620 | /*! 621 | Ionicons, v1.4.1 622 | Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ 623 | https://twitter.com/benjsperry https://twitter.com/ionicframework 624 | MIT License: https://github.com/driftyco/ionicons 625 | */ 626 | @font-face { 627 | font-family: "Ionicons"; 628 | src: url("../fonts/ionicons.eot?v=1.4.1"); 629 | src: url("../fonts/ionicons.eot?v=1.4.1#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=1.4.1") format("truetype"), url("../fonts/ionicons.woff?v=1.4.1") format("woff"), url("../fonts/ionicons.svg?v=1.4.1#Ionicons") format("svg"); 630 | font-weight: normal; 631 | font-style: normal; } 632 | 633 | .ion, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading, .ionicons, .ion-alert, .ion-alert-circled, .ion-android-add, .ion-android-add-contact, .ion-android-alarm, .ion-android-archive, .ion-android-arrow-back, .ion-android-arrow-down-left, .ion-android-arrow-down-right, .ion-android-arrow-up-left, .ion-android-arrow-up-right, .ion-android-battery, .ion-android-book, .ion-android-calendar, .ion-android-call, .ion-android-camera, .ion-android-chat, .ion-android-checkmark, .ion-android-clock, .ion-android-close, .ion-android-contact, .ion-android-contacts, .ion-android-data, .ion-android-developer, .ion-android-display, .ion-android-download, .ion-android-dropdown, .ion-android-earth, .ion-android-folder, .ion-android-forums, .ion-android-friends, .ion-android-hand, .ion-android-image, .ion-android-inbox, .ion-android-information, .ion-android-keypad, .ion-android-lightbulb, .ion-android-locate, .ion-android-location, .ion-android-mail, .ion-android-microphone, .ion-android-mixer, .ion-android-more, .ion-android-note, .ion-android-playstore, .ion-android-printer, .ion-android-promotion, .ion-android-reminder, .ion-android-remove, .ion-android-search, .ion-android-send, .ion-android-settings, .ion-android-share, .ion-android-social, .ion-android-social-user, .ion-android-sort, .ion-android-star, .ion-android-stopwatch, .ion-android-storage, .ion-android-system-back, .ion-android-system-home, .ion-android-system-windows, .ion-android-timer, .ion-android-trash, .ion-android-volume, .ion-android-wifi, .ion-archive, .ion-arrow-down-a, .ion-arrow-down-b, .ion-arrow-down-c, .ion-arrow-expand, .ion-arrow-graph-down-left, .ion-arrow-graph-down-right, .ion-arrow-graph-up-left, .ion-arrow-graph-up-right, .ion-arrow-left-a, .ion-arrow-left-b, .ion-arrow-left-c, .ion-arrow-move, .ion-arrow-resize, .ion-arrow-return-left, .ion-arrow-return-right, .ion-arrow-right-a, .ion-arrow-right-b, .ion-arrow-right-c, .ion-arrow-shrink, .ion-arrow-swap, .ion-arrow-up-a, .ion-arrow-up-b, .ion-arrow-up-c, .ion-at, .ion-bag, .ion-battery-charging, .ion-battery-empty, .ion-battery-full, .ion-battery-half, .ion-battery-low, .ion-beaker, .ion-beer, .ion-bluetooth, .ion-bookmark, .ion-briefcase, .ion-bug, .ion-calculator, .ion-calendar, .ion-camera, .ion-card, .ion-chatbox, .ion-chatbox-working, .ion-chatboxes, .ion-chatbubble, .ion-chatbubble-working, .ion-chatbubbles, .ion-checkmark, .ion-checkmark-circled, .ion-checkmark-round, .ion-chevron-down, .ion-chevron-left, .ion-chevron-right, .ion-chevron-up, .ion-clipboard, .ion-clock, .ion-close, .ion-close-circled, .ion-close-round, .ion-cloud, .ion-code, .ion-code-download, .ion-code-working, .ion-coffee, .ion-compass, .ion-compose, .ion-connection-bars, .ion-contrast, .ion-disc, .ion-document, .ion-document-text, .ion-drag, .ion-earth, .ion-edit, .ion-egg, .ion-eject, .ion-email, .ion-eye, .ion-eye-disabled, .ion-female, .ion-filing, .ion-film-marker, .ion-flag, .ion-flash, .ion-flash-off, .ion-flask, .ion-folder, .ion-fork, .ion-fork-repo, .ion-forward, .ion-game-controller-a, .ion-game-controller-b, .ion-gear-a, .ion-gear-b, .ion-grid, .ion-hammer, .ion-headphone, .ion-heart, .ion-help, .ion-help-buoy, .ion-help-circled, .ion-home, .ion-icecream, .ion-icon-social-google-plus, .ion-icon-social-google-plus-outline, .ion-image, .ion-images, .ion-information, .ion-information-circled, .ion-ionic, .ion-ios7-alarm, .ion-ios7-alarm-outline, .ion-ios7-albums, .ion-ios7-albums-outline, .ion-ios7-arrow-back, .ion-ios7-arrow-down, .ion-ios7-arrow-forward, .ion-ios7-arrow-left, .ion-ios7-arrow-right, .ion-ios7-arrow-thin-down, .ion-ios7-arrow-thin-left, .ion-ios7-arrow-thin-right, .ion-ios7-arrow-thin-up, .ion-ios7-arrow-up, .ion-ios7-at, .ion-ios7-at-outline, .ion-ios7-bell, .ion-ios7-bell-outline, .ion-ios7-bolt, .ion-ios7-bolt-outline, .ion-ios7-bookmarks, .ion-ios7-bookmarks-outline, .ion-ios7-box, .ion-ios7-box-outline, .ion-ios7-briefcase, .ion-ios7-briefcase-outline, .ion-ios7-browsers, .ion-ios7-browsers-outline, .ion-ios7-calculator, .ion-ios7-calculator-outline, .ion-ios7-calendar, .ion-ios7-calendar-outline, .ion-ios7-camera, .ion-ios7-camera-outline, .ion-ios7-cart, .ion-ios7-cart-outline, .ion-ios7-chatboxes, .ion-ios7-chatboxes-outline, .ion-ios7-chatbubble, .ion-ios7-chatbubble-outline, .ion-ios7-checkmark, .ion-ios7-checkmark-empty, .ion-ios7-checkmark-outline, .ion-ios7-circle-filled, .ion-ios7-circle-outline, .ion-ios7-clock, .ion-ios7-clock-outline, .ion-ios7-close, .ion-ios7-close-empty, .ion-ios7-close-outline, .ion-ios7-cloud, .ion-ios7-cloud-download, .ion-ios7-cloud-download-outline, .ion-ios7-cloud-outline, .ion-ios7-cloud-upload, .ion-ios7-cloud-upload-outline, .ion-ios7-cloudy, .ion-ios7-cloudy-night, .ion-ios7-cloudy-night-outline, .ion-ios7-cloudy-outline, .ion-ios7-cog, .ion-ios7-cog-outline, .ion-ios7-compose, .ion-ios7-compose-outline, .ion-ios7-contact, .ion-ios7-contact-outline, .ion-ios7-copy, .ion-ios7-copy-outline, .ion-ios7-download, .ion-ios7-download-outline, .ion-ios7-drag, .ion-ios7-email, .ion-ios7-email-outline, .ion-ios7-eye, .ion-ios7-eye-outline, .ion-ios7-fastforward, .ion-ios7-fastforward-outline, .ion-ios7-filing, .ion-ios7-filing-outline, .ion-ios7-film, .ion-ios7-film-outline, .ion-ios7-flag, .ion-ios7-flag-outline, .ion-ios7-folder, .ion-ios7-folder-outline, .ion-ios7-gear, .ion-ios7-gear-outline, .ion-ios7-glasses, .ion-ios7-glasses-outline, .ion-ios7-heart, .ion-ios7-heart-outline, .ion-ios7-help, .ion-ios7-help-empty, .ion-ios7-help-outline, .ion-ios7-infinite, .ion-ios7-infinite-outline, .ion-ios7-information, .ion-ios7-information-empty, .ion-ios7-information-outline, .ion-ios7-ionic-outline, .ion-ios7-keypad, .ion-ios7-keypad-outline, .ion-ios7-lightbulb, .ion-ios7-lightbulb-outline, .ion-ios7-location, .ion-ios7-location-outline, .ion-ios7-locked, .ion-ios7-locked-outline, .ion-ios7-medkit, .ion-ios7-medkit-outline, .ion-ios7-mic, .ion-ios7-mic-off, .ion-ios7-mic-outline, .ion-ios7-minus, .ion-ios7-minus-empty, .ion-ios7-minus-outline, .ion-ios7-monitor, .ion-ios7-monitor-outline, .ion-ios7-moon, .ion-ios7-moon-outline, .ion-ios7-more, .ion-ios7-more-outline, .ion-ios7-musical-note, .ion-ios7-musical-notes, .ion-ios7-navigate, .ion-ios7-navigate-outline, .ion-ios7-paperplane, .ion-ios7-paperplane-outline, .ion-ios7-partlysunny, .ion-ios7-partlysunny-outline, .ion-ios7-pause, .ion-ios7-pause-outline, .ion-ios7-people, .ion-ios7-people-outline, .ion-ios7-person, .ion-ios7-person-outline, .ion-ios7-personadd, .ion-ios7-personadd-outline, .ion-ios7-photos, .ion-ios7-photos-outline, .ion-ios7-pie, .ion-ios7-pie-outline, .ion-ios7-play, .ion-ios7-play-outline, .ion-ios7-plus, .ion-ios7-plus-empty, .ion-ios7-plus-outline, .ion-ios7-pricetag, .ion-ios7-pricetag-outline, .ion-ios7-printer, .ion-ios7-printer-outline, .ion-ios7-rainy, .ion-ios7-rainy-outline, .ion-ios7-recording, .ion-ios7-recording-outline, .ion-ios7-redo, .ion-ios7-redo-outline, .ion-ios7-refresh, .ion-ios7-refresh-empty, .ion-ios7-refresh-outline, .ion-ios7-reload, .ion-ios7-rewind, .ion-ios7-rewind-outline, .ion-ios7-search, .ion-ios7-search-strong, .ion-ios7-skipbackward, .ion-ios7-skipbackward-outline, .ion-ios7-skipforward, .ion-ios7-skipforward-outline, .ion-ios7-snowy, .ion-ios7-speedometer, .ion-ios7-speedometer-outline, .ion-ios7-star, .ion-ios7-star-outline, .ion-ios7-stopwatch, .ion-ios7-stopwatch-outline, .ion-ios7-sunny, .ion-ios7-sunny-outline, .ion-ios7-telephone, .ion-ios7-telephone-outline, .ion-ios7-thunderstorm, .ion-ios7-thunderstorm-outline, .ion-ios7-time, .ion-ios7-time-outline, .ion-ios7-timer, .ion-ios7-timer-outline, .ion-ios7-trash, .ion-ios7-trash-outline, .ion-ios7-undo, .ion-ios7-undo-outline, .ion-ios7-unlocked, .ion-ios7-unlocked-outline, .ion-ios7-upload, .ion-ios7-upload-outline, .ion-ios7-videocam, .ion-ios7-videocam-outline, .ion-ios7-volume-high, .ion-ios7-volume-low, .ion-ios7-wineglass, .ion-ios7-wineglass-outline, .ion-ios7-world, .ion-ios7-world-outline, .ion-ipad, .ion-iphone, .ion-ipod, .ion-jet, .ion-key, .ion-knife, .ion-laptop, .ion-leaf, .ion-levels, .ion-lightbulb, .ion-link, .ion-load-a, .ion-load-b, .ion-load-c, .ion-load-d, .ion-location, .ion-locked, .ion-log-in, .ion-log-out, .ion-loop, .ion-magnet, .ion-male, .ion-man, .ion-map, .ion-medkit, .ion-mic-a, .ion-mic-b, .ion-mic-c, .ion-minus, .ion-minus-circled, .ion-minus-round, .ion-model-s, .ion-monitor, .ion-more, .ion-music-note, .ion-navicon, .ion-navicon-round, .ion-navigate, .ion-no-smoking, .ion-nuclear, .ion-paper-airplane, .ion-paperclip, .ion-pause, .ion-person, .ion-person-add, .ion-person-stalker, .ion-pie-graph, .ion-pin, .ion-pinpoint, .ion-pizza, .ion-plane, .ion-play, .ion-playstation, .ion-plus, .ion-plus-circled, .ion-plus-round, .ion-pound, .ion-power, .ion-pricetag, .ion-pricetags, .ion-printer, .ion-radio-waves, .ion-record, .ion-refresh, .ion-reply, .ion-reply-all, .ion-search, .ion-settings, .ion-share, .ion-shuffle, .ion-skip-backward, .ion-skip-forward, .ion-social-android, .ion-social-android-outline, .ion-social-apple, .ion-social-apple-outline, .ion-social-bitcoin, .ion-social-bitcoin-outline, .ion-social-buffer, .ion-social-buffer-outline, .ion-social-designernews, .ion-social-designernews-outline, .ion-social-dribbble, .ion-social-dribbble-outline, .ion-social-dropbox, .ion-social-dropbox-outline, .ion-social-facebook, .ion-social-facebook-outline, .ion-social-freebsd-devil, .ion-social-github, .ion-social-github-outline, .ion-social-googleplus, .ion-social-googleplus-outline, .ion-social-hackernews, .ion-social-hackernews-outline, .ion-social-linkedin, .ion-social-linkedin-outline, .ion-social-pinterest, .ion-social-pinterest-outline, .ion-social-reddit, .ion-social-reddit-outline, .ion-social-rss, .ion-social-rss-outline, .ion-social-skype, .ion-social-skype-outline, .ion-social-tumblr, .ion-social-tumblr-outline, .ion-social-tux, .ion-social-twitter, .ion-social-twitter-outline, .ion-social-vimeo, .ion-social-vimeo-outline, .ion-social-windows, .ion-social-windows-outline, .ion-social-wordpress, .ion-social-wordpress-outline, .ion-social-yahoo, .ion-social-yahoo-outline, .ion-social-youtube, .ion-social-youtube-outline, .ion-speakerphone, .ion-speedometer, .ion-spoon, .ion-star, .ion-stats-bars, .ion-steam, .ion-stop, .ion-thermometer, .ion-thumbsdown, .ion-thumbsup, .ion-trash-a, .ion-trash-b, .ion-umbrella, .ion-unlocked, .ion-upload, .ion-usb, .ion-videocamera, .ion-volume-high, .ion-volume-low, .ion-volume-medium, .ion-volume-mute, .ion-waterdrop, .ion-wifi, .ion-wineglass, .ion-woman, .ion-wrench, .ion-xbox { 634 | display: inline-block; 635 | font-family: "Ionicons"; 636 | speak: none; 637 | font-style: normal; 638 | font-weight: normal; 639 | font-variant: normal; 640 | text-transform: none; 641 | text-rendering: auto; 642 | line-height: 1; 643 | -webkit-font-smoothing: antialiased; 644 | -moz-osx-font-smoothing: grayscale; } 645 | 646 | .ion-spin, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading { 647 | -webkit-animation: spin 1s infinite linear; 648 | -moz-animation: spin 1s infinite linear; 649 | -o-animation: spin 1s infinite linear; 650 | animation: spin 1s infinite linear; } 651 | 652 | @-moz-keyframes spin { 653 | 0% { 654 | -moz-transform: rotate(0deg); } 655 | 656 | 100% { 657 | -moz-transform: rotate(359deg); } } 658 | 659 | @-webkit-keyframes spin { 660 | 0% { 661 | -webkit-transform: rotate(0deg); } 662 | 663 | 100% { 664 | -webkit-transform: rotate(359deg); } } 665 | 666 | @-o-keyframes spin { 667 | 0% { 668 | -o-transform: rotate(0deg); } 669 | 670 | 100% { 671 | -o-transform: rotate(359deg); } } 672 | 673 | @-ms-keyframes spin { 674 | 0% { 675 | -ms-transform: rotate(0deg); } 676 | 677 | 100% { 678 | -ms-transform: rotate(359deg); } } 679 | 680 | @keyframes spin { 681 | 0% { 682 | transform: rotate(0deg); } 683 | 684 | 100% { 685 | transform: rotate(359deg); } } 686 | 687 | .ion-loading-a { 688 | -webkit-animation-timing-function: steps(8, start); 689 | -moz-animation-timing-function: steps(8, start); 690 | animation-timing-function: steps(8, start); } 691 | 692 | .ion-alert:before { 693 | content: "\f101"; } 694 | 695 | .ion-alert-circled:before { 696 | content: "\f100"; } 697 | 698 | .ion-android-add:before { 699 | content: "\f2c7"; } 700 | 701 | .ion-android-add-contact:before { 702 | content: "\f2c6"; } 703 | 704 | .ion-android-alarm:before { 705 | content: "\f2c8"; } 706 | 707 | .ion-android-archive:before { 708 | content: "\f2c9"; } 709 | 710 | .ion-android-arrow-back:before { 711 | content: "\f2ca"; } 712 | 713 | .ion-android-arrow-down-left:before { 714 | content: "\f2cb"; } 715 | 716 | .ion-android-arrow-down-right:before { 717 | content: "\f2cc"; } 718 | 719 | .ion-android-arrow-up-left:before { 720 | content: "\f2cd"; } 721 | 722 | .ion-android-arrow-up-right:before { 723 | content: "\f2ce"; } 724 | 725 | .ion-android-battery:before { 726 | content: "\f2cf"; } 727 | 728 | .ion-android-book:before { 729 | content: "\f2d0"; } 730 | 731 | .ion-android-calendar:before { 732 | content: "\f2d1"; } 733 | 734 | .ion-android-call:before { 735 | content: "\f2d2"; } 736 | 737 | .ion-android-camera:before { 738 | content: "\f2d3"; } 739 | 740 | .ion-android-chat:before { 741 | content: "\f2d4"; } 742 | 743 | .ion-android-checkmark:before { 744 | content: "\f2d5"; } 745 | 746 | .ion-android-clock:before { 747 | content: "\f2d6"; } 748 | 749 | .ion-android-close:before { 750 | content: "\f2d7"; } 751 | 752 | .ion-android-contact:before { 753 | content: "\f2d8"; } 754 | 755 | .ion-android-contacts:before { 756 | content: "\f2d9"; } 757 | 758 | .ion-android-data:before { 759 | content: "\f2da"; } 760 | 761 | .ion-android-developer:before { 762 | content: "\f2db"; } 763 | 764 | .ion-android-display:before { 765 | content: "\f2dc"; } 766 | 767 | .ion-android-download:before { 768 | content: "\f2dd"; } 769 | 770 | .ion-android-dropdown:before { 771 | content: "\f2de"; } 772 | 773 | .ion-android-earth:before { 774 | content: "\f2df"; } 775 | 776 | .ion-android-folder:before { 777 | content: "\f2e0"; } 778 | 779 | .ion-android-forums:before { 780 | content: "\f2e1"; } 781 | 782 | .ion-android-friends:before { 783 | content: "\f2e2"; } 784 | 785 | .ion-android-hand:before { 786 | content: "\f2e3"; } 787 | 788 | .ion-android-image:before { 789 | content: "\f2e4"; } 790 | 791 | .ion-android-inbox:before { 792 | content: "\f2e5"; } 793 | 794 | .ion-android-information:before { 795 | content: "\f2e6"; } 796 | 797 | .ion-android-keypad:before { 798 | content: "\f2e7"; } 799 | 800 | .ion-android-lightbulb:before { 801 | content: "\f2e8"; } 802 | 803 | .ion-android-locate:before { 804 | content: "\f2e9"; } 805 | 806 | .ion-android-location:before { 807 | content: "\f2ea"; } 808 | 809 | .ion-android-mail:before { 810 | content: "\f2eb"; } 811 | 812 | .ion-android-microphone:before { 813 | content: "\f2ec"; } 814 | 815 | .ion-android-mixer:before { 816 | content: "\f2ed"; } 817 | 818 | .ion-android-more:before { 819 | content: "\f2ee"; } 820 | 821 | .ion-android-note:before { 822 | content: "\f2ef"; } 823 | 824 | .ion-android-playstore:before { 825 | content: "\f2f0"; } 826 | 827 | .ion-android-printer:before { 828 | content: "\f2f1"; } 829 | 830 | .ion-android-promotion:before { 831 | content: "\f2f2"; } 832 | 833 | .ion-android-reminder:before { 834 | content: "\f2f3"; } 835 | 836 | .ion-android-remove:before { 837 | content: "\f2f4"; } 838 | 839 | .ion-android-search:before { 840 | content: "\f2f5"; } 841 | 842 | .ion-android-send:before { 843 | content: "\f2f6"; } 844 | 845 | .ion-android-settings:before { 846 | content: "\f2f7"; } 847 | 848 | .ion-android-share:before { 849 | content: "\f2f8"; } 850 | 851 | .ion-android-social:before { 852 | content: "\f2fa"; } 853 | 854 | .ion-android-social-user:before { 855 | content: "\f2f9"; } 856 | 857 | .ion-android-sort:before { 858 | content: "\f2fb"; } 859 | 860 | .ion-android-star:before { 861 | content: "\f2fc"; } 862 | 863 | .ion-android-stopwatch:before { 864 | content: "\f2fd"; } 865 | 866 | .ion-android-storage:before { 867 | content: "\f2fe"; } 868 | 869 | .ion-android-system-back:before { 870 | content: "\f2ff"; } 871 | 872 | .ion-android-system-home:before { 873 | content: "\f300"; } 874 | 875 | .ion-android-system-windows:before { 876 | content: "\f301"; } 877 | 878 | .ion-android-timer:before { 879 | content: "\f302"; } 880 | 881 | .ion-android-trash:before { 882 | content: "\f303"; } 883 | 884 | .ion-android-volume:before { 885 | content: "\f304"; } 886 | 887 | .ion-android-wifi:before { 888 | content: "\f305"; } 889 | 890 | .ion-archive:before { 891 | content: "\f102"; } 892 | 893 | .ion-arrow-down-a:before { 894 | content: "\f103"; } 895 | 896 | .ion-arrow-down-b:before { 897 | content: "\f104"; } 898 | 899 | .ion-arrow-down-c:before { 900 | content: "\f105"; } 901 | 902 | .ion-arrow-expand:before { 903 | content: "\f25e"; } 904 | 905 | .ion-arrow-graph-down-left:before { 906 | content: "\f25f"; } 907 | 908 | .ion-arrow-graph-down-right:before { 909 | content: "\f260"; } 910 | 911 | .ion-arrow-graph-up-left:before { 912 | content: "\f261"; } 913 | 914 | .ion-arrow-graph-up-right:before { 915 | content: "\f262"; } 916 | 917 | .ion-arrow-left-a:before { 918 | content: "\f106"; } 919 | 920 | .ion-arrow-left-b:before { 921 | content: "\f107"; } 922 | 923 | .ion-arrow-left-c:before { 924 | content: "\f108"; } 925 | 926 | .ion-arrow-move:before { 927 | content: "\f263"; } 928 | 929 | .ion-arrow-resize:before { 930 | content: "\f264"; } 931 | 932 | .ion-arrow-return-left:before { 933 | content: "\f265"; } 934 | 935 | .ion-arrow-return-right:before { 936 | content: "\f266"; } 937 | 938 | .ion-arrow-right-a:before { 939 | content: "\f109"; } 940 | 941 | .ion-arrow-right-b:before { 942 | content: "\f10a"; } 943 | 944 | .ion-arrow-right-c:before { 945 | content: "\f10b"; } 946 | 947 | .ion-arrow-shrink:before { 948 | content: "\f267"; } 949 | 950 | .ion-arrow-swap:before { 951 | content: "\f268"; } 952 | 953 | .ion-arrow-up-a:before { 954 | content: "\f10c"; } 955 | 956 | .ion-arrow-up-b:before { 957 | content: "\f10d"; } 958 | 959 | .ion-arrow-up-c:before { 960 | content: "\f10e"; } 961 | 962 | .ion-at:before { 963 | content: "\f10f"; } 964 | 965 | .ion-bag:before { 966 | content: "\f110"; } 967 | 968 | .ion-battery-charging:before { 969 | content: "\f111"; } 970 | 971 | .ion-battery-empty:before { 972 | content: "\f112"; } 973 | 974 | .ion-battery-full:before { 975 | content: "\f113"; } 976 | 977 | .ion-battery-half:before { 978 | content: "\f114"; } 979 | 980 | .ion-battery-low:before { 981 | content: "\f115"; } 982 | 983 | .ion-beaker:before { 984 | content: "\f269"; } 985 | 986 | .ion-beer:before { 987 | content: "\f26a"; } 988 | 989 | .ion-bluetooth:before { 990 | content: "\f116"; } 991 | 992 | .ion-bookmark:before { 993 | content: "\f26b"; } 994 | 995 | .ion-briefcase:before { 996 | content: "\f26c"; } 997 | 998 | .ion-bug:before { 999 | content: "\f2be"; } 1000 | 1001 | .ion-calculator:before { 1002 | content: "\f26d"; } 1003 | 1004 | .ion-calendar:before { 1005 | content: "\f117"; } 1006 | 1007 | .ion-camera:before { 1008 | content: "\f118"; } 1009 | 1010 | .ion-card:before { 1011 | content: "\f119"; } 1012 | 1013 | .ion-chatbox:before { 1014 | content: "\f11b"; } 1015 | 1016 | .ion-chatbox-working:before { 1017 | content: "\f11a"; } 1018 | 1019 | .ion-chatboxes:before { 1020 | content: "\f11c"; } 1021 | 1022 | .ion-chatbubble:before { 1023 | content: "\f11e"; } 1024 | 1025 | .ion-chatbubble-working:before { 1026 | content: "\f11d"; } 1027 | 1028 | .ion-chatbubbles:before { 1029 | content: "\f11f"; } 1030 | 1031 | .ion-checkmark:before { 1032 | content: "\f122"; } 1033 | 1034 | .ion-checkmark-circled:before { 1035 | content: "\f120"; } 1036 | 1037 | .ion-checkmark-round:before { 1038 | content: "\f121"; } 1039 | 1040 | .ion-chevron-down:before { 1041 | content: "\f123"; } 1042 | 1043 | .ion-chevron-left:before { 1044 | content: "\f124"; } 1045 | 1046 | .ion-chevron-right:before { 1047 | content: "\f125"; } 1048 | 1049 | .ion-chevron-up:before { 1050 | content: "\f126"; } 1051 | 1052 | .ion-clipboard:before { 1053 | content: "\f127"; } 1054 | 1055 | .ion-clock:before { 1056 | content: "\f26e"; } 1057 | 1058 | .ion-close:before { 1059 | content: "\f12a"; } 1060 | 1061 | .ion-close-circled:before { 1062 | content: "\f128"; } 1063 | 1064 | .ion-close-round:before { 1065 | content: "\f129"; } 1066 | 1067 | .ion-cloud:before { 1068 | content: "\f12b"; } 1069 | 1070 | .ion-code:before { 1071 | content: "\f271"; } 1072 | 1073 | .ion-code-download:before { 1074 | content: "\f26f"; } 1075 | 1076 | .ion-code-working:before { 1077 | content: "\f270"; } 1078 | 1079 | .ion-coffee:before { 1080 | content: "\f272"; } 1081 | 1082 | .ion-compass:before { 1083 | content: "\f273"; } 1084 | 1085 | .ion-compose:before { 1086 | content: "\f12c"; } 1087 | 1088 | .ion-connection-bars:before { 1089 | content: "\f274"; } 1090 | 1091 | .ion-contrast:before { 1092 | content: "\f275"; } 1093 | 1094 | .ion-disc:before { 1095 | content: "\f12d"; } 1096 | 1097 | .ion-document:before { 1098 | content: "\f12f"; } 1099 | 1100 | .ion-document-text:before { 1101 | content: "\f12e"; } 1102 | 1103 | .ion-drag:before { 1104 | content: "\f130"; } 1105 | 1106 | .ion-earth:before { 1107 | content: "\f276"; } 1108 | 1109 | .ion-edit:before { 1110 | content: "\f2bf"; } 1111 | 1112 | .ion-egg:before { 1113 | content: "\f277"; } 1114 | 1115 | .ion-eject:before { 1116 | content: "\f131"; } 1117 | 1118 | .ion-email:before { 1119 | content: "\f132"; } 1120 | 1121 | .ion-eye:before { 1122 | content: "\f133"; } 1123 | 1124 | .ion-eye-disabled:before { 1125 | content: "\f306"; } 1126 | 1127 | .ion-female:before { 1128 | content: "\f278"; } 1129 | 1130 | .ion-filing:before { 1131 | content: "\f134"; } 1132 | 1133 | .ion-film-marker:before { 1134 | content: "\f135"; } 1135 | 1136 | .ion-flag:before { 1137 | content: "\f279"; } 1138 | 1139 | .ion-flash:before { 1140 | content: "\f137"; } 1141 | 1142 | .ion-flash-off:before { 1143 | content: "\f136"; } 1144 | 1145 | .ion-flask:before { 1146 | content: "\f138"; } 1147 | 1148 | .ion-folder:before { 1149 | content: "\f139"; } 1150 | 1151 | .ion-fork:before { 1152 | content: "\f27a"; } 1153 | 1154 | .ion-fork-repo:before { 1155 | content: "\f2c0"; } 1156 | 1157 | .ion-forward:before { 1158 | content: "\f13a"; } 1159 | 1160 | .ion-game-controller-a:before { 1161 | content: "\f13b"; } 1162 | 1163 | .ion-game-controller-b:before { 1164 | content: "\f13c"; } 1165 | 1166 | .ion-gear-a:before { 1167 | content: "\f13d"; } 1168 | 1169 | .ion-gear-b:before { 1170 | content: "\f13e"; } 1171 | 1172 | .ion-grid:before { 1173 | content: "\f13f"; } 1174 | 1175 | .ion-hammer:before { 1176 | content: "\f27b"; } 1177 | 1178 | .ion-headphone:before { 1179 | content: "\f140"; } 1180 | 1181 | .ion-heart:before { 1182 | content: "\f141"; } 1183 | 1184 | .ion-help:before { 1185 | content: "\f143"; } 1186 | 1187 | .ion-help-buoy:before { 1188 | content: "\f27c"; } 1189 | 1190 | .ion-help-circled:before { 1191 | content: "\f142"; } 1192 | 1193 | .ion-home:before { 1194 | content: "\f144"; } 1195 | 1196 | .ion-icecream:before { 1197 | content: "\f27d"; } 1198 | 1199 | .ion-icon-social-google-plus:before { 1200 | content: "\f146"; } 1201 | 1202 | .ion-icon-social-google-plus-outline:before { 1203 | content: "\f145"; } 1204 | 1205 | .ion-image:before { 1206 | content: "\f147"; } 1207 | 1208 | .ion-images:before { 1209 | content: "\f148"; } 1210 | 1211 | .ion-information:before { 1212 | content: "\f14a"; } 1213 | 1214 | .ion-information-circled:before { 1215 | content: "\f149"; } 1216 | 1217 | .ion-ionic:before { 1218 | content: "\f14b"; } 1219 | 1220 | .ion-ios7-alarm:before { 1221 | content: "\f14d"; } 1222 | 1223 | .ion-ios7-alarm-outline:before { 1224 | content: "\f14c"; } 1225 | 1226 | .ion-ios7-albums:before { 1227 | content: "\f14f"; } 1228 | 1229 | .ion-ios7-albums-outline:before { 1230 | content: "\f14e"; } 1231 | 1232 | .ion-ios7-arrow-back:before { 1233 | content: "\f150"; } 1234 | 1235 | .ion-ios7-arrow-down:before { 1236 | content: "\f151"; } 1237 | 1238 | .ion-ios7-arrow-forward:before { 1239 | content: "\f152"; } 1240 | 1241 | .ion-ios7-arrow-left:before { 1242 | content: "\f153"; } 1243 | 1244 | .ion-ios7-arrow-right:before { 1245 | content: "\f154"; } 1246 | 1247 | .ion-ios7-arrow-thin-down:before { 1248 | content: "\f27e"; } 1249 | 1250 | .ion-ios7-arrow-thin-left:before { 1251 | content: "\f27f"; } 1252 | 1253 | .ion-ios7-arrow-thin-right:before { 1254 | content: "\f280"; } 1255 | 1256 | .ion-ios7-arrow-thin-up:before { 1257 | content: "\f281"; } 1258 | 1259 | .ion-ios7-arrow-up:before { 1260 | content: "\f155"; } 1261 | 1262 | .ion-ios7-at:before { 1263 | content: "\f157"; } 1264 | 1265 | .ion-ios7-at-outline:before { 1266 | content: "\f156"; } 1267 | 1268 | .ion-ios7-bell:before { 1269 | content: "\f159"; } 1270 | 1271 | .ion-ios7-bell-outline:before { 1272 | content: "\f158"; } 1273 | 1274 | .ion-ios7-bolt:before { 1275 | content: "\f15b"; } 1276 | 1277 | .ion-ios7-bolt-outline:before { 1278 | content: "\f15a"; } 1279 | 1280 | .ion-ios7-bookmarks:before { 1281 | content: "\f15d"; } 1282 | 1283 | .ion-ios7-bookmarks-outline:before { 1284 | content: "\f15c"; } 1285 | 1286 | .ion-ios7-box:before { 1287 | content: "\f15f"; } 1288 | 1289 | .ion-ios7-box-outline:before { 1290 | content: "\f15e"; } 1291 | 1292 | .ion-ios7-briefcase:before { 1293 | content: "\f283"; } 1294 | 1295 | .ion-ios7-briefcase-outline:before { 1296 | content: "\f282"; } 1297 | 1298 | .ion-ios7-browsers:before { 1299 | content: "\f161"; } 1300 | 1301 | .ion-ios7-browsers-outline:before { 1302 | content: "\f160"; } 1303 | 1304 | .ion-ios7-calculator:before { 1305 | content: "\f285"; } 1306 | 1307 | .ion-ios7-calculator-outline:before { 1308 | content: "\f284"; } 1309 | 1310 | .ion-ios7-calendar:before { 1311 | content: "\f163"; } 1312 | 1313 | .ion-ios7-calendar-outline:before { 1314 | content: "\f162"; } 1315 | 1316 | .ion-ios7-camera:before { 1317 | content: "\f165"; } 1318 | 1319 | .ion-ios7-camera-outline:before { 1320 | content: "\f164"; } 1321 | 1322 | .ion-ios7-cart:before { 1323 | content: "\f167"; } 1324 | 1325 | .ion-ios7-cart-outline:before { 1326 | content: "\f166"; } 1327 | 1328 | .ion-ios7-chatboxes:before { 1329 | content: "\f169"; } 1330 | 1331 | .ion-ios7-chatboxes-outline:before { 1332 | content: "\f168"; } 1333 | 1334 | .ion-ios7-chatbubble:before { 1335 | content: "\f16b"; } 1336 | 1337 | .ion-ios7-chatbubble-outline:before { 1338 | content: "\f16a"; } 1339 | 1340 | .ion-ios7-checkmark:before { 1341 | content: "\f16e"; } 1342 | 1343 | .ion-ios7-checkmark-empty:before { 1344 | content: "\f16c"; } 1345 | 1346 | .ion-ios7-checkmark-outline:before { 1347 | content: "\f16d"; } 1348 | 1349 | .ion-ios7-circle-filled:before { 1350 | content: "\f16f"; } 1351 | 1352 | .ion-ios7-circle-outline:before { 1353 | content: "\f170"; } 1354 | 1355 | .ion-ios7-clock:before { 1356 | content: "\f172"; } 1357 | 1358 | .ion-ios7-clock-outline:before { 1359 | content: "\f171"; } 1360 | 1361 | .ion-ios7-close:before { 1362 | content: "\f2bc"; } 1363 | 1364 | .ion-ios7-close-empty:before { 1365 | content: "\f2bd"; } 1366 | 1367 | .ion-ios7-close-outline:before { 1368 | content: "\f2bb"; } 1369 | 1370 | .ion-ios7-cloud:before { 1371 | content: "\f178"; } 1372 | 1373 | .ion-ios7-cloud-download:before { 1374 | content: "\f174"; } 1375 | 1376 | .ion-ios7-cloud-download-outline:before { 1377 | content: "\f173"; } 1378 | 1379 | .ion-ios7-cloud-outline:before { 1380 | content: "\f175"; } 1381 | 1382 | .ion-ios7-cloud-upload:before { 1383 | content: "\f177"; } 1384 | 1385 | .ion-ios7-cloud-upload-outline:before { 1386 | content: "\f176"; } 1387 | 1388 | .ion-ios7-cloudy:before { 1389 | content: "\f17a"; } 1390 | 1391 | .ion-ios7-cloudy-night:before { 1392 | content: "\f308"; } 1393 | 1394 | .ion-ios7-cloudy-night-outline:before { 1395 | content: "\f307"; } 1396 | 1397 | .ion-ios7-cloudy-outline:before { 1398 | content: "\f179"; } 1399 | 1400 | .ion-ios7-cog:before { 1401 | content: "\f17c"; } 1402 | 1403 | .ion-ios7-cog-outline:before { 1404 | content: "\f17b"; } 1405 | 1406 | .ion-ios7-compose:before { 1407 | content: "\f17e"; } 1408 | 1409 | .ion-ios7-compose-outline:before { 1410 | content: "\f17d"; } 1411 | 1412 | .ion-ios7-contact:before { 1413 | content: "\f180"; } 1414 | 1415 | .ion-ios7-contact-outline:before { 1416 | content: "\f17f"; } 1417 | 1418 | .ion-ios7-copy:before { 1419 | content: "\f182"; } 1420 | 1421 | .ion-ios7-copy-outline:before { 1422 | content: "\f181"; } 1423 | 1424 | .ion-ios7-download:before { 1425 | content: "\f184"; } 1426 | 1427 | .ion-ios7-download-outline:before { 1428 | content: "\f183"; } 1429 | 1430 | .ion-ios7-drag:before { 1431 | content: "\f185"; } 1432 | 1433 | .ion-ios7-email:before { 1434 | content: "\f187"; } 1435 | 1436 | .ion-ios7-email-outline:before { 1437 | content: "\f186"; } 1438 | 1439 | .ion-ios7-eye:before { 1440 | content: "\f189"; } 1441 | 1442 | .ion-ios7-eye-outline:before { 1443 | content: "\f188"; } 1444 | 1445 | .ion-ios7-fastforward:before { 1446 | content: "\f18b"; } 1447 | 1448 | .ion-ios7-fastforward-outline:before { 1449 | content: "\f18a"; } 1450 | 1451 | .ion-ios7-filing:before { 1452 | content: "\f18d"; } 1453 | 1454 | .ion-ios7-filing-outline:before { 1455 | content: "\f18c"; } 1456 | 1457 | .ion-ios7-film:before { 1458 | content: "\f18f"; } 1459 | 1460 | .ion-ios7-film-outline:before { 1461 | content: "\f18e"; } 1462 | 1463 | .ion-ios7-flag:before { 1464 | content: "\f191"; } 1465 | 1466 | .ion-ios7-flag-outline:before { 1467 | content: "\f190"; } 1468 | 1469 | .ion-ios7-folder:before { 1470 | content: "\f193"; } 1471 | 1472 | .ion-ios7-folder-outline:before { 1473 | content: "\f192"; } 1474 | 1475 | .ion-ios7-gear:before { 1476 | content: "\f195"; } 1477 | 1478 | .ion-ios7-gear-outline:before { 1479 | content: "\f194"; } 1480 | 1481 | .ion-ios7-glasses:before { 1482 | content: "\f197"; } 1483 | 1484 | .ion-ios7-glasses-outline:before { 1485 | content: "\f196"; } 1486 | 1487 | .ion-ios7-heart:before { 1488 | content: "\f199"; } 1489 | 1490 | .ion-ios7-heart-outline:before { 1491 | content: "\f198"; } 1492 | 1493 | .ion-ios7-help:before { 1494 | content: "\f19c"; } 1495 | 1496 | .ion-ios7-help-empty:before { 1497 | content: "\f19a"; } 1498 | 1499 | .ion-ios7-help-outline:before { 1500 | content: "\f19b"; } 1501 | 1502 | .ion-ios7-infinite:before { 1503 | content: "\f19e"; } 1504 | 1505 | .ion-ios7-infinite-outline:before { 1506 | content: "\f19d"; } 1507 | 1508 | .ion-ios7-information:before { 1509 | content: "\f1a1"; } 1510 | 1511 | .ion-ios7-information-empty:before { 1512 | content: "\f19f"; } 1513 | 1514 | .ion-ios7-information-outline:before { 1515 | content: "\f1a0"; } 1516 | 1517 | .ion-ios7-ionic-outline:before { 1518 | content: "\f1a2"; } 1519 | 1520 | .ion-ios7-keypad:before { 1521 | content: "\f1a4"; } 1522 | 1523 | .ion-ios7-keypad-outline:before { 1524 | content: "\f1a3"; } 1525 | 1526 | .ion-ios7-lightbulb:before { 1527 | content: "\f287"; } 1528 | 1529 | .ion-ios7-lightbulb-outline:before { 1530 | content: "\f286"; } 1531 | 1532 | .ion-ios7-location:before { 1533 | content: "\f1a6"; } 1534 | 1535 | .ion-ios7-location-outline:before { 1536 | content: "\f1a5"; } 1537 | 1538 | .ion-ios7-locked:before { 1539 | content: "\f1a8"; } 1540 | 1541 | .ion-ios7-locked-outline:before { 1542 | content: "\f1a7"; } 1543 | 1544 | .ion-ios7-medkit:before { 1545 | content: "\f289"; } 1546 | 1547 | .ion-ios7-medkit-outline:before { 1548 | content: "\f288"; } 1549 | 1550 | .ion-ios7-mic:before { 1551 | content: "\f1ab"; } 1552 | 1553 | .ion-ios7-mic-off:before { 1554 | content: "\f1a9"; } 1555 | 1556 | .ion-ios7-mic-outline:before { 1557 | content: "\f1aa"; } 1558 | 1559 | .ion-ios7-minus:before { 1560 | content: "\f1ae"; } 1561 | 1562 | .ion-ios7-minus-empty:before { 1563 | content: "\f1ac"; } 1564 | 1565 | .ion-ios7-minus-outline:before { 1566 | content: "\f1ad"; } 1567 | 1568 | .ion-ios7-monitor:before { 1569 | content: "\f1b0"; } 1570 | 1571 | .ion-ios7-monitor-outline:before { 1572 | content: "\f1af"; } 1573 | 1574 | .ion-ios7-moon:before { 1575 | content: "\f1b2"; } 1576 | 1577 | .ion-ios7-moon-outline:before { 1578 | content: "\f1b1"; } 1579 | 1580 | .ion-ios7-more:before { 1581 | content: "\f1b4"; } 1582 | 1583 | .ion-ios7-more-outline:before { 1584 | content: "\f1b3"; } 1585 | 1586 | .ion-ios7-musical-note:before { 1587 | content: "\f1b5"; } 1588 | 1589 | .ion-ios7-musical-notes:before { 1590 | content: "\f1b6"; } 1591 | 1592 | .ion-ios7-navigate:before { 1593 | content: "\f1b8"; } 1594 | 1595 | .ion-ios7-navigate-outline:before { 1596 | content: "\f1b7"; } 1597 | 1598 | .ion-ios7-paperplane:before { 1599 | content: "\f1ba"; } 1600 | 1601 | .ion-ios7-paperplane-outline:before { 1602 | content: "\f1b9"; } 1603 | 1604 | .ion-ios7-partlysunny:before { 1605 | content: "\f1bc"; } 1606 | 1607 | .ion-ios7-partlysunny-outline:before { 1608 | content: "\f1bb"; } 1609 | 1610 | .ion-ios7-pause:before { 1611 | content: "\f1be"; } 1612 | 1613 | .ion-ios7-pause-outline:before { 1614 | content: "\f1bd"; } 1615 | 1616 | .ion-ios7-people:before { 1617 | content: "\f1c0"; } 1618 | 1619 | .ion-ios7-people-outline:before { 1620 | content: "\f1bf"; } 1621 | 1622 | .ion-ios7-person:before { 1623 | content: "\f1c2"; } 1624 | 1625 | .ion-ios7-person-outline:before { 1626 | content: "\f1c1"; } 1627 | 1628 | .ion-ios7-personadd:before { 1629 | content: "\f1c4"; } 1630 | 1631 | .ion-ios7-personadd-outline:before { 1632 | content: "\f1c3"; } 1633 | 1634 | .ion-ios7-photos:before { 1635 | content: "\f1c6"; } 1636 | 1637 | .ion-ios7-photos-outline:before { 1638 | content: "\f1c5"; } 1639 | 1640 | .ion-ios7-pie:before { 1641 | content: "\f28b"; } 1642 | 1643 | .ion-ios7-pie-outline:before { 1644 | content: "\f28a"; } 1645 | 1646 | .ion-ios7-play:before { 1647 | content: "\f1c8"; } 1648 | 1649 | .ion-ios7-play-outline:before { 1650 | content: "\f1c7"; } 1651 | 1652 | .ion-ios7-plus:before { 1653 | content: "\f1cb"; } 1654 | 1655 | .ion-ios7-plus-empty:before { 1656 | content: "\f1c9"; } 1657 | 1658 | .ion-ios7-plus-outline:before { 1659 | content: "\f1ca"; } 1660 | 1661 | .ion-ios7-pricetag:before { 1662 | content: "\f28d"; } 1663 | 1664 | .ion-ios7-pricetag-outline:before { 1665 | content: "\f28c"; } 1666 | 1667 | .ion-ios7-printer:before { 1668 | content: "\f1cd"; } 1669 | 1670 | .ion-ios7-printer-outline:before { 1671 | content: "\f1cc"; } 1672 | 1673 | .ion-ios7-rainy:before { 1674 | content: "\f1cf"; } 1675 | 1676 | .ion-ios7-rainy-outline:before { 1677 | content: "\f1ce"; } 1678 | 1679 | .ion-ios7-recording:before { 1680 | content: "\f1d1"; } 1681 | 1682 | .ion-ios7-recording-outline:before { 1683 | content: "\f1d0"; } 1684 | 1685 | .ion-ios7-redo:before { 1686 | content: "\f1d3"; } 1687 | 1688 | .ion-ios7-redo-outline:before { 1689 | content: "\f1d2"; } 1690 | 1691 | .ion-ios7-refresh:before { 1692 | content: "\f1d6"; } 1693 | 1694 | .ion-ios7-refresh-empty:before { 1695 | content: "\f1d4"; } 1696 | 1697 | .ion-ios7-refresh-outline:before { 1698 | content: "\f1d5"; } 1699 | 1700 | .ion-ios7-reload:before, .ion-ios7-reloading:before { 1701 | content: "\f28e"; } 1702 | 1703 | .ion-ios7-rewind:before { 1704 | content: "\f1d8"; } 1705 | 1706 | .ion-ios7-rewind-outline:before { 1707 | content: "\f1d7"; } 1708 | 1709 | .ion-ios7-search:before { 1710 | content: "\f1da"; } 1711 | 1712 | .ion-ios7-search-strong:before { 1713 | content: "\f1d9"; } 1714 | 1715 | .ion-ios7-skipbackward:before { 1716 | content: "\f1dc"; } 1717 | 1718 | .ion-ios7-skipbackward-outline:before { 1719 | content: "\f1db"; } 1720 | 1721 | .ion-ios7-skipforward:before { 1722 | content: "\f1de"; } 1723 | 1724 | .ion-ios7-skipforward-outline:before { 1725 | content: "\f1dd"; } 1726 | 1727 | .ion-ios7-snowy:before { 1728 | content: "\f309"; } 1729 | 1730 | .ion-ios7-speedometer:before { 1731 | content: "\f290"; } 1732 | 1733 | .ion-ios7-speedometer-outline:before { 1734 | content: "\f28f"; } 1735 | 1736 | .ion-ios7-star:before { 1737 | content: "\f1e0"; } 1738 | 1739 | .ion-ios7-star-outline:before { 1740 | content: "\f1df"; } 1741 | 1742 | .ion-ios7-stopwatch:before { 1743 | content: "\f1e2"; } 1744 | 1745 | .ion-ios7-stopwatch-outline:before { 1746 | content: "\f1e1"; } 1747 | 1748 | .ion-ios7-sunny:before { 1749 | content: "\f1e4"; } 1750 | 1751 | .ion-ios7-sunny-outline:before { 1752 | content: "\f1e3"; } 1753 | 1754 | .ion-ios7-telephone:before { 1755 | content: "\f1e6"; } 1756 | 1757 | .ion-ios7-telephone-outline:before { 1758 | content: "\f1e5"; } 1759 | 1760 | .ion-ios7-thunderstorm:before { 1761 | content: "\f1e8"; } 1762 | 1763 | .ion-ios7-thunderstorm-outline:before { 1764 | content: "\f1e7"; } 1765 | 1766 | .ion-ios7-time:before { 1767 | content: "\f292"; } 1768 | 1769 | .ion-ios7-time-outline:before { 1770 | content: "\f291"; } 1771 | 1772 | .ion-ios7-timer:before { 1773 | content: "\f1ea"; } 1774 | 1775 | .ion-ios7-timer-outline:before { 1776 | content: "\f1e9"; } 1777 | 1778 | .ion-ios7-trash:before { 1779 | content: "\f1ec"; } 1780 | 1781 | .ion-ios7-trash-outline:before { 1782 | content: "\f1eb"; } 1783 | 1784 | .ion-ios7-undo:before { 1785 | content: "\f1ee"; } 1786 | 1787 | .ion-ios7-undo-outline:before { 1788 | content: "\f1ed"; } 1789 | 1790 | .ion-ios7-unlocked:before { 1791 | content: "\f1f0"; } 1792 | 1793 | .ion-ios7-unlocked-outline:before { 1794 | content: "\f1ef"; } 1795 | 1796 | .ion-ios7-upload:before { 1797 | content: "\f1f2"; } 1798 | 1799 | .ion-ios7-upload-outline:before { 1800 | content: "\f1f1"; } 1801 | 1802 | .ion-ios7-videocam:before { 1803 | content: "\f1f4"; } 1804 | 1805 | .ion-ios7-videocam-outline:before { 1806 | content: "\f1f3"; } 1807 | 1808 | .ion-ios7-volume-high:before { 1809 | content: "\f1f5"; } 1810 | 1811 | .ion-ios7-volume-low:before { 1812 | content: "\f1f6"; } 1813 | 1814 | .ion-ios7-wineglass:before { 1815 | content: "\f294"; } 1816 | 1817 | .ion-ios7-wineglass-outline:before { 1818 | content: "\f293"; } 1819 | 1820 | .ion-ios7-world:before { 1821 | content: "\f1f8"; } 1822 | 1823 | .ion-ios7-world-outline:before { 1824 | content: "\f1f7"; } 1825 | 1826 | .ion-ipad:before { 1827 | content: "\f1f9"; } 1828 | 1829 | .ion-iphone:before { 1830 | content: "\f1fa"; } 1831 | 1832 | .ion-ipod:before { 1833 | content: "\f1fb"; } 1834 | 1835 | .ion-jet:before { 1836 | content: "\f295"; } 1837 | 1838 | .ion-key:before { 1839 | content: "\f296"; } 1840 | 1841 | .ion-knife:before { 1842 | content: "\f297"; } 1843 | 1844 | .ion-laptop:before { 1845 | content: "\f1fc"; } 1846 | 1847 | .ion-leaf:before { 1848 | content: "\f1fd"; } 1849 | 1850 | .ion-levels:before { 1851 | content: "\f298"; } 1852 | 1853 | .ion-lightbulb:before { 1854 | content: "\f299"; } 1855 | 1856 | .ion-link:before { 1857 | content: "\f1fe"; } 1858 | 1859 | .ion-load-a:before, .ion-loading-a:before { 1860 | content: "\f29a"; } 1861 | 1862 | .ion-load-b:before, .ion-loading-b:before { 1863 | content: "\f29b"; } 1864 | 1865 | .ion-load-c:before, .ion-loading-c:before { 1866 | content: "\f29c"; } 1867 | 1868 | .ion-load-d:before, .ion-loading-d:before { 1869 | content: "\f29d"; } 1870 | 1871 | .ion-location:before { 1872 | content: "\f1ff"; } 1873 | 1874 | .ion-locked:before { 1875 | content: "\f200"; } 1876 | 1877 | .ion-log-in:before { 1878 | content: "\f29e"; } 1879 | 1880 | .ion-log-out:before { 1881 | content: "\f29f"; } 1882 | 1883 | .ion-loop:before, .ion-looping:before { 1884 | content: "\f201"; } 1885 | 1886 | .ion-magnet:before { 1887 | content: "\f2a0"; } 1888 | 1889 | .ion-male:before { 1890 | content: "\f2a1"; } 1891 | 1892 | .ion-man:before { 1893 | content: "\f202"; } 1894 | 1895 | .ion-map:before { 1896 | content: "\f203"; } 1897 | 1898 | .ion-medkit:before { 1899 | content: "\f2a2"; } 1900 | 1901 | .ion-mic-a:before { 1902 | content: "\f204"; } 1903 | 1904 | .ion-mic-b:before { 1905 | content: "\f205"; } 1906 | 1907 | .ion-mic-c:before { 1908 | content: "\f206"; } 1909 | 1910 | .ion-minus:before { 1911 | content: "\f209"; } 1912 | 1913 | .ion-minus-circled:before { 1914 | content: "\f207"; } 1915 | 1916 | .ion-minus-round:before { 1917 | content: "\f208"; } 1918 | 1919 | .ion-model-s:before { 1920 | content: "\f2c1"; } 1921 | 1922 | .ion-monitor:before { 1923 | content: "\f20a"; } 1924 | 1925 | .ion-more:before { 1926 | content: "\f20b"; } 1927 | 1928 | .ion-music-note:before { 1929 | content: "\f20c"; } 1930 | 1931 | .ion-navicon:before { 1932 | content: "\f20e"; } 1933 | 1934 | .ion-navicon-round:before { 1935 | content: "\f20d"; } 1936 | 1937 | .ion-navigate:before { 1938 | content: "\f2a3"; } 1939 | 1940 | .ion-no-smoking:before { 1941 | content: "\f2c2"; } 1942 | 1943 | .ion-nuclear:before { 1944 | content: "\f2a4"; } 1945 | 1946 | .ion-paper-airplane:before { 1947 | content: "\f2c3"; } 1948 | 1949 | .ion-paperclip:before { 1950 | content: "\f20f"; } 1951 | 1952 | .ion-pause:before { 1953 | content: "\f210"; } 1954 | 1955 | .ion-person:before { 1956 | content: "\f213"; } 1957 | 1958 | .ion-person-add:before { 1959 | content: "\f211"; } 1960 | 1961 | .ion-person-stalker:before { 1962 | content: "\f212"; } 1963 | 1964 | .ion-pie-graph:before { 1965 | content: "\f2a5"; } 1966 | 1967 | .ion-pin:before { 1968 | content: "\f2a6"; } 1969 | 1970 | .ion-pinpoint:before { 1971 | content: "\f2a7"; } 1972 | 1973 | .ion-pizza:before { 1974 | content: "\f2a8"; } 1975 | 1976 | .ion-plane:before { 1977 | content: "\f214"; } 1978 | 1979 | .ion-play:before { 1980 | content: "\f215"; } 1981 | 1982 | .ion-playstation:before { 1983 | content: "\f30a"; } 1984 | 1985 | .ion-plus:before { 1986 | content: "\f218"; } 1987 | 1988 | .ion-plus-circled:before { 1989 | content: "\f216"; } 1990 | 1991 | .ion-plus-round:before { 1992 | content: "\f217"; } 1993 | 1994 | .ion-pound:before { 1995 | content: "\f219"; } 1996 | 1997 | .ion-power:before { 1998 | content: "\f2a9"; } 1999 | 2000 | .ion-pricetag:before { 2001 | content: "\f2aa"; } 2002 | 2003 | .ion-pricetags:before { 2004 | content: "\f2ab"; } 2005 | 2006 | .ion-printer:before { 2007 | content: "\f21a"; } 2008 | 2009 | .ion-radio-waves:before { 2010 | content: "\f2ac"; } 2011 | 2012 | .ion-record:before { 2013 | content: "\f21b"; } 2014 | 2015 | .ion-refresh:before, .ion-refreshing:before { 2016 | content: "\f21c"; } 2017 | 2018 | .ion-reply:before { 2019 | content: "\f21e"; } 2020 | 2021 | .ion-reply-all:before { 2022 | content: "\f21d"; } 2023 | 2024 | .ion-search:before { 2025 | content: "\f21f"; } 2026 | 2027 | .ion-settings:before { 2028 | content: "\f2ad"; } 2029 | 2030 | .ion-share:before { 2031 | content: "\f220"; } 2032 | 2033 | .ion-shuffle:before { 2034 | content: "\f221"; } 2035 | 2036 | .ion-skip-backward:before { 2037 | content: "\f222"; } 2038 | 2039 | .ion-skip-forward:before { 2040 | content: "\f223"; } 2041 | 2042 | .ion-social-android:before { 2043 | content: "\f225"; } 2044 | 2045 | .ion-social-android-outline:before { 2046 | content: "\f224"; } 2047 | 2048 | .ion-social-apple:before { 2049 | content: "\f227"; } 2050 | 2051 | .ion-social-apple-outline:before { 2052 | content: "\f226"; } 2053 | 2054 | .ion-social-bitcoin:before { 2055 | content: "\f2af"; } 2056 | 2057 | .ion-social-bitcoin-outline:before { 2058 | content: "\f2ae"; } 2059 | 2060 | .ion-social-buffer:before { 2061 | content: "\f229"; } 2062 | 2063 | .ion-social-buffer-outline:before { 2064 | content: "\f228"; } 2065 | 2066 | .ion-social-designernews:before { 2067 | content: "\f22b"; } 2068 | 2069 | .ion-social-designernews-outline:before { 2070 | content: "\f22a"; } 2071 | 2072 | .ion-social-dribbble:before { 2073 | content: "\f22d"; } 2074 | 2075 | .ion-social-dribbble-outline:before { 2076 | content: "\f22c"; } 2077 | 2078 | .ion-social-dropbox:before { 2079 | content: "\f22f"; } 2080 | 2081 | .ion-social-dropbox-outline:before { 2082 | content: "\f22e"; } 2083 | 2084 | .ion-social-facebook:before { 2085 | content: "\f231"; } 2086 | 2087 | .ion-social-facebook-outline:before { 2088 | content: "\f230"; } 2089 | 2090 | .ion-social-freebsd-devil:before { 2091 | content: "\f2c4"; } 2092 | 2093 | .ion-social-github:before { 2094 | content: "\f233"; } 2095 | 2096 | .ion-social-github-outline:before { 2097 | content: "\f232"; } 2098 | 2099 | .ion-social-googleplus:before { 2100 | content: "\f235"; } 2101 | 2102 | .ion-social-googleplus-outline:before { 2103 | content: "\f234"; } 2104 | 2105 | .ion-social-hackernews:before { 2106 | content: "\f237"; } 2107 | 2108 | .ion-social-hackernews-outline:before { 2109 | content: "\f236"; } 2110 | 2111 | .ion-social-linkedin:before { 2112 | content: "\f239"; } 2113 | 2114 | .ion-social-linkedin-outline:before { 2115 | content: "\f238"; } 2116 | 2117 | .ion-social-pinterest:before { 2118 | content: "\f2b1"; } 2119 | 2120 | .ion-social-pinterest-outline:before { 2121 | content: "\f2b0"; } 2122 | 2123 | .ion-social-reddit:before { 2124 | content: "\f23b"; } 2125 | 2126 | .ion-social-reddit-outline:before { 2127 | content: "\f23a"; } 2128 | 2129 | .ion-social-rss:before { 2130 | content: "\f23d"; } 2131 | 2132 | .ion-social-rss-outline:before { 2133 | content: "\f23c"; } 2134 | 2135 | .ion-social-skype:before { 2136 | content: "\f23f"; } 2137 | 2138 | .ion-social-skype-outline:before { 2139 | content: "\f23e"; } 2140 | 2141 | .ion-social-tumblr:before { 2142 | content: "\f241"; } 2143 | 2144 | .ion-social-tumblr-outline:before { 2145 | content: "\f240"; } 2146 | 2147 | .ion-social-tux:before { 2148 | content: "\f2c5"; } 2149 | 2150 | .ion-social-twitter:before { 2151 | content: "\f243"; } 2152 | 2153 | .ion-social-twitter-outline:before { 2154 | content: "\f242"; } 2155 | 2156 | .ion-social-vimeo:before { 2157 | content: "\f245"; } 2158 | 2159 | .ion-social-vimeo-outline:before { 2160 | content: "\f244"; } 2161 | 2162 | .ion-social-windows:before { 2163 | content: "\f247"; } 2164 | 2165 | .ion-social-windows-outline:before { 2166 | content: "\f246"; } 2167 | 2168 | .ion-social-wordpress:before { 2169 | content: "\f249"; } 2170 | 2171 | .ion-social-wordpress-outline:before { 2172 | content: "\f248"; } 2173 | 2174 | .ion-social-yahoo:before { 2175 | content: "\f24b"; } 2176 | 2177 | .ion-social-yahoo-outline:before { 2178 | content: "\f24a"; } 2179 | 2180 | .ion-social-youtube:before { 2181 | content: "\f24d"; } 2182 | 2183 | .ion-social-youtube-outline:before { 2184 | content: "\f24c"; } 2185 | 2186 | .ion-speakerphone:before { 2187 | content: "\f2b2"; } 2188 | 2189 | .ion-speedometer:before { 2190 | content: "\f2b3"; } 2191 | 2192 | .ion-spoon:before { 2193 | content: "\f2b4"; } 2194 | 2195 | .ion-star:before { 2196 | content: "\f24e"; } 2197 | 2198 | .ion-stats-bars:before { 2199 | content: "\f2b5"; } 2200 | 2201 | .ion-steam:before { 2202 | content: "\f30b"; } 2203 | 2204 | .ion-stop:before { 2205 | content: "\f24f"; } 2206 | 2207 | .ion-thermometer:before { 2208 | content: "\f2b6"; } 2209 | 2210 | .ion-thumbsdown:before { 2211 | content: "\f250"; } 2212 | 2213 | .ion-thumbsup:before { 2214 | content: "\f251"; } 2215 | 2216 | .ion-trash-a:before { 2217 | content: "\f252"; } 2218 | 2219 | .ion-trash-b:before { 2220 | content: "\f253"; } 2221 | 2222 | .ion-umbrella:before { 2223 | content: "\f2b7"; } 2224 | 2225 | .ion-unlocked:before { 2226 | content: "\f254"; } 2227 | 2228 | .ion-upload:before { 2229 | content: "\f255"; } 2230 | 2231 | .ion-usb:before { 2232 | content: "\f2b8"; } 2233 | 2234 | .ion-videocamera:before { 2235 | content: "\f256"; } 2236 | 2237 | .ion-volume-high:before { 2238 | content: "\f257"; } 2239 | 2240 | .ion-volume-low:before { 2241 | content: "\f258"; } 2242 | 2243 | .ion-volume-medium:before { 2244 | content: "\f259"; } 2245 | 2246 | .ion-volume-mute:before { 2247 | content: "\f25a"; } 2248 | 2249 | .ion-waterdrop:before { 2250 | content: "\f25b"; } 2251 | 2252 | .ion-wifi:before { 2253 | content: "\f25c"; } 2254 | 2255 | .ion-wineglass:before { 2256 | content: "\f2b9"; } 2257 | 2258 | .ion-woman:before { 2259 | content: "\f25d"; } 2260 | 2261 | .ion-wrench:before { 2262 | content: "\f2ba"; } 2263 | 2264 | .ion-xbox:before { 2265 | content: "\f30c"; } 2266 | 2267 | html { 2268 | height: 100%; } 2269 | 2270 | body { 2271 | min-height: 100%; } 2272 | 2273 | body#card { 2274 | background: #f1f1fa; 2275 | padding-top: 4em; 2276 | font-size: 0.9em; 2277 | text-align: center; } 2278 | 2279 | .tooltip { 2280 | font-weight: 600; 2281 | cursor: help; } 2282 | 2283 | #title { 2284 | text-align: center; 2285 | margin-bottom: 3em; } 2286 | #title h1 { 2287 | font-size: 1.2em; } 2288 | #title img { 2289 | max-width: 70px; } 2290 | 2291 | .row.section { 2292 | padding-top: 5em; 2293 | padding-bottom: 5em; 2294 | border-bottom: 1px solid #ddd; } 2295 | .row.section#header { 2296 | border-color: #359173; } 2297 | 2298 | #header { 2299 | border-bottom: 1px solid #ddd; } 2300 | #header i { 2301 | font-size: 4em; 2302 | color: #1b3544; } 2303 | #header .next { 2304 | opacity: 0.5; } 2305 | #header .success i { 2306 | color: #359173; } 2307 | #header .error i { 2308 | color: #ff1708; } 2309 | #header .done { 2310 | opacity: 0.3; } 2311 | #header .done p { 2312 | text-decoration: line-through; } 2313 | #header .done i, #header .current i { 2314 | color: #359173; } 2315 | 2316 | .container { 2317 | padding-top: 1em; 2318 | padding-bottom: 1em; } 2319 | @media (max-width: 760px) { 2320 | .container { 2321 | padding-bottom: 0 !important; 2322 | padding-top: 0 !important; } } 2323 | .container.block { 2324 | padding-bottom: 1.5em; 2325 | padding-top: 1.5em; } 2326 | @media (max-width: 760px) { 2327 | .container.block { 2328 | padding-top: 0 !important; 2329 | padding-bottom: 0 !important; } } 2330 | .container.block:first-child { 2331 | padding-top: 0; } 2332 | .container.block:last-child { 2333 | padding-bottom: 0; } 2334 | .container.card { 2335 | max-width: 500px; } 2336 | 2337 | .card { 2338 | padding: 0.9em; 2339 | background: #fff; 2340 | border: 1px solid #dddddd; } 2341 | .card h1 { 2342 | font-size: 1.8em; } 2343 | 2344 | .row.grey { 2345 | background: #f1f1fa; } 2346 | 2347 | p { 2348 | line-height: 1.5em; } 2349 | 2350 | p.code { 2351 | font-size: 0.8em; 2352 | font-family: "source-code-pro"; 2353 | border: 1px solid #dddddd; 2354 | background: #fff; } 2355 | @media (max-width: 760px) { 2356 | p.code { 2357 | overflow: auto; } } 2358 | 2359 | span.code { 2360 | font-family: "source-code-pro"; 2361 | display: inline-block; 2362 | padding: 0 0.2em; 2363 | border: 1px solid #dddddd; 2364 | background: #fff; 2365 | font-size: 0.9em; } 2366 | 2367 | input, textarea { 2368 | font-size: 0.8em; 2369 | font-family: "source-code-pro"; 2370 | border: 1px solid #dddddd; 2371 | background: #fff; 2372 | padding: 0.9em; 2373 | transition: all 0.3s ease-in-out; 2374 | width: 100%; } 2375 | input:focus, textarea:focus { 2376 | border-color: #359173; 2377 | outline: none; 2378 | box-shadow: 0 0 5px 1px #359173; } 2379 | 2380 | form input, form textarea { 2381 | margin-bottom: 0.5em; } 2382 | 2383 | button, a.button { 2384 | font-size: 1em; 2385 | text-transform: uppercase; 2386 | font-weight: 600; 2387 | border: 2px solid #359173; 2388 | color: #359173; 2389 | background: transparent; 2390 | line-height: 1em; 2391 | padding: 0.6em 0.9em; 2392 | transition: all 0.3s ease-in-out; } 2393 | button:hover, a.button:hover { 2394 | border-color: #359173; } 2395 | 2396 | .animate { 2397 | -moz-animation-iteration-count: once; 2398 | -moz-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22); 2399 | -moz-animation-duration: 0.4s; 2400 | -webkit-animation-iteration-count: once; 2401 | -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22); 2402 | -webkit-animation-duration: 0.4s; } 2403 | .animate.dropIn { 2404 | -moz-animation-name: dropIn; 2405 | -webkit-animation-name: dropIn; } 2406 | 2407 | @-webkit-keyframes fadeIn { 2408 | 0% { 2409 | -webkit-transform: translate3d(0, 0, 0); 2410 | -moz-transform: translate3d(0, 0, 0); 2411 | opacity: 0; } 2412 | 2413 | 100% { 2414 | -webkit-transform: translate3d(0, 0, 0); 2415 | -moz-transform: translate3d(0, 0, 0); 2416 | opacity: 1; } } 2417 | 2418 | @-webkit-keyframes dropIn { 2419 | 0% { 2420 | opacity: 0; 2421 | -webkit-transform: translate3d(0, -150px, 0); 2422 | -moz-transform: translate3d(0, -150px, 0); } 2423 | 2424 | 100% { 2425 | opacity: 1; 2426 | -webkit-transform: translate3d(0, 0, 0); 2427 | -moz-transform: translate3d(0, 0, 0); } } 2428 | 2429 | @-webkit-keyframes dropInLong { 2430 | 0% { 2431 | opacity: 0; 2432 | -webkit-transform: translate3d(0, -450px, 0); 2433 | -moz-transform: translate3d(0, -450px, 0); } 2434 | 2435 | 100% { 2436 | opacity: 1; 2437 | -webkit-transform: translate3d(0, 0, 0); 2438 | -moz-transform: translate3d(0, 0, 0); } } 2439 | 2440 | @-webkit-keyframes rotate { 2441 | 100% { 2442 | -webkit-transform: rotate(45deg); 2443 | -moz-transform: rotate(45deg); } } 2444 | 2445 | @-webkit-keyframes rotateBack { 2446 | 100% { 2447 | -webkit-transform: rotate(0deg); 2448 | -moz-transform: rotate(0deg); } } 2449 | 2450 | .overlay { 2451 | position: fixed; 2452 | width: 100%; 2453 | height: 100%; 2454 | top: -10000px; 2455 | left: -10000px; 2456 | opacity: 0; 2457 | transition: opacity 0.4s linear; 2458 | background: rgba(255, 255, 255, 0.96); } 2459 | 2460 | body.showOverlay { 2461 | overflow: hidden; } 2462 | body.showOverlay .overlay { 2463 | top: 0; 2464 | left: 0; 2465 | opacity: 1; } 2466 | body.showOverlay .overlay iframe { 2467 | -webkit-animation-iteration-count: once; 2468 | -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22); 2469 | -webkit-animation-duration: 0.4s; 2470 | -moz-animation-name: dropInLong; 2471 | -webkit-animation-name: dropInLong; } 2472 | 2473 | .toggleOverlay { 2474 | cursor: pointer; 2475 | position: fixed; 2476 | top: 20px; 2477 | left: 20px; 2478 | font-size: 2.2em; 2479 | font-weight: 600; 2480 | -moz-animation-iteration-count: once; 2481 | -moz-animation-fill-mode: forwards; 2482 | -moz-animation-timing-function: linear; 2483 | -moz-animation-duration: 0.2s; 2484 | -webkit-animation-iteration-count: once; 2485 | -webkit-animation-fill-mode: forwards; 2486 | -webkit-animation-timing-function: linear; 2487 | -webkit-animation-duration: 0.2s; } 2488 | 2489 | body.showOverlay .toggleOverlay { 2490 | -moz-animation-name: rotate; 2491 | -webkit-animation-name: rotate; } 2492 | -------------------------------------------------------------------------------- /forms/static/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braceio/forms/deb12f37447d6167ad284ae68085a02454c8f649/forms/static/fonts/ionicons.eot -------------------------------------------------------------------------------- /forms/static/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braceio/forms/deb12f37447d6167ad284ae68085a02454c8f649/forms/static/fonts/ionicons.ttf -------------------------------------------------------------------------------- /forms/static/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braceio/forms/deb12f37447d6167ad284ae68085a02454c8f649/forms/static/fonts/ionicons.woff -------------------------------------------------------------------------------- /forms/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braceio/forms/deb12f37447d6167ad284ae68085a02454c8f649/forms/static/img/favicon.ico -------------------------------------------------------------------------------- /forms/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braceio/forms/deb12f37447d6167ad284ae68085a02454c8f649/forms/static/img/logo.png -------------------------------------------------------------------------------- /forms/static/scss/formspree.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | -moz-box-sizing: border-box; 4 | -webkit-box-sizing: border-box; 5 | } 6 | 7 | /* base stuff */ 8 | 9 | body, html { 10 | height: 100%; 11 | min-height: 100%; 12 | } 13 | 14 | body { 15 | background: $accent-blue; 16 | text-align: center; 17 | padding: 50px; 18 | @media (max-width: 760px) { 19 | padding: 10px; 20 | } 21 | } 22 | 23 | .container.card { 24 | background: #fff; 25 | padding: 2em; 26 | border: 1px solid $accent; 27 | margin-bottom: 1.5em; 28 | text-align: center; 29 | } 30 | 31 | #header { 32 | margin-bottom: 1.5em; 33 | padding-bottom: 1.5em; 34 | border-bottom: 1px solid $accent; 35 | @media (max-width: 760px) { 36 | display: none; 37 | } 38 | } 39 | 40 | .header { 41 | i { 42 | font-size: 3.5em; 43 | color: $green; 44 | } 45 | 46 | &.info { 47 | i { 48 | color: $dark-blue; 49 | } 50 | } 51 | 52 | &.done { 53 | //opacity: 0.5; 54 | p { 55 | text-decoration: line-through; 56 | } 57 | i { 58 | color: $accent-blue; 59 | } 60 | } 61 | &.current { 62 | i { 63 | color: $dark-green; 64 | } 65 | } 66 | 67 | &.success { 68 | i { 69 | color: $dark-green; 70 | font-size: 6em; 71 | } 72 | } 73 | 74 | &.error { 75 | i { 76 | color: $red; 77 | font-size: 3.5em; 78 | } 79 | } 80 | } 81 | 82 | h1 { 83 | font-size: 1.7em; 84 | } 85 | 86 | .animate { 87 | display: inline; 88 | position: relative; 89 | -moz-animation-iteration-count: 1; 90 | -moz-animation-timing-function: linear; 91 | -moz-animation-duration: 0.4s; 92 | 93 | -webkit-animation-iteration-count: 1; 94 | -webkit-animation-timing-function: linear; 95 | -webkit-animation-duration: 0.4s; 96 | 97 | &.dropIn { 98 | -moz-animation-name: dropIn; 99 | -webkit-animation-name: dropIn; 100 | } 101 | 102 | } 103 | 104 | @-webkit-keyframes fadeIn { 105 | 0% { 106 | -webkit-transform: translate3d(0, 0, 0); 107 | -moz-transform: translate3d(0, 0, 0); 108 | opacity: 0; 109 | } 110 | 100% { 111 | -webkit-transform: translate3d(0, 0, 0); 112 | -moz-transform: translate3d(0, 0, 0); 113 | opacity: 1; 114 | } 115 | } 116 | 117 | @-webkit-keyframes dropIn { 118 | 0% { 119 | opacity: 0; 120 | -webkit-transform: translate3d(0, -150px, 0); 121 | -moz-transform: translate3d(0, -150px, 0); 122 | } 123 | 100% { 124 | opacity: 1; 125 | -webkit-transform: translate3d(0, 0, 0); 126 | -moz-transform: translate3d(0, 0, 0); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /forms/static/scss/grid.scss: -------------------------------------------------------------------------------- 1 | .row { 2 | width: 100%; 3 | &:after { 4 | content: "."; 5 | display: block; 6 | clear: both; 7 | visibility: hidden; 8 | line-height: 0; 9 | height: 0; 10 | } 11 | } 12 | 13 | .container { 14 | width: 100%; 15 | max-width: 950px; 16 | margin: 0 auto; 17 | 18 | &:after { 19 | content: "."; 20 | display: block; 21 | clear: both; 22 | visibility: hidden; 23 | line-height: 0; 24 | height: 0; 25 | } 26 | 27 | &.narrow { 28 | max-width: 600px; 29 | } 30 | 31 | @media (max-width: 760px) { 32 | max-width: 100% !important; 33 | } 34 | } 35 | 36 | @mixin col { 37 | float: left; 38 | padding: 0 20px; 39 | 40 | @media (max-width: 760px) { 41 | width: 100% !important; 42 | margin-bottom: 20px !important; 43 | } 44 | 45 | } 46 | 47 | .col-1-1 { 48 | @include col; 49 | width: 100%; 50 | } 51 | 52 | .col-1-2 { 53 | @include col; 54 | width: 50%; 55 | } 56 | 57 | .col-1-3 { 58 | @include col; 59 | width: 33.33%; 60 | } 61 | 62 | .col-2-3 { 63 | @include col; 64 | width: 66.66%; 65 | } 66 | 67 | .col-1-4 { 68 | @include col; 69 | width: 25%; 70 | } 71 | 72 | .col-3-4 { 73 | @include col; 74 | width: 75%; 75 | } 76 | 77 | .col-2-5 { 78 | @include col; 79 | width: 40%; 80 | } 81 | 82 | .col-3-5 { 83 | @include col; 84 | width: 60%; 85 | } -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-always.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-always.scss 3 | * 4 | * Defines a persisted tooltip which shows always. 5 | * 6 | * Classes added: 7 | * 1) hint--always 8 | * 9 | */ 10 | 11 | .#{$prefix}always { 12 | &:after, &:before { 13 | opacity: 1; 14 | visibility: visible; 15 | } 16 | 17 | &.#{$prefix}top { 18 | @include set-margin('translateY', -1); 19 | } 20 | 21 | &.#{$prefix}bottom { 22 | @include set-margin('translateY', 1); 23 | } 24 | 25 | &.#{$prefix}left { 26 | @include set-margin('translateX', -1); 27 | } 28 | 29 | &.#{$prefix}right { 30 | @include set-margin('translateX', 1); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-color-types.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-color-types.scss 3 | * 4 | * Contains tooltips of various types based on color differences. 5 | * 6 | * Classes added: 7 | * 1) hint--error 8 | * 2) hint--warning 9 | * 3) hint--info 10 | * 4) hint--success 11 | * 12 | */ 13 | 14 | 15 | // mixin to generate different color style tooltips 16 | @mixin hint-type($color) { 17 | &:after { 18 | background-color: $color; 19 | //text-shadow: 0 -1px 0px darken($color, $textShadowDarkenAmount); 20 | } 21 | 22 | // generate arrow color style 23 | @include arrow-border-color($color); 24 | } 25 | 26 | /** 27 | * Error 28 | */ 29 | .#{$prefix}error { 30 | @include hint-type($errorColor); 31 | } 32 | 33 | /** 34 | * Warning 35 | */ 36 | .#{$prefix}warning { 37 | @include hint-type($warningColor) 38 | } 39 | 40 | /** 41 | * Info 42 | */ 43 | .#{$prefix}info { 44 | @include hint-type($infoColor) 45 | } 46 | 47 | /** 48 | * Success 49 | */ 50 | .#{$prefix}success { 51 | @include hint-type($successColor) 52 | } 53 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-core.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-core.scss 3 | * 4 | * Defines the basic styling for the tooltip. 5 | * Each tooltip is made of 2 parts: 6 | * 1) body (:after) 7 | * 2) arrow (:before) 8 | * 9 | * Classes added: 10 | * 1) hint 11 | */ 12 | 13 | .hint, [data-hint] { 14 | position: relative; 15 | display: inline-block; 16 | 17 | &:before, &:after { 18 | position: absolute; 19 | 20 | // HACK: Trigger hardware accelerated rendering, otherwise transform was not 21 | // working on a hidden element 22 | -webkit-transform: translate3d(0, 0, 0); 23 | -moz-transform: translate3d(0, 0, 0); 24 | transform: translate3d(0, 0, 0); 25 | 26 | // HACK: visibility is set to hidden because IE & Opera don't support 27 | // pointer-events on HTML content yet because of which hovering a hidden tooltip 28 | // shows the tooltip. 29 | visibility: hidden; 30 | opacity: 0; 31 | z-index: $zIndex; 32 | // shouldn't receive pointer events, otherwise even hovering tooltip will make it appear 33 | pointer-events: none; 34 | 35 | -webkit-transition: 0.3s ease; 36 | -moz-transition: 0.3s ease; 37 | transition: 0.3s ease; 38 | } 39 | 40 | &:hover:before, &:hover:after, 41 | &:focus:before, &:focus:after { 42 | visibility: visible; 43 | opacity: 1; 44 | } 45 | 46 | /** 47 | * tooltip arrow 48 | */ 49 | &:before { 50 | content: ''; 51 | position: absolute; 52 | background: transparent; 53 | border: $arrowBorderWidth solid transparent; 54 | // move z-index 1 up than :after so that it shows over box-shadow 55 | z-index: 1000001; 56 | } 57 | 58 | /** 59 | * tooltip body 60 | */ 61 | &:after { 62 | font-family: 'myriad-pro', sans-serif; 63 | font-weight: 400; 64 | content: attr(data-hint); 65 | background: $defaultColor; 66 | color: white; 67 | //text-shadow: 0 -1px 0px darken($defaultColor, $textShadowDarkenAmount); 68 | padding: $verticalPadding $horizontalPadding; 69 | font-size: $fontSize; 70 | line-height: $fontSize; 71 | white-space: nowrap; 72 | //box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-effects.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-effects.scss 3 | * 4 | * Defines various transition effects for the tooltips. 5 | * 6 | * Classes added: 7 | * 1) hint--bounce 8 | * 9 | */ 10 | 11 | .#{$prefix}bounce { 12 | &:before, &:after { 13 | -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(.71,1.7,.77,1.24); 14 | -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(.71,1.7,.77,1.24); 15 | transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(.71,1.7,.77,1.24); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-mixins.scss: -------------------------------------------------------------------------------- 1 | // hint-mixins.scss 2 | // 3 | // Place to store common mixins. 4 | 5 | 6 | // Generates border-color rules for all 4 positions 7 | @mixin arrow-border-color($color, $isInsideSelector: "true") { 8 | @each $position in top, bottom, left, right { 9 | // if the current mixin is called from within a selector, use a '&'. Otherwise not. 10 | @if $isInsideSelector == "true" { 11 | &.#{$prefix}#{$position}:before { 12 | border-#{$position}-color: $color; 13 | } 14 | } 15 | @else { 16 | .#{$prefix}#{$position}:before { 17 | border-#{$position}-color: $color; 18 | } 19 | } 20 | } 21 | } 22 | 23 | 24 | // mixin to set margin on tooltip using translate transform 25 | @mixin set-margin($property, $transitionDirection) { 26 | $value: unquote("#{$property}(#{$transitionDistance * $transitionDirection})"); 27 | &:after, &:before { 28 | -webkit-transform: $value; 29 | -moz-transform: $value; 30 | transform: $value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-position.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-position.scss 3 | * 4 | * Defines the positoning logic for the tooltips. 5 | * 6 | * Classes added: 7 | * 1) hint--top 8 | * 2) hint--bottom 9 | * 3) hint--left 10 | * 4) hint--right 11 | */ 12 | 13 | @mixin vertical-positioned-tooltip($propertyY, $transitionDirection) { 14 | &:before { 15 | // get the arrow out 16 | margin-#{$propertyY}: -2 * $arrowBorderWidth; 17 | } 18 | 19 | &:after { 20 | // bring back the tooltip by some offset so that arrow doesn't stick at end 21 | margin-left: -1 * $arrowOffsetX; 22 | } 23 | 24 | &:before, &:after { 25 | #{$propertyY}: 100%; 26 | left: $arrowOffsetX; 27 | } 28 | 29 | &:hover, &:focus { 30 | @include set-margin('translateY', $transitionDirection); 31 | } 32 | } 33 | 34 | @mixin horizontal-positioned-tooltip($propertyX, $transitionDirection) { 35 | &:before { 36 | // get the arrow out 37 | margin-#{$propertyX}: -2 * $arrowBorderWidth; 38 | // bring back to center 39 | margin-bottom: -1 * $arrowBorderWidth; 40 | } 41 | 42 | &:after { 43 | // bring back to center 44 | margin-bottom: -1 * floor($tooltipHeight / 2); 45 | } 46 | 47 | &:before, &:after { 48 | #{$propertyX}: 100%; 49 | bottom: 50%; 50 | } 51 | 52 | &:hover, &:focus { 53 | @include set-margin('translateX', $transitionDirection); 54 | } 55 | } 56 | 57 | 58 | /** 59 | * set default color for tooltip arrows 60 | */ 61 | @include arrow-border-color($defaultColor, 'false'); 62 | 63 | /** 64 | * top tooltip 65 | */ 66 | .#{$prefix}top { 67 | @include vertical-positioned-tooltip('bottom', -1); 68 | } 69 | 70 | /** 71 | * bottom tooltip 72 | */ 73 | .#{$prefix}bottom { 74 | @include vertical-positioned-tooltip('top', 1); 75 | } 76 | 77 | /** 78 | * right tooltip 79 | */ 80 | .#{$prefix}right { 81 | @include horizontal-positioned-tooltip('left', 1); 82 | } 83 | 84 | /** 85 | * left tooltip 86 | */ 87 | .#{$prefix}left { 88 | @include horizontal-positioned-tooltip('right', -1); 89 | } 90 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-rounded.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * source: hint-rounded.scss 3 | * 4 | * Defines rounded corner tooltips. 5 | * 6 | * Classes added: 7 | * 1) hint--rounded 8 | * 9 | */ 10 | 11 | .#{$prefix}rounded { 12 | &:after { 13 | border-radius: 4px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint-variables.scss: -------------------------------------------------------------------------------- 1 | // hint-variables.scss 2 | // 3 | // Declares some variables used within the library. 4 | 5 | // Prefix for all classes. By default, BEM naming convention is used 6 | $prefix: 'hint--' !default; 7 | 8 | // font size 9 | $fontSize: 16px; 10 | 11 | // paddings 12 | $verticalPadding: 12px; 13 | $horizontalPadding: 15px; 14 | 15 | // default tooltip height 16 | $tooltipHeight: $fontSize + 2 * $verticalPadding !default; 17 | 18 | // border-width for tooltip arrow 19 | $arrowBorderWidth: 6px !default; 20 | 21 | // horizontal arrow offset 22 | $arrowOffsetX: 3 * $arrowBorderWidth !default; 23 | 24 | // text-shadow darken percentage 25 | $textShadowDarkenAmount: 0% !default; 26 | 27 | // transition distance 28 | $transitionDistance: 8px !default; 29 | 30 | // z-index for tooltips 31 | $zIndex: 1000000 !default; 32 | 33 | 34 | // Various colors 35 | // Default color is blackish 36 | $defaultColor: #1b3544 !default; 37 | 38 | // Error color 39 | $errorColor: hsl(1, 40%, 50%) !default; 40 | 41 | // Warning color 42 | $warningColor: hsl(38, 46%, 54%) !default; 43 | 44 | // Info Color 45 | $infoColor: hsl(200, 50%, 45%) !default; 46 | 47 | // Success Color 48 | $successColor: hsl(121, 32%, 40%) !default; 49 | -------------------------------------------------------------------------------- /forms/static/scss/hint/hint.scss: -------------------------------------------------------------------------------- 1 | // hint.scss 2 | // 3 | // Aggregates all other sass files. 4 | 5 | /*-------------------------------------*\ 6 | HINT.css - A CSS tooltip library 7 | \*-------------------------------------*/ 8 | 9 | 10 | /** 11 | * HINT.css is a tooltip library made in pure CSS. 12 | * 13 | * Source: https://github.com/chinchang/hint.css 14 | * Demo: http://kushagragour.in/lab/hint/ 15 | * 16 | * Release under The MIT License 17 | * 18 | */ 19 | 20 | 21 | // root path needs to be specified because of a bug in grunt-sass 22 | @import "hint-variables"; 23 | @import "hint-mixins"; 24 | @import "hint-core"; 25 | @import "hint-position"; 26 | @import "hint-color-types"; 27 | @import "hint-always"; 28 | @import "hint-rounded"; 29 | @import "hint-effects"; 30 | -------------------------------------------------------------------------------- /forms/static/scss/ionicons.min.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | Ionicons, v1.4.1 3 | Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ 4 | https://twitter.com/benjsperry https://twitter.com/ionicframework 5 | MIT License: https://github.com/driftyco/ionicons 6 | */@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot?v=1.4.1");src:url("../fonts/ionicons.eot?v=1.4.1#iefix") format("embedded-opentype"),url("../fonts/ionicons.ttf?v=1.4.1") format("truetype"),url("../fonts/ionicons.woff?v=1.4.1") format("woff"),url("../fonts/ionicons.svg?v=1.4.1#Ionicons") format("svg");font-weight:normal;font-style:normal}.ion,.ion-loading-a,.ion-loading-b,.ion-loading-c,.ion-loading-d,.ion-looping,.ion-refreshing,.ion-ios7-reloading,.ionicons,.ion-alert,.ion-alert-circled,.ion-android-add,.ion-android-add-contact,.ion-android-alarm,.ion-android-archive,.ion-android-arrow-back,.ion-android-arrow-down-left,.ion-android-arrow-down-right,.ion-android-arrow-up-left,.ion-android-arrow-up-right,.ion-android-battery,.ion-android-book,.ion-android-calendar,.ion-android-call,.ion-android-camera,.ion-android-chat,.ion-android-checkmark,.ion-android-clock,.ion-android-close,.ion-android-contact,.ion-android-contacts,.ion-android-data,.ion-android-developer,.ion-android-display,.ion-android-download,.ion-android-dropdown,.ion-android-earth,.ion-android-folder,.ion-android-forums,.ion-android-friends,.ion-android-hand,.ion-android-image,.ion-android-inbox,.ion-android-information,.ion-android-keypad,.ion-android-lightbulb,.ion-android-locate,.ion-android-location,.ion-android-mail,.ion-android-microphone,.ion-android-mixer,.ion-android-more,.ion-android-note,.ion-android-playstore,.ion-android-printer,.ion-android-promotion,.ion-android-reminder,.ion-android-remove,.ion-android-search,.ion-android-send,.ion-android-settings,.ion-android-share,.ion-android-social,.ion-android-social-user,.ion-android-sort,.ion-android-star,.ion-android-stopwatch,.ion-android-storage,.ion-android-system-back,.ion-android-system-home,.ion-android-system-windows,.ion-android-timer,.ion-android-trash,.ion-android-volume,.ion-android-wifi,.ion-archive,.ion-arrow-down-a,.ion-arrow-down-b,.ion-arrow-down-c,.ion-arrow-expand,.ion-arrow-graph-down-left,.ion-arrow-graph-down-right,.ion-arrow-graph-up-left,.ion-arrow-graph-up-right,.ion-arrow-left-a,.ion-arrow-left-b,.ion-arrow-left-c,.ion-arrow-move,.ion-arrow-resize,.ion-arrow-return-left,.ion-arrow-return-right,.ion-arrow-right-a,.ion-arrow-right-b,.ion-arrow-right-c,.ion-arrow-shrink,.ion-arrow-swap,.ion-arrow-up-a,.ion-arrow-up-b,.ion-arrow-up-c,.ion-at,.ion-bag,.ion-battery-charging,.ion-battery-empty,.ion-battery-full,.ion-battery-half,.ion-battery-low,.ion-beaker,.ion-beer,.ion-bluetooth,.ion-bookmark,.ion-briefcase,.ion-bug,.ion-calculator,.ion-calendar,.ion-camera,.ion-card,.ion-chatbox,.ion-chatbox-working,.ion-chatboxes,.ion-chatbubble,.ion-chatbubble-working,.ion-chatbubbles,.ion-checkmark,.ion-checkmark-circled,.ion-checkmark-round,.ion-chevron-down,.ion-chevron-left,.ion-chevron-right,.ion-chevron-up,.ion-clipboard,.ion-clock,.ion-close,.ion-close-circled,.ion-close-round,.ion-cloud,.ion-code,.ion-code-download,.ion-code-working,.ion-coffee,.ion-compass,.ion-compose,.ion-connection-bars,.ion-contrast,.ion-disc,.ion-document,.ion-document-text,.ion-drag,.ion-earth,.ion-edit,.ion-egg,.ion-eject,.ion-email,.ion-eye,.ion-eye-disabled,.ion-female,.ion-filing,.ion-film-marker,.ion-flag,.ion-flash,.ion-flash-off,.ion-flask,.ion-folder,.ion-fork,.ion-fork-repo,.ion-forward,.ion-game-controller-a,.ion-game-controller-b,.ion-gear-a,.ion-gear-b,.ion-grid,.ion-hammer,.ion-headphone,.ion-heart,.ion-help,.ion-help-buoy,.ion-help-circled,.ion-home,.ion-icecream,.ion-icon-social-google-plus,.ion-icon-social-google-plus-outline,.ion-image,.ion-images,.ion-information,.ion-information-circled,.ion-ionic,.ion-ios7-alarm,.ion-ios7-alarm-outline,.ion-ios7-albums,.ion-ios7-albums-outline,.ion-ios7-arrow-back,.ion-ios7-arrow-down,.ion-ios7-arrow-forward,.ion-ios7-arrow-left,.ion-ios7-arrow-right,.ion-ios7-arrow-thin-down,.ion-ios7-arrow-thin-left,.ion-ios7-arrow-thin-right,.ion-ios7-arrow-thin-up,.ion-ios7-arrow-up,.ion-ios7-at,.ion-ios7-at-outline,.ion-ios7-bell,.ion-ios7-bell-outline,.ion-ios7-bolt,.ion-ios7-bolt-outline,.ion-ios7-bookmarks,.ion-ios7-bookmarks-outline,.ion-ios7-box,.ion-ios7-box-outline,.ion-ios7-briefcase,.ion-ios7-briefcase-outline,.ion-ios7-browsers,.ion-ios7-browsers-outline,.ion-ios7-calculator,.ion-ios7-calculator-outline,.ion-ios7-calendar,.ion-ios7-calendar-outline,.ion-ios7-camera,.ion-ios7-camera-outline,.ion-ios7-cart,.ion-ios7-cart-outline,.ion-ios7-chatboxes,.ion-ios7-chatboxes-outline,.ion-ios7-chatbubble,.ion-ios7-chatbubble-outline,.ion-ios7-checkmark,.ion-ios7-checkmark-empty,.ion-ios7-checkmark-outline,.ion-ios7-circle-filled,.ion-ios7-circle-outline,.ion-ios7-clock,.ion-ios7-clock-outline,.ion-ios7-close,.ion-ios7-close-empty,.ion-ios7-close-outline,.ion-ios7-cloud,.ion-ios7-cloud-download,.ion-ios7-cloud-download-outline,.ion-ios7-cloud-outline,.ion-ios7-cloud-upload,.ion-ios7-cloud-upload-outline,.ion-ios7-cloudy,.ion-ios7-cloudy-night,.ion-ios7-cloudy-night-outline,.ion-ios7-cloudy-outline,.ion-ios7-cog,.ion-ios7-cog-outline,.ion-ios7-compose,.ion-ios7-compose-outline,.ion-ios7-contact,.ion-ios7-contact-outline,.ion-ios7-copy,.ion-ios7-copy-outline,.ion-ios7-download,.ion-ios7-download-outline,.ion-ios7-drag,.ion-ios7-email,.ion-ios7-email-outline,.ion-ios7-eye,.ion-ios7-eye-outline,.ion-ios7-fastforward,.ion-ios7-fastforward-outline,.ion-ios7-filing,.ion-ios7-filing-outline,.ion-ios7-film,.ion-ios7-film-outline,.ion-ios7-flag,.ion-ios7-flag-outline,.ion-ios7-folder,.ion-ios7-folder-outline,.ion-ios7-gear,.ion-ios7-gear-outline,.ion-ios7-glasses,.ion-ios7-glasses-outline,.ion-ios7-heart,.ion-ios7-heart-outline,.ion-ios7-help,.ion-ios7-help-empty,.ion-ios7-help-outline,.ion-ios7-infinite,.ion-ios7-infinite-outline,.ion-ios7-information,.ion-ios7-information-empty,.ion-ios7-information-outline,.ion-ios7-ionic-outline,.ion-ios7-keypad,.ion-ios7-keypad-outline,.ion-ios7-lightbulb,.ion-ios7-lightbulb-outline,.ion-ios7-location,.ion-ios7-location-outline,.ion-ios7-locked,.ion-ios7-locked-outline,.ion-ios7-medkit,.ion-ios7-medkit-outline,.ion-ios7-mic,.ion-ios7-mic-off,.ion-ios7-mic-outline,.ion-ios7-minus,.ion-ios7-minus-empty,.ion-ios7-minus-outline,.ion-ios7-monitor,.ion-ios7-monitor-outline,.ion-ios7-moon,.ion-ios7-moon-outline,.ion-ios7-more,.ion-ios7-more-outline,.ion-ios7-musical-note,.ion-ios7-musical-notes,.ion-ios7-navigate,.ion-ios7-navigate-outline,.ion-ios7-paperplane,.ion-ios7-paperplane-outline,.ion-ios7-partlysunny,.ion-ios7-partlysunny-outline,.ion-ios7-pause,.ion-ios7-pause-outline,.ion-ios7-people,.ion-ios7-people-outline,.ion-ios7-person,.ion-ios7-person-outline,.ion-ios7-personadd,.ion-ios7-personadd-outline,.ion-ios7-photos,.ion-ios7-photos-outline,.ion-ios7-pie,.ion-ios7-pie-outline,.ion-ios7-play,.ion-ios7-play-outline,.ion-ios7-plus,.ion-ios7-plus-empty,.ion-ios7-plus-outline,.ion-ios7-pricetag,.ion-ios7-pricetag-outline,.ion-ios7-printer,.ion-ios7-printer-outline,.ion-ios7-rainy,.ion-ios7-rainy-outline,.ion-ios7-recording,.ion-ios7-recording-outline,.ion-ios7-redo,.ion-ios7-redo-outline,.ion-ios7-refresh,.ion-ios7-refresh-empty,.ion-ios7-refresh-outline,.ion-ios7-reload,.ion-ios7-rewind,.ion-ios7-rewind-outline,.ion-ios7-search,.ion-ios7-search-strong,.ion-ios7-skipbackward,.ion-ios7-skipbackward-outline,.ion-ios7-skipforward,.ion-ios7-skipforward-outline,.ion-ios7-snowy,.ion-ios7-speedometer,.ion-ios7-speedometer-outline,.ion-ios7-star,.ion-ios7-star-outline,.ion-ios7-stopwatch,.ion-ios7-stopwatch-outline,.ion-ios7-sunny,.ion-ios7-sunny-outline,.ion-ios7-telephone,.ion-ios7-telephone-outline,.ion-ios7-thunderstorm,.ion-ios7-thunderstorm-outline,.ion-ios7-time,.ion-ios7-time-outline,.ion-ios7-timer,.ion-ios7-timer-outline,.ion-ios7-trash,.ion-ios7-trash-outline,.ion-ios7-undo,.ion-ios7-undo-outline,.ion-ios7-unlocked,.ion-ios7-unlocked-outline,.ion-ios7-upload,.ion-ios7-upload-outline,.ion-ios7-videocam,.ion-ios7-videocam-outline,.ion-ios7-volume-high,.ion-ios7-volume-low,.ion-ios7-wineglass,.ion-ios7-wineglass-outline,.ion-ios7-world,.ion-ios7-world-outline,.ion-ipad,.ion-iphone,.ion-ipod,.ion-jet,.ion-key,.ion-knife,.ion-laptop,.ion-leaf,.ion-levels,.ion-lightbulb,.ion-link,.ion-load-a,.ion-load-b,.ion-load-c,.ion-load-d,.ion-location,.ion-locked,.ion-log-in,.ion-log-out,.ion-loop,.ion-magnet,.ion-male,.ion-man,.ion-map,.ion-medkit,.ion-mic-a,.ion-mic-b,.ion-mic-c,.ion-minus,.ion-minus-circled,.ion-minus-round,.ion-model-s,.ion-monitor,.ion-more,.ion-music-note,.ion-navicon,.ion-navicon-round,.ion-navigate,.ion-no-smoking,.ion-nuclear,.ion-paper-airplane,.ion-paperclip,.ion-pause,.ion-person,.ion-person-add,.ion-person-stalker,.ion-pie-graph,.ion-pin,.ion-pinpoint,.ion-pizza,.ion-plane,.ion-play,.ion-playstation,.ion-plus,.ion-plus-circled,.ion-plus-round,.ion-pound,.ion-power,.ion-pricetag,.ion-pricetags,.ion-printer,.ion-radio-waves,.ion-record,.ion-refresh,.ion-reply,.ion-reply-all,.ion-search,.ion-settings,.ion-share,.ion-shuffle,.ion-skip-backward,.ion-skip-forward,.ion-social-android,.ion-social-android-outline,.ion-social-apple,.ion-social-apple-outline,.ion-social-bitcoin,.ion-social-bitcoin-outline,.ion-social-buffer,.ion-social-buffer-outline,.ion-social-designernews,.ion-social-designernews-outline,.ion-social-dribbble,.ion-social-dribbble-outline,.ion-social-dropbox,.ion-social-dropbox-outline,.ion-social-facebook,.ion-social-facebook-outline,.ion-social-freebsd-devil,.ion-social-github,.ion-social-github-outline,.ion-social-googleplus,.ion-social-googleplus-outline,.ion-social-hackernews,.ion-social-hackernews-outline,.ion-social-linkedin,.ion-social-linkedin-outline,.ion-social-pinterest,.ion-social-pinterest-outline,.ion-social-reddit,.ion-social-reddit-outline,.ion-social-rss,.ion-social-rss-outline,.ion-social-skype,.ion-social-skype-outline,.ion-social-tumblr,.ion-social-tumblr-outline,.ion-social-tux,.ion-social-twitter,.ion-social-twitter-outline,.ion-social-vimeo,.ion-social-vimeo-outline,.ion-social-windows,.ion-social-windows-outline,.ion-social-wordpress,.ion-social-wordpress-outline,.ion-social-yahoo,.ion-social-yahoo-outline,.ion-social-youtube,.ion-social-youtube-outline,.ion-speakerphone,.ion-speedometer,.ion-spoon,.ion-star,.ion-stats-bars,.ion-steam,.ion-stop,.ion-thermometer,.ion-thumbsdown,.ion-thumbsup,.ion-trash-a,.ion-trash-b,.ion-umbrella,.ion-unlocked,.ion-upload,.ion-usb,.ion-videocamera,.ion-volume-high,.ion-volume-low,.ion-volume-medium,.ion-volume-mute,.ion-waterdrop,.ion-wifi,.ion-wineglass,.ion-woman,.ion-wrench,.ion-xbox{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-spin,.ion-loading-a,.ion-loading-b,.ion-loading-c,.ion-loading-d,.ion-looping,.ion-refreshing,.ion-ios7-reloading{-webkit-animation:spin 1s infinite linear;-moz-animation:spin 1s infinite linear;-o-animation:spin 1s infinite linear;animation:spin 1s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.ion-loading-a{-webkit-animation-timing-function:steps(8, start);-moz-animation-timing-function:steps(8, start);animation-timing-function:steps(8, start)}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-contact:before{content:"\f2c6"}.ion-android-alarm:before{content:"\f2c8"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down-left:before{content:"\f2cb"}.ion-android-arrow-down-right:before{content:"\f2cc"}.ion-android-arrow-up-left:before{content:"\f2cd"}.ion-android-arrow-up-right:before{content:"\f2ce"}.ion-android-battery:before{content:"\f2cf"}.ion-android-book:before{content:"\f2d0"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkmark:before{content:"\f2d5"}.ion-android-clock:before{content:"\f2d6"}.ion-android-close:before{content:"\f2d7"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-data:before{content:"\f2da"}.ion-android-developer:before{content:"\f2db"}.ion-android-display:before{content:"\f2dc"}.ion-android-download:before{content:"\f2dd"}.ion-android-dropdown:before{content:"\f2de"}.ion-android-earth:before{content:"\f2df"}.ion-android-folder:before{content:"\f2e0"}.ion-android-forums:before{content:"\f2e1"}.ion-android-friends:before{content:"\f2e2"}.ion-android-hand:before{content:"\f2e3"}.ion-android-image:before{content:"\f2e4"}.ion-android-inbox:before{content:"\f2e5"}.ion-android-information:before{content:"\f2e6"}.ion-android-keypad:before{content:"\f2e7"}.ion-android-lightbulb:before{content:"\f2e8"}.ion-android-locate:before{content:"\f2e9"}.ion-android-location:before{content:"\f2ea"}.ion-android-mail:before{content:"\f2eb"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-mixer:before{content:"\f2ed"}.ion-android-more:before{content:"\f2ee"}.ion-android-note:before{content:"\f2ef"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-printer:before{content:"\f2f1"}.ion-android-promotion:before{content:"\f2f2"}.ion-android-reminder:before{content:"\f2f3"}.ion-android-remove:before{content:"\f2f4"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-social:before{content:"\f2fa"}.ion-android-social-user:before{content:"\f2f9"}.ion-android-sort:before{content:"\f2fb"}.ion-android-star:before{content:"\f2fc"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-storage:before{content:"\f2fe"}.ion-android-system-back:before{content:"\f2ff"}.ion-android-system-home:before{content:"\f300"}.ion-android-system-windows:before{content:"\f301"}.ion-android-timer:before{content:"\f302"}.ion-android-trash:before{content:"\f303"}.ion-android-volume:before{content:"\f304"}.ion-android-wifi:before{content:"\f305"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-at:before{content:"\f10f"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bookmark:before{content:"\f26b"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-flag:before{content:"\f279"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-flask:before{content:"\f138"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-game-controller-a:before{content:"\f13b"}.ion-game-controller-b:before{content:"\f13c"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-icon-social-google-plus:before{content:"\f146"}.ion-icon-social-google-plus-outline:before{content:"\f145"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios7-alarm:before{content:"\f14d"}.ion-ios7-alarm-outline:before{content:"\f14c"}.ion-ios7-albums:before{content:"\f14f"}.ion-ios7-albums-outline:before{content:"\f14e"}.ion-ios7-arrow-back:before{content:"\f150"}.ion-ios7-arrow-down:before{content:"\f151"}.ion-ios7-arrow-forward:before{content:"\f152"}.ion-ios7-arrow-left:before{content:"\f153"}.ion-ios7-arrow-right:before{content:"\f154"}.ion-ios7-arrow-thin-down:before{content:"\f27e"}.ion-ios7-arrow-thin-left:before{content:"\f27f"}.ion-ios7-arrow-thin-right:before{content:"\f280"}.ion-ios7-arrow-thin-up:before{content:"\f281"}.ion-ios7-arrow-up:before{content:"\f155"}.ion-ios7-at:before{content:"\f157"}.ion-ios7-at-outline:before{content:"\f156"}.ion-ios7-bell:before{content:"\f159"}.ion-ios7-bell-outline:before{content:"\f158"}.ion-ios7-bolt:before{content:"\f15b"}.ion-ios7-bolt-outline:before{content:"\f15a"}.ion-ios7-bookmarks:before{content:"\f15d"}.ion-ios7-bookmarks-outline:before{content:"\f15c"}.ion-ios7-box:before{content:"\f15f"}.ion-ios7-box-outline:before{content:"\f15e"}.ion-ios7-briefcase:before{content:"\f283"}.ion-ios7-briefcase-outline:before{content:"\f282"}.ion-ios7-browsers:before{content:"\f161"}.ion-ios7-browsers-outline:before{content:"\f160"}.ion-ios7-calculator:before{content:"\f285"}.ion-ios7-calculator-outline:before{content:"\f284"}.ion-ios7-calendar:before{content:"\f163"}.ion-ios7-calendar-outline:before{content:"\f162"}.ion-ios7-camera:before{content:"\f165"}.ion-ios7-camera-outline:before{content:"\f164"}.ion-ios7-cart:before{content:"\f167"}.ion-ios7-cart-outline:before{content:"\f166"}.ion-ios7-chatboxes:before{content:"\f169"}.ion-ios7-chatboxes-outline:before{content:"\f168"}.ion-ios7-chatbubble:before{content:"\f16b"}.ion-ios7-chatbubble-outline:before{content:"\f16a"}.ion-ios7-checkmark:before{content:"\f16e"}.ion-ios7-checkmark-empty:before{content:"\f16c"}.ion-ios7-checkmark-outline:before{content:"\f16d"}.ion-ios7-circle-filled:before{content:"\f16f"}.ion-ios7-circle-outline:before{content:"\f170"}.ion-ios7-clock:before{content:"\f172"}.ion-ios7-clock-outline:before{content:"\f171"}.ion-ios7-close:before{content:"\f2bc"}.ion-ios7-close-empty:before{content:"\f2bd"}.ion-ios7-close-outline:before{content:"\f2bb"}.ion-ios7-cloud:before{content:"\f178"}.ion-ios7-cloud-download:before{content:"\f174"}.ion-ios7-cloud-download-outline:before{content:"\f173"}.ion-ios7-cloud-outline:before{content:"\f175"}.ion-ios7-cloud-upload:before{content:"\f177"}.ion-ios7-cloud-upload-outline:before{content:"\f176"}.ion-ios7-cloudy:before{content:"\f17a"}.ion-ios7-cloudy-night:before{content:"\f308"}.ion-ios7-cloudy-night-outline:before{content:"\f307"}.ion-ios7-cloudy-outline:before{content:"\f179"}.ion-ios7-cog:before{content:"\f17c"}.ion-ios7-cog-outline:before{content:"\f17b"}.ion-ios7-compose:before{content:"\f17e"}.ion-ios7-compose-outline:before{content:"\f17d"}.ion-ios7-contact:before{content:"\f180"}.ion-ios7-contact-outline:before{content:"\f17f"}.ion-ios7-copy:before{content:"\f182"}.ion-ios7-copy-outline:before{content:"\f181"}.ion-ios7-download:before{content:"\f184"}.ion-ios7-download-outline:before{content:"\f183"}.ion-ios7-drag:before{content:"\f185"}.ion-ios7-email:before{content:"\f187"}.ion-ios7-email-outline:before{content:"\f186"}.ion-ios7-eye:before{content:"\f189"}.ion-ios7-eye-outline:before{content:"\f188"}.ion-ios7-fastforward:before{content:"\f18b"}.ion-ios7-fastforward-outline:before{content:"\f18a"}.ion-ios7-filing:before{content:"\f18d"}.ion-ios7-filing-outline:before{content:"\f18c"}.ion-ios7-film:before{content:"\f18f"}.ion-ios7-film-outline:before{content:"\f18e"}.ion-ios7-flag:before{content:"\f191"}.ion-ios7-flag-outline:before{content:"\f190"}.ion-ios7-folder:before{content:"\f193"}.ion-ios7-folder-outline:before{content:"\f192"}.ion-ios7-gear:before{content:"\f195"}.ion-ios7-gear-outline:before{content:"\f194"}.ion-ios7-glasses:before{content:"\f197"}.ion-ios7-glasses-outline:before{content:"\f196"}.ion-ios7-heart:before{content:"\f199"}.ion-ios7-heart-outline:before{content:"\f198"}.ion-ios7-help:before{content:"\f19c"}.ion-ios7-help-empty:before{content:"\f19a"}.ion-ios7-help-outline:before{content:"\f19b"}.ion-ios7-infinite:before{content:"\f19e"}.ion-ios7-infinite-outline:before{content:"\f19d"}.ion-ios7-information:before{content:"\f1a1"}.ion-ios7-information-empty:before{content:"\f19f"}.ion-ios7-information-outline:before{content:"\f1a0"}.ion-ios7-ionic-outline:before{content:"\f1a2"}.ion-ios7-keypad:before{content:"\f1a4"}.ion-ios7-keypad-outline:before{content:"\f1a3"}.ion-ios7-lightbulb:before{content:"\f287"}.ion-ios7-lightbulb-outline:before{content:"\f286"}.ion-ios7-location:before{content:"\f1a6"}.ion-ios7-location-outline:before{content:"\f1a5"}.ion-ios7-locked:before{content:"\f1a8"}.ion-ios7-locked-outline:before{content:"\f1a7"}.ion-ios7-medkit:before{content:"\f289"}.ion-ios7-medkit-outline:before{content:"\f288"}.ion-ios7-mic:before{content:"\f1ab"}.ion-ios7-mic-off:before{content:"\f1a9"}.ion-ios7-mic-outline:before{content:"\f1aa"}.ion-ios7-minus:before{content:"\f1ae"}.ion-ios7-minus-empty:before{content:"\f1ac"}.ion-ios7-minus-outline:before{content:"\f1ad"}.ion-ios7-monitor:before{content:"\f1b0"}.ion-ios7-monitor-outline:before{content:"\f1af"}.ion-ios7-moon:before{content:"\f1b2"}.ion-ios7-moon-outline:before{content:"\f1b1"}.ion-ios7-more:before{content:"\f1b4"}.ion-ios7-more-outline:before{content:"\f1b3"}.ion-ios7-musical-note:before{content:"\f1b5"}.ion-ios7-musical-notes:before{content:"\f1b6"}.ion-ios7-navigate:before{content:"\f1b8"}.ion-ios7-navigate-outline:before{content:"\f1b7"}.ion-ios7-paperplane:before{content:"\f1ba"}.ion-ios7-paperplane-outline:before{content:"\f1b9"}.ion-ios7-partlysunny:before{content:"\f1bc"}.ion-ios7-partlysunny-outline:before{content:"\f1bb"}.ion-ios7-pause:before{content:"\f1be"}.ion-ios7-pause-outline:before{content:"\f1bd"}.ion-ios7-people:before{content:"\f1c0"}.ion-ios7-people-outline:before{content:"\f1bf"}.ion-ios7-person:before{content:"\f1c2"}.ion-ios7-person-outline:before{content:"\f1c1"}.ion-ios7-personadd:before{content:"\f1c4"}.ion-ios7-personadd-outline:before{content:"\f1c3"}.ion-ios7-photos:before{content:"\f1c6"}.ion-ios7-photos-outline:before{content:"\f1c5"}.ion-ios7-pie:before{content:"\f28b"}.ion-ios7-pie-outline:before{content:"\f28a"}.ion-ios7-play:before{content:"\f1c8"}.ion-ios7-play-outline:before{content:"\f1c7"}.ion-ios7-plus:before{content:"\f1cb"}.ion-ios7-plus-empty:before{content:"\f1c9"}.ion-ios7-plus-outline:before{content:"\f1ca"}.ion-ios7-pricetag:before{content:"\f28d"}.ion-ios7-pricetag-outline:before{content:"\f28c"}.ion-ios7-printer:before{content:"\f1cd"}.ion-ios7-printer-outline:before{content:"\f1cc"}.ion-ios7-rainy:before{content:"\f1cf"}.ion-ios7-rainy-outline:before{content:"\f1ce"}.ion-ios7-recording:before{content:"\f1d1"}.ion-ios7-recording-outline:before{content:"\f1d0"}.ion-ios7-redo:before{content:"\f1d3"}.ion-ios7-redo-outline:before{content:"\f1d2"}.ion-ios7-refresh:before{content:"\f1d6"}.ion-ios7-refresh-empty:before{content:"\f1d4"}.ion-ios7-refresh-outline:before{content:"\f1d5"}.ion-ios7-reload:before,.ion-ios7-reloading:before{content:"\f28e"}.ion-ios7-rewind:before{content:"\f1d8"}.ion-ios7-rewind-outline:before{content:"\f1d7"}.ion-ios7-search:before{content:"\f1da"}.ion-ios7-search-strong:before{content:"\f1d9"}.ion-ios7-skipbackward:before{content:"\f1dc"}.ion-ios7-skipbackward-outline:before{content:"\f1db"}.ion-ios7-skipforward:before{content:"\f1de"}.ion-ios7-skipforward-outline:before{content:"\f1dd"}.ion-ios7-snowy:before{content:"\f309"}.ion-ios7-speedometer:before{content:"\f290"}.ion-ios7-speedometer-outline:before{content:"\f28f"}.ion-ios7-star:before{content:"\f1e0"}.ion-ios7-star-outline:before{content:"\f1df"}.ion-ios7-stopwatch:before{content:"\f1e2"}.ion-ios7-stopwatch-outline:before{content:"\f1e1"}.ion-ios7-sunny:before{content:"\f1e4"}.ion-ios7-sunny-outline:before{content:"\f1e3"}.ion-ios7-telephone:before{content:"\f1e6"}.ion-ios7-telephone-outline:before{content:"\f1e5"}.ion-ios7-thunderstorm:before{content:"\f1e8"}.ion-ios7-thunderstorm-outline:before{content:"\f1e7"}.ion-ios7-time:before{content:"\f292"}.ion-ios7-time-outline:before{content:"\f291"}.ion-ios7-timer:before{content:"\f1ea"}.ion-ios7-timer-outline:before{content:"\f1e9"}.ion-ios7-trash:before{content:"\f1ec"}.ion-ios7-trash-outline:before{content:"\f1eb"}.ion-ios7-undo:before{content:"\f1ee"}.ion-ios7-undo-outline:before{content:"\f1ed"}.ion-ios7-unlocked:before{content:"\f1f0"}.ion-ios7-unlocked-outline:before{content:"\f1ef"}.ion-ios7-upload:before{content:"\f1f2"}.ion-ios7-upload-outline:before{content:"\f1f1"}.ion-ios7-videocam:before{content:"\f1f4"}.ion-ios7-videocam-outline:before{content:"\f1f3"}.ion-ios7-volume-high:before{content:"\f1f5"}.ion-ios7-volume-low:before{content:"\f1f6"}.ion-ios7-wineglass:before{content:"\f294"}.ion-ios7-wineglass-outline:before{content:"\f293"}.ion-ios7-world:before{content:"\f1f8"}.ion-ios7-world-outline:before{content:"\f1f7"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before,.ion-loading-a:before{content:"\f29a"}.ion-load-b:before,.ion-loading-b:before{content:"\f29b"}.ion-load-c:before,.ion-loading-c:before{content:"\f29c"}.ion-load-d:before,.ion-loading-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before,.ion-looping:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before,.ion-refreshing:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-umbrella:before{content:"\f2b7"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} 7 | -------------------------------------------------------------------------------- /forms/static/scss/main.scss: -------------------------------------------------------------------------------- 1 | $green: #4ca1a7; 2 | $dark-green: #359173; 3 | 4 | $dark-blue: #1b3544; 5 | $accent-blue: #f1f1fa; 6 | $accent: #ddd; 7 | 8 | $red: #ff1708; 9 | $green: #359173; 10 | 11 | @import 'normalize.scss'; 12 | @import 'grid.scss'; 13 | @import 'typography.scss'; 14 | @import 'hint/hint.scss'; 15 | @import 'ionicons.min.scss'; 16 | 17 | 18 | html { 19 | height: 100%; 20 | } 21 | body { 22 | min-height: 100%; 23 | } 24 | 25 | body#card { 26 | background: $accent-blue; 27 | padding-top: 4em; 28 | font-size: 0.9em; 29 | text-align: center; 30 | } 31 | 32 | .tooltip { 33 | font-weight: 600; 34 | cursor: help; 35 | } 36 | 37 | #title { 38 | text-align: center; 39 | margin-bottom: 3em; 40 | h1 { 41 | font-size: 1.2em; 42 | } 43 | img { 44 | max-width: 70px; 45 | } 46 | } 47 | 48 | 49 | .row.section { 50 | padding-top: 5em; 51 | padding-bottom: 5em; 52 | border-bottom: 1px solid #ddd; 53 | &#header { 54 | border-color: $green; 55 | } 56 | } 57 | 58 | #header { 59 | 60 | i { 61 | font-size: 4em; 62 | color: $dark-blue; 63 | } 64 | 65 | .next { 66 | opacity: 0.5; 67 | } 68 | 69 | .success { 70 | i { 71 | color: $green; 72 | } 73 | } 74 | 75 | .error { 76 | i { 77 | color: $red; 78 | } 79 | } 80 | 81 | .done { 82 | opacity: 0.3; 83 | p { 84 | text-decoration: line-through; 85 | } 86 | } 87 | 88 | .done, .current { 89 | i { 90 | color: $green; 91 | } 92 | } 93 | 94 | border-bottom: 1px solid #ddd; 95 | } 96 | 97 | 98 | .container { 99 | padding-top: 1em; 100 | padding-bottom: 1em; 101 | 102 | @media (max-width: 760px) { 103 | padding-bottom: 0 !important; 104 | padding-top: 0 !important; 105 | } 106 | 107 | &.block { 108 | padding-bottom: 1.5em; 109 | padding-top: 1.5em; 110 | 111 | @media (max-width: 760px) { 112 | padding-top: 0 !important; 113 | padding-bottom: 0 !important; 114 | } 115 | 116 | &:first-child{ 117 | padding-top: 0; 118 | } 119 | &:last-child{ 120 | padding-bottom: 0; 121 | } 122 | } 123 | 124 | &.card { 125 | max-width: 500px; 126 | } 127 | 128 | } 129 | 130 | 131 | .card { 132 | padding: 0.9em; 133 | background: #fff; 134 | border: 1px solid $accent; 135 | 136 | h1 { 137 | font-size: 1.8em; 138 | } 139 | 140 | } 141 | 142 | .row.grey { 143 | background: $accent-blue; 144 | } 145 | 146 | 147 | p { 148 | line-height: 1.5em; 149 | } 150 | 151 | p.code { 152 | font-size: 0.8em; 153 | font-family: "source-code-pro"; 154 | border: 1px solid $accent; 155 | background: #fff; 156 | @media (max-width: 760px) { 157 | overflow: auto; 158 | } 159 | } 160 | 161 | span.code { 162 | font-family: "source-code-pro"; 163 | display: inline-block; 164 | padding: 0 0.2em; 165 | border: 1px solid $accent; 166 | background: #fff; 167 | font-size: 0.9em; 168 | } 169 | 170 | input, textarea { 171 | font-size: 0.8em; 172 | font-family: "source-code-pro"; 173 | border: 1px solid $accent; 174 | background: #fff; 175 | padding: 0.9em; 176 | transition: all 0.3s ease-in-out; 177 | width: 100%; 178 | &:focus{ 179 | border-color: $dark-green; 180 | outline: none; 181 | box-shadow: 0 0 5px 1px $green; 182 | } 183 | } 184 | 185 | form input, form textarea { 186 | margin-bottom: 0.5em; 187 | } 188 | 189 | button, a.button { 190 | font-size: 1em; 191 | text-transform: uppercase; 192 | font-weight: 600; 193 | border: 2px solid $green; 194 | color: $dark-green; 195 | background: transparent; 196 | line-height: 1em; 197 | padding: 0.6em 0.9em; 198 | transition: all 0.3s ease-in-out; 199 | &:hover { 200 | border-color: $dark-green; 201 | } 202 | } 203 | 204 | 205 | .animate { 206 | 207 | -moz-animation-iteration-count: once; 208 | -moz-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);; 209 | -moz-animation-duration: 0.4s; 210 | 211 | -webkit-animation-iteration-count: once; 212 | -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);; 213 | -webkit-animation-duration: 0.4s; 214 | 215 | &.dropIn { 216 | -moz-animation-name: dropIn; 217 | -webkit-animation-name: dropIn; 218 | } 219 | 220 | } 221 | 222 | @-webkit-keyframes fadeIn { 223 | 0% { 224 | -webkit-transform: translate3d(0, 0, 0); 225 | -moz-transform: translate3d(0, 0, 0); 226 | opacity: 0; 227 | } 228 | 100% { 229 | -webkit-transform: translate3d(0, 0, 0); 230 | -moz-transform: translate3d(0, 0, 0); 231 | opacity: 1; 232 | } 233 | } 234 | 235 | @-webkit-keyframes dropIn { 236 | 0% { 237 | opacity: 0; 238 | -webkit-transform: translate3d(0, -150px, 0); 239 | -moz-transform: translate3d(0, -150px, 0); 240 | } 241 | 100% { 242 | opacity: 1; 243 | -webkit-transform: translate3d(0, 0, 0); 244 | -moz-transform: translate3d(0, 0, 0); 245 | } 246 | } 247 | 248 | @-webkit-keyframes dropInLong { 249 | 0% { 250 | opacity: 0; 251 | -webkit-transform: translate3d(0, -450px, 0); 252 | -moz-transform: translate3d(0, -450px, 0); 253 | } 254 | 100% { 255 | opacity: 1; 256 | -webkit-transform: translate3d(0, 0, 0); 257 | -moz-transform: translate3d(0, 0, 0); 258 | } 259 | } 260 | 261 | @-webkit-keyframes rotate { 262 | 100% { 263 | -webkit-transform: rotate(45deg); 264 | -moz-transform: rotate(45deg); 265 | } 266 | } 267 | 268 | @-webkit-keyframes rotateBack { 269 | 100% { 270 | -webkit-transform: rotate(0deg); 271 | -moz-transform: rotate(0deg); 272 | } 273 | } 274 | 275 | .overlay { 276 | position: fixed; 277 | width: 100%; 278 | height: 100%; 279 | 280 | top: -10000px; 281 | left: -10000px; 282 | opacity: 0; 283 | 284 | transition: opacity 0.4s linear; 285 | 286 | background: rgba(255,255,255,0.96); 287 | } 288 | 289 | body.showOverlay { 290 | overflow: hidden; 291 | 292 | .overlay { 293 | top: 0; 294 | left: 0; 295 | opacity: 1; 296 | 297 | iframe { 298 | -webkit-animation-iteration-count: once; 299 | -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);; 300 | -webkit-animation-duration: 0.4s; 301 | 302 | -moz-animation-name: dropInLong; 303 | -webkit-animation-name: dropInLong; 304 | } 305 | 306 | } 307 | } 308 | 309 | .toggleOverlay { 310 | cursor: pointer; 311 | position: fixed; top: 20px; left: 20px; 312 | font-size: 2.2em; 313 | font-weight: 600; 314 | 315 | -moz-animation-iteration-count: once; 316 | -moz-animation-fill-mode: forwards; 317 | -moz-animation-timing-function: linear; 318 | -moz-animation-duration: 0.2s; 319 | 320 | -webkit-animation-iteration-count: once; 321 | -webkit-animation-fill-mode: forwards; 322 | -webkit-animation-timing-function: linear; 323 | -webkit-animation-duration: 0.2s; 324 | 325 | } 326 | 327 | body.showOverlay .toggleOverlay { 328 | -moz-animation-name: rotate; 329 | -webkit-animation-name: rotate; 330 | } 331 | 332 | -------------------------------------------------------------------------------- /forms/static/scss/normalize.scss: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // Normalize.scss based on Nicolas Gallagher and Jonathan Neal's 3 | // normalize.css v2.1.3 | MIT License | git.io/normalize 4 | // ============================================================================= 5 | 6 | // ============================================================================= 7 | // Normalize.scss settings 8 | // ============================================================================= 9 | 10 | 11 | // Set to true if you want to add support for IE6 and IE7 12 | // Notice: setting to true might render some elements 13 | // slightly differently than when set to false 14 | $legacy_support_for_ie: false !default; // Used also in Compass 15 | 16 | 17 | // Set the default font family here so you don't have to override it later 18 | $normalized_font_family: sans-serif !default; 19 | 20 | $normalize_headings: true !default; 21 | 22 | $h1_font_size: 2em !default; 23 | $h2_font_size: 1.5em !default; 24 | $h3_font_size: 1.17em !default; 25 | $h4_font_size: 1em !default; 26 | $h5_font_size: 0.83em !default; 27 | $h6_font_size: 0.75em !default; 28 | 29 | $h1_margin: 0.67em 0 !default; 30 | $h2_margin: 0.83em 0 !default; 31 | $h3_margin: 1em 0 !default; 32 | $h4_margin: 1.33em 0 !default; 33 | $h5_margin: 1.67em 0 !default; 34 | $h6_margin: 2.33em 0 !default; 35 | 36 | $background: #fff !default; 37 | $color: #000 !default; 38 | 39 | // ============================================================================= 40 | // HTML5 display definitions 41 | // ============================================================================= 42 | 43 | // Corrects block display not defined in IE6/7/8/9 & FF3 44 | 45 | article, 46 | aside, 47 | details, 48 | figcaption, 49 | figure, 50 | footer, 51 | header, 52 | hgroup, 53 | nav, 54 | section, 55 | summary { 56 | display: block; 57 | } 58 | 59 | // Corrects inline-block display not defined in IE6/7/8/9 & FF3 60 | 61 | audio, 62 | canvas, 63 | video { 64 | display: inline-block; 65 | @if $legacy_support_for_ie { 66 | *display: inline; 67 | *zoom: 1; 68 | } 69 | } 70 | 71 | // 1. Prevents modern browsers from displaying 'audio' without controls 72 | // 2. Remove excess height in iOS5 devices 73 | 74 | audio:not([controls]) { 75 | display: none; // 1 76 | height: 0; // 2 77 | } 78 | 79 | // 80 | // Address `[hidden]` styling not present in IE 8/9. 81 | // Hide the `template` element in IE, Safari, and Firefox < 22. 82 | // 83 | 84 | [hidden], template { 85 | display: none; 86 | } 87 | 88 | // ============================================================================= 89 | // Base 90 | // ============================================================================= 91 | 92 | // 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units 93 | // http://clagnut.com/blog/348/#c790 94 | // 2. Prevents iOS text size adjust after orientation change, without disabling user zoom 95 | // www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ 96 | 97 | html { 98 | @if $legacy_support_for_ie { 99 | font-size: 100%; // 1 100 | } 101 | background: $background; 102 | color: $color; 103 | -webkit-text-size-adjust: 100%; // 2 104 | -ms-text-size-adjust: 100%; // 2 105 | } 106 | 107 | // Addresses font-family inconsistency between 'textarea' and other form elements. 108 | 109 | html, 110 | button, 111 | input, 112 | select, 113 | textarea { 114 | font-family: $normalized_font_family; 115 | } 116 | 117 | // Addresses margins handled incorrectly in IE6/7 118 | 119 | body { 120 | margin: 0; 121 | } 122 | 123 | // ============================================================================= 124 | // Links 125 | // ============================================================================= 126 | 127 | // 1. Remove the gray background color from active links in IE 10. 128 | // 2. Addresses outline displayed oddly in Chrome 129 | // 3. Improves readability when focused and also mouse hovered in all browsers 130 | // people.opera.com/patrickl/experiments/keyboard/test 131 | 132 | a { 133 | // 1 134 | 135 | background: transparent; 136 | 137 | // 2 138 | 139 | &:focus { 140 | outline: thin dotted; 141 | } 142 | 143 | // 3 144 | 145 | &:hover, 146 | &:active { 147 | outline: 0; 148 | } 149 | } 150 | 151 | // ============================================================================= 152 | // Typography 153 | // ============================================================================= 154 | 155 | // Addresses font sizes and margins set differently in IE6/7 156 | // Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 157 | 158 | @if $normalize_headings == true { 159 | h1 { 160 | font-size: $h1_font_size; 161 | margin: $h1_margin; 162 | } 163 | 164 | h2 { 165 | font-size: $h2_font_size; 166 | margin: $h2_margin; 167 | } 168 | 169 | h3 { 170 | font-size: $h3_font_size; 171 | margin: $h3_margin; 172 | } 173 | 174 | h4 { 175 | font-size: $h4_font_size; 176 | margin: $h4_margin; 177 | } 178 | 179 | h5 { 180 | font-size: $h5_font_size; 181 | margin: $h5_margin; 182 | } 183 | 184 | h6 { 185 | font-size: $h6_font_size; 186 | margin: $h6_margin; 187 | } 188 | } 189 | 190 | // Addresses styling not present in IE 8/9, S5, Chrome 191 | 192 | abbr[title] { 193 | border-bottom: 1px dotted; 194 | } 195 | 196 | // Addresses style set to 'bolder' in FF3+, S4/5, Chrome 197 | 198 | b, 199 | strong { 200 | font-weight: bold; 201 | } 202 | 203 | @if $legacy_support_for_ie { 204 | blockquote { 205 | margin: 1em 40px; 206 | } 207 | } 208 | 209 | // Addresses styling not present in S5, Chrome 210 | 211 | dfn { 212 | font-style: italic; 213 | } 214 | 215 | // Addresses styling not present in IE6/7/8/9 216 | 217 | mark { 218 | background: #ff0; 219 | color: #000; 220 | } 221 | 222 | // Addresses margins set differently in IE6/7 223 | @if $legacy_support_for_ie { 224 | p, 225 | pre { 226 | margin: 1em 0; 227 | } 228 | } 229 | 230 | // Corrects font family set oddly in IE6, S4/5, Chrome 231 | // en.wikipedia.org/wiki/User:Davidgothberg/Test59 232 | 233 | code, 234 | kbd, 235 | pre, 236 | samp { 237 | font-family: monospace, serif; 238 | @if $legacy_support_for_ie { 239 | _font-family: 'courier new', monospace; 240 | } 241 | font-size: 1em; 242 | } 243 | 244 | // Improves readability of pre-formatted text in all browsers 245 | 246 | pre { 247 | white-space: pre; 248 | white-space: pre-wrap; 249 | word-wrap: break-word; 250 | } 251 | 252 | // Set consistent quote types. 253 | 254 | q { 255 | quotes: "\201C" "\201D" "\2018" "\2019"; 256 | } 257 | 258 | // 1. Addresses CSS quotes not supported in IE6/7 259 | // 2. Addresses quote property not supported in S4 260 | 261 | // 1 262 | @if $legacy_support_for_ie { 263 | q { 264 | quotes: none; 265 | } 266 | } 267 | 268 | // 2 269 | q:before, 270 | q:after { 271 | content: ''; 272 | content: none; 273 | } 274 | 275 | // Address inconsistent and variable font size in all browsers. 276 | 277 | small { 278 | font-size: 80%; 279 | } 280 | 281 | // Prevents sub and sup affecting line-height in all browsers 282 | // gist.github.com/413930 283 | 284 | sub, 285 | sup { 286 | font-size: 75%; 287 | line-height: 0; 288 | position: relative; 289 | vertical-align: baseline; 290 | } 291 | 292 | sup { 293 | top: -0.5em; 294 | } 295 | 296 | sub { 297 | bottom: -0.25em; 298 | } 299 | 300 | // ============================================================================= 301 | // Lists 302 | // ============================================================================= 303 | 304 | // Addresses margins set differently in IE6/7 305 | @if $legacy_support_for_ie { 306 | dl, 307 | menu, 308 | ol, 309 | ul { 310 | margin: 1em 0; 311 | } 312 | } 313 | 314 | @if $legacy_support_for_ie { 315 | dd { 316 | margin: 0 0 0 40px; 317 | } 318 | } 319 | 320 | // Addresses paddings set differently in IE6/7 321 | @if $legacy_support_for_ie { 322 | menu, 323 | ol, 324 | ul { 325 | padding: 0 0 0 40px; 326 | } 327 | } 328 | 329 | // Corrects list images handled incorrectly in IE7 330 | 331 | nav { 332 | ul, 333 | ol { 334 | @if $legacy_support_for_ie { 335 | list-style-image: none; 336 | } 337 | } 338 | } 339 | 340 | // ============================================================================= 341 | // Embedded content 342 | // ============================================================================= 343 | 344 | // 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 345 | // 2. Improves image quality when scaled in IE7 346 | // code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ 347 | 348 | img { 349 | border: 0; // 1 350 | @if $legacy_support_for_ie { 351 | -ms-interpolation-mode: bicubic; // 2 352 | } 353 | } 354 | 355 | // Corrects overflow displayed oddly in IE9 356 | 357 | svg:not(:root) { 358 | overflow: hidden; 359 | } 360 | 361 | // ============================================================================= 362 | // Figures 363 | // ============================================================================= 364 | 365 | // Addresses margin not present in IE6/7/8/9, S5, O11 366 | 367 | figure { 368 | margin: 0; 369 | } 370 | 371 | // ============================================================================= 372 | // Forms 373 | // ============================================================================= 374 | 375 | // Corrects margin displayed oddly in IE6/7 376 | @if $legacy_support_for_ie { 377 | form { 378 | margin: 0; 379 | } 380 | } 381 | 382 | // Define consistent border, margin, and padding 383 | 384 | fieldset { 385 | border: 1px solid #c0c0c0; 386 | margin: 0 2px; 387 | padding: 0.35em 0.625em 0.75em; 388 | } 389 | 390 | // 1. Corrects color not being inherited in IE6/7/8/9 391 | // 2. Remove padding so people aren't caught out if they zero out fieldsets. 392 | // 3. Corrects text not wrapping in FF3 393 | // 4. Corrects alignment displayed oddly in IE6/7 394 | 395 | legend { 396 | border: 0; // 1 397 | padding: 0; // 2 398 | white-space: normal; // 3 399 | @if $legacy_support_for_ie { 400 | *margin-left: -7px; // 4 401 | } 402 | } 403 | 404 | // 1. Correct font family not being inherited in all browsers. 405 | // 2. Corrects font size not being inherited in all browsers 406 | // 3. Addresses margins set differently in IE6/7, FF3+, S5, Chrome 407 | // 4. Improves appearance and consistency in all browsers 408 | 409 | button, 410 | input, 411 | select, 412 | textarea { 413 | font-family: inherit; // 1 414 | font-size: 100%; // 2 415 | margin: 0; // 3 416 | vertical-align: baseline; // 4 417 | @if $legacy_support_for_ie { 418 | *vertical-align: middle; // 4 419 | } 420 | } 421 | 422 | // Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet 423 | 424 | button, 425 | input { 426 | line-height: normal; 427 | } 428 | 429 | // Address inconsistent `text-transform` inheritance for `button` and `select`. 430 | // All other form control elements do not inherit `text-transform` values. 431 | // Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. 432 | // Correct `select` style inheritance in Firefox 4+ and Opera. 433 | 434 | button, 435 | select { 436 | text-transform: none; 437 | } 438 | 439 | // 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 440 | // and `video` controls 441 | // 2. Corrects inability to style clickable 'input' types in iOS 442 | // 3. Improves usability and consistency of cursor style between image-type 443 | // 'input' and others 444 | // 4. Removes inner spacing in IE7 without affecting normal text inputs 445 | // Known issue: inner spacing remains in IE6 446 | 447 | button, 448 | html input[type="button"], // 1 449 | input[type="reset"], 450 | input[type="submit"] { 451 | -webkit-appearance: button; // 2 452 | cursor: pointer; // 3 453 | @if $legacy_support_for_ie { 454 | *overflow: visible; // 4 455 | } 456 | } 457 | 458 | // Re-set default cursor for disabled elements 459 | 460 | button[disabled], 461 | input[disabled] { 462 | cursor: default; 463 | } 464 | 465 | // 1. Address box sizing set to `content-box` in IE 8/9/10. 466 | // 2. Remove excess padding in IE 8/9/10. 467 | // 3. Removes excess padding in IE7 468 | // Known issue: excess padding remains in IE6 469 | 470 | input[type="checkbox"], 471 | input[type="radio"] { 472 | box-sizing: border-box; // 1 473 | padding: 0; // 2 474 | @if $legacy_support_for_ie { 475 | *height: 13px; // 3 476 | *width: 13px; // 3 477 | } 478 | } 479 | 480 | // 1. Addresses appearance set to searchfield in S5, Chrome 481 | // 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) 482 | 483 | input[type="search"] { 484 | -webkit-appearance: textfield; // 1 485 | -moz-box-sizing: content-box; 486 | -webkit-box-sizing: content-box; // 2 487 | box-sizing: content-box; 488 | } 489 | 490 | // Remove inner padding and search cancel button in Safari 5 and Chrome 491 | // on OS X. 492 | 493 | input[type="search"]::-webkit-search-cancel-button, 494 | input[type="search"]::-webkit-search-decoration { 495 | -webkit-appearance: none; 496 | } 497 | 498 | // Removes inner padding and border in FF3+ 499 | // www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ 500 | 501 | button, input { 502 | &::-moz-focus-inner { 503 | border: 0; 504 | padding: 0; 505 | } 506 | } 507 | 508 | // 1. Removes default vertical scrollbar in IE6/7/8/9 509 | // 2. Improves readability and alignment in all browsers 510 | 511 | textarea { 512 | overflow: auto; // 1 513 | vertical-align: top; // 2 514 | } 515 | 516 | // ============================================================================= 517 | // Tables 518 | // ============================================================================= 519 | 520 | // Remove most spacing between table cells 521 | 522 | table { 523 | border-collapse: collapse; 524 | border-spacing: 0; 525 | } 526 | 527 | 528 | * { 529 | box-sizing: border-box; 530 | -moz-box-sizing: border-box; 531 | -webkit-box-sizing: border-box; 532 | } -------------------------------------------------------------------------------- /forms/static/scss/reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /forms/static/scss/typography.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 18px; 3 | line-height: 1.5em; 4 | font-family: 'proxima-nova-soft', sans-serif; 5 | } 6 | 7 | h1, h2, h3, h4, h5, h6, p { 8 | 9 | font-family: 'proxima-nova-soft', sans-serif; 10 | 11 | &:first-child { 12 | margin-top: 0; 13 | } 14 | &:last-child { 15 | margin-bottom: 0; 16 | } 17 | 18 | &>small { 19 | font-size: 0.65em; 20 | color: #aaa; 21 | } 22 | 23 | -webkit-font-smoothing: antialiased; 24 | } 25 | 26 | h1, h2, h3, h4, h5, h6 { 27 | font-weight: 600; 28 | line-height: 1.3em; 29 | 30 | 31 | color: $dark-blue; 32 | 33 | &.light { 34 | font-weight: 400; 35 | color: #444; 36 | } 37 | } 38 | 39 | p { 40 | line-height: 1.5em; 41 | color: #444; 42 | } 43 | 44 | a { 45 | color: $green; 46 | text-decoration: none; 47 | transition: color 0.3s ease-in-out; 48 | &:hover{ 49 | color: $dark-green; 50 | } 51 | } 52 | 53 | .center { 54 | text-align: center; 55 | } 56 | 57 | .right { 58 | text-align: right; 59 | } 60 | 61 | .caps { 62 | text-transform: uppercase; 63 | } -------------------------------------------------------------------------------- /forms/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 |
5 |
6 |

We couldn't find the page

7 |

It's missing, no idea where it is.

8 |
9 |
10 | 11 | {% endblock %} -------------------------------------------------------------------------------- /forms/templates/500.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 |
5 |
6 |

Something went wrong

7 |

Sorry, we're investigating.

8 |
9 |
10 | 11 | {% endblock %} -------------------------------------------------------------------------------- /forms/templates/confirmation_sent.html: -------------------------------------------------------------------------------- 1 | {% set current_step = 'progress' %} 2 | 3 | {% extends 'layouts/progress.html' %} 4 | 5 | {% block content %} 6 | 7 |

Confirm your email

8 |

We've sent a link to your email. To prevent spam, you'll have to confirm your email before things start working.

9 |

Email: {{email}}, Site {{host}}

10 | 11 | {% endblock %} -------------------------------------------------------------------------------- /forms/templates/email/confirm.html: -------------------------------------------------------------------------------- 1 |

Thanks for using {{config.SERVICE_NAME}}. Congrats, you're one step away from making forms on {{host}} functional.

2 | 3 |

All you have to do is click the link below to confirm your email. To prevent spamming, you'll have to repeat this step for every page where you insert your form. Note that you won't be receiving any emails from the site before you confirm your email.

4 | 5 |

Click here to confirm

6 | 7 |

We hope you enjoy using {{config.SERVICE_NAME}}. If you have any questions, feel free to shoot an email to {{config.CONTACT_EMAIL}}

8 | 9 |

Best,
10 | Lauri and Cole

11 | 12 |
13 | 14 |

Why did I receive this email?
15 | Someone (hopefully you?) used your email with the {{config.SERVICE_NAME}} API on {{host}}. If this wasn't you, no worries. This is the only email you'll get.

-------------------------------------------------------------------------------- /forms/templates/email/confirm.txt: -------------------------------------------------------------------------------- 1 | Thanks for using {{config.SERVICE_NAME}}. Congrats, you're one step away from making forms on {{host}} functional. 2 | 3 | All you have to do is click the link below to confirm your email. To prevent spamming, you'll have to repeat this step for every page where you insert your form. Note that you won't be receiving any emails from the site before you confirm your email. 4 | 5 | Link: {{nonce_link}} 6 | 7 | We hope you enjoy using {{config.SERVICE_NAME}}. If you have any questions, feel free to shoot an email to {{config.CONTACT_EMAIL}}. 8 | 9 | Best, 10 | Lauri and Cole 11 | 12 | ---- 13 | 14 | Why did I receive this email? 15 | 16 | Someone (hopefully you?) used your email with the {{config.SERVICE_NAME}} API on {{host}}. If this wasn't you, no worries. This is the only email you'll get. -------------------------------------------------------------------------------- /forms/templates/email/form.html: -------------------------------------------------------------------------------- 1 |

Hey there, 2 | 3 |

Someone just submitted your form on {{host}}.

4 | 5 |

Here's what they had to say:

6 | 7 |
8 | 9 | 10 | {% for k in keys %} 11 | 12 | 13 | 14 | 15 | {% endfor %} 16 |
{{k}}: {{data.get(k,'')|nl2br|safe}}
17 | 18 |
19 | 20 |

You are receiving this because you confirmed this email address on {{config.SERVICE_NAME}}. If you don't remember doing that, or no longer wish to receive these emails, please remove the form on {{host}} or send an email to {{config.CONTACT_EMAIL}}.

21 | -------------------------------------------------------------------------------- /forms/templates/email/form.txt: -------------------------------------------------------------------------------- 1 | Hey there, 2 | 3 | Someone just submitted your form on {{host}}. Here's what they had to say: 4 | 5 | {% for k in keys %} 6 | {{k}}: 7 | {{data[k]}} 8 | 9 | {% endfor %} 10 | --- 11 | 12 | You are receiving this because you confirmed this email address on {{config.SERVICE_NAME}}. If you don't remember doing that, or no longer wish to receive these emails, please remove the form on {{host}} or send an email to {{config.CONTACT_EMAIL}}. 13 | -------------------------------------------------------------------------------- /forms/templates/email_confirmed.html: -------------------------------------------------------------------------------- 1 | {% set current_step = 'done' %} 2 | 3 | {% extends 'layouts/progress.html' %} 4 | 5 | {% block content %} 6 | 7 |

Email confirmed

8 |

Wohoo, your email has been confirmed. Next time someone submits your form, we'll forward it to your email. Enjoy!

9 |

Email: {{email}}, Site {{host}}

10 | 11 | {% endblock %} -------------------------------------------------------------------------------- /forms/templates/error.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 | 9 | 10 | 11 | 12 |
13 |
14 | 15 | {% if title %} 16 |

{{title}}

17 | {% endif %} 18 | 19 | {% if text %} 20 |

{{text|safe}}

21 | {% endif %} 22 | 23 |
24 |
25 | 26 | {% endblock %} 27 | 28 | {% block footer %}Service by {{config.SERVICE_NAME}}. Read more.{% endblock %} -------------------------------------------------------------------------------- /forms/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{config.SERVICE_NAME}} | Functional HTML forms 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 46 | 47 |
48 | 49 |
50 |
51 |

Setting it up is easy and free. Here's how:

52 |

You don't even have to register.

53 |
54 |
55 | 56 |
57 |
58 |

1. Setup the HTML form

59 |

Change your form's action-attribute to this and replace your@email.com with your own email.

60 |

61 |
62 |
63 | 64 |
65 |
66 |

2. Submit the form and confirm your email address

67 |

Go to your website and submit the form once. This will send you an email asking to confirm your email address, so that no one can start sending you spam from random websites.

68 |
69 |
70 | 71 |
72 |
73 |

3. All set, receive emails

74 |

From now on, when someone submits that form, we'll forward you the data as email.

75 | 76 |
77 |
78 | 79 |
80 | 81 |
82 | 83 |
84 |

Some questions you might have:

85 |
86 | 87 |
88 |
89 |
90 |

Who are you guys?

91 |

We're the same folks who make Brace.io, the simple way to host websites. {{config.SERVICE_NAME}} is a side project that solves a problem many of Brace.io users seem to face: having forms on otherwise static HTML pages.

92 |
93 |
94 |
95 |
96 |

What about privacy?

97 |

We don't store contents of the form submissions. Emails are sent using Mailgun's API, so on that end their privacy policies apply.

98 |
99 |
100 |
101 | 102 |
103 |
104 |
105 |

How much does it cost?

106 |

{{config.SERVICE_NAME}} are free for 1000 submissions per email each month. If you need more, please reach out.

107 |
108 |
109 |
110 |
111 |

Are there any limits?

112 |

Yep, for now we cap submissions to 1000 per email for each month. If you need more, please reach out to {{config.CONTACT_EMAIL}}.

113 |
114 |
115 |
116 | 117 |
118 | 119 |
120 | 121 |
122 |
123 |

Advanced features:

124 |

Form inputs can have specially named name-attributes, which alter functionality. They are all prefixed with an underscore.

125 |
126 |
127 | 128 |
129 |
130 |

_replyto

131 |

This value is used for the email's Reply-To field. This way you can directly "Reply" to the email to respond to the person who originally submitted the form.

132 |

133 |
134 |
135 | 136 |
137 |
138 |

_next

139 |

By default, after submitting a form the user is shown the {{config.SERVICE_NAME}} "Thank You" page. You can provide an alternative URL for that page.

140 |

141 |
142 |
143 | 144 |
145 |
146 |

_subject

147 |

This value is used for the email's subject, so that you can quickly reply to submissions without having to edit the subject line each time.

148 |

149 |
150 |
151 | 152 |
153 |
154 |

_cc

155 |

This value is used for the email's CC Field. This lets you send a copy of each submission to another email address.

156 |

157 |
158 |
159 | 160 |
161 |
162 |

_gotcha

163 |

Add this "honeypot" field to avoid spam by fooling scrapers. If a value is provided, the submission will be silently ignored. The input should be hidden with CSS.

164 |

165 |
166 |
167 | 168 |
169 |
170 |

Using AJAX

171 |

You can use {{config.SERVICE_NAME}} via AJAX. This even works cross-origin. The trick is to set the Accept header to application/json. If you're using jQuery this can be done like so: 172 |

173 | $.ajax({
174 |     url: "{{config.API_ROOT}}/you@email.com",
175 |     method: "POST",
176 |     data: {message: "hello!"},
177 |     dataType: "json"
178 | }); 179 |

180 |
181 |
182 | 183 | 191 | 192 |
193 | 194 |
195 | 196 |
197 |
198 |

{{config.SERVICE_NAME}} is a tool made by Brace.io. To contact us send an email to {{config.CONTACT_EMAIL}} or use the form on the right.

199 |
200 |
201 |
202 | 203 | 204 | 205 | 206 |
207 |
208 |
209 | 210 |
211 | 212 | 213 | -------------------------------------------------------------------------------- /forms/templates/info.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 | 9 | 10 | 11 | 12 |
13 |
14 | 15 | {% if title %} 16 |

{{title}}

17 | {% endif %} 18 | 19 | {% if text %} 20 |

{{text|safe}}

21 | {% endif %} 22 | 23 |
24 |
25 | 26 | {% endblock %} 27 | 28 | {% block footer %}Service by {{config.SERVICE_NAME}}. Read more.{% endblock %} -------------------------------------------------------------------------------- /forms/templates/layouts/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}{{config.SERVICE_NAME}}{% endblock %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | {% block base %} 21 |

Nothing to see here

22 | {% endblock %} 23 |
24 |
25 | 26 |
27 |
28 | 29 | -------------------------------------------------------------------------------- /forms/templates/layouts/progress.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 | 5 | 19 | 20 | 21 | 22 |
23 |
24 | {% block content %} 25 | 26 | {% endblock %} 27 |
28 |
29 | 30 | {% endblock %} 31 | 32 | {% block footer %}Part of the {{config.SERVICE_NAME}} sign up process. Read more.{% endblock %} -------------------------------------------------------------------------------- /forms/templates/loaderio-d7b004d89a8ac03ebe643374fab3a57b.html: -------------------------------------------------------------------------------- 1 | loaderio-d7b004d89a8ac03ebe643374fab3a57b -------------------------------------------------------------------------------- /forms/templates/thanks.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.html' %} 2 | 3 | {% block base %} 4 | 5 | 10 | 11 |
12 |
13 |

Form submitted successfully

14 | {% if request.args.get('next') %} 15 | Return to original site 16 | {% endif %} 17 |
18 |
19 | 20 | 21 | 22 | {% endblock %} -------------------------------------------------------------------------------- /forms/utils.py: -------------------------------------------------------------------------------- 1 | from datetime import timedelta 2 | from functools import update_wrapper 3 | from flask import make_response, current_app, request, url_for, jsonify 4 | 5 | import uuid 6 | 7 | # decorators 8 | 9 | def crossdomain(origin=None, methods=None, headers=None, 10 | max_age=21600, attach_to_all=True, 11 | automatic_options=True): 12 | if methods is not None: 13 | methods = ', '.join(sorted(x.upper() for x in methods)) 14 | if headers is not None and not isinstance(headers, basestring): 15 | headers = ', '.join(x.upper() for x in headers) 16 | if not isinstance(origin, basestring): 17 | origin = ', '.join(origin) 18 | if isinstance(max_age, timedelta): 19 | max_age = max_age.total_seconds() 20 | 21 | def get_methods(): 22 | if methods is not None: 23 | return methods 24 | 25 | options_resp = current_app.make_default_options_response() 26 | return options_resp.headers['allow'] 27 | 28 | def decorator(f): 29 | def wrapped_function(*args, **kwargs): 30 | if automatic_options and request.method == 'OPTIONS': 31 | resp = current_app.make_default_options_response() 32 | else: 33 | resp = make_response(f(*args, **kwargs)) 34 | if not attach_to_all and request.method != 'OPTIONS': 35 | return resp 36 | 37 | h = resp.headers 38 | h['Access-Control-Allow-Origin'] = origin 39 | 40 | if request.method == 'OPTIONS': 41 | h['Access-Control-Allow-Methods'] = get_methods() 42 | h['Access-Control-Max-Age'] = str(max_age) 43 | if headers is not None: 44 | h['Access-Control-Allow-Headers'] = headers 45 | 46 | return resp 47 | 48 | f.provide_automatic_options = False 49 | return update_wrapper(wrapped_function, f) 50 | return decorator 51 | 52 | 53 | def request_wants_json(): 54 | if request.headers.get('X_REQUESTED_WITH','').lower() == 'xmlhttprequest': 55 | return True 56 | best = request.accept_mimetypes \ 57 | .best_match(['application/json', 'text/html']) 58 | return best == 'application/json' and \ 59 | request.accept_mimetypes[best] > \ 60 | request.accept_mimetypes['text/html'] 61 | 62 | 63 | def jsonerror(code, *args, **kwargs): 64 | resp = jsonify(*args, **kwargs) 65 | resp.status_code = code 66 | return resp 67 | 68 | 69 | def uuidslug(): 70 | return uuid2slug(uuid.uuid4()) 71 | 72 | 73 | def uuid2slug(uuidobj): 74 | return uuidobj.bytes.encode('base64').rstrip('=\n').replace('/', '_') 75 | 76 | 77 | def slug2uuid(slug): 78 | return str(uuid.UUID(bytes=(slug + '==').replace('_', '/').decode('base64'))) 79 | 80 | 81 | def get_url(endpoint, secure=False, **values): 82 | ''' protocol preserving url_for ''' 83 | path = url_for(endpoint, **values) 84 | if secure: 85 | url_parts = request.url.split('/', 3) 86 | path = "https://" + url_parts[2] + path 87 | return path -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from flask.ext.script import Manager 4 | 5 | from forms import create_app, app 6 | 7 | forms_app = create_app() 8 | manager = Manager(forms_app) 9 | 10 | @manager.command 11 | def run(port=5000): 12 | app.run(port=int(port)) 13 | 14 | @manager.command 15 | def show_list(): 16 | print 'Listing all referer / email pairs and counts...' 17 | 18 | values = [] 19 | 20 | for key in app.REDIS.keys('*counter*'): 21 | count = int(app.REDIS.get(key)) 22 | keyhash = key.split('_')[-1] 23 | email, host = app._get_values_for_hash(keyhash) 24 | values.append((count, email, host)) 25 | 26 | values.sort(key=lambda x: x[0], reverse=True) 27 | 28 | total = {} 29 | total['Pairs'] = len(values) 30 | total['Sent'] = sum([x[0] for x in values]) 31 | total['Unique'] = len(set([x[1] for x in values])) 32 | 33 | def format_dict(d): 34 | return ', '.join([k+': '+str(d[k]) for k in d]) 35 | 36 | print '\n---\n' 37 | 38 | print 'Totals - ', format_dict(total) 39 | 40 | print '\n---\n' 41 | 42 | for v in values: print v 43 | 44 | print '\n---\n' 45 | 46 | print 'Totals - ', format_dict(total) 47 | 48 | print 'Done' 49 | 50 | 51 | def _matchhosts(name): 52 | r = app.REDIS 53 | keys = r.keys('forms_hash_host_*') 54 | hosts = filter(lambda x: re.match(r".*%s"%name, r.get(x)), keys) 55 | return map(lambda x: x.split("_")[-1], hosts) 56 | 57 | 58 | def _print(hostid): 59 | r = app.REDIS 60 | keys = r.keys("*%s*" % hostid) 61 | results = dict((k,r.get(k)) for k in keys) 62 | print results 63 | 64 | 65 | def _del(hostid): 66 | r = app.REDIS 67 | keys = r.keys("*%s*" % hostid) 68 | for k in keys: 69 | r.delete(k) 70 | 71 | 72 | @manager.command 73 | def print_hosts(name): 74 | count = 0 75 | for host in _matchhosts(name): 76 | _print(host) 77 | count +=1 78 | print "found %d items" % count 79 | 80 | 81 | @manager.command 82 | def delete_hosts(name): 83 | count = 0 84 | for host in _matchhosts(name): 85 | _del(host) 86 | count +=1 87 | print "deleted %d items" % count 88 | 89 | 90 | if __name__ == "__main__": 91 | manager.run() 92 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | flask-script 3 | redis 4 | requests==2.0.0 5 | paste 6 | gunicorn --------------------------------------------------------------------------------