tres 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -1
- data/Gemfile.lock +9 -9
- data/VERSION +1 -1
- data/javascripts/backbone-min.js +37 -33
- data/javascripts/jquery-1.8.3.min.js +2 -0
- data/javascripts/tres.coffee +166 -94
- data/lib/tres/asset_manager.rb +5 -2
- data/lib/tres.rb +3 -4
- data/sass/tres/base.scss +118 -80
- data/sass/tres/mixins.scss +57 -0
- data/sass/tres/themes/default.scss +22 -10
- data/templates/all.coffee +5 -5
- data/templates/config.ru +9 -2
- data/templates/home.coffee +1 -2
- data/tres.gemspec +2 -3
- metadata +8 -29
- data/javascripts/jquery-1.8.0.min.js +0 -2
data/javascripts/tres.coffee
CHANGED
@@ -1,210 +1,282 @@
|
|
1
|
+
# Tres
|
2
|
+
# ====
|
3
|
+
|
4
|
+
# The whole framework should fit nicely in a single file. Avoid magic,
|
5
|
+
# avoid indirection
|
6
|
+
|
7
|
+
# Grab all variables to shorter references we'll use throughout
|
1
8
|
Tres = {}
|
2
9
|
$ = window.jQuery
|
3
10
|
_ = window._
|
4
11
|
Backbone = window.Backbone
|
5
12
|
JST = window.JST
|
6
|
-
$window = $
|
7
|
-
$body = $
|
13
|
+
$window = $ window
|
14
|
+
$body = $ 'body'
|
8
15
|
make = Backbone.View.prototype.make
|
9
16
|
|
10
|
-
|
17
|
+
# Default screen template
|
18
|
+
defaultTemplate = _.template """
|
11
19
|
<header></header>
|
12
20
|
<h1>Tres</h1>
|
13
21
|
<p>Welcome to Tres</p>
|
14
|
-
"""
|
22
|
+
"""
|
23
|
+
# ---
|
15
24
|
|
16
|
-
# Tres.Device handles/exposes device events (orientation change, accellerometer,
|
17
|
-
# other hardware-related goodies
|
25
|
+
# Tres.Device handles/exposes device events (orientation change, accellerometer,
|
26
|
+
# etc), screen width, and other hardware-related goodies
|
18
27
|
class Device
|
19
|
-
constructor
|
28
|
+
constructor: ->
|
20
29
|
_.extend @, Backbone.Events
|
21
|
-
$window.on 'orientationchange',
|
30
|
+
$window.on 'orientationchange', =>
|
31
|
+
@trigger 'orientation:change'
|
32
|
+
# Fix <html> not stretching beyond 320px
|
33
|
+
$('html').width window.innerWidth
|
34
|
+
window.scrollTo 0, 0
|
22
35
|
|
23
|
-
width
|
24
|
-
height
|
25
|
-
orientation
|
36
|
+
width: -> window.outerWidth
|
37
|
+
height: -> window.outerHeight
|
38
|
+
orientation: ->
|
26
39
|
|
27
40
|
Tres.Device = new Device
|
28
41
|
|
29
|
-
#
|
42
|
+
# ---
|
43
|
+
|
44
|
+
# Tres.Screen is the base screen class. So you'll pretty have one of these for
|
45
|
+
# each "route" in your app
|
30
46
|
class Tres.Screen extends Backbone.View
|
31
47
|
|
32
48
|
# Defaults to using sections for screens
|
33
|
-
tagName
|
49
|
+
tagName: 'section'
|
34
50
|
|
35
|
-
# Ensure one can still declare events in a view without getting in the
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
"click a[href]:not([href^='http://'])" : 'touchLink'
|
51
|
+
# Ensure one can still declare events in a view without getting in the
|
52
|
+
# way of the defaults
|
53
|
+
__events:
|
54
|
+
"click a[href]:not([href^='http://'])": 'touchLink'
|
40
55
|
|
41
|
-
# Provide a convenience method `submit` which gets fired when you
|
42
|
-
#
|
43
|
-
|
56
|
+
# Provide a convenience method `submit` which gets fired when you
|
57
|
+
# submit a form in a screen. You can still trap forms normally.
|
58
|
+
# This is just a shortcut in case you have 1 form in a screen
|
59
|
+
"submit form": '__submit'
|
44
60
|
|
45
|
-
events
|
61
|
+
events: {}
|
46
62
|
|
47
|
-
initialize
|
63
|
+
initialize: (options = {}) ->
|
48
64
|
_.extend @, options
|
49
65
|
|
50
|
-
# Returns the title of the screen, which will only exist if there's a
|
51
|
-
# inside of it
|
52
|
-
title
|
66
|
+
# Returns the title of the screen, which will only exist if there's a
|
67
|
+
# header with a <h1> inside of it
|
68
|
+
title: (title = null) ->
|
53
69
|
if title?
|
54
|
-
@$el.find('h1').html
|
70
|
+
@$el.find('h1').html title
|
55
71
|
else
|
56
72
|
@$el.find('h1').html()
|
57
73
|
|
58
|
-
|
59
|
-
|
60
|
-
|
74
|
+
# Renders the screen's template into the container element, and applies
|
75
|
+
# the screen's events and the default screen class
|
76
|
+
render: ->
|
77
|
+
@$el.html (@template or defaultTemplate)(@model)
|
78
|
+
@$el.addClass 'screen'
|
79
|
+
@delegateEvents _.extend @events, @__events
|
61
80
|
@
|
62
81
|
|
63
|
-
# Embeds a Tres.Screen into the <body>. Returns false in case it's already
|
64
|
-
|
82
|
+
# Embeds a Tres.Screen into the <body>. Returns false in case it's already
|
83
|
+
# embedded
|
84
|
+
embed: ->
|
65
85
|
return false if @embedded
|
66
86
|
@render()
|
67
|
-
$body.
|
87
|
+
$body.prepend @el
|
68
88
|
@embedded = true
|
69
89
|
@
|
70
90
|
|
71
|
-
|
91
|
+
# Click/touch on links will trigger pushState, but stay in the app
|
92
|
+
touchLink: (event) ->
|
72
93
|
event.preventDefault()
|
73
94
|
Tres.Router.navigate $(event.currentTarget).attr('href'), true
|
74
95
|
|
75
|
-
|
96
|
+
# Runs whatever @submit method is declared, with the added bonus of
|
97
|
+
# un-focusing any text fields that are currently focused
|
98
|
+
__submit: (event) ->
|
76
99
|
@submit.apply @, arguments
|
77
100
|
@$el.find(':focus').blur()
|
78
101
|
|
79
|
-
submit
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
|
84
|
-
|
102
|
+
# Default @submit to noop
|
103
|
+
submit: ->
|
104
|
+
|
105
|
+
# Sets the class "current" to this screen, removing the class from
|
106
|
+
# whatever other sections that have it. Call the `active` method in
|
107
|
+
# case a screen has one. Removes -webkit-transform to prevent Webkit from
|
108
|
+
# screwing a whole lot of stuff
|
109
|
+
activate: ->
|
110
|
+
if not @modal
|
111
|
+
$body.find('>section')
|
112
|
+
.removeClass('current')
|
113
|
+
.css '-webkit-transform', ''
|
85
114
|
@$el.addClass 'current'
|
86
|
-
|
115
|
+
@$el.addClass 'modal' if @modal
|
116
|
+
@$el.css
|
117
|
+
'min-height': window.innerHeight+50
|
118
|
+
'-webkit-transform': 'none'
|
119
|
+
@active.apply @, arguments if _.isFunction @active
|
87
120
|
|
121
|
+
# ---
|
122
|
+
|
123
|
+
# This class is used as controller for each Tres.List item
|
88
124
|
class Tres.ListEntry extends Backbone.View
|
89
125
|
initialize : (options = {}) ->
|
90
126
|
_.extend @, options
|
91
127
|
|
92
|
-
render
|
93
|
-
@$el.html
|
94
|
-
@delegateEvents
|
128
|
+
render: ->
|
129
|
+
@$el.html @template @model
|
130
|
+
@delegateEvents 'click': 'touch' if _.isFunction @url
|
95
131
|
@
|
96
132
|
|
97
|
-
|
133
|
+
# If a @url method is defined, means we want the user to touch and
|
134
|
+
# visit the URL
|
135
|
+
touch: (event) ->
|
98
136
|
Tres.Router.navigate @url(), true
|
99
137
|
|
138
|
+
# ---
|
100
139
|
|
101
|
-
# Tres.List is a convenience class for rendering lists of things
|
140
|
+
# Tres.List is a convenience class for rendering lists of things
|
102
141
|
class Tres.List extends Backbone.View
|
142
|
+
|
143
|
+
# A map of likely child tags for each parent tag
|
103
144
|
_tagMap :
|
104
145
|
'UL' : 'LI'
|
105
146
|
'OL' : 'LI'
|
106
147
|
'DIV' : 'DIV'
|
107
148
|
|
108
|
-
|
149
|
+
# Keep the DOM in sync with all interactions made with the collection
|
150
|
+
initialize: (options = {}) ->
|
109
151
|
_.extend @, options
|
110
|
-
@setElement
|
152
|
+
@setElement @el
|
111
153
|
@collection.on 'add', @__add, @
|
112
154
|
@collection.on 'remove', @__remove, @
|
113
155
|
@collection.on 'reset', @__addAll, @
|
114
156
|
|
115
|
-
|
157
|
+
# Adds one record to the list, wrapping it in a Tres.List
|
158
|
+
__add: (model) ->
|
116
159
|
tag = @entry?.tagName or @_tagMap[@$el.get(0).tagName]
|
117
|
-
template = new Tres.ListEntry
|
160
|
+
template = new Tres.ListEntry _.extend(@entry, { tagName : tag, model : model })
|
118
161
|
model.template = template
|
119
162
|
@$el.append template.render().el
|
120
163
|
|
121
|
-
|
164
|
+
# Removes the list from the DOM
|
165
|
+
__remove: (model) ->
|
122
166
|
model.template.remove()
|
123
167
|
|
124
|
-
|
168
|
+
# Adds all the elements the @collection to the list, removing any existing
|
169
|
+
# ones
|
170
|
+
__addAll: ->
|
125
171
|
@$el.empty()
|
126
|
-
@collection.each (model) => @__add
|
172
|
+
@collection.each (model) => @__add model
|
127
173
|
|
128
|
-
|
174
|
+
# Deletes the instance of Tres.List, ensuring any bound events to
|
175
|
+
# @collection are removed
|
176
|
+
remove: ->
|
129
177
|
@collection.off() if @collection?
|
130
178
|
super
|
131
179
|
|
180
|
+
# ---
|
181
|
+
|
182
|
+
# Handles form submissions and a few other helpers such as accessing
|
183
|
+
# fieldsets individually, and loading model data into fields
|
132
184
|
class Tres.Form
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
185
|
+
|
186
|
+
# Takes a jQuery-wrapped form object
|
187
|
+
constructor: (@$el) ->
|
188
|
+
|
189
|
+
# Returns a new instance of Tres.Form, narrowed down to a single
|
190
|
+
# fieldset
|
191
|
+
fieldset: (filter) ->
|
192
|
+
new Tres.Form @$el.find('fieldset').filter(filter)
|
193
|
+
|
194
|
+
# Returns all the form data in a single object, in key/value
|
195
|
+
# pairs by `name` attribute and value
|
196
|
+
attributes: (options = {})->
|
139
197
|
attributes = {}
|
140
198
|
if options.only?
|
141
|
-
inputs = @$el.find
|
199
|
+
inputs = @$el.find "#{options.only} :input[name]"
|
142
200
|
else
|
143
|
-
inputs = @$el.find
|
201
|
+
inputs = @$el.find ':input[name]'
|
144
202
|
_.each inputs, (el) ->
|
145
|
-
$el = $
|
146
|
-
if $el.is
|
147
|
-
attributes[ $el.attr
|
203
|
+
$el = $ el
|
204
|
+
if $el.is ':checkbox'
|
205
|
+
attributes[ $el.attr 'name' ] = $el.is ':checked'
|
148
206
|
else
|
149
|
-
attributes[ $el.attr
|
207
|
+
attributes[ $el.attr 'name' ] = $el.val()
|
150
208
|
attributes
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
209
|
+
|
210
|
+
# Fills the form's fields whose `name` match the model's attributes
|
211
|
+
setFromModel: (model) ->
|
212
|
+
_.each _.keys model.attributes, (key) =>
|
213
|
+
$el = @$el.find "[name=\"#{key}\"]"
|
214
|
+
if $el.is ':checkbox' and model.attributes[key] is true
|
215
|
+
$el.attr 'checked', 'checked'
|
157
216
|
else
|
158
217
|
$el.val model.attributes[key]
|
159
|
-
|
160
|
-
clear : ->
|
161
|
-
_.each @$el.find(':input'), (el) ->
|
162
|
-
$el = $(el)
|
163
|
-
$el.removeAttr('checked') if $el.is(':checkbox')
|
164
|
-
$el.val('')
|
165
|
-
@
|
166
218
|
|
167
|
-
#
|
219
|
+
# Clears the form
|
220
|
+
clear: ->
|
221
|
+
_.each @$el.find ':input', (el) ->
|
222
|
+
$el = $ el
|
223
|
+
$el.removeAttr 'checked' if $el.is ':checkbox'
|
224
|
+
$el.val ''
|
225
|
+
|
226
|
+
# ---
|
227
|
+
|
228
|
+
# Handles displaying in-app notifications
|
168
229
|
Tres.Notifier =
|
169
|
-
$el
|
230
|
+
$el: $ make('ul', id: 'notifications')
|
170
231
|
|
171
232
|
notify : (message, options = { duration : 5000, type : 'exclamation-sign' }) ->
|
172
233
|
@$el.appendTo $body
|
173
|
-
$li = $
|
234
|
+
$li = $ make 'li', { class: "icon-#{options.type}" }, message
|
174
235
|
@$el.append $li
|
175
236
|
$li.slideDown 250, =>
|
176
237
|
_.delay =>
|
177
238
|
$li.slideUp => $li.remove()
|
178
239
|
, options.duration
|
179
240
|
|
180
|
-
#
|
241
|
+
# ---
|
242
|
+
|
243
|
+
# Just a regular Backbone.Router for now. You'll have one for application
|
181
244
|
class Router extends Backbone.Router
|
182
245
|
|
183
|
-
# Make the router it accessible
|
184
246
|
Tres.Router = new Router
|
185
247
|
|
248
|
+
# ---
|
249
|
+
|
186
250
|
class Tres.App
|
187
|
-
|
251
|
+
|
252
|
+
constructor: (options = {}) ->
|
188
253
|
_.extend @, options
|
189
254
|
|
190
|
-
screens
|
255
|
+
# All the screens that are currently instanced
|
256
|
+
screens: []
|
191
257
|
|
192
|
-
|
258
|
+
# Takes a hash to use as a mapping of URLs -> Tres.Screen objects
|
259
|
+
on: (map = {}) ->
|
193
260
|
_.each _.keys(map), (url) =>
|
194
261
|
Tres.Router.route url, _.uniqueId('r'), =>
|
195
262
|
screen = map[url]
|
196
263
|
screen.embed() unless screen.embedded is true
|
197
264
|
args = arguments
|
198
|
-
|
265
|
+
window.scroll 0, 0
|
266
|
+
_.defer => screen.activate.apply screen, args
|
199
267
|
|
200
|
-
|
268
|
+
# Boots the app, executing the routes and adding a handy `before`
|
269
|
+
# event to the router
|
270
|
+
boot: (options = {}) ->
|
201
271
|
__super = Backbone.history.loadUrl
|
202
272
|
Backbone.history.loadUrl = =>
|
203
|
-
|
273
|
+
if _.isFunction Tres.Router.before
|
274
|
+
Tres.Router.before Backbone.history.getFragment()
|
204
275
|
Tres.Router.trigger 'navigate'
|
205
|
-
window.scroll(0, 0)
|
206
276
|
__super.apply Backbone.history, arguments
|
207
|
-
Backbone.history.start
|
277
|
+
Backbone.history.start _.extend(options, pushState : true)
|
208
278
|
|
279
|
+
# ---
|
209
280
|
|
210
|
-
|
281
|
+
# Export to `window`
|
282
|
+
window.Tres = Tres
|
data/lib/tres/asset_manager.rb
CHANGED
@@ -19,10 +19,13 @@ module Tres
|
|
19
19
|
env.append_path path.to_s
|
20
20
|
end
|
21
21
|
env.append_path Tres.styles_dir
|
22
|
-
env.append_path Tres.scripts_dir
|
22
|
+
env.append_path Tres.scripts_dir
|
23
23
|
env.append_path @assets/'javascripts'
|
24
24
|
env.append_path @assets/'stylesheets'
|
25
25
|
env.append_path @assets
|
26
|
+
env.context_class.class_eval do
|
27
|
+
def asset_path path, options = {}; path end
|
28
|
+
end
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
@@ -42,4 +45,4 @@ module Tres
|
|
42
45
|
def coffeescript?
|
43
46
|
end
|
44
47
|
end
|
45
|
-
end
|
48
|
+
end
|
data/lib/tres.rb
CHANGED
@@ -3,7 +3,6 @@ $:.unshift File.dirname(__FILE__)
|
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'logger'
|
6
|
-
require 'json/pure'
|
7
6
|
require 'ext/string'
|
8
7
|
require 'ext/filemethods'
|
9
8
|
require 'tres/app'
|
@@ -21,15 +20,15 @@ module Tres
|
|
21
20
|
def quiet!
|
22
21
|
@quiet = true
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
def quiet?
|
26
25
|
!!@quiet
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
def verbose!
|
30
29
|
@quiet = false
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
def say something
|
34
33
|
STDOUT.puts(OUTPUT_FORMAT % something) unless quiet?
|
35
34
|
yield if block_given?
|
data/sass/tres/base.scss
CHANGED
@@ -1,131 +1,169 @@
|
|
1
|
-
|
1
|
+
// Tres base grid and grid related settings
|
2
|
+
// ========================================
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
@import 'mixins';
|
5
|
+
|
6
|
+
// Resets
|
7
|
+
|
8
|
+
// Quick FontAwesome fix so icons push the sentence a bit to the right
|
5
9
|
[class^="icon-"]:before { margin-right : .5rem }
|
10
|
+
input[class^="icon-"] {
|
11
|
+
position: relative;
|
12
|
+
|
13
|
+
&:before {
|
14
|
+
@include translate(0, -50%);
|
15
|
+
position: absolute;
|
16
|
+
top: 50%
|
17
|
+
}
|
18
|
+
}
|
6
19
|
|
7
|
-
* {
|
8
|
-
margin : 0;
|
9
|
-
padding : 0;
|
10
|
-
outline : 0;
|
11
|
-
border : 0;
|
12
|
-
-webkit-box-sizing : border-box
|
20
|
+
* {
|
21
|
+
margin : 0;
|
22
|
+
padding : 0;
|
23
|
+
outline : 0;
|
24
|
+
border : 0;
|
25
|
+
-webkit-box-sizing : border-box;
|
26
|
+
box-sizing: border-box;
|
13
27
|
}
|
14
28
|
|
15
|
-
ul
|
29
|
+
ul { list-style : none }
|
16
30
|
input, button, textarea { font-size : 100% }
|
17
31
|
|
18
|
-
|
19
|
-
|
32
|
+
// ---
|
33
|
+
|
34
|
+
$spacing: .5rem;
|
35
|
+
|
36
|
+
// Structural settings for getting screens to use the whole vertical space.
|
37
|
+
|
38
|
+
html {
|
39
|
+
min-height: 420px;
|
40
|
+
min-width: 100%;
|
41
|
+
font-size : 62.5%;
|
42
|
+
}
|
43
|
+
html, body { overflow: hidden; width: 100%; height: 100% }
|
20
44
|
body {
|
21
|
-
|
45
|
+
position: fixed;
|
46
|
+
top: 0;
|
47
|
+
right: 0;
|
48
|
+
bottom: 0;
|
49
|
+
left: 0;
|
22
50
|
line-height : 2.3rem;
|
23
|
-
width : 100%;
|
24
51
|
-webkit-perspective : 800;
|
25
52
|
-webkit-text-size-adjust : none;
|
26
53
|
-webkit-transform-style : preserve-3d;
|
27
|
-
-webkit-user-select : none
|
54
|
+
-webkit-user-select : none
|
28
55
|
}
|
29
56
|
|
57
|
+
// ---
|
58
|
+
|
30
59
|
// A base section unit. Think of this as a "screen".
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
60
|
+
.screen {
|
61
|
+
-webkit-transition : all 0.25s ease-out;
|
62
|
+
-webkit-transform-style : preserve-3d;
|
63
|
+
-webkit-transform : translate3d(100%,0%,0);
|
64
|
+
position : fixed;
|
35
65
|
top : 0;
|
66
|
+
right : 0;
|
67
|
+
bottom : 0;
|
36
68
|
left : 0;
|
37
|
-
width : 100%;
|
38
69
|
opacity : 0;
|
39
70
|
overflow : auto;
|
40
|
-
overflow-x : hidden;
|
41
71
|
pointer-events : none;
|
42
|
-
|
43
|
-
-webkit-transform-style : preserve-3d;
|
44
|
-
-webkit-transform : translate3d(100%,0%,0);
|
45
|
-
&>*:not(header) {
|
46
|
-
margin-left : 1rem !important;
|
47
|
-
margin-right : 1rem !important;
|
48
|
-
}
|
72
|
+
|
49
73
|
&.current {
|
50
74
|
opacity : 1;
|
51
75
|
pointer-events : auto;
|
52
76
|
-webkit-transform : translate3d(0%,0%, 0)
|
53
77
|
}
|
78
|
+
|
79
|
+
&.modal { z-index: 1000 }
|
54
80
|
}
|
55
81
|
|
56
|
-
//
|
57
|
-
|
82
|
+
// ---
|
83
|
+
|
84
|
+
// Headers
|
85
|
+
|
86
|
+
.screen > header {
|
87
|
+
position : fixed;
|
88
|
+
top : 0;
|
89
|
+
right : 0;
|
90
|
+
left : 0;
|
58
91
|
margin : 0;
|
59
92
|
text-align : center;
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
}
|
67
|
-
& + * { margin-top : 4.6rem !important }
|
93
|
+
overflow : hidden;
|
94
|
+
z-index : 100;
|
95
|
+
|
96
|
+
& + .content { top : 60px }
|
97
|
+
|
98
|
+
& > * { margin: $spacing*2 0 }
|
68
99
|
h1 {
|
69
|
-
font-size : 1.
|
70
|
-
margin :
|
100
|
+
font-size : 1.6rem;
|
101
|
+
margin : 1.1rem 0;
|
71
102
|
white-space : nowrap
|
72
103
|
}
|
73
|
-
a {
|
74
|
-
position
|
75
|
-
|
76
|
-
|
104
|
+
&>a, &>button {
|
105
|
+
position: absolute;
|
106
|
+
top : 0;
|
107
|
+
width : 2.9rem;
|
108
|
+
font-size : 2.1rem;
|
77
109
|
text-decoration : none;
|
78
|
-
|
79
|
-
|
110
|
+
|
111
|
+
|
112
|
+
&.left { left: $spacing }
|
113
|
+
&.right { right: $spacing }
|
80
114
|
}
|
115
|
+
menu {
|
116
|
+
@extend .spans-horizontally;
|
117
|
+
a, button {
|
118
|
+
font-size: 2.3rem
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
// ---
|
124
|
+
|
125
|
+
// Screen content
|
126
|
+
|
127
|
+
.screen > .content {
|
128
|
+
position: fixed;
|
129
|
+
top: 0;
|
130
|
+
right: 0;
|
131
|
+
bottom: 0;
|
132
|
+
left: 0;
|
133
|
+
overflow: auto;
|
134
|
+
-webkit-overflow-scrolling: touch;
|
81
135
|
}
|
82
136
|
|
137
|
+
// ---
|
138
|
+
|
83
139
|
// Type margins and sizes
|
84
|
-
|
140
|
+
.screen {
|
85
141
|
h1 { font-size: 2.9rem; margin-bottom : 1.6rem }
|
86
142
|
h2 { font-size: 2.6rem; margin: 1.3rem 0 }
|
87
|
-
p, input, textarea, button, li { font-size : 1.
|
88
|
-
p { margin :
|
143
|
+
p, input, textarea, button, li { font-size : 1.3rem }
|
144
|
+
p { margin : 1.1rem 0 }
|
89
145
|
}
|
90
146
|
|
147
|
+
// ---
|
148
|
+
|
149
|
+
// Default form settings
|
150
|
+
|
91
151
|
form {
|
92
152
|
margin : 1.3rem 0;
|
93
|
-
|
94
|
-
display : block;
|
95
|
-
margin : 0.25em 0;
|
96
|
-
font-weight : bold;
|
97
|
-
}
|
98
|
-
input, textarea {
|
153
|
+
input:not([type="checkbox"]), textarea {
|
99
154
|
display : block;
|
100
155
|
padding : 0.9rem;
|
101
156
|
width : 100%;
|
102
157
|
font-family : inherit;
|
103
158
|
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
159
|
+
input[type="checkbox"] {
|
160
|
+
width: 1rem;
|
161
|
+
height: 1rem
|
162
|
+
}
|
163
|
+
input[type="checkbox"] + label {
|
164
|
+
display: inline-block;
|
165
|
+
margin-left: $spacing;
|
109
166
|
}
|
110
167
|
}
|
111
168
|
|
112
|
-
//
|
113
|
-
.t-centered { text-align : center }
|
114
|
-
.t-padded-top { padding-top : 5rem }
|
115
|
-
.t-left-align { text-align : left }
|
116
|
-
h1.t-bigger { font-size : 3.9rem }
|
117
|
-
|
118
|
-
|
119
|
-
#notifications {
|
120
|
-
position : fixed;
|
121
|
-
right : 0;
|
122
|
-
bottom : 0;
|
123
|
-
left : 0;
|
124
|
-
li {
|
125
|
-
display : none;
|
126
|
-
padding : 0.6rem 1rem;
|
127
|
-
font-weight : bold;
|
128
|
-
font-size : 1.6rem;
|
129
|
-
&:before { margin-right : 1rem }
|
130
|
-
}
|
131
|
-
}
|
169
|
+
// ---
|