tres 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
// ---
|