├── public
├── favicon.png
├── style
│ ├── icon
│ │ ├── todos.eot
│ │ ├── todos.ttf
│ │ ├── todos.woff
│ │ └── todos.svg
│ ├── font
│ │ ├── OpenSans-Light-webfont.eot
│ │ ├── OpenSans-Light-webfont.ttf
│ │ ├── OpenSans-Light-webfont.woff
│ │ ├── OpenSans-Regular-webfont.eot
│ │ ├── OpenSans-Regular-webfont.ttf
│ │ ├── OpenSans-Regular-webfont.woff
│ │ └── OpenSans-Light-webfont.svg
│ ├── main.css
│ └── reset.css
├── apple-touch-icon-precomposed.png
├── index.html
└── img
│ └── logo-todos.svg
├── .gitignore
├── README.md
├── lib
├── util.js
├── constants.js
└── store.js
├── server.js
├── webpack.config.js
├── client
├── views
│ ├── Notifications.jsx
│ ├── App.jsx
│ ├── User.jsx
│ ├── list
│ │ ├── TaskItems.jsx
│ │ ├── Tasks.jsx
│ │ └── ListName.jsx
│ ├── ListTodos.jsx
│ ├── SignIn.jsx
│ └── Join.jsx
├── index.jsx
└── transfer.js
├── package.json
└── server
├── data.js
├── transfer.js
└── db.js
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/favicon.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | node_modules/
3 | .brackets.json
4 | public/bundle.js
5 | rethinkdb_data/
--------------------------------------------------------------------------------
/public/style/icon/todos.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/icon/todos.eot
--------------------------------------------------------------------------------
/public/style/icon/todos.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/icon/todos.ttf
--------------------------------------------------------------------------------
/public/style/icon/todos.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/icon/todos.woff
--------------------------------------------------------------------------------
/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Light-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Light-webfont.eot
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Light-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Light-webfont.ttf
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Light-webfont.woff
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Regular-webfont.eot
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Regular-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Regular-webfont.ttf
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobiblazeski/rio/HEAD/public/style/font/OpenSans-Regular-webfont.woff
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rio
2 | Port of meteor realtime todos application using RethinkDB, Rxjs, Socket.io & React
3 |
4 | Story https://medium.com/@bobiblazeski/of-pipes-and-feeds-6b443b9713e0
5 |
--------------------------------------------------------------------------------
/lib/util.js:
--------------------------------------------------------------------------------
1 | var Util = module.exports = {};
2 |
3 | var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
4 |
5 | Util.validateEmail = function validateEmail(email) {
6 | return re.test(email);
7 | };
8 |
9 | Util.validatePassword = function validatePassword(password) {
10 | return R.is(String,password) && password.length > 3;
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var app = require('koa')(),
2 | http= require('http'),
3 | serve= require('koa-static');
4 |
5 |
6 | app.use(serve(__dirname+'/public'));
7 |
8 | // This must come after last app.use()
9 | var server = http.Server(app.callback());
10 |
11 | var transfer = require('./server/transfer');
12 | transfer.setup(server);
13 |
14 |
15 | server.listen(4000);
16 | console.info('Now running on localhost:4000');
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './client/index.jsx',
3 | output: {
4 | path:__dirname+'/public',
5 | filename: "bundle.js"
6 | },
7 | module: {
8 | loaders: [
9 | {
10 | test: /\.jsx$/,
11 | loader: 'babel-loader'
12 | }
13 | ]
14 | },
15 | externals: {
16 | 'react': 'React',
17 | 'rx':'Rx',
18 | 'ramda':'R',
19 | 'immutable':'Immutable'
20 | },
21 | resolve: {
22 | extensions: ['','.js','.jsx']
23 | }
24 | };
--------------------------------------------------------------------------------
/client/views/Notifications.jsx:
--------------------------------------------------------------------------------
1 | var Notifications = module.exports = React.createClass({
2 | render : function(){
3 | return (
4 |
5 |
6 |
7 |
8 |
Trying to connect
9 |
There seems to be a connection issue
10 |
11 |
12 |
13 | );
14 | }
15 | });
--------------------------------------------------------------------------------
/lib/constants.js:
--------------------------------------------------------------------------------
1 | var Constants = module.exports = {
2 | sendAll: 'send all',
3 |
4 | taskChange: 'task change',
5 | taskCreate: 'task create',
6 | taskUpdate: 'task update',
7 | taskDelete: 'task delete',
8 |
9 | listChange: 'list change',
10 | listCreate: 'list create',
11 | listUpdate: 'list update',
12 | listDelete: 'list delete',
13 |
14 | signInRequest: 'signin request',
15 | signInResult: 'signin result',
16 | joinRequest: 'signup request',
17 | joinResult: 'signup result',
18 | clearAll: 'clear all',
19 | user: { email: '', id: '00000000-0000-0000-0000-000000000000'}
20 | };
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rio",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "start": "node server.js"
6 | },
7 | "dependencies": {
8 | "async": "^1.0.0",
9 | "immutable": "^3.7.3",
10 | "koa": "^0.20.0",
11 | "koa-static": "^1.4.9",
12 | "ramda": "^0.14.0",
13 | "react": "^0.13.3",
14 | "react-router": "^0.13.3",
15 | "rethinkdbdash": "^2.0.11",
16 | "rx": "^2.5.2",
17 | "socket.io": "^1.3.5"
18 | },
19 | "devDependencies": {
20 | "babel-core": "^5.4.7",
21 | "babel-loader": "^5.1.3",
22 | "node-libs-browser": "^0.5.2",
23 | "nodemon": "^1.3.7",
24 | "webpack": "^1.9.8"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Todos
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/client/views/App.jsx:
--------------------------------------------------------------------------------
1 | var { RouteHandler} = require('react-router');
2 |
3 | var Notifications = require('./Notifications');
4 | var ListTodos = require('./ListTodos');
5 | var User = require('./User');
6 |
7 | var App = module.exports = React.createClass({
8 | render: function () {
9 | return (
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 | }
23 | });
24 | //Below
25 | //
--------------------------------------------------------------------------------
/client/index.jsx:
--------------------------------------------------------------------------------
1 | var Router = require('react-router');
2 | var { Route, Redirect, RouteHandler, DefaultRoute, Link} = Router;
3 |
4 | var App = require('./views/App');
5 | var SignIn = require('./views/SignIn');
6 | var Join = require('./views/Join');
7 | var Tasks = require('./views/list/Tasks');
8 | var Transfer = require('./transfer');
9 |
10 |
11 | var routes = (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | Router.run(routes, Router.HistoryLocation, function(Handler){
21 | React.render(, document.body)
22 | });
23 |
24 | //
--------------------------------------------------------------------------------
/lib/store.js:
--------------------------------------------------------------------------------
1 | var Rx = require('rx');
2 | var Immutable = require('immutable');
3 | var Constants = require('./constants');
4 |
5 | var Store = module.exports = {
6 | user : new Rx.BehaviorSubject(Constants.user), // Client only
7 | allLists : new Rx.BehaviorSubject(Immutable.Map({})),// Client only
8 | allTasks : new Rx.BehaviorSubject(Immutable.Map({})),// Client only
9 | sendAll: new Rx.BehaviorSubject(),
10 |
11 | signInRequest : new Rx.BehaviorSubject(),
12 | signInResult : new Rx.BehaviorSubject(),
13 | joinRequest : new Rx.BehaviorSubject(),
14 | joinResult : new Rx.BehaviorSubject(),
15 | listChange : new Rx.BehaviorSubject(),
16 | listCreate : new Rx.BehaviorSubject(),
17 | listUpdate : new Rx.BehaviorSubject(),
18 | listDelete : new Rx.BehaviorSubject(),
19 | taskChange : new Rx.BehaviorSubject(),
20 | taskCreate : new Rx.BehaviorSubject(),
21 | taskUpdate : new Rx.BehaviorSubject(),
22 | taskDelete : new Rx.BehaviorSubject()
23 | };
--------------------------------------------------------------------------------
/client/views/User.jsx:
--------------------------------------------------------------------------------
1 | var { Link} = require('react-router');
2 |
3 | var Store = require('../../lib/store');
4 | var Constants = require('../../lib/constants');
5 |
6 | var User = module.exports = React.createClass({
7 | getInitialState: function () {
8 | return Store.user.value;
9 | },
10 | componentWillMount: function () {
11 |
12 | this.onLogout = function(){
13 | Store.user.onNext(Constants.user);
14 | }
15 | },
16 | render: function () {
17 | return this.state.email === '' ?
18 | (
19 | Sign In
20 | Join
21 |
) :
22 | ();
29 | },
30 | componentDidMount: function(){
31 | Store.user.skip(1).subscribe(function(user){
32 | console.log('User componentWillMount',user);
33 | this.setState(user);
34 | }.bind(this));
35 | }
36 |
37 | });
38 |
39 |
--------------------------------------------------------------------------------
/client/views/list/TaskItems.jsx:
--------------------------------------------------------------------------------
1 | var Store = require('../../../lib/store');
2 |
3 | var TaskItems = module.exports = React.createClass({
4 | componentWillMount: function(){
5 | this.onChecked = function(user,taskId,event) {
6 | Store.taskUpdate.onNext({
7 | id: taskId,
8 | user: user,
9 | done: event.target.value
10 | })
11 | }.bind(this);
12 | },
13 | render: function(){
14 | var items = this.props.tasks.map(function (d) {
15 | var key = d.user+':'+d.list+':'+d.item;
16 | return (
17 |
30 | );
31 | }.bind(this));
32 | return (
33 |
34 | {items}
35 |
36 | );
37 | }
38 | });
--------------------------------------------------------------------------------
/client/views/list/Tasks.jsx:
--------------------------------------------------------------------------------
1 | var Store = require('../../../lib/store');
2 | var TaskItems = require('./TaskItems.jsx');
3 | var ListName = require('./ListName.jsx');
4 |
5 | var Tasks = module.exports = React.createClass({
6 | contextTypes: {
7 | router: React.PropTypes.func
8 | },
9 | getInitialState: function () {
10 | return {
11 | lists: Store.allLists.value,
12 | tasks: Store.allTasks.value
13 | }
14 | },
15 | componentWillMount: function () {
16 | Store.allLists.subscribe(function (lists) {
17 | this.setState({lists: lists});
18 | }.bind(this));
19 | Store.allTasks.subscribe(function (tasks) {
20 | this.setState({tasks: tasks});
21 | }.bind(this));
22 | },
23 | render: function () {
24 | var nameParam = this.context.router.getCurrentParams().name;
25 | if (!nameParam && this.state.lists.count() > 0) {
26 | nameParam = this.state.lists.first().id;
27 | }
28 | var list = this.state.lists.get(nameParam) || {id: '', name: 'unknown'};
29 | var tasksGrouped = R.groupBy(R.prop('list'), this.state.tasks.toArray());
30 | var tasks = tasksGrouped.hasOwnProperty(nameParam) ?
31 | tasksGrouped[nameParam] : [];
32 | return (
33 |
34 |
35 |
36 |
37 | );
38 | }
39 | });
--------------------------------------------------------------------------------
/server/data.js:
--------------------------------------------------------------------------------
1 | var R = require('ramda');
2 | var Constants = require('../lib/constants');
3 |
4 |
5 | var lists = [
6 | {
7 | user:Constants.user.id,
8 | name: "Meteor Principles",
9 | items: ["Data on the Wire",
10 | "One Language",
11 | "Database Everywhere",
12 | "Latency Compensation",
13 | "Full Stack Reactivity",
14 | "Embrace the Ecosystem",
15 | "Simplicity Equals Productivity"
16 | ]
17 | },
18 | {
19 | user:Constants.user.id,
20 | name: "Languages",
21 | items: ["Lisp",
22 | "C",
23 | "C++",
24 | "Python",
25 | "Ruby",
26 | "JavaScript",
27 | "Scala",
28 | "Erlang",
29 | "6502 Assembly"
30 | ]
31 | },
32 | {
33 | user:Constants.user.id,
34 | name: "Favorite Scientists",
35 | items: ["Ada Lovelace",
36 | "Grace Hopper",
37 | "Marie Curie",
38 | "Carl Friedrich Gauss",
39 | "Nikola Tesla",
40 | "Claude Shannon"
41 | ]
42 | }
43 | ];
44 |
45 | exports.lists = R.map(R.pick(['name','user']),lists);
46 |
47 | exports.tasks = function (dbLists) {
48 | console.log(dbLists);
49 | return R.reduce(function(acc,d) {
50 | return acc.concat(R.map(function (e) {
51 | var dbList = R.find(function(dbEntry){
52 | return dbEntry.name == d.name;
53 | },dbLists);
54 | return {
55 | user: Constants.user.id,
56 | list: dbList.id,
57 | item: e,
58 | done: false
59 | }
60 | }, d.items));
61 | },[],lists);
62 | };
63 |
64 |
65 |
--------------------------------------------------------------------------------
/client/views/ListTodos.jsx:
--------------------------------------------------------------------------------
1 | var Link = require('react-router').Link;
2 | var Store = require('../../lib/store');
3 |
4 |
5 | var ListTodos = module.exports = React.createClass({
6 | getInitialState: function(){
7 | return {
8 | lists: Immutable.Map({}),
9 | tasks: Immutable.Map({})
10 | }
11 | },
12 | componentWillMount : function(){
13 | Store.allLists.subscribe(function(lists){
14 | this.setState({ lists: lists });
15 | }.bind(this));
16 | Store.allTasks.subscribe(function(tasks){
17 | this.setState({ tasks: tasks });
18 | }.bind(this));
19 | this.onCreateList = function(){
20 | Store.listCreate.onNext({
21 | user: '',
22 | name: 'List '+Math.random().toFixed(3).toString()
23 | });
24 | }
25 | },
26 | render: function () {
27 | var pairs=R.toPairs( R.groupBy(R.prop('id'),this.state.lists.toArray()));
28 | var tasksGrouped=R.groupBy(R.prop('list'),this.state.tasks.toArray());
29 | var items = pairs.map(function(pair){
30 | var key = pair[0];
31 | var count = tasksGrouped.hasOwnProperty(key) ?
32 | R.reject(R.prop('done'), tasksGrouped[key]).length : 0;
33 | return (
34 |
38 | {count}
39 | {pair[1][0].name}
40 |
41 | );
42 | });
43 | return (
44 |
49 | );
50 | }
51 | });
--------------------------------------------------------------------------------
/client/views/SignIn.jsx:
--------------------------------------------------------------------------------
1 | var Link = require('react-router').Link;
2 | var Store = require('../../lib/store');
3 |
4 | var SignIn = module.exports = React.createClass({
5 | contextTypes: {
6 | router: React.PropTypes.func
7 | },
8 | getInitialState: function () {
9 | return {
10 | enabled : false,
11 | errors: []
12 | }
13 | },
14 | componentWillMount: function () {
15 | this.onSignIn = function(e){
16 | e.preventDefault();
17 | var email = React.findDOMNode(this.refs.email).value;
18 | var password = React.findDOMNode(this.refs.password).value;
19 | Store.signInRequest.onNext({
20 | email: email,
21 | password: password
22 | });
23 | }.bind(this);
24 | },
25 | render: function () {
26 | return (
27 |
28 |
35 |
36 |
37 |
Sign In.
38 |
Signing in allows you to view private lists
39 |
53 |
54 |
Need an account? Join Now.
55 |
56 |
57 | );
58 | }
59 | });
--------------------------------------------------------------------------------
/client/transfer.js:
--------------------------------------------------------------------------------
1 | var Store= require('../lib/store');
2 | var Ramda = require('ramda');
3 | var Constants = require('../lib/constants');
4 |
5 | var socket = io();
6 |
7 | var Transfer = module.exports = {};
8 |
9 | Transfer.setup = function setup(socket){
10 | socket.on(Constants.listChange,function(change){
11 | Store.listChange.onNext(change);
12 | });
13 | socket.on(Constants.taskChange,function(change){
14 | Store.taskChange.onNext(change);
15 | });
16 | function emit(address, data){
17 | console.log(address,data);
18 | socket.emit(address, R.merge(data,{ user: Store.user.value.id}));
19 | console.log('after emit',address,data);
20 | }
21 |
22 | Store.taskCreate.skip(1).subscribe(R.partial(emit,Constants.taskCreate));
23 | Store.taskUpdate.skip(1).subscribe(R.partial(emit,Constants.taskUpdate));
24 | Store.taskDelete.skip(1).subscribe(R.partial(emit,Constants.taskDelete));
25 |
26 | Store.listCreate.skip(1).subscribe(R.partial(emit,Constants.listCreate));
27 | Store.listUpdate.skip(1).subscribe(R.partial(emit,Constants.listUpdate));
28 | Store.listDelete.skip(1).subscribe(R.partial(emit,Constants.listDelete));
29 | // User management
30 | Store.signInRequest.skip(1).subscribe(R.partial(emit,Constants.signInRequest));
31 | socket.on(Constants.signInResult,function(result){
32 | Store.signInResult.onNext(result);
33 | });
34 | Store.joinRequest.skip(1).subscribe(R.partial(emit,Constants.joinRequest));
35 | socket.on(Constants.joinResult, function(result){
36 | console.log(Constants.joinResult,result);
37 | Store.joinResult.onNext(result);
38 | console.log('after',Constants.joinResult,result);
39 | });
40 | Store.user.subscribe(function(user){
41 | Store.allLists.onNext(filtered(Store.allLists.value,user.id));
42 | Store.allTasks.onNext(filtered(Store.allTasks.value,user.id));
43 | emit(Constants.sendAll,user);
44 | });
45 | };
46 |
47 | Transfer.setup(socket);
48 |
49 | Store.listChange.skip(1).subscribe(function(change){
50 | if(!change.new_val) { // DELETE
51 | Store.allLists.onNext(Store.allLists.value.delete(change.old_val.id));
52 | } else { // READ, UPDATE
53 | Store.allLists.onNext(Store.allLists.value.set(change.new_val.id, change.new_val));
54 | }
55 | });
56 |
57 | Store.taskChange.skip(1).subscribe(function(change){
58 | if(!change.new_val) { // DELETE
59 | Store.allTasks.onNext(Store.allTasks.value.delete(change.old_val.id));
60 | } else { // READ, UPDATE
61 | Store.allTasks.onNext(Store.allTasks.value.set(change.new_val.id, change.new_val));
62 | }
63 | });
64 |
65 | Store.signInResult.skip(1).subscribe(function(d){
66 | Store.user.onNext(d);
67 | });
68 |
69 | function filtered(map,user){
70 | return map.filter(function(d){
71 | return d.user == user;
72 | });
73 | }
74 |
--------------------------------------------------------------------------------
/server/transfer.js:
--------------------------------------------------------------------------------
1 | var socketIo = require('socket.io');
2 | var R = require('ramda');
3 | var Data = require('./data');
4 | var Db = require('./db');
5 | var Store = require('../lib/store');
6 | var Constants = require('../lib/constants');
7 |
8 | var Transfer = module.exports = {};
9 |
10 |
11 | Transfer.setup = function setup(server) {
12 | var io = socketIo(server);
13 | io.on('connection', function (socket) {
14 | Db.setup(function (err) {
15 | if (!err) {
16 | Db.changes(Store.listChange,'list');
17 | Db.changes(Store.taskChange,'task');
18 | listen(socket);
19 | }
20 | console.log('Database setup err:', err);
21 | });
22 | });
23 | };
24 |
25 | Store.joinRequest.skip(1).subscribe(function (val) {
26 | Db.join(val, function (res) {
27 | Store.joinResult.onNext(res);
28 | });
29 | });
30 |
31 | Store.signInRequest.skip(1).subscribe(function (val) {
32 | Db.signIn(val, function (res) {
33 | Store.signInResult.onNext(res);
34 | });
35 | });
36 |
37 |
38 | Store.taskCreate.skip(1).subscribe(R.partial(Db.createEntry,'task'));
39 | Store.taskUpdate.skip(1).subscribe(Db.taskUpdate);
40 | Store.taskDelete.skip(1).subscribe(Db.taskDelete);
41 |
42 | Store.listCreate.skip(1).subscribe(R.partial(Db.createEntry,'list'));
43 | Store.listUpdate.skip(1).subscribe(Db.listUpdate);
44 | Store.listDelete.skip(1).subscribe(Db.listDelete);
45 |
46 | var toChange = R.map(function (entry) {
47 | return entry.hasOwnProperty('old_val') ? entry
48 | : {old_val: null, new_val: entry};
49 | });
50 |
51 | function listen(socket) {
52 | function emit(address, change) {
53 | socket.emit(address, change);
54 | }
55 |
56 | socket.on(Constants.sendAll, function sendAll(user) {
57 | Db.allLists(user.id, function (err, res) {
58 | toChange(err ? [] : res).forEach(function (d) {
59 | emit(Constants.listChange, d);
60 | });
61 | });
62 | Db.allTasks(user.id, function (err, res) {
63 | toChange(err ? [] : res).forEach(function (d) {
64 | emit(Constants.taskChange, d);
65 | });
66 | });
67 | });
68 |
69 | Store.listChange.skip(1).subscribe(R.partial(emit, Constants.listChange));
70 | Store.taskChange.skip(1).subscribe(R.partial(emit, Constants.taskChange));
71 | Store.signInRequest.skip(1).subscribe(function (data) {
72 | socket.emit('signin', data);
73 | });
74 | function onNext(subject, data) {
75 | console.log(data);
76 | subject.onNext(data);
77 | }
78 |
79 | socket.on(Constants.taskCreate, R.partial(onNext, Store.taskCreate));
80 | socket.on(Constants.taskUpdate, R.partial(onNext, Store.taskUpdate));
81 | socket.on(Constants.taskDelete, R.partial(onNext, Store.taskDelete));
82 | socket.on(Constants.listCreate, R.partial(onNext, Store.listCreate));
83 | socket.on(Constants.listUpdate, R.partial(onNext, Store.listUpdate));
84 | socket.on(Constants.listDelete, R.partial(onNext, Store.listDelete));
85 | socket.on(Constants.joinRequest, R.partial(onNext, Store.joinRequest));
86 | socket.on(Constants.signInRequest, R.partial(onNext, Store.signInRequest));
87 |
88 | Store.joinResult.skip(1).subscribe(function (data) {
89 | socket.emit(Constants.joinResult, data);
90 | });
91 | Store.signInResult.skip(1).subscribe(function (data) {
92 | socket.emit(Constants.signInResult, data);
93 | });
94 | }
95 |
--------------------------------------------------------------------------------
/client/views/Join.jsx:
--------------------------------------------------------------------------------
1 | var Link = require('react-router').Link;
2 | var Util = require('../../lib/util');
3 | var Store = require('../../lib/store');
4 |
5 | var Join = module.exports = React.createClass({
6 | contextTypes: {
7 | router: React.PropTypes.func
8 | },
9 | getInitialState: function(){
10 | return { errors: []};
11 | },
12 | componentWillMount: function(){
13 | Store.joinResult.skip(1).subscribe(function(res){
14 | if(res.hasOwnProperty('errors')){
15 | this.setState({ errors: res.errors });
16 | } else {
17 | Store.user.onNext(res);
18 | this.context.router.transitionTo('/');
19 | }
20 | }.bind(this));
21 | this.onJoin = function(e){
22 | e.preventDefault();
23 | var errors = validateJoin(this.refs.email.value,
24 | this.refs.password.value, this.refs.confirm.value);
25 | if(errors.length) {
26 | this.setState({errors: errors});
27 | } else {
28 | var email = React.findDOMNode(this.refs.email).value;
29 | var password = React.findDOMNode(this.refs.password).value;
30 | console.log('onJoin',email,password);
31 | Store.joinRequest.onNext({
32 | email: email,
33 | password: password
34 | });
35 | }
36 | }.bind(this);
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
49 |
50 |
51 |
Join.
52 |
Joining allows you to make private lists
53 |
70 |
71 |
Have an account? Sign in
72 |
73 |
74 | );
75 | }
76 | });
77 |
78 | function validateJoin(email,password,confirm) {
79 | var errors = [];
80 | if(Util.validateEmail(email)) {
81 | errors.push('Invalid email');
82 | }
83 | if(Util.validatePassword(password)) {
84 | errors.push('Invalid password');
85 | }
86 | if(password !== confirm) {
87 | errors.push('Passwords do not match');
88 | }
89 | return errors;
90 | }
--------------------------------------------------------------------------------
/client/views/list/ListName.jsx:
--------------------------------------------------------------------------------
1 | var Store = require('../../../lib/store');
2 |
3 | var TaskName = module.exports = React.createClass({
4 | contextTypes: {
5 | router: React.PropTypes.func
6 | },
7 | getInitialState: function () {
8 | return { edit: false }
9 | },
10 | componentWillMount: function () {
11 | this.onDeleteList = function () {
12 | Store.listDelete.onNext({ id: this.props.listId });
13 | this.context.router.transitionTo('/');
14 | }.bind(this);
15 | this.onEditList = function(){
16 | this.setState({edit:true});
17 | }.bind(this);
18 | this.onUpdateListName = function(e){
19 | e.preventDefault();
20 | var listName = React.findDOMNode(this.refs.listName).value.trim();
21 | if(listName && listName != '') {
22 | Store.listUpdate.onNext({
23 | id: this.props.listId,
24 | name: listName
25 | });
26 | this.setState({ edit:false }, function(){
27 | React.findDOMNode(this.refs.theInput).value
28 | }.bind(this));
29 | }
30 | }.bind(this);
31 | this.onCreateTask = function(e){
32 | e.preventDefault();
33 | var taskName = React.findDOMNode(this.refs.taskName).value.trim();
34 | if(taskName && taskName != '') {
35 | Store.taskCreate.onNext({
36 | done: false,
37 | item: taskName,
38 | list: this.props.listId
39 | });
40 | this.setState({ edit:false },function(){
41 | React.findDOMNode(this.refs.taskName).value = '';
42 | }.bind(this));
43 | }
44 |
45 | }.bind(this);
46 | },
47 | render: function () {
48 | var listName = this.state.edit ?
49 | () :
60 | (
61 |
66 |
67 | {this.props.listName}
68 | {this.props.tasks.length}
69 |
70 |
81 |
);
82 | return (
83 |
90 | );
91 | }
92 | });
--------------------------------------------------------------------------------
/public/img/logo-todos.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
52 |
--------------------------------------------------------------------------------
/server/db.js:
--------------------------------------------------------------------------------
1 | var async = require('async');
2 | var R = require('ramda');
3 | var data = require('./data');
4 | var Constants = require('../lib/constants');
5 |
6 |
7 | var r = require('rethinkdbdash')({
8 | host: 'localhost',
9 | port: 28015,
10 | db: 'test'
11 | });
12 |
13 | var Db = module.exports = {};
14 |
15 |
16 | Db.allTasks = function (userId, cb) {
17 | r.db('rio').table('task').filter({user: userId}).run(cb);
18 | };
19 |
20 | Db.allLists = function (userId, cb) {
21 | r.db('rio').table('list').filter({user: userId}).run(cb);
22 | };
23 |
24 |
25 | function logError(err) {
26 | if (err) console.log(err);
27 | }
28 | Db.changes = function (subject,table) {
29 | r.db('rio').table(table).changes().run(function iterateCursor(err, cursor) {
30 | cursor.each(function (res, change) {
31 | subject.onNext(change);
32 | });
33 | });
34 | };
35 |
36 | Db.createEntry = function (table,data) {
37 | r.db('rio').table(table).insert(data).run(logError);
38 | };
39 |
40 |
41 | Db.taskUpdate = function (task) {
42 | r.db('rio').table('task').get(task.id).update(task).run(logError);
43 | };
44 |
45 | Db.taskDelete = function (task) {
46 | r.db('rio').table('task').get(task.id).delete().run(logError);
47 | };
48 |
49 | Db.listUpdate = function (info) {
50 | r.db('rio').table('list').get(info.id).update({name: info.name}).run(logError);
51 | };
52 |
53 | Db.listDelete = function (data) {
54 | r.db('rio').table('list').get(data.id).delete().run(logError);
55 | };
56 |
57 | Db.signIn = function signIn(info, cb) {
58 | r.db('rio').table('user').filter(R.pick(['email', 'password'], info))
59 | .run(function (err, res) {
60 | cb(err || res.length == 0 ? Constants.user : res[0])
61 | });
62 | };
63 |
64 | Db.join = function join(info, cb) {
65 | r.db('rio').table('user')
66 | .filter({email: info.email})
67 | .run(function (err, res) {
68 | if (err) {
69 | cb({errors: [err]});
70 | } else {
71 | r.db('rio').table('user')
72 | .insert(R.omit(['id'], info))
73 | .run(function (err, res) {
74 | cb(!err && res.inserted ? {
75 | email: info.email,
76 | id: res.generated_keys[0]
77 | } : {errors: ['server error']});
78 | });
79 | }
80 | });
81 | };
82 |
83 | Db.setup = function setup(mainCallback) {
84 | async.waterfall([
85 | function (callback) {
86 | r.dbList().run(function (err, res) {
87 | callback(err, res);
88 | });
89 | },
90 | function (databases, callback) {
91 | if (databases.indexOf('rio') == -1) {
92 | r.dbCreate('rio').run(function (err) {
93 | callback(err, true);
94 | });
95 | } else {
96 | callback(null, false);
97 | }
98 | },
99 | function (create, callback) {
100 | if (create) {
101 | r.db('rio').tableCreate('user')
102 | .run(function (err, res) {
103 | callback(err, create);
104 | });
105 | } else {
106 | callback(null, create);
107 | }
108 |
109 | },
110 | function (create, callback) {
111 | if (create) {
112 | r.db('rio').tableCreate('list')
113 | .run(function (err, res) {
114 | callback(err, create);
115 | });
116 | } else {
117 | callback(null, create);
118 | }
119 | },
120 | function (create, callback) {
121 | if (create) {
122 | r.db('rio').tableCreate('task')
123 | .run(function (err, res) {
124 | callback(err, create);
125 | });
126 | } else {
127 | callback(null, create);
128 | }
129 | },
130 | function (create, callback) {
131 | if (create) {
132 | r.db('rio').table('list').insert(data.lists)
133 | .run(function (err, res) {
134 | callback(err, res);
135 | });
136 | } else {
137 | callback(null, create);
138 | }
139 | },
140 | function (create, callback) {
141 | if (create) {
142 | r.db('rio').table('list')
143 | .run(function (err, res) {
144 | if (err) {
145 | callback(err, res);
146 | } else {
147 | r.db('rio').table('task').insert(data.tasks(res))
148 | .run(function (err, res) {
149 | callback(err, res);
150 | });
151 | }
152 | });
153 | } else {
154 | callback(null);
155 | }
156 | }
157 | ], function (err, res) {
158 | mainCallback(err, res);
159 | })
160 | };
161 |
162 |
--------------------------------------------------------------------------------
/public/style/icon/todos.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/style/main.css:
--------------------------------------------------------------------------------
1 | /* Reset.less
2 | * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc).
3 | * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
4 | html,
5 | body {
6 | margin: 0;
7 | padding: 0;
8 | }
9 | h1,
10 | h2,
11 | h3,
12 | h4,
13 | h5,
14 | h6,
15 | p,
16 | blockquote,
17 | pre,
18 | a,
19 | abbr,
20 | acronym,
21 | address,
22 | cite,
23 | code,
24 | del,
25 | dfn,
26 | em,
27 | img,
28 | q,
29 | s,
30 | samp,
31 | small,
32 | strike,
33 | strong,
34 | sub,
35 | sup,
36 | tt,
37 | var,
38 | dd,
39 | dl,
40 | dt,
41 | li,
42 | ol,
43 | ul,
44 | fieldset,
45 | form,
46 | label,
47 | legend,
48 | button,
49 | table,
50 | caption,
51 | tbody,
52 | tfoot,
53 | thead,
54 | tr,
55 | th,
56 | td {
57 | margin: 0;
58 | padding: 0;
59 | border: 0;
60 | font-weight: normal;
61 | font-style: normal;
62 | font-size: 100%;
63 | line-height: 1;
64 | font-family: inherit;
65 | }
66 | table {
67 | border-collapse: collapse;
68 | border-spacing: 0;
69 | }
70 | ol,
71 | ul {
72 | list-style: none;
73 | }
74 | q:before,
75 | q:after,
76 | blockquote:before,
77 | blockquote:after {
78 | content: "";
79 | }
80 | html {
81 | font-size: 100%;
82 | -webkit-text-size-adjust: 100%;
83 | -ms-text-size-adjust: 100%;
84 | }
85 | a:focus {
86 | outline: thin dotted;
87 | }
88 | a:hover,
89 | a:active {
90 | outline: 0;
91 | }
92 | article,
93 | aside,
94 | details,
95 | figcaption,
96 | figure,
97 | footer,
98 | header,
99 | hgroup,
100 | nav,
101 | section {
102 | display: block;
103 | }
104 | audio,
105 | canvas,
106 | video {
107 | display: inline-block;
108 | *display: inline;
109 | *zoom: 1;
110 | }
111 | audio:not([controls]) {
112 | display: none;
113 | }
114 | sub,
115 | sup {
116 | font-size: 75%;
117 | line-height: 0;
118 | position: relative;
119 | vertical-align: baseline;
120 | }
121 | sup {
122 | top: -0.5em;
123 | }
124 | sub {
125 | bottom: -0.25em;
126 | }
127 | img {
128 | border: 0;
129 | -ms-interpolation-mode: bicubic;
130 | }
131 | button,
132 | input,
133 | select,
134 | textarea {
135 | font-size: 100%;
136 | margin: 0;
137 | vertical-align: baseline;
138 | *vertical-align: middle;
139 | }
140 | button,
141 | input {
142 | line-height: normal;
143 | *overflow: visible;
144 | }
145 | button::-moz-focus-inner,
146 | input::-moz-focus-inner {
147 | border: 0;
148 | padding: 0;
149 | }
150 | button,
151 | input[type="button"],
152 | input[type="reset"],
153 | input[type="submit"] {
154 | cursor: pointer;
155 | -webkit-appearance: button;
156 | }
157 | input[type="search"] {
158 | -webkit-appearance: textfield;
159 | -webkit-box-sizing: content-box;
160 | -moz-box-sizing: content-box;
161 | box-sizing: content-box;
162 | }
163 | input[type="search"]::-webkit-search-decoration {
164 | -webkit-appearance: none;
165 | }
166 | textarea {
167 | overflow: auto;
168 | vertical-align: top;
169 | }
170 | @font-face {
171 | font-family: 'Open Sans';
172 | src: url('font/OpenSans-Light-webfont.eot');
173 | src: url('font/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), url('font/OpenSans-Light-webfont.woff') format('woff'), url('font/OpenSans-Light-webfont.ttf') format('truetype'), url('font/OpenSans-Light-webfont.svg#OpenSansLight') format('svg');
174 | font-weight: 200;
175 | font-style: normal;
176 | }
177 | @font-face {
178 | font-family: 'Open Sans';
179 | src: url('font/OpenSans-Regular-webfont.eot');
180 | src: url('font/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), url('font/OpenSans-Regular-webfont.woff') format('woff'), url('font/OpenSans-Regular-webfont.ttf') format('truetype'), url('font/OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg');
181 | font-weight: normal;
182 | font-weight: 400;
183 | font-style: normal;
184 | }
185 | .force-wrap {
186 | word-wrap: break-word;
187 | word-break: break-all;
188 | -ms-word-break: break-all;
189 | word-break: break-word;
190 | -webkit-hyphens: auto;
191 | -moz-hyphens: auto;
192 | -ms-hyphens: auto;
193 | hyphens: auto;
194 | }
195 | .type-light {
196 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
197 | font-weight: 300;
198 | }
199 | * {
200 | -webkit-box-sizing: border-box;
201 | -moz-box-sizing: border-box;
202 | box-sizing: border-box;
203 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
204 | -webkit-tap-highlight-color: transparent;
205 | }
206 | html,
207 | button,
208 | input,
209 | textarea,
210 | select {
211 | outline: none;
212 | -webkit-font-smoothing: antialiased;
213 | -moz-osx-font-smoothing: grayscale;
214 | }
215 | body {
216 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
217 | font-style: 400;
218 | color: #333333;
219 | font-size: 16px;
220 | }
221 | h1,
222 | h2,
223 | h3,
224 | h4,
225 | h5,
226 | h6 {
227 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
228 | font-style: 400;
229 | margin: 0;
230 | padding: 0;
231 | }
232 | h1 {
233 | font-size: 40px;
234 | line-height: 48px;
235 | }
236 | h2 {
237 | font-size: 28px;
238 | line-height: 32px;
239 | }
240 | h3 {
241 | font-size: 24px;
242 | line-height: 28px;
243 | }
244 | h4 {
245 | font-size: 20px;
246 | line-height: 24px;
247 | }
248 | h5 {
249 | font-size: 14px;
250 | line-height: 20px;
251 | color: #cccccc;
252 | text-transform: uppercase;
253 | }
254 | h6 {
255 | color: #aaaaaa;
256 | }
257 | p {
258 | font-size: 16px;
259 | line-height: 24px;
260 | }
261 | sub,
262 | sup {
263 | font-size: .8em;
264 | }
265 | sub {
266 | bottom: -0.2em;
267 | }
268 | sup {
269 | top: -0.2em;
270 | }
271 | b {
272 | font-weight: bold;
273 | }
274 | em {
275 | font-style: italic;
276 | }
277 | [class^="btn-"],
278 | [class*=" btn-"] {
279 | font-size: 14px;
280 | line-height: 20px;
281 | line-height: 20px !important;
282 | padding: 1em 1.25em;
283 | letter-spacing: .3em;
284 | text-indent: .3em;
285 | text-transform: uppercase;
286 | -webkit-transition: all 200ms ease-in;
287 | -moz-transition: all 200ms ease-in;
288 | -o-transition: all 200ms ease-in;
289 | transition: all 200ms ease-in;
290 | color: #ffffff;
291 | display: inline-block;
292 | position: relative;
293 | text-align: center;
294 | text-decoration: none !important;
295 | vertical-align: middle;
296 | white-space: nowrap;
297 | }
298 | [class^="btn-"][class*="primary"],
299 | [class*=" btn-"][class*="primary"] {
300 | background-color: #2cc5d2;
301 | color: #ffffff;
302 | }
303 | [class^="btn-"][class*="primary"]:hover,
304 | [class*=" btn-"][class*="primary"]:hover {
305 | background-color: #28b1bd;
306 | }
307 | [class^="btn-"][class*="primary"]:active,
308 | [class*=" btn-"][class*="primary"]:active {
309 | box-shadow: rgba(0, 0, 0, 0.3) 0 1px 3px 0 inset;
310 | }
311 | [class^="btn-"][class*="secondary"],
312 | [class*=" btn-"][class*="secondary"] {
313 | -webkit-transition: all 300ms ease-in;
314 | -moz-transition: all 300ms ease-in;
315 | -o-transition: all 300ms ease-in;
316 | transition: all 300ms ease-in;
317 | box-shadow: #5a7ca6 0 0 0 1px inset;
318 | color: #ffffff;
319 | }
320 | [class^="btn-"][class*="secondary"]:hover,
321 | [class*=" btn-"][class*="secondary"]:hover {
322 | color: #eeeeee;
323 | }
324 | [class^="btn-"][class*="secondary"]:active,
325 | [class*=" btn-"][class*="secondary"]:active,
326 | [class^="btn-"][class*="secondary"].active,
327 | [class*=" btn-"][class*="secondary"].active {
328 | box-shadow: #9db1ca 0 0 0 1px inset;
329 | }
330 | [class^="btn-"][disabled],
331 | [class*=" btn-"][disabled] {
332 | opacity: .5;
333 | }
334 | .btns-group {
335 | display: -webkit-box;
336 | display: -moz-box;
337 | display: -webkit-flex;
338 | display: -ms-flexbox;
339 | display: flex;
340 | -webkit-flex-wrap: wrap;
341 | -ms-flex-wrap: wrap;
342 | flex-wrap: wrap;
343 | width: 100%;
344 | }
345 | .btns-group [class*="btn-"] {
346 | overflow: hidden;
347 | text-overflow: ellipsis;
348 | white-space: nowrap;
349 | -webkit-box-flex: 1;
350 | -moz-box-flex: 1;
351 | -webkit-flex: 1;
352 | -ms-flex: 1;
353 | flex: 1;
354 | }
355 | .btns-group [class*="btn-"] + [class*="btn-"] {
356 | margin-left: -1px;
357 | }
358 | input[type="text"],
359 | input[type="email"],
360 | input[type="password"],
361 | textarea {
362 | font-size: 14px;
363 | line-height: 20px;
364 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
365 | font-style: 400;
366 | padding: .75rem 0;
367 | line-height: 1.5rem !important;
368 | border: none;
369 | border-radius: 0;
370 | box-sizing: border-box;
371 | color: #333333;
372 | outline: none;
373 | }
374 | input[type="text"]::-webkit-input-placeholder,
375 | input[type="email"]::-webkit-input-placeholder,
376 | input[type="password"]::-webkit-input-placeholder,
377 | textarea::-webkit-input-placeholder {
378 | color: #778b91;
379 | }
380 | input[type="text"]:-moz-placeholder,
381 | input[type="email"]:-moz-placeholder,
382 | input[type="password"]:-moz-placeholder,
383 | textarea:-moz-placeholder {
384 | color: #778b91;
385 | }
386 | input[type="text"]::-moz-placeholder,
387 | input[type="email"]::-moz-placeholder,
388 | input[type="password"]::-moz-placeholder,
389 | textarea::-moz-placeholder {
390 | color: #778b91;
391 | }
392 | input[type="text"]:-ms-input-placeholder,
393 | input[type="email"]:-ms-input-placeholder,
394 | input[type="password"]:-ms-input-placeholder,
395 | textarea:-ms-input-placeholder {
396 | color: #778b91;
397 | }
398 | input[type="text"][disabled],
399 | input[type="email"][disabled],
400 | input[type="password"][disabled],
401 | textarea[disabled] {
402 | opacity: .5;
403 | }
404 | input:-webkit-autofill {
405 | -webkit-box-shadow: 0 0 0 1000px #ffffff inset;
406 | }
407 | .checkbox {
408 | display: inline-block;
409 | height: 3rem;
410 | position: relative;
411 | vertical-align: middle;
412 | width: 44px;
413 | }
414 | .checkbox input[type="checkbox"] {
415 | font-size: 1em;
416 | visibility: hidden;
417 | }
418 | .checkbox input[type="checkbox"] + span:before {
419 | position: absolute;
420 | top: 50%;
421 | right: auto;
422 | bottom: auto;
423 | left: 50%;
424 | width: 0.85em;
425 | height: 0.85em;
426 | -webkit-transform: translate3d(-50%, -50%, 0);
427 | -moz-transform: translate3d(-50%, -50%, 0);
428 | -ms-transform: translate3d(-50%, -50%, 0);
429 | -o-transform: translate3d(-50%, -50%, 0);
430 | transform: translate3d(-50%, -50%, 0);
431 | background: transparent;
432 | box-shadow: #abdfe3 0 0 0 1px inset;
433 | content: '';
434 | display: block;
435 | }
436 | .checkbox input[type="checkbox"]:checked + span:before {
437 | box-shadow: none;
438 | color: #cccccc;
439 | font-family: 'todos';
440 | speak: none;
441 | font-style: normal;
442 | font-weight: normal;
443 | font-variant: normal;
444 | text-transform: none;
445 | line-height: 1;
446 | -webkit-font-smoothing: antialiased;
447 | -moz-osx-font-smoothing: grayscale;
448 | content: "\e612";
449 | }
450 | .input-symbol {
451 | display: inline-block;
452 | position: relative;
453 | }
454 | .input-symbol.error [class^="icon-"],
455 | .input-symbol.error [class*=" icon-"] {
456 | color: #ff4400;
457 | }
458 | .input-symbol [class^="icon-"],
459 | .input-symbol [class*=" icon-"] {
460 | left: 1em;
461 | }
462 | .input-symbol input {
463 | padding-left: 3em;
464 | }
465 | .input-symbol input {
466 | width: 100%;
467 | }
468 | .input-symbol input:focus + [class^="icon-"],
469 | .input-symbol input:focus + [class*=" icon-"] {
470 | color: #2cc5d2;
471 | }
472 | .input-symbol [class^="icon-"],
473 | .input-symbol [class*=" icon-"] {
474 | -webkit-transition: all 300ms ease-in;
475 | -moz-transition: all 300ms ease-in;
476 | -o-transition: all 300ms ease-in;
477 | transition: all 300ms ease-in;
478 | -webkit-transform: translate3d(0, -50%, 0);
479 | -moz-transform: translate3d(0, -50%, 0);
480 | -ms-transform: translate3d(0, -50%, 0);
481 | -o-transform: translate3d(0, -50%, 0);
482 | transform: translate3d(0, -50%, 0);
483 | background: transparent;
484 | color: #aaaaaa;
485 | font-size: 1em;
486 | height: 1em;
487 | position: absolute;
488 | top: 50%;
489 | width: 1em;
490 | }
491 | @font-face {
492 | font-family: 'todos';
493 | src: url('icon/todos.eot?-5w3um4');
494 | src: url('icon/todos.eot?#iefix5w3um4') format('embedded-opentype'), url('icon/todos.woff?5w3um4') format('woff'), url('icon/todos.ttf?5w3um4') format('truetype'), url('icon/todos.svg?5w3um4#todos') format('svg');
495 | font-weight: normal;
496 | font-style: normal;
497 | }
498 | [class^="icon-"],
499 | [class*=" icon-"] {
500 | font-family: 'todos';
501 | speak: none;
502 | font-style: normal;
503 | font-weight: normal;
504 | font-variant: normal;
505 | text-transform: none;
506 | line-height: 1;
507 | -webkit-font-smoothing: antialiased;
508 | -moz-osx-font-smoothing: grayscale;
509 | }
510 | .icon-unlock:before {
511 | content: "\e600";
512 | }
513 | .icon-user-add:before {
514 | content: "\e604";
515 | }
516 | .icon-cog:before {
517 | content: "\e606";
518 | }
519 | .icon-trash:before {
520 | content: "\e607";
521 | }
522 | .icon-edit:before {
523 | content: "\e608";
524 | }
525 | .icon-add:before {
526 | content: "\e60a";
527 | }
528 | .icon-plus:before {
529 | content: "\e60b";
530 | }
531 | .icon-close:before {
532 | content: "\e60c";
533 | }
534 | .icon-cross:before {
535 | content: "\e60d";
536 | }
537 | .icon-sync:before {
538 | content: "\e60e";
539 | }
540 | .icon-lock:before {
541 | content: "\e610";
542 | }
543 | .icon-check:before {
544 | content: "\e612";
545 | }
546 | .icon-share:before {
547 | content: "\e617";
548 | }
549 | .icon-email:before {
550 | content: "\e619";
551 | }
552 | .icon-arrow-up:before {
553 | content: "\e623";
554 | }
555 | .icon-arrow-down:before {
556 | content: "\e626";
557 | }
558 | .icon-list-unordered:before {
559 | content: "\e634";
560 | }
561 | body {
562 | position: absolute;
563 | top: 0;
564 | right: 0;
565 | bottom: 0;
566 | left: 0;
567 | width: auto;
568 | height: auto;
569 | background-color: #315481;
570 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMzMTU0ODEiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzkxOGU4MiIgc3RvcC1vcGFjaXR5PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2xlc3NoYXQtZ2VuZXJhdGVkKSIgLz48L3N2Zz4=);
571 | background-image: -webkit-linear-gradient(top, #315481, #918e82 100%);
572 | background-image: -moz-linear-gradient(top, #315481, #918e82 100%);
573 | background-image: -o-linear-gradient(top, #315481, #918e82 100%);
574 | background-image: linear-gradient(to bottom, #315481, #918e82 100%);
575 | background-repeat: no-repeat;
576 | background-attachment: fixed;
577 | }
578 | #container {
579 | position: absolute;
580 | top: 0;
581 | right: 0;
582 | bottom: 0;
583 | left: 0;
584 | width: auto;
585 | height: auto;
586 | overflow: hidden;
587 | }
588 | @media screen and (min-width: 60em) {
589 | #container {
590 | left: 5.55555%;
591 | right: 5.55555%;
592 | }
593 | }
594 | @media screen and (min-width: 80em) {
595 | #container {
596 | left: 11.1111%;
597 | right: 11.1111%;
598 | }
599 | }
600 | #menu {
601 | position: absolute;
602 | top: 0;
603 | right: 0;
604 | bottom: 0;
605 | left: 0;
606 | width: 270px;
607 | height: auto;
608 | }
609 | #content-container {
610 | position: absolute;
611 | top: 0;
612 | right: 0;
613 | bottom: 0;
614 | left: 0;
615 | width: auto;
616 | height: auto;
617 | -webkit-transition: all 200ms ease-out;
618 | -moz-transition: all 200ms ease-out;
619 | -o-transition: all 200ms ease-out;
620 | transition: all 200ms ease-out;
621 | -webkit-transform: translate3d(0, 0, 0);
622 | -moz-transform: translate3d(0, 0, 0);
623 | -ms-transform: translate3d(0, 0, 0);
624 | -o-transform: translate3d(0, 0, 0);
625 | transform: translate3d(0, 0, 0);
626 | background: #d2edf4;
627 | opacity: 1;
628 | }
629 | @media screen and (min-width: 40em) {
630 | #content-container {
631 | left: 270px;
632 | }
633 | }
634 | #content-container .content-scrollable {
635 | position: absolute;
636 | top: 0;
637 | right: 0;
638 | bottom: 0;
639 | left: 0;
640 | width: auto;
641 | height: auto;
642 | -webkit-transform: translate3d(0, 0, 0);
643 | -moz-transform: translate3d(0, 0, 0);
644 | -ms-transform: translate3d(0, 0, 0);
645 | -o-transform: translate3d(0, 0, 0);
646 | transform: translate3d(0, 0, 0);
647 | overflow-y: auto;
648 | -webkit-overflow-scrolling: touch;
649 | }
650 | .menu-open #content-container {
651 | -webkit-transform: translate3d(270px, 0, 0);
652 | -moz-transform: translate3d(270px, 0, 0);
653 | -ms-transform: translate3d(270px, 0, 0);
654 | -o-transform: translate3d(270px, 0, 0);
655 | transform: translate3d(270px, 0, 0);
656 | opacity: .85;
657 | left: 0;
658 | }
659 | @media screen and (min-width: 40em) {
660 | .menu-open #content-container {
661 | -webkit-transform: translate3d(0, 0, 0);
662 | -moz-transform: translate3d(0, 0, 0);
663 | -ms-transform: translate3d(0, 0, 0);
664 | -o-transform: translate3d(0, 0, 0);
665 | transform: translate3d(0, 0, 0);
666 | opacity: 1;
667 | left: 270px;
668 | }
669 | }
670 | .content-overlay {
671 | position: absolute;
672 | top: 0;
673 | right: 0;
674 | bottom: 0;
675 | left: 0;
676 | width: auto;
677 | height: auto;
678 | cursor: pointer;
679 | }
680 | .menu-open .content-overlay {
681 | -webkit-transform: translate3d(270px, 0, 0);
682 | -moz-transform: translate3d(270px, 0, 0);
683 | -ms-transform: translate3d(270px, 0, 0);
684 | -o-transform: translate3d(270px, 0, 0);
685 | transform: translate3d(270px, 0, 0);
686 | z-index: 1;
687 | }
688 | @media screen and (min-width: 40em) {
689 | .content-overlay {
690 | display: none;
691 | }
692 | }
693 | a {
694 | -webkit-transition: all 200ms ease-in;
695 | -moz-transition: all 200ms ease-in;
696 | -o-transition: all 200ms ease-in;
697 | transition: all 200ms ease-in;
698 | color: #5db9ff;
699 | cursor: pointer;
700 | text-decoration: none;
701 | }
702 | a:hover {
703 | color: #239da8;
704 | }
705 | a:active {
706 | color: #555555;
707 | }
708 | a:focus {
709 | outline: none;
710 | }
711 | #menu {
712 | overflow-y: auto;
713 | -webkit-overflow-scrolling: touch;
714 | }
715 | #menu .btns-group,
716 | #menu .btns-group-vertical {
717 | margin: 2em auto 2em;
718 | width: 80%;
719 | }
720 | #menu .btns-group .btn-secondary,
721 | #menu .btns-group-vertical .btn-secondary {
722 | font-size: 12px;
723 | line-height: 16px;
724 | padding-top: .5em;
725 | padding-bottom: .5em;
726 | }
727 | #menu .btns-group-vertical .btn-secondary {
728 | word-wrap: break-word;
729 | word-break: break-all;
730 | -ms-word-break: break-all;
731 | word-break: break-word;
732 | -webkit-hyphens: auto;
733 | -moz-hyphens: auto;
734 | -ms-hyphens: auto;
735 | hyphens: auto;
736 | padding-right: 2.5em;
737 | text-align: left;
738 | text-indent: 0;
739 | white-space: normal;
740 | width: 100%;
741 | }
742 | #menu .btns-group-vertical .btn-secondary + .btn-secondary {
743 | margin-top: .5rem;
744 | }
745 | #menu .btns-group-vertical .btn-secondary + .btn-secondary:before {
746 | position: absolute;
747 | top: -0.5rem;
748 | right: 50%;
749 | bottom: auto;
750 | left: auto;
751 | width: 1px;
752 | height: 0.5rem;
753 | background: #5a7ca6;
754 | content: '';
755 | }
756 | #menu .btns-group-vertical .btn-secondary [class^="icon-"],
757 | #menu .btns-group-vertical .btn-secondary [class*=" icon-"] {
758 | position: absolute;
759 | top: 0.5em;
760 | right: 0.5em;
761 | bottom: auto;
762 | left: auto;
763 | width: auto;
764 | height: auto;
765 | line-height: 20px;
766 | }
767 | #menu .list-todos a {
768 | box-shadow: rgba(255, 255, 255, 0.15) 0 1px 0 0;
769 | display: block;
770 | line-height: 1.5em;
771 | padding: .75em 2.5em;
772 | position: relative;
773 | }
774 | #menu .list-todos .count-list {
775 | -webkit-transition: all 200ms ease-in;
776 | -moz-transition: all 200ms ease-in;
777 | -o-transition: all 200ms ease-in;
778 | transition: all 200ms ease-in;
779 | background: rgba(255, 255, 255, 0.1);
780 | border-radius: 1em;
781 | float: right;
782 | font-size: .7rem;
783 | line-height: 1;
784 | margin-top: .25rem;
785 | margin-right: -1.5em;
786 | padding: .3em .5em;
787 | }
788 | #menu .list-todos [class^="icon-"],
789 | #menu .list-todos [class*=" icon-"] {
790 | font-size: 14px;
791 | line-height: 20px;
792 | float: left;
793 | margin-left: -1.5rem;
794 | margin-right: .5rem;
795 | margin-top: .1rem;
796 | width: 1em;
797 | }
798 | #menu .list-todos .icon-lock {
799 | font-size: 12px;
800 | line-height: 16px;
801 | margin-top: .2rem;
802 | opacity: .8;
803 | }
804 | #menu .list-todos .list-todo {
805 | color: rgba(255, 255, 255, 0.4);
806 | }
807 | #menu .list-todos .list-todo:hover,
808 | #menu .list-todos .list-todo:active,
809 | #menu .list-todos .list-todo.active {
810 | color: #ffffff;
811 | }
812 | #menu .list-todos .list-todo:hover .count-list,
813 | #menu .list-todos .list-todo:active .count-list,
814 | #menu .list-todos .list-todo.active .count-list {
815 | background: #2cc5d2;
816 | }
817 | .cordova #menu .list-todos .list-todo:hover {
818 | color: rgba(255, 255, 255, 0.4);
819 | }
820 | nav {
821 | position: absolute;
822 | top: 0;
823 | right: 0;
824 | bottom: auto;
825 | left: 0;
826 | width: auto;
827 | height: auto;
828 | -webkit-transform: translate3d(0, 0, 0);
829 | -moz-transform: translate3d(0, 0, 0);
830 | -ms-transform: translate3d(0, 0, 0);
831 | -o-transform: translate3d(0, 0, 0);
832 | transform: translate3d(0, 0, 0);
833 | -webkit-transition: all 200ms ease-out;
834 | -moz-transition: all 200ms ease-out;
835 | -o-transition: all 200ms ease-out;
836 | transition: all 200ms ease-out;
837 | z-index: 10;
838 | }
839 | nav .nav-item {
840 | font-size: 20px;
841 | line-height: 24px;
842 | color: #1c3f53;
843 | display: inline-block;
844 | height: 3rem;
845 | text-align: center;
846 | width: 3rem;
847 | }
848 | nav .nav-item:active {
849 | opacity: .5;
850 | }
851 | nav .nav-item [class^="icon-"],
852 | nav .nav-item [class*=" icon-"] {
853 | line-height: 3rem;
854 | vertical-align: middle;
855 | }
856 | nav .nav-group {
857 | position: absolute;
858 | top: 0;
859 | right: auto;
860 | bottom: auto;
861 | left: 0;
862 | width: auto;
863 | height: auto;
864 | z-index: 1;
865 | }
866 | nav .nav-group.right {
867 | left: auto;
868 | right: 0;
869 | }
870 | .page.lists-show nav {
871 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNkMGVkZjUiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2UxZTVmMCIgc3RvcC1vcGFjaXR5PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2xlc3NoYXQtZ2VuZXJhdGVkKSIgLz48L3N2Zz4=);
872 | background-image: -webkit-linear-gradient(top, #d0edf5, #e1e5f0 100%);
873 | background-image: -moz-linear-gradient(top, #d0edf5, #e1e5f0 100%);
874 | background-image: -o-linear-gradient(top, #d0edf5, #e1e5f0 100%);
875 | background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%);
876 | height: 5em;
877 | text-align: center;
878 | }
879 | @media screen and (min-width: 40em) {
880 | .page.lists-show nav {
881 | text-align: left;
882 | }
883 | }
884 | .page.lists-show nav .title-page {
885 | position: absolute;
886 | top: 0;
887 | right: 3rem;
888 | bottom: auto;
889 | left: 3rem;
890 | width: auto;
891 | height: auto;
892 | cursor: pointer;
893 | font-size: 1.125em;
894 | white-space: nowrap;
895 | }
896 | @media screen and (min-width: 40em) {
897 | .page.lists-show nav .title-page {
898 | left: 1rem;
899 | right: 6rem;
900 | }
901 | }
902 | .page.lists-show nav .title-page .title-wrapper {
903 | overflow: hidden;
904 | text-overflow: ellipsis;
905 | white-space: nowrap;
906 | color: #1c3f53;
907 | display: inline-block;
908 | padding-right: 1.5rem;
909 | vertical-align: top;
910 | max-width: 100%;
911 | }
912 | .page.lists-show nav .title-page .count-list {
913 | background: #2cc5d2;
914 | border-radius: 1em;
915 | color: #ffffff;
916 | display: inline-block;
917 | font-size: .7rem;
918 | line-height: 1;
919 | margin-left: -1.25rem;
920 | margin-top: -4px;
921 | padding: .3em .5em;
922 | vertical-align: middle;
923 | }
924 | .page.lists-show nav form.todo-new {
925 | position: absolute;
926 | top: 3em;
927 | right: 0;
928 | bottom: auto;
929 | left: 0;
930 | width: auto;
931 | height: auto;
932 | }
933 | .page.lists-show nav form.todo-new input[type="text"] {
934 | background: transparent;
935 | padding-bottom: .25em;
936 | padding-left: 44px !important;
937 | padding-top: .25em;
938 | }
939 | .page.lists-show nav form.list-edit-form {
940 | position: relative;
941 | }
942 | .page.lists-show nav form.list-edit-form input[type="text"] {
943 | background: transparent;
944 | font-size: 1.125em;
945 | width: 100%;
946 | padding-right: 3em;
947 | padding-left: 1rem;
948 | }
949 | .page.lists-show nav select.list-edit {
950 | font-size: 14px;
951 | line-height: 20px;
952 | position: absolute;
953 | top: 0;
954 | right: 0;
955 | bottom: 0;
956 | left: 0;
957 | width: auto;
958 | height: auto;
959 | background: transparent;
960 | opacity: 0;
961 | }
962 | .page.lists-show nav .options-web {
963 | display: none;
964 | }
965 | .page.lists-show nav .options-web .nav-item {
966 | font-size: 16px;
967 | line-height: 24px;
968 | width: 2rem;
969 | }
970 | .page.lists-show nav .options-web .nav-item:last-child {
971 | margin-right: .5rem;
972 | }
973 | @media screen and (min-width: 40em) {
974 | .page.lists-show nav .nav-group:not(.right) {
975 | display: none !important;
976 | }
977 | .page.lists-show nav .options-mobile {
978 | display: none;
979 | }
980 | .page.lists-show nav .options-web {
981 | display: block;
982 | }
983 | }
984 | @media screen and (min-width: 40em) {
985 | .page.auth .nav-group {
986 | display: none;
987 | }
988 | .page.not-found .nav-group {
989 | display: none;
990 | }
991 | }
992 | .list-items .list-item {
993 | font-size: 14px;
994 | line-height: 20px;
995 | display: -webkit-box;
996 | display: -moz-box;
997 | display: -webkit-flex;
998 | display: -ms-flexbox;
999 | display: flex;
1000 | -webkit-flex-wrap: wrap;
1001 | -ms-flex-wrap: wrap;
1002 | flex-wrap: wrap;
1003 | height: 3rem;
1004 | width: 100%;
1005 | }
1006 | .list-items .list-item .checkbox {
1007 | -webkit-box-flex: 0;
1008 | -moz-box-flex: 0;
1009 | -webkit-flex: 0 0 44px;
1010 | -ms-flex: 0 0 44px;
1011 | flex: 0 0 44px;
1012 | cursor: pointer;
1013 | }
1014 | .list-items .list-item input[type="text"] {
1015 | -webkit-box-flex: 1;
1016 | -moz-box-flex: 1;
1017 | -webkit-flex: 1;
1018 | -ms-flex: 1;
1019 | flex: 1;
1020 | }
1021 | .list-items .list-item .delete-item {
1022 | -webkit-box-flex: 0;
1023 | -moz-box-flex: 0;
1024 | -webkit-flex: 0 0 3rem;
1025 | -ms-flex: 0 0 3rem;
1026 | flex: 0 0 3rem;
1027 | }
1028 | .list-items .list-item input[type="text"] {
1029 | background: transparent;
1030 | cursor: pointer;
1031 | }
1032 | .list-items .list-item input[type="text"]:focus {
1033 | cursor: text;
1034 | }
1035 | .list-items .list-item .delete-item {
1036 | color: #cccccc;
1037 | line-height: 3rem;
1038 | text-align: center;
1039 | }
1040 | .list-items .list-item .delete-item:hover {
1041 | color: #2cc5d2;
1042 | }
1043 | .list-items .list-item .delete-item:active {
1044 | color: #555555;
1045 | }
1046 | .list-items .list-item .delete-item .icon-trash {
1047 | font-size: 1.1em;
1048 | }
1049 | .list-items .list-item + .list-item {
1050 | border-top: 1px solid #f0f9fb;
1051 | }
1052 | .list-items .list-item.checked input[type="text"] {
1053 | color: #cccccc;
1054 | text-decoration: line-through;
1055 | }
1056 | .list-items .list-item.checked .delete-item {
1057 | display: inline-block;
1058 | }
1059 | .list-items .list-item .delete-item {
1060 | display: none;
1061 | }
1062 | .list-items .list-item.editing .delete-item {
1063 | display: inline-block;
1064 | }
1065 | .wrapper-message {
1066 | position: absolute;
1067 | top: 45%;
1068 | right: 0;
1069 | bottom: auto;
1070 | left: 0;
1071 | width: auto;
1072 | height: auto;
1073 | -webkit-transform: translate3d(0, -50%, 0);
1074 | -moz-transform: translate3d(0, -50%, 0);
1075 | -ms-transform: translate3d(0, -50%, 0);
1076 | -o-transform: translate3d(0, -50%, 0);
1077 | transform: translate3d(0, -50%, 0);
1078 | text-align: center;
1079 | }
1080 | .wrapper-message .title-message {
1081 | font-size: 24px;
1082 | line-height: 28px;
1083 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
1084 | font-weight: 300;
1085 | color: #1c3f53;
1086 | margin-bottom: .5em;
1087 | }
1088 | .wrapper-message .subtitle-message {
1089 | font-size: 14px;
1090 | line-height: 20px;
1091 | color: #aaaaaa;
1092 | }
1093 | @-webkit-keyframes spin {
1094 | 0% {
1095 | -webkit-transform: rotate(0deg);
1096 | -moz-transform: rotate(0deg);
1097 | -ms-transform: rotate(0deg);
1098 | -o-transform: rotate(0deg);
1099 | transform: rotate(0deg);
1100 | }
1101 | 100% {
1102 | -webkit-transform: rotate(359deg);
1103 | -moz-transform: rotate(359deg);
1104 | -ms-transform: rotate(359deg);
1105 | -o-transform: rotate(359deg);
1106 | transform: rotate(359deg);
1107 | }
1108 | }
1109 | @keyframes spin {
1110 | 0% {
1111 | -webkit-transform: rotate(0deg);
1112 | -moz-transform: rotate(0deg);
1113 | -ms-transform: rotate(0deg);
1114 | -o-transform: rotate(0deg);
1115 | transform: rotate(0deg);
1116 | }
1117 | 100% {
1118 | -webkit-transform: rotate(359deg);
1119 | -moz-transform: rotate(359deg);
1120 | -ms-transform: rotate(359deg);
1121 | -o-transform: rotate(359deg);
1122 | transform: rotate(359deg);
1123 | }
1124 | }
1125 | .notifications {
1126 | position: absolute;
1127 | top: auto;
1128 | right: auto;
1129 | bottom: 10px;
1130 | left: 50%;
1131 | width: 280px;
1132 | height: auto;
1133 | -webkit-transform: translate3d(-50%, 0, 0);
1134 | -moz-transform: translate3d(-50%, 0, 0);
1135 | -ms-transform: translate3d(-50%, 0, 0);
1136 | -o-transform: translate3d(-50%, 0, 0);
1137 | transform: translate3d(-50%, 0, 0);
1138 | z-index: 1;
1139 | }
1140 | @media screen and (min-width: 40em) {
1141 | .notifications {
1142 | -webkit-transform: translate3d(0, 0, 0);
1143 | -moz-transform: translate3d(0, 0, 0);
1144 | -ms-transform: translate3d(0, 0, 0);
1145 | -o-transform: translate3d(0, 0, 0);
1146 | transform: translate3d(0, 0, 0);
1147 | bottom: auto;
1148 | right: 1rem;
1149 | top: 1rem;
1150 | left: auto;
1151 | }
1152 | }
1153 | .notifications .notification {
1154 | font-size: 12px;
1155 | line-height: 16px;
1156 | background: rgba(51, 51, 51, 0.85);
1157 | color: #ffffff;
1158 | margin-bottom: .25rem;
1159 | padding: .5rem .75rem;
1160 | position: relative;
1161 | width: 100%;
1162 | }
1163 | .notifications .notification .icon-sync {
1164 | position: absolute;
1165 | top: 30%;
1166 | right: auto;
1167 | bottom: auto;
1168 | left: 1rem;
1169 | width: auto;
1170 | height: auto;
1171 | -webkit-animation: spin 2s infinite linear;
1172 | -moz-animation: spin 2s infinite linear;
1173 | -o-animation: spin 2s infinite linear;
1174 | animation: spin 2s infinite linear;
1175 | color: #ffffff;
1176 | font-size: 1.5em;
1177 | }
1178 | .notifications .notification .meta {
1179 | overflow: hidden;
1180 | padding-left: 3em;
1181 | }
1182 | .notifications .notification .meta .title-notification {
1183 | letter-spacing: .3em;
1184 | text-indent: .3em;
1185 | text-transform: uppercase;
1186 | display: block;
1187 | }
1188 | .notifications .notification .meta .description {
1189 | display: block;
1190 | }
1191 | .page.lists-show .content-scrollable {
1192 | background: #ffffff;
1193 | top: 5em !important;
1194 | }
1195 | .page.auth {
1196 | text-align: center;
1197 | }
1198 | .page.auth .content-scrollable {
1199 | background: #d2edf4;
1200 | }
1201 | .page.auth .wrapper-auth {
1202 | padding-top: 4em;
1203 | }
1204 | @media screen and (min-width: 40em) {
1205 | .page.auth .wrapper-auth {
1206 | margin: 0 auto;
1207 | max-width: 480px;
1208 | width: 80%;
1209 | }
1210 | }
1211 | .page.auth .wrapper-auth .title-auth {
1212 | font-size: 40px;
1213 | line-height: 48px;
1214 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
1215 | font-weight: 300;
1216 | color: #1c3f53;
1217 | margin-bottom: .75rem;
1218 | }
1219 | .page.auth .wrapper-auth .subtitle-auth {
1220 | color: #666666;
1221 | margin: 0 15% 3rem;
1222 | }
1223 | .page.auth .wrapper-auth form .input-symbol {
1224 | margin-bottom: 1px;
1225 | width: 100%;
1226 | }
1227 | .page.auth .wrapper-auth form .btn-primary {
1228 | margin: 1em 5% 0;
1229 | width: 90%;
1230 | }
1231 | @media screen and (min-width: 40em) {
1232 | .page.auth .wrapper-auth form .btn-primary {
1233 | margin-left: 0;
1234 | margin-right: 0;
1235 | width: 100%;
1236 | }
1237 | }
1238 | .page.auth .wrapper-auth .list-errors {
1239 | margin-top: -2rem;
1240 | }
1241 | .page.auth .wrapper-auth .list-errors .list-item {
1242 | letter-spacing: .3em;
1243 | text-indent: .3em;
1244 | text-transform: uppercase;
1245 | background: #f6fccf;
1246 | color: #ff4400;
1247 | font-size: .625em;
1248 | margin-bottom: 1px;
1249 | padding: .7rem 0;
1250 | }
1251 | .page.auth .link-auth-alt {
1252 | font-size: 12px;
1253 | line-height: 16px;
1254 | position: absolute;
1255 | top: auto;
1256 | right: 0;
1257 | bottom: 1em;
1258 | left: 0;
1259 | width: auto;
1260 | height: auto;
1261 | color: #aaaaaa;
1262 | display: inline-block;
1263 | }
1264 | @media screen and (min-width: 40em) {
1265 | .page.auth .link-auth-alt {
1266 | bottom: 0;
1267 | margin-top: 1rem;
1268 | position: relative;
1269 | }
1270 | }
1271 | .page.not-found .content-scrollable {
1272 | background: #d2edf4;
1273 | }
1274 | .loading-app {
1275 | position: absolute;
1276 | top: 50%;
1277 | right: 50%;
1278 | bottom: auto;
1279 | left: auto;
1280 | width: 50%;
1281 | height: auto;
1282 | -webkit-transform: translate3d(50%, -50%, 0);
1283 | -moz-transform: translate3d(50%, -50%, 0);
1284 | -ms-transform: translate3d(50%, -50%, 0);
1285 | -o-transform: translate3d(50%, -50%, 0);
1286 | transform: translate3d(50%, -50%, 0);
1287 | min-width: 160px;
1288 | max-width: 320px;
1289 | }
1290 |
--------------------------------------------------------------------------------
/public/style/reset.css:
--------------------------------------------------------------------------------
1 | /* Reset.less
2 | * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc).
3 | * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
4 |
5 | html,
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | }
10 |
11 | h1,
12 | h2,
13 | h3,
14 | h4,
15 | h5,
16 | h6,
17 | p,
18 | blockquote,
19 | pre,
20 | a,
21 | abbr,
22 | acronym,
23 | address,
24 | cite,
25 | code,
26 | del,
27 | dfn,
28 | em,
29 | img,
30 | q,
31 | s,
32 | samp,
33 | small,
34 | strike,
35 | strong,
36 | sub,
37 | sup,
38 | tt,
39 | var,
40 | dd,
41 | dl,
42 | dt,
43 | li,
44 | ol,
45 | ul,
46 | fieldset,
47 | form,
48 | label,
49 | legend,
50 | button,
51 | table,
52 | caption,
53 | tbody,
54 | tfoot,
55 | thead,
56 | tr,
57 | th,
58 | td {
59 | margin: 0;
60 | padding: 0;
61 | border: 0;
62 | font-weight: normal;
63 | font-style: normal;
64 | font-size: 100%;
65 | line-height: 1;
66 | font-family: inherit;
67 | }
68 |
69 | table {
70 | border-collapse: collapse;
71 | border-spacing: 0;
72 | }
73 |
74 | ol,
75 | ul {
76 | list-style: none;
77 | }
78 |
79 | q:before,
80 | q:after,
81 | blockquote:before,
82 | blockquote:after {
83 | content: "";
84 | }
85 |
86 | html {
87 | font-size: 100%;
88 | -webkit-text-size-adjust: 100%;
89 | -ms-text-size-adjust: 100%;
90 | }
91 |
92 | a:focus {
93 | outline: thin dotted;
94 | }
95 |
96 | a:hover,
97 | a:active {
98 | outline: 0;
99 | }
100 |
101 | article,
102 | aside,
103 | details,
104 | figcaption,
105 | figure,
106 | footer,
107 | header,
108 | hgroup,
109 | nav,
110 | section {
111 | display: block;
112 | }
113 |
114 | audio,
115 | canvas,
116 | video {
117 | display: inline-block;
118 | *display: inline;
119 | *zoom: 1;
120 | }
121 |
122 | audio:not([controls]) {
123 | display: none;
124 | }
125 |
126 | sub,
127 | sup {
128 | font-size: 75%;
129 | line-height: 0;
130 | position: relative;
131 | vertical-align: baseline;
132 | }
133 |
134 | sup {
135 | top: -0.5em;
136 | }
137 |
138 | sub {
139 | bottom: -0.25em;
140 | }
141 |
142 | img {
143 | border: 0;
144 | -ms-interpolation-mode: bicubic;
145 | }
146 |
147 | button,
148 | input,
149 | select,
150 | textarea {
151 | font-size: 100%;
152 | margin: 0;
153 | vertical-align: baseline;
154 | *vertical-align: middle;
155 | }
156 |
157 | button,
158 | input {
159 | line-height: normal;
160 | *overflow: visible;
161 | }
162 |
163 | button::-moz-focus-inner,
164 | input::-moz-focus-inner {
165 | border: 0;
166 | padding: 0;
167 | }
168 |
169 | button,
170 | input[type="button"],
171 | input[type="reset"],
172 | input[type="submit"] {
173 | cursor: pointer;
174 | -webkit-appearance: button;
175 | }
176 |
177 | input[type="search"] {
178 | -webkit-appearance: textfield;
179 | -webkit-box-sizing: content-box;
180 | -moz-box-sizing: content-box;
181 | box-sizing: content-box;
182 | }
183 |
184 | input[type="search"]::-webkit-search-decoration {
185 | -webkit-appearance: none;
186 | }
187 |
188 | textarea {
189 | overflow: auto;
190 | vertical-align: top;
191 | }
192 |
193 | @font-face {
194 | font-family: 'Open Sans';
195 | src: url('/font/OpenSans-Light-webfont.eot');
196 | src: url('/font/OpenSans-Light-webfont.eot?') format('embedded-opentype'), url('/font/OpenSans-Light-webfont.woff') format('woff'), url('/font/OpenSans-Light-webfont.ttf') format('truetype'), url('/font/OpenSans-Light-webfont.svg') format('svg');
197 | font-weight: 200;
198 | font-style: normal;
199 | }
200 |
201 | @font-face {
202 | font-family: 'Open Sans';
203 | src: url('/font/OpenSans-Regular-webfont.eot');
204 | src: url('/font/OpenSans-Regular-webfont.eot?') format('embedded-opentype'), url('/font/OpenSans-Regular-webfont.woff') format('woff'), url('/font/OpenSans-Regular-webfont.ttf') format('truetype'), url('/font/OpenSans-Regular-webfont.svg') format('svg');
205 | font-weight: normal;
206 | font-weight: 400;
207 | font-style: normal;
208 | }
209 |
210 | .force-wrap {
211 | word-wrap: break-word;
212 | word-break: break-all;
213 | -ms-word-break: break-all;
214 | word-break: break-word;
215 | -webkit-hyphens: auto;
216 | -moz-hyphens: auto;
217 | -ms-hyphens: auto;
218 | hyphens: auto;
219 | }
220 |
221 | .type-light {
222 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
223 | font-weight: 300;
224 | }
225 |
226 | * {
227 | -webkit-box-sizing: border-box;
228 | -moz-box-sizing: border-box;
229 | box-sizing: border-box;
230 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
231 | -webkit-tap-highlight-color: transparent;
232 | }
233 |
234 | html,
235 | button,
236 | input,
237 | textarea,
238 | select {
239 | outline: none;
240 | -webkit-font-smoothing: antialiased;
241 | -moz-osx-font-smoothing: grayscale;
242 | }
243 |
244 | body {
245 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
246 | font-style: 400;
247 | color: #333333;
248 | font-size: 16px;
249 | }
250 |
251 | h1,
252 | h2,
253 | h3,
254 | h4,
255 | h5,
256 | h6 {
257 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
258 | font-style: 400;
259 | margin: 0;
260 | padding: 0;
261 | }
262 |
263 | h1 {
264 | font-size: 40px;
265 | line-height: 48px;
266 | }
267 |
268 | h2 {
269 | font-size: 28px;
270 | line-height: 32px;
271 | }
272 |
273 | h3 {
274 | font-size: 24px;
275 | line-height: 28px;
276 | }
277 |
278 | h4 {
279 | font-size: 20px;
280 | line-height: 24px;
281 | }
282 |
283 | h5 {
284 | font-size: 14px;
285 | line-height: 20px;
286 | color: #cccccc;
287 | text-transform: uppercase;
288 | }
289 |
290 | h6 {
291 | color: #aaaaaa;
292 | }
293 |
294 | p {
295 | font-size: 16px;
296 | line-height: 24px;
297 | }
298 |
299 | sub,
300 | sup {
301 | font-size: .8em;
302 | }
303 |
304 | sub {
305 | bottom: -0.2em;
306 | }
307 |
308 | sup {
309 | top: -0.2em;
310 | }
311 |
312 | b {
313 | font-weight: bold;
314 | }
315 |
316 | em {
317 | font-style: italic;
318 | }
319 |
320 | [class^="btn-"],
321 | [class*=" btn-"] {
322 | font-size: 14px;
323 | line-height: 20px;
324 | line-height: 20px !important;
325 | padding: 1em 1.25em;
326 | letter-spacing: .3em;
327 | text-indent: .3em;
328 | text-transform: uppercase;
329 | -webkit-transition: all 200ms ease-in;
330 | -moz-transition: all 200ms ease-in;
331 | -o-transition: all 200ms ease-in;
332 | transition: all 200ms ease-in;
333 | color: #ffffff;
334 | display: inline-block;
335 | position: relative;
336 | text-align: center;
337 | text-decoration: none !important;
338 | vertical-align: middle;
339 | white-space: nowrap;
340 | }
341 |
342 | [class^="btn-"][class*="primary"],
343 | [class*=" btn-"][class*="primary"] {
344 | background-color: #2cc5d2;
345 | color: #ffffff;
346 | }
347 |
348 | [class^="btn-"][class*="primary"]:hover,
349 | [class*=" btn-"][class*="primary"]:hover {
350 | background-color: #28b1bd;
351 | }
352 |
353 | [class^="btn-"][class*="primary"]:active,
354 | [class*=" btn-"][class*="primary"]:active {
355 | box-shadow: rgba(0, 0, 0, 0.3) 0 1px 3px 0 inset;
356 | }
357 |
358 | [class^="btn-"][class*="secondary"],
359 | [class*=" btn-"][class*="secondary"] {
360 | -webkit-transition: all 300ms ease-in;
361 | -moz-transition: all 300ms ease-in;
362 | -o-transition: all 300ms ease-in;
363 | transition: all 300ms ease-in;
364 | box-shadow: #5a7ca6 0 0 0 1px inset;
365 | color: #ffffff;
366 | }
367 |
368 | [class^="btn-"][class*="secondary"]:hover,
369 | [class*=" btn-"][class*="secondary"]:hover {
370 | color: #eeeeee;
371 | }
372 |
373 | [class^="btn-"][class*="secondary"]:active,
374 | [class*=" btn-"][class*="secondary"]:active,
375 | [class^="btn-"][class*="secondary"].active,
376 | [class*=" btn-"][class*="secondary"].active {
377 | box-shadow: #9db1ca 0 0 0 1px inset;
378 | }
379 |
380 | [class^="btn-"][disabled],
381 | [class*=" btn-"][disabled] {
382 | opacity: .5;
383 | }
384 |
385 | .btns-group {
386 | display: -webkit-box;
387 | display: -moz-box;
388 | display: -webkit-flex;
389 | display: -ms-flexbox;
390 | display: flex;
391 | -webkit-flex-wrap: wrap;
392 | -ms-flex-wrap: wrap;
393 | flex-wrap: wrap;
394 | width: 100%;
395 | }
396 |
397 | .btns-group [class*="btn-"] {
398 | overflow: hidden;
399 | text-overflow: ellipsis;
400 | white-space: nowrap;
401 | -webkit-box-flex: 1;
402 | -moz-box-flex: 1;
403 | -webkit-flex: 1;
404 | -ms-flex: 1;
405 | flex: 1;
406 | }
407 |
408 | .btns-group [class*="btn-"] + [class*="btn-"] {
409 | margin-left: -1px;
410 | }
411 |
412 | input[type="text"],
413 | input[type="email"],
414 | input[type="password"],
415 | textarea {
416 | font-size: 14px;
417 | line-height: 20px;
418 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
419 | font-style: 400;
420 | padding: .75rem 0;
421 | line-height: 1.5rem !important;
422 | border: none;
423 | border-radius: 0;
424 | box-sizing: border-box;
425 | color: #333333;
426 | outline: none;
427 | }
428 |
429 | input[type="text"]::-webkit-input-placeholder,
430 | input[type="email"]::-webkit-input-placeholder,
431 | input[type="password"]::-webkit-input-placeholder,
432 | textarea::-webkit-input-placeholder {
433 | color: #778b91;
434 | }
435 |
436 | input[type="text"]:-moz-placeholder,
437 | input[type="email"]:-moz-placeholder,
438 | input[type="password"]:-moz-placeholder,
439 | textarea:-moz-placeholder {
440 | color: #778b91;
441 | }
442 |
443 | input[type="text"]::-moz-placeholder,
444 | input[type="email"]::-moz-placeholder,
445 | input[type="password"]::-moz-placeholder,
446 | textarea::-moz-placeholder {
447 | color: #778b91;
448 | }
449 |
450 | input[type="text"]:-ms-input-placeholder,
451 | input[type="email"]:-ms-input-placeholder,
452 | input[type="password"]:-ms-input-placeholder,
453 | textarea:-ms-input-placeholder {
454 | color: #778b91;
455 | }
456 |
457 | input[type="text"][disabled],
458 | input[type="email"][disabled],
459 | input[type="password"][disabled],
460 | textarea[disabled] {
461 | opacity: .5;
462 | }
463 |
464 | input:-webkit-autofill {
465 | -webkit-box-shadow: 0 0 0 1000px #ffffff inset;
466 | }
467 |
468 | .checkbox {
469 | display: inline-block;
470 | height: 3rem;
471 | position: relative;
472 | vertical-align: middle;
473 | width: 44px;
474 | }
475 |
476 | .checkbox input[type="checkbox"] {
477 | font-size: 1em;
478 | visibility: hidden;
479 | }
480 |
481 | .checkbox input[type="checkbox"] + span:before {
482 | position: absolute;
483 | top: 50%;
484 | right: auto;
485 | bottom: auto;
486 | left: 50%;
487 | width: 0.85em;
488 | height: 0.85em;
489 | -webkit-transform: translate3d(-50%, -50%, 0);
490 | -moz-transform: translate3d(-50%, -50%, 0);
491 | -ms-transform: translate3d(-50%, -50%, 0);
492 | -o-transform: translate3d(-50%, -50%, 0);
493 | transform: translate3d(-50%, -50%, 0);
494 | background: transparent;
495 | box-shadow: #abdfe3 0 0 0 1px inset;
496 | content: '';
497 | display: block;
498 | }
499 |
500 | .checkbox input[type="checkbox"]:checked + span:before {
501 | box-shadow: none;
502 | color: #cccccc;
503 | font-family: 'todos';
504 | speak: none;
505 | font-style: normal;
506 | font-weight: normal;
507 | font-variant: normal;
508 | text-transform: none;
509 | line-height: 1;
510 | -webkit-font-smoothing: antialiased;
511 | -moz-osx-font-smoothing: grayscale;
512 | content: "\e612";
513 | }
514 |
515 | .input-symbol {
516 | display: inline-block;
517 | position: relative;
518 | }
519 |
520 | .input-symbol.error [class^="icon-"],
521 | .input-symbol.error [class*=" icon-"] {
522 | color: #ff4400;
523 | }
524 |
525 | .input-symbol [class^="icon-"],
526 | .input-symbol [class*=" icon-"] {
527 | left: 1em;
528 | }
529 |
530 | .input-symbol input {
531 | padding-left: 3em;
532 | }
533 |
534 | .input-symbol input {
535 | width: 100%;
536 | }
537 |
538 | .input-symbol input:focus + [class^="icon-"],
539 | .input-symbol input:focus + [class*=" icon-"] {
540 | color: #2cc5d2;
541 | }
542 |
543 | .input-symbol [class^="icon-"],
544 | .input-symbol [class*=" icon-"] {
545 | -webkit-transition: all 300ms ease-in;
546 | -moz-transition: all 300ms ease-in;
547 | -o-transition: all 300ms ease-in;
548 | transition: all 300ms ease-in;
549 | -webkit-transform: translate3d(0, -50%, 0);
550 | -moz-transform: translate3d(0, -50%, 0);
551 | -ms-transform: translate3d(0, -50%, 0);
552 | -o-transform: translate3d(0, -50%, 0);
553 | transform: translate3d(0, -50%, 0);
554 | background: transparent;
555 | color: #aaaaaa;
556 | font-size: 1em;
557 | height: 1em;
558 | position: absolute;
559 | top: 50%;
560 | width: 1em;
561 | }
562 |
563 | @font-face {
564 | font-family: 'todos';
565 | src: url('/icon/todos.eot?-5w3um4');
566 | src: url('/icon/todos.eot?') format('embedded-opentype'), url('/icon/todos.woff?5w3um4') format('woff'), url('/icon/todos.ttf?5w3um4') format('truetype'), url('/icon/todos.svg?5w3um4') format('svg');
567 | font-weight: normal;
568 | font-style: normal;
569 | }
570 |
571 | [class^="icon-"],
572 | [class*=" icon-"] {
573 | font-family: 'todos';
574 | speak: none;
575 | font-style: normal;
576 | font-weight: normal;
577 | font-variant: normal;
578 | text-transform: none;
579 | line-height: 1;
580 | -webkit-font-smoothing: antialiased;
581 | -moz-osx-font-smoothing: grayscale;
582 | }
583 |
584 | .icon-unlock:before {
585 | content: "\e600";
586 | }
587 |
588 | .icon-user-add:before {
589 | content: "\e604";
590 | }
591 |
592 | .icon-cog:before {
593 | content: "\e606";
594 | }
595 |
596 | .icon-trash:before {
597 | content: "\e607";
598 | }
599 |
600 | .icon-edit:before {
601 | content: "\e608";
602 | }
603 |
604 | .icon-add:before {
605 | content: "\e60a";
606 | }
607 |
608 | .icon-plus:before {
609 | content: "\e60b";
610 | }
611 |
612 | .icon-close:before {
613 | content: "\e60c";
614 | }
615 |
616 | .icon-cross:before {
617 | content: "\e60d";
618 | }
619 |
620 | .icon-sync:before {
621 | content: "\e60e";
622 | }
623 |
624 | .icon-lock:before {
625 | content: "\e610";
626 | }
627 |
628 | .icon-check:before {
629 | content: "\e612";
630 | }
631 |
632 | .icon-share:before {
633 | content: "\e617";
634 | }
635 |
636 | .icon-email:before {
637 | content: "\e619";
638 | }
639 |
640 | .icon-arrow-up:before {
641 | content: "\e623";
642 | }
643 |
644 | .icon-arrow-down:before {
645 | content: "\e626";
646 | }
647 |
648 | .icon-list-unordered:before {
649 | content: "\e634";
650 | }
651 |
652 | body {
653 | position: absolute;
654 | top: 0;
655 | right: 0;
656 | bottom: 0;
657 | left: 0;
658 | width: auto;
659 | height: auto;
660 | background-color: #315481;
661 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMzMTU0ODEiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzkxOGU4MiIgc3RvcC1vcGFjaXR5PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2xlc3NoYXQtZ2VuZXJhdGVkKSIgLz48L3N2Zz4=);
662 | background-image: -webkit-linear-gradient(top, #315481, #918e82 100%);
663 | background-image: -moz-linear-gradient(top, #315481, #918e82 100%);
664 | background-image: -o-linear-gradient(top, #315481, #918e82 100%);
665 | background-image: linear-gradient(to bottom, #315481, #918e82 100%);
666 | background-repeat: no-repeat;
667 | background-attachment: fixed;
668 | }
669 |
670 | #container {
671 | position: absolute;
672 | top: 0;
673 | right: 0;
674 | bottom: 0;
675 | left: 0;
676 | width: auto;
677 | height: auto;
678 | overflow: hidden;
679 | }
680 |
681 | @media screen and (min-width: 60em) {
682 | #container {
683 | left: 5.55555%;
684 | right: 5.55555%;
685 | }
686 | }
687 |
688 | @media screen and (min-width: 80em) {
689 | #container {
690 | left: 11.1111%;
691 | right: 11.1111%;
692 | }
693 | }
694 |
695 | #menu {
696 | position: absolute;
697 | top: 0;
698 | right: 0;
699 | bottom: 0;
700 | left: 0;
701 | width: 270px;
702 | height: auto;
703 | }
704 |
705 | #content-container {
706 | position: absolute;
707 | top: 0;
708 | right: 0;
709 | bottom: 0;
710 | left: 0;
711 | width: auto;
712 | height: auto;
713 | -webkit-transition: all 200ms ease-out;
714 | -moz-transition: all 200ms ease-out;
715 | -o-transition: all 200ms ease-out;
716 | transition: all 200ms ease-out;
717 | -webkit-transform: translate3d(0, 0, 0);
718 | -moz-transform: translate3d(0, 0, 0);
719 | -ms-transform: translate3d(0, 0, 0);
720 | -o-transform: translate3d(0, 0, 0);
721 | transform: translate3d(0, 0, 0);
722 | background: #d2edf4;
723 | opacity: 1;
724 | }
725 |
726 | @media screen and (min-width: 40em) {
727 | #content-container {
728 | left: 270px;
729 | }
730 | }
731 |
732 | #content-container .content-scrollable {
733 | position: absolute;
734 | top: 0;
735 | right: 0;
736 | bottom: 0;
737 | left: 0;
738 | width: auto;
739 | height: auto;
740 | -webkit-transform: translate3d(0, 0, 0);
741 | -moz-transform: translate3d(0, 0, 0);
742 | -ms-transform: translate3d(0, 0, 0);
743 | -o-transform: translate3d(0, 0, 0);
744 | transform: translate3d(0, 0, 0);
745 | overflow-y: auto;
746 | -webkit-overflow-scrolling: touch;
747 | }
748 |
749 | .menu-open #content-container {
750 | -webkit-transform: translate3d(270px, 0, 0);
751 | -moz-transform: translate3d(270px, 0, 0);
752 | -ms-transform: translate3d(270px, 0, 0);
753 | -o-transform: translate3d(270px, 0, 0);
754 | transform: translate3d(270px, 0, 0);
755 | opacity: .85;
756 | left: 0;
757 | }
758 |
759 | @media screen and (min-width: 40em) {
760 | .menu-open #content-container {
761 | -webkit-transform: translate3d(0, 0, 0);
762 | -moz-transform: translate3d(0, 0, 0);
763 | -ms-transform: translate3d(0, 0, 0);
764 | -o-transform: translate3d(0, 0, 0);
765 | transform: translate3d(0, 0, 0);
766 | opacity: 1;
767 | left: 270px;
768 | }
769 | }
770 |
771 | .content-overlay {
772 | position: absolute;
773 | top: 0;
774 | right: 0;
775 | bottom: 0;
776 | left: 0;
777 | width: auto;
778 | height: auto;
779 | cursor: pointer;
780 | }
781 |
782 | .menu-open .content-overlay {
783 | -webkit-transform: translate3d(270px, 0, 0);
784 | -moz-transform: translate3d(270px, 0, 0);
785 | -ms-transform: translate3d(270px, 0, 0);
786 | -o-transform: translate3d(270px, 0, 0);
787 | transform: translate3d(270px, 0, 0);
788 | z-index: 1;
789 | }
790 |
791 | @media screen and (min-width: 40em) {
792 | .content-overlay {
793 | display: none;
794 | }
795 | }
796 |
797 | a {
798 | -webkit-transition: all 200ms ease-in;
799 | -moz-transition: all 200ms ease-in;
800 | -o-transition: all 200ms ease-in;
801 | transition: all 200ms ease-in;
802 | color: #5db9ff;
803 | cursor: pointer;
804 | text-decoration: none;
805 | }
806 |
807 | a:hover {
808 | color: #239da8;
809 | }
810 |
811 | a:active {
812 | color: #555555;
813 | }
814 |
815 | a:focus {
816 | outline: none;
817 | }
818 |
819 | #menu {
820 | overflow-y: auto;
821 | -webkit-overflow-scrolling: touch;
822 | }
823 |
824 | #menu .btns-group,
825 | #menu .btns-group-vertical {
826 | margin: 2em auto 2em;
827 | width: 80%;
828 | }
829 |
830 | #menu .btns-group .btn-secondary,
831 | #menu .btns-group-vertical .btn-secondary {
832 | font-size: 12px;
833 | line-height: 16px;
834 | padding-top: .5em;
835 | padding-bottom: .5em;
836 | }
837 |
838 | #menu .btns-group-vertical .btn-secondary {
839 | word-wrap: break-word;
840 | word-break: break-all;
841 | -ms-word-break: break-all;
842 | word-break: break-word;
843 | -webkit-hyphens: auto;
844 | -moz-hyphens: auto;
845 | -ms-hyphens: auto;
846 | hyphens: auto;
847 | padding-right: 2.5em;
848 | text-align: left;
849 | text-indent: 0;
850 | white-space: normal;
851 | width: 100%;
852 | }
853 |
854 | #menu .btns-group-vertical .btn-secondary + .btn-secondary {
855 | margin-top: .5rem;
856 | }
857 |
858 | #menu .btns-group-vertical .btn-secondary + .btn-secondary:before {
859 | position: absolute;
860 | top: -0.5rem;
861 | right: 50%;
862 | bottom: auto;
863 | left: auto;
864 | width: 1px;
865 | height: 0.5rem;
866 | background: #5a7ca6;
867 | content: '';
868 | }
869 |
870 | #menu .btns-group-vertical .btn-secondary [class^="icon-"],
871 | #menu .btns-group-vertical .btn-secondary [class*=" icon-"] {
872 | position: absolute;
873 | top: 0.5em;
874 | right: 0.5em;
875 | bottom: auto;
876 | left: auto;
877 | width: auto;
878 | height: auto;
879 | line-height: 20px;
880 | }
881 |
882 | #menu .list-todos a {
883 | box-shadow: rgba(255, 255, 255, 0.15) 0 1px 0 0;
884 | display: block;
885 | line-height: 1.5em;
886 | padding: .75em 2.5em;
887 | position: relative;
888 | }
889 |
890 | #menu .list-todos .count-list {
891 | -webkit-transition: all 200ms ease-in;
892 | -moz-transition: all 200ms ease-in;
893 | -o-transition: all 200ms ease-in;
894 | transition: all 200ms ease-in;
895 | background: rgba(255, 255, 255, 0.1);
896 | border-radius: 1em;
897 | float: right;
898 | font-size: .7rem;
899 | line-height: 1;
900 | margin-top: .25rem;
901 | margin-right: -1.5em;
902 | padding: .3em .5em;
903 | }
904 |
905 | #menu .list-todos [class^="icon-"],
906 | #menu .list-todos [class*=" icon-"] {
907 | font-size: 14px;
908 | line-height: 20px;
909 | float: left;
910 | margin-left: -1.5rem;
911 | margin-right: .5rem;
912 | margin-top: .1rem;
913 | width: 1em;
914 | }
915 |
916 | #menu .list-todos .icon-lock {
917 | font-size: 12px;
918 | line-height: 16px;
919 | margin-top: .2rem;
920 | opacity: .8;
921 | }
922 |
923 | #menu .list-todos .list-todo {
924 | color: rgba(255, 255, 255, 0.4);
925 | }
926 |
927 | #menu .list-todos .list-todo:hover,
928 | #menu .list-todos .list-todo:active,
929 | #menu .list-todos .list-todo.active {
930 | color: #ffffff;
931 | }
932 |
933 | #menu .list-todos .list-todo:hover .count-list,
934 | #menu .list-todos .list-todo:active .count-list,
935 | #menu .list-todos .list-todo.active .count-list {
936 | background: #2cc5d2;
937 | }
938 |
939 | .cordova #menu .list-todos .list-todo:hover {
940 | color: rgba(255, 255, 255, 0.4);
941 | }
942 |
943 | nav {
944 | position: absolute;
945 | top: 0;
946 | right: 0;
947 | bottom: auto;
948 | left: 0;
949 | width: auto;
950 | height: auto;
951 | -webkit-transform: translate3d(0, 0, 0);
952 | -moz-transform: translate3d(0, 0, 0);
953 | -ms-transform: translate3d(0, 0, 0);
954 | -o-transform: translate3d(0, 0, 0);
955 | transform: translate3d(0, 0, 0);
956 | -webkit-transition: all 200ms ease-out;
957 | -moz-transition: all 200ms ease-out;
958 | -o-transition: all 200ms ease-out;
959 | transition: all 200ms ease-out;
960 | z-index: 10;
961 | }
962 |
963 | nav .nav-item {
964 | font-size: 20px;
965 | line-height: 24px;
966 | color: #1c3f53;
967 | display: inline-block;
968 | height: 3rem;
969 | text-align: center;
970 | width: 3rem;
971 | }
972 |
973 | nav .nav-item:active {
974 | opacity: .5;
975 | }
976 |
977 | nav .nav-item [class^="icon-"],
978 | nav .nav-item [class*=" icon-"] {
979 | line-height: 3rem;
980 | vertical-align: middle;
981 | }
982 |
983 | nav .nav-group {
984 | position: absolute;
985 | top: 0;
986 | right: auto;
987 | bottom: auto;
988 | left: 0;
989 | width: auto;
990 | height: auto;
991 | z-index: 1;
992 | }
993 |
994 | nav .nav-group.right {
995 | left: auto;
996 | right: 0;
997 | }
998 |
999 | .page.lists-show nav {
1000 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj48bGluZWFyR3JhZGllbnQgaWQ9Imxlc3NoYXQtZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNkMGVkZjUiIHN0b3Atb3BhY2l0eT0iMSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2UxZTVmMCIgc3RvcC1vcGFjaXR5PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2xlc3NoYXQtZ2VuZXJhdGVkKSIgLz48L3N2Zz4=);
1001 | background-image: -webkit-linear-gradient(top, #d0edf5, #e1e5f0 100%);
1002 | background-image: -moz-linear-gradient(top, #d0edf5, #e1e5f0 100%);
1003 | background-image: -o-linear-gradient(top, #d0edf5, #e1e5f0 100%);
1004 | background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%);
1005 | height: 5em;
1006 | text-align: center;
1007 | }
1008 |
1009 | @media screen and (min-width: 40em) {
1010 | .page.lists-show nav {
1011 | text-align: left;
1012 | }
1013 | }
1014 |
1015 | .page.lists-show nav .title-page {
1016 | position: absolute;
1017 | top: 0;
1018 | right: 3rem;
1019 | bottom: auto;
1020 | left: 3rem;
1021 | width: auto;
1022 | height: auto;
1023 | cursor: pointer;
1024 | font-size: 1.125em;
1025 | white-space: nowrap;
1026 | }
1027 |
1028 | @media screen and (min-width: 40em) {
1029 | .page.lists-show nav .title-page {
1030 | left: 1rem;
1031 | right: 6rem;
1032 | }
1033 | }
1034 |
1035 | .page.lists-show nav .title-page .title-wrapper {
1036 | overflow: hidden;
1037 | text-overflow: ellipsis;
1038 | white-space: nowrap;
1039 | color: #1c3f53;
1040 | display: inline-block;
1041 | padding-right: 1.5rem;
1042 | vertical-align: top;
1043 | max-width: 100%;
1044 | }
1045 |
1046 | .page.lists-show nav .title-page .count-list {
1047 | background: #2cc5d2;
1048 | border-radius: 1em;
1049 | color: #ffffff;
1050 | display: inline-block;
1051 | font-size: .7rem;
1052 | line-height: 1;
1053 | margin-left: -1.25rem;
1054 | margin-top: -4px;
1055 | padding: .3em .5em;
1056 | vertical-align: middle;
1057 | }
1058 |
1059 | .page.lists-show nav form.todo-new {
1060 | position: absolute;
1061 | top: 3em;
1062 | right: 0;
1063 | bottom: auto;
1064 | left: 0;
1065 | width: auto;
1066 | height: auto;
1067 | }
1068 |
1069 | .page.lists-show nav form.todo-new input[type="text"] {
1070 | background: transparent;
1071 | padding-bottom: .25em;
1072 | padding-left: 44px !important;
1073 | padding-top: .25em;
1074 | }
1075 |
1076 | .page.lists-show nav form.list-edit-form {
1077 | position: relative;
1078 | }
1079 |
1080 | .page.lists-show nav form.list-edit-form input[type="text"] {
1081 | background: transparent;
1082 | font-size: 1.125em;
1083 | width: 100%;
1084 | padding-right: 3em;
1085 | padding-left: 1rem;
1086 | }
1087 |
1088 | .page.lists-show nav select.list-edit {
1089 | font-size: 14px;
1090 | line-height: 20px;
1091 | position: absolute;
1092 | top: 0;
1093 | right: 0;
1094 | bottom: 0;
1095 | left: 0;
1096 | width: auto;
1097 | height: auto;
1098 | background: transparent;
1099 | opacity: 0;
1100 | }
1101 |
1102 | .page.lists-show nav .options-web {
1103 | display: none;
1104 | }
1105 |
1106 | .page.lists-show nav .options-web .nav-item {
1107 | font-size: 16px;
1108 | line-height: 24px;
1109 | width: 2rem;
1110 | }
1111 |
1112 | .page.lists-show nav .options-web .nav-item:last-child {
1113 | margin-right: .5rem;
1114 | }
1115 |
1116 | @media screen and (min-width: 40em) {
1117 | .page.lists-show nav .nav-group:not(.right) {
1118 | display: none !important;
1119 | }
1120 |
1121 | .page.lists-show nav .options-mobile {
1122 | display: none;
1123 | }
1124 |
1125 | .page.lists-show nav .options-web {
1126 | display: block;
1127 | }
1128 | }
1129 |
1130 | @media screen and (min-width: 40em) {
1131 | .page.auth .nav-group {
1132 | display: none;
1133 | }
1134 |
1135 | .page.not-found .nav-group {
1136 | display: none;
1137 | }
1138 | }
1139 |
1140 | .list-items .list-item {
1141 | font-size: 14px;
1142 | line-height: 20px;
1143 | display: -webkit-box;
1144 | display: -moz-box;
1145 | display: -webkit-flex;
1146 | display: -ms-flexbox;
1147 | display: flex;
1148 | -webkit-flex-wrap: wrap;
1149 | -ms-flex-wrap: wrap;
1150 | flex-wrap: wrap;
1151 | height: 3rem;
1152 | width: 100%;
1153 | }
1154 |
1155 | .list-items .list-item .checkbox {
1156 | -webkit-box-flex: 0;
1157 | -moz-box-flex: 0;
1158 | -webkit-flex: 0 0 44px;
1159 | -ms-flex: 0 0 44px;
1160 | flex: 0 0 44px;
1161 | cursor: pointer;
1162 | }
1163 |
1164 | .list-items .list-item input[type="text"] {
1165 | -webkit-box-flex: 1;
1166 | -moz-box-flex: 1;
1167 | -webkit-flex: 1;
1168 | -ms-flex: 1;
1169 | flex: 1;
1170 | }
1171 |
1172 | .list-items .list-item .delete-item {
1173 | -webkit-box-flex: 0;
1174 | -moz-box-flex: 0;
1175 | -webkit-flex: 0 0 3rem;
1176 | -ms-flex: 0 0 3rem;
1177 | flex: 0 0 3rem;
1178 | }
1179 |
1180 | .list-items .list-item input[type="text"] {
1181 | background: transparent;
1182 | cursor: pointer;
1183 | }
1184 |
1185 | .list-items .list-item input[type="text"]:focus {
1186 | cursor: text;
1187 | }
1188 |
1189 | .list-items .list-item .delete-item {
1190 | color: #cccccc;
1191 | line-height: 3rem;
1192 | text-align: center;
1193 | }
1194 |
1195 | .list-items .list-item .delete-item:hover {
1196 | color: #2cc5d2;
1197 | }
1198 |
1199 | .list-items .list-item .delete-item:active {
1200 | color: #555555;
1201 | }
1202 |
1203 | .list-items .list-item .delete-item .icon-trash {
1204 | font-size: 1.1em;
1205 | }
1206 |
1207 | .list-items .list-item + .list-item {
1208 | border-top: 1px solid #f0f9fb;
1209 | }
1210 |
1211 | .list-items .list-item.checked input[type="text"] {
1212 | color: #cccccc;
1213 | text-decoration: line-through;
1214 | }
1215 |
1216 | .list-items .list-item.checked .delete-item {
1217 | display: inline-block;
1218 | }
1219 |
1220 | .list-items .list-item .delete-item {
1221 | display: none;
1222 | }
1223 |
1224 | .list-items .list-item.editing .delete-item {
1225 | display: inline-block;
1226 | }
1227 |
1228 | .wrapper-message {
1229 | position: absolute;
1230 | top: 45%;
1231 | right: 0;
1232 | bottom: auto;
1233 | left: 0;
1234 | width: auto;
1235 | height: auto;
1236 | -webkit-transform: translate3d(0, -50%, 0);
1237 | -moz-transform: translate3d(0, -50%, 0);
1238 | -ms-transform: translate3d(0, -50%, 0);
1239 | -o-transform: translate3d(0, -50%, 0);
1240 | transform: translate3d(0, -50%, 0);
1241 | text-align: center;
1242 | }
1243 |
1244 | .wrapper-message .title-message {
1245 | font-size: 24px;
1246 | line-height: 28px;
1247 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
1248 | font-weight: 300;
1249 | color: #1c3f53;
1250 | margin-bottom: .5em;
1251 | }
1252 |
1253 | .wrapper-message .subtitle-message {
1254 | font-size: 14px;
1255 | line-height: 20px;
1256 | color: #aaaaaa;
1257 | }
1258 |
1259 | @-webkit-keyframes spin {
1260 | 0% {
1261 | -webkit-transform: rotate(0deg);
1262 | -moz-transform: rotate(0deg);
1263 | -ms-transform: rotate(0deg);
1264 | -o-transform: rotate(0deg);
1265 | transform: rotate(0deg);
1266 | }
1267 |
1268 | 100% {
1269 | -webkit-transform: rotate(359deg);
1270 | -moz-transform: rotate(359deg);
1271 | -ms-transform: rotate(359deg);
1272 | -o-transform: rotate(359deg);
1273 | transform: rotate(359deg);
1274 | }
1275 | }
1276 |
1277 | @keyframes spin {
1278 | 0% {
1279 | -webkit-transform: rotate(0deg);
1280 | -moz-transform: rotate(0deg);
1281 | -ms-transform: rotate(0deg);
1282 | -o-transform: rotate(0deg);
1283 | transform: rotate(0deg);
1284 | }
1285 |
1286 | 100% {
1287 | -webkit-transform: rotate(359deg);
1288 | -moz-transform: rotate(359deg);
1289 | -ms-transform: rotate(359deg);
1290 | -o-transform: rotate(359deg);
1291 | transform: rotate(359deg);
1292 | }
1293 | }
1294 |
1295 | .notifications {
1296 | position: absolute;
1297 | top: auto;
1298 | right: auto;
1299 | bottom: 10px;
1300 | left: 50%;
1301 | width: 280px;
1302 | height: auto;
1303 | -webkit-transform: translate3d(-50%, 0, 0);
1304 | -moz-transform: translate3d(-50%, 0, 0);
1305 | -ms-transform: translate3d(-50%, 0, 0);
1306 | -o-transform: translate3d(-50%, 0, 0);
1307 | transform: translate3d(-50%, 0, 0);
1308 | z-index: 1;
1309 | }
1310 |
1311 | @media screen and (min-width: 40em) {
1312 | .notifications {
1313 | -webkit-transform: translate3d(0, 0, 0);
1314 | -moz-transform: translate3d(0, 0, 0);
1315 | -ms-transform: translate3d(0, 0, 0);
1316 | -o-transform: translate3d(0, 0, 0);
1317 | transform: translate3d(0, 0, 0);
1318 | bottom: auto;
1319 | right: 1rem;
1320 | top: 1rem;
1321 | left: auto;
1322 | }
1323 | }
1324 |
1325 | .notifications .notification {
1326 | font-size: 12px;
1327 | line-height: 16px;
1328 | background: rgba(51, 51, 51, 0.85);
1329 | color: #ffffff;
1330 | margin-bottom: .25rem;
1331 | padding: .5rem .75rem;
1332 | position: relative;
1333 | width: 100%;
1334 | }
1335 |
1336 | .notifications .notification .icon-sync {
1337 | position: absolute;
1338 | top: 30%;
1339 | right: auto;
1340 | bottom: auto;
1341 | left: 1rem;
1342 | width: auto;
1343 | height: auto;
1344 | -webkit-animation: spin 2s infinite linear;
1345 | -moz-animation: spin 2s infinite linear;
1346 | -o-animation: spin 2s infinite linear;
1347 | animation: spin 2s infinite linear;
1348 | color: #ffffff;
1349 | font-size: 1.5em;
1350 | }
1351 |
1352 | .notifications .notification .meta {
1353 | overflow: hidden;
1354 | padding-left: 3em;
1355 | }
1356 |
1357 | .notifications .notification .meta .title-notification {
1358 | letter-spacing: .3em;
1359 | text-indent: .3em;
1360 | text-transform: uppercase;
1361 | display: block;
1362 | }
1363 |
1364 | .notifications .notification .meta .description {
1365 | display: block;
1366 | }
1367 |
1368 | .page.lists-show .content-scrollable {
1369 | background: #ffffff;
1370 | top: 5em !important;
1371 | }
1372 |
1373 | .page.auth {
1374 | text-align: center;
1375 | }
1376 |
1377 | .page.auth .content-scrollable {
1378 | background: #d2edf4;
1379 | }
1380 |
1381 | .page.auth .wrapper-auth {
1382 | padding-top: 4em;
1383 | }
1384 |
1385 | @media screen and (min-width: 40em) {
1386 | .page.auth .wrapper-auth {
1387 | margin: 0 auto;
1388 | max-width: 480px;
1389 | width: 80%;
1390 | }
1391 | }
1392 |
1393 | .page.auth .wrapper-auth .title-auth {
1394 | font-size: 40px;
1395 | line-height: 48px;
1396 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
1397 | font-weight: 300;
1398 | color: #1c3f53;
1399 | margin-bottom: .75rem;
1400 | }
1401 |
1402 | .page.auth .wrapper-auth .subtitle-auth {
1403 | color: #666666;
1404 | margin: 0 15% 3rem;
1405 | }
1406 |
1407 | .page.auth .wrapper-auth form .input-symbol {
1408 | margin-bottom: 1px;
1409 | width: 100%;
1410 | }
1411 |
1412 | .page.auth .wrapper-auth form .btn-primary {
1413 | margin: 1em 5% 0;
1414 | width: 90%;
1415 | }
1416 |
1417 | @media screen and (min-width: 40em) {
1418 | .page.auth .wrapper-auth form .btn-primary {
1419 | margin-left: 0;
1420 | margin-right: 0;
1421 | width: 100%;
1422 | }
1423 | }
1424 |
1425 | .page.auth .wrapper-auth .list-errors {
1426 | margin-top: -2rem;
1427 | }
1428 |
1429 | .page.auth .wrapper-auth .list-errors .list-item {
1430 | letter-spacing: .3em;
1431 | text-indent: .3em;
1432 | text-transform: uppercase;
1433 | background: #f6fccf;
1434 | color: #ff4400;
1435 | font-size: .625em;
1436 | margin-bottom: 1px;
1437 | padding: .7rem 0;
1438 | }
1439 |
1440 | .page.auth .link-auth-alt {
1441 | font-size: 12px;
1442 | line-height: 16px;
1443 | position: absolute;
1444 | top: auto;
1445 | right: 0;
1446 | bottom: 1em;
1447 | left: 0;
1448 | width: auto;
1449 | height: auto;
1450 | color: #aaaaaa;
1451 | display: inline-block;
1452 | }
1453 |
1454 | @media screen and (min-width: 40em) {
1455 | .page.auth .link-auth-alt {
1456 | bottom: 0;
1457 | margin-top: 1rem;
1458 | position: relative;
1459 | }
1460 | }
1461 |
1462 | .page.not-found .content-scrollable {
1463 | background: #d2edf4;
1464 | }
1465 |
1466 | .loading-app {
1467 | position: absolute;
1468 | top: 50%;
1469 | right: 50%;
1470 | bottom: auto;
1471 | left: auto;
1472 | width: 50%;
1473 | height: auto;
1474 | -webkit-transform: translate3d(50%, -50%, 0);
1475 | -moz-transform: translate3d(50%, -50%, 0);
1476 | -ms-transform: translate3d(50%, -50%, 0);
1477 | -o-transform: translate3d(50%, -50%, 0);
1478 | transform: translate3d(50%, -50%, 0);
1479 | min-width: 160px;
1480 | max-width: 320px;
1481 | }
--------------------------------------------------------------------------------
/public/style/font/OpenSans-Light-webfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------