sinatra-assetpack 0.0.5

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.
Files changed (55) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +2 -0
  3. data/HISTORY.md +45 -0
  4. data/README.md +248 -0
  5. data/Rakefile +3 -0
  6. data/example/.gitignore +1 -0
  7. data/example/Rakefile +7 -0
  8. data/example/app.rb +28 -0
  9. data/example/app/css/test.sass +11 -0
  10. data/example/app/images/icon.png +0 -0
  11. data/example/app/js/app.js +3 -0
  12. data/example/app/js/vendor/jquery.js +2 -0
  13. data/example/app/js/vendor/jquery.plugin.js +2 -0
  14. data/example/app/js/vendor/underscore.js +2 -0
  15. data/example/views/index.erb +26 -0
  16. data/lib/sinatra/assetpack.rb +55 -0
  17. data/lib/sinatra/assetpack/buster_helpers.rb +21 -0
  18. data/lib/sinatra/assetpack/class_methods.rb +68 -0
  19. data/lib/sinatra/assetpack/compressor.rb +109 -0
  20. data/lib/sinatra/assetpack/configurator.rb +15 -0
  21. data/lib/sinatra/assetpack/css.rb +35 -0
  22. data/lib/sinatra/assetpack/hasharray.rb +70 -0
  23. data/lib/sinatra/assetpack/helpers.rb +48 -0
  24. data/lib/sinatra/assetpack/html_helpers.rb +17 -0
  25. data/lib/sinatra/assetpack/image.rb +37 -0
  26. data/lib/sinatra/assetpack/options.rb +223 -0
  27. data/lib/sinatra/assetpack/package.rb +111 -0
  28. data/lib/sinatra/assetpack/rake.rb +23 -0
  29. data/lib/sinatra/assetpack/version.rb +7 -0
  30. data/sinatra-assetpack.gemspec +23 -0
  31. data/test/app/.gitignore +1 -0
  32. data/test/app/Rakefile +7 -0
  33. data/test/app/app.rb +51 -0
  34. data/test/app/app/css/js2c.css +494 -0
  35. data/test/app/app/css/screen.sass +9 -0
  36. data/test/app/app/css/sqwishable.css +7 -0
  37. data/test/app/app/css/style.css +2 -0
  38. data/test/app/app/images/background.jpg +1 -0
  39. data/test/app/app/images/email.png +0 -0
  40. data/test/app/app/js/hello.js +1 -0
  41. data/test/app/app/js/hi.coffee +2 -0
  42. data/test/app/app/views/index.haml +1 -0
  43. data/test/build_test.rb +20 -0
  44. data/test/cache_test.rb +10 -0
  45. data/test/helpers_test.rb +23 -0
  46. data/test/img_test.rb +13 -0
  47. data/test/options_test.rb +17 -0
  48. data/test/order_test.rb +21 -0
  49. data/test/preproc_test.rb +23 -0
  50. data/test/simplecss_test.rb +16 -0
  51. data/test/sqwish_test.rb +29 -0
  52. data/test/test_helper.rb +38 -0
  53. data/test/unit_test.rb +96 -0
  54. data/test/yui_test.rb +22 -0
  55. metadata +200 -0
@@ -0,0 +1,111 @@
1
+ module Sinatra
2
+ module AssetPack
3
+ # A package.
4
+ #
5
+ # == Common usage
6
+ #
7
+ # package = assets.packages['application.css']
8
+ #
9
+ # package.files # List of local files
10
+ # package.paths # List of URI paths
11
+ #
12
+ # package.type # :css or :js
13
+ # package.css?
14
+ # package.js?
15
+ #
16
+ # package.path # '/css/application.css' => where to serve the compressed file
17
+ #
18
+ # package.to_development_html
19
+ # package.to_production_html
20
+ #
21
+ class Package
22
+ include HtmlHelpers
23
+ include BusterHelpers
24
+
25
+ def initialize(assets, name, type, path, filespecs)
26
+ @assets = assets # Options instance
27
+ @name = name # "application"
28
+ @type = type # :js or :css
29
+ @path = path # '/js/app.js' -- where to served the compressed file
30
+ @filespecs = filespecs # [ '/js/*.js' ]
31
+ end
32
+
33
+ attr_reader :type
34
+ attr_reader :path
35
+ attr_reader :filespecs
36
+ attr_reader :name
37
+
38
+ # Returns a list of URIs
39
+ def paths_and_files
40
+ @assets.glob *@filespecs
41
+ end
42
+
43
+ def files
44
+ paths_and_files.values
45
+ end
46
+
47
+ def paths
48
+ paths_and_files.keys
49
+ end
50
+
51
+ def mtime
52
+ files.map { |f| File.mtime(f).to_i }.max
53
+ end
54
+
55
+ # Returns the regex for the route, including cache buster crap.
56
+ def route_regex
57
+ re = @path.gsub(/(.[^.]+)$/) { |ext| "(?:\.[0-9]+)?#{ext}" }
58
+ /#{re}/
59
+ end
60
+
61
+ def to_development_html(options={})
62
+ paths_and_files.map { |path, file|
63
+ path = add_cache_buster(path, file) # app.css => app.829378.css
64
+ link_tag(path, options)
65
+ }.join("\n")
66
+ end
67
+
68
+ # The URI path of the minified file (with cache buster)
69
+ def production_path
70
+ add_cache_buster @path, *files
71
+ end
72
+
73
+ def to_production_html(options={})
74
+ link_tag production_path, options
75
+ end
76
+
77
+ def minify
78
+ engine = @assets.send(:"#{@type}_compression")
79
+ options = @assets.send(:"#{@type}_compression_options")
80
+
81
+ Compressor.compress combined, @type, engine, options
82
+ end
83
+
84
+ # The cache hash.
85
+ def hash
86
+ if @assets.app.development?
87
+ "#{name}.#{type}/#{mtime}"
88
+ else
89
+ "#{name}.#{type}"
90
+ end
91
+ end
92
+
93
+ def combined
94
+ session = Rack::Test::Session.new(@assets.app)
95
+ paths.map { |path| session.get(path).body }.join("\n")
96
+ end
97
+
98
+ def js?() @type == :js; end
99
+ def css?() @type == :css; end
100
+
101
+ private
102
+ def link_tag(file, options={})
103
+ if js?
104
+ "<script type='text/javascript' src='#{e file}'#{kv options}></script>"
105
+ elsif css?
106
+ "<link rel='stylesheet' type='text/css' href='#{e file}'#{kv options} />"
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,23 @@
1
+ unless defined?(APP_FILE) && defined?(APP_CLASS)
2
+ $stderr.write "Error: Please set APP_FILE and APP_CLASS before setting up AssetPack rake tasks.\n"
3
+ $stderr.write "Example:\n"
4
+ $stderr.write " APP_FILE = 'init.rb'\n"
5
+ $stderr.write " APP_CLASS = 'Application'\n"
6
+ $stderr.write " require 'sinatra/assetpack/rake'\n"
7
+ $stderr.write "\n"
8
+ exit
9
+ end
10
+
11
+ def app
12
+ require File.expand_path(APP_FILE, Dir.pwd)
13
+ Object.const_get(APP_CLASS.to_sym)
14
+ end
15
+
16
+ namespace :assetpack do
17
+ desc "Build assets"
18
+ task :build do
19
+ app.assets.build! { |file|
20
+ puts "+ #{file.gsub(Dir.pwd, '')}"
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Sinatra
2
+ module AssetPack
3
+ def self.version
4
+ "0.0.5"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require './lib/sinatra/assetpack/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "sinatra-assetpack"
5
+ s.version = Sinatra::AssetPack.version
6
+ s.summary = %{Asset packager for Sinatra.}
7
+ s.description = %Q{Package your assets for Sinatra.}
8
+ s.authors = ["Rico Sta. Cruz"]
9
+ s.email = ["rico@sinefunc.com"]
10
+ s.homepage = "http://github.com/rstacruz/sinatra-assetpack"
11
+ s.files = `git ls-files`.strip.split("\n")
12
+ s.executables = Dir["bin/*"].map { |f| File.basename(f) }
13
+
14
+ s.add_dependency "sinatra"
15
+ s.add_dependency "jsmin"
16
+ s.add_dependency "rack-test"
17
+ s.add_development_dependency "yui-compressor"
18
+ s.add_development_dependency "sass"
19
+ s.add_development_dependency "haml"
20
+ s.add_development_dependency "coffee-script"
21
+ s.add_development_dependency "contest"
22
+ s.add_development_dependency "mocha"
23
+ end
@@ -0,0 +1 @@
1
+ public
@@ -0,0 +1,7 @@
1
+ $:.unshift File.expand_path('../../../lib', __FILE__)
2
+
3
+ APP_FILE = 'app.rb'
4
+ APP_CLASS = 'Main'
5
+
6
+ require 'sinatra/assetpack/rake'
7
+
@@ -0,0 +1,51 @@
1
+ $:.unshift File.expand_path('../../../lib', __FILE__)
2
+
3
+ require 'sinatra/base'
4
+ require 'sinatra/assetpack'
5
+ require 'coffee-script'
6
+
7
+ class Main < Sinatra::Base
8
+ set :root, File.dirname(__FILE__)
9
+ set :views, "#{root}/app/views"
10
+
11
+ register Sinatra::AssetPack
12
+
13
+ enable :raise_errors
14
+ disable :show_exceptions
15
+
16
+ assets {
17
+ #serve '/js', :from => 'app/js'
18
+ serve '/css', :from => 'app/css'
19
+ serve '/images', :from => 'app/images'
20
+
21
+ js :app, '/js/app.js', [
22
+ '/js/vendor/**/*.js',
23
+ '/js/assets/**/*.js',
24
+ '/js/hi.js',
25
+ '/js/hell*.js'
26
+ ]
27
+
28
+ css :application, '/css/application.css', [
29
+ '/css/screen.css'
30
+ ]
31
+
32
+ css :js2, '/css/js2.css', [
33
+ '/css/js2c.css'
34
+ ]
35
+
36
+ css :sq, '/css/sq.css', [
37
+ '/css/sqwishable.css'
38
+ ]
39
+ }
40
+
41
+ get '/index.html' do
42
+ haml :index
43
+ end
44
+
45
+ get '/helpers/css' do
46
+ haml %{
47
+ != css :application, :media => 'screen'
48
+ }.strip
49
+ end
50
+ end
51
+
@@ -0,0 +1,494 @@
1
+ html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
2
+ margin: 0;
3
+ padding: 0;
4
+ border: 0;
5
+ font-size: 100%;
6
+ font: inherit;
7
+ vertical-align: baseline;
8
+ }
9
+
10
+ body {
11
+ line-height: 1;
12
+ }
13
+
14
+ ol,ul {
15
+ list-style: none;
16
+ }
17
+
18
+ table {
19
+ border-collapse: collapse;
20
+ border-spacing: 0;
21
+ }
22
+
23
+ caption,th,td {
24
+ text-align: left;
25
+ font-weight: normal;
26
+ vertical-align: middle;
27
+ }
28
+
29
+ q,blockquote {
30
+ quotes: none;
31
+ }
32
+
33
+ q:before,q:after,blockquote:before,blockquote:after {
34
+ content: "";
35
+ content: none;
36
+ }
37
+
38
+ a img {
39
+ border: none;
40
+ }
41
+
42
+ article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary {
43
+ display: block;
44
+ }
45
+
46
+ div,dl,dt,dd,ul,ol,li,form,fieldset,input,blockquote,th,td,legend {
47
+ margin: 0;
48
+ padding: 0;
49
+ }
50
+
51
+ pre,p,blockquote,h1,h2,h3,h4,h5,h6 {
52
+ margin: 1em 0 1em 0;
53
+ }
54
+
55
+ h1 {
56
+ font-size: 1.4em;
57
+ }
58
+
59
+ h2 {
60
+ font-size: 1.3em;
61
+ }
62
+
63
+ h3 {
64
+ font-size: 1.2em;
65
+ }
66
+
67
+ h4 {
68
+ font-size: 1.1em;
69
+ }
70
+
71
+ h5 {
72
+ font-size: 0.9em;
73
+ }
74
+
75
+ h6 {
76
+ font-size: 0.9em;
77
+ }
78
+
79
+ ol,ul {
80
+ margin-left: 2em;
81
+ }
82
+
83
+ blockquote {
84
+ border-left: solid 2px #ccc;
85
+ padding: 0 1em;
86
+ margin-left: 0.2em;
87
+ color: #888;
88
+ }
89
+
90
+ html,body {
91
+ margin: 0;
92
+ padding: 0;
93
+ }
94
+
95
+ button,body,td,input,textarea {
96
+ font-family: arial, helvetica, sans-serif;
97
+ font-size: 1em;
98
+ }
99
+
100
+ body {
101
+ font-size: 0.75em;
102
+ line-height: 1.5;
103
+ background: #fff;
104
+ color: #333;
105
+ }
106
+
107
+ #all {
108
+ margin: 0 auto;
109
+ width: auto;
110
+ position: relative;
111
+ }
112
+
113
+ h1,h2,h3,h4,h5,h6 {
114
+ font-family: arial, helvetica, sans-serif;
115
+ }
116
+
117
+ input,textarea {
118
+ line-height: 1.4;
119
+ }
120
+
121
+ textarea {
122
+ resize: vertical;
123
+ }
124
+
125
+ a {
126
+ color: #379;
127
+ text-decoration: none;
128
+ }
129
+
130
+ a:visited {
131
+ color: #3882a8;
132
+ }
133
+
134
+ a:hover {
135
+ color: #2d6b89;
136
+ text-decoration: underline;
137
+ }
138
+
139
+ a img {
140
+ border: 0;
141
+ }
142
+
143
+ button {
144
+ cursor: pointer;
145
+ }
146
+
147
+ article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary {
148
+ display: block;
149
+ }
150
+
151
+ .ace_scroller::-webkit-scrollbar,.ace_sb::-webkit-scrollbar {
152
+ height: 15px;
153
+ width: 15px;
154
+ }
155
+
156
+ .ace_scroller::-webkit-scrollbar-thumb,.ace_sb::-webkit-scrollbar-thumb {
157
+ border-width: 7px 7px 7px 7px;
158
+ -webkit-border-image: url(/images/scroll-dark.png) 7 7 7 7 round round;
159
+ }
160
+
161
+ html,body {
162
+ min-height: 100%;
163
+ }
164
+
165
+ a:hover {
166
+ text-decoration: none;
167
+ }
168
+
169
+ .hide {
170
+ display: none;
171
+ }
172
+
173
+ body {
174
+ background: #4d362d url(/images/bg-brown.jpg);
175
+ font-size: 11pt;
176
+ line-height: 1.6;
177
+ }
178
+
179
+ body,h1,h2,h3,h4,h5,h6,td {
180
+ font-family: palatino,serif;
181
+ }
182
+
183
+ #tabs {
184
+ overflow: hidden;
185
+ margin-top: 20px;
186
+ margin-left: 40px;
187
+ }
188
+
189
+ #tabs ul {
190
+ zoom: 1;
191
+ }
192
+
193
+ #tabs ul,#tabs ul li {
194
+ margin: 0;
195
+ padding: 0;
196
+ list-style-type: none;
197
+ display: block;
198
+ }
199
+
200
+ #tabs ul li {
201
+ background-image: none;
202
+ }
203
+
204
+ #tabs ul:after {
205
+ content: '';
206
+ clear: both;
207
+ display: block;
208
+ line-height: 0;
209
+ height: 0;
210
+ visibility: hidden;
211
+ zoom: 1;
212
+ }
213
+
214
+ #tabs ul li {
215
+ float: left;
216
+ }
217
+
218
+ #tabs a {
219
+ margin: 0 2px;
220
+ display: inline-block;
221
+ background: rgba(230,228,224,0.5);
222
+ -moz-border-radius-topleft: 4px;
223
+ -webkit-border-top-left-radius: 4px;
224
+ -o-border-top-left-radius: 4px;
225
+ -ms-border-top-left-radius: 4px;
226
+ -khtml-border-top-left-radius: 4px;
227
+ border-top-left-radius: 4px;
228
+ -moz-border-radius-topright: 4px;
229
+ -webkit-border-top-right-radius: 4px;
230
+ -o-border-top-right-radius: 4px;
231
+ -ms-border-top-right-radius: 4px;
232
+ -khtml-border-top-right-radius: 4px;
233
+ border-top-right-radius: 4px;
234
+ padding: 5px 25px;
235
+ color: rgba(238,238,238,0.7);
236
+ text-shadow: 1px 1px 0 rgba(0,0,0,0.3);
237
+ font-family: lato;
238
+ font-weight: 800;
239
+ font-size: 8pt;
240
+ }
241
+
242
+ #tabs a:hover {
243
+ background: rgba(230,228,224,0.7);
244
+ color: rgba(238,238,238,0.9);
245
+ }
246
+
247
+ #tabs a.active {
248
+ opacity: 1;
249
+ color: #333;
250
+ text-shadow: 0 0 1px rgba(255,255,255,0.6);
251
+ }
252
+
253
+ #tabs a.active.js2coffee {
254
+ background: #e6e4e0;
255
+ }
256
+
257
+ #tabs a.active.coffee2js {
258
+ background: #d3e9ed;
259
+ }
260
+
261
+ #editors {
262
+ overflow: hidden;
263
+ height: 640px;
264
+ }
265
+
266
+ #editors form {
267
+ position: relative;
268
+ height: 640px;
269
+ margin: 0 30px 10px 30px;
270
+ -moz-box-shadow: 1px 1px 0 rgba(0,0,0,0.1),0 2px 8px rgba(0,0,0,0.2);
271
+ -webkit-box-shadow: 1px 1px 0 rgba(0,0,0,0.1),0 2px 8px rgba(0,0,0,0.2);
272
+ -o-box-shadow: 1px 1px 0 rgba(0,0,0,0.1),0 2px 8px rgba(0,0,0,0.2);
273
+ box-shadow: 1px 1px 0 rgba(0,0,0,0.1),0 2px 8px rgba(0,0,0,0.2);
274
+ -moz-border-radius: 2px;
275
+ -webkit-border-radius: 2px;
276
+ -o-border-radius: 2px;
277
+ -ms-border-radius: 2px;
278
+ -khtml-border-radius: 2px;
279
+ border-radius: 2px;
280
+ }
281
+
282
+ #editors form#js2coffee {
283
+ background: #e6e4e0;
284
+ background-color: #e6e4e0;
285
+ background-image: -moz-linear-gradient(top, #e6e4e0, #faf9f8);
286
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #e6e4e0), color-stop(1, #faf9f8));
287
+ background-color: #e6e4e0;
288
+ background-image: -moz-linear-gradient(top, #e6e4e0, #e9e7e3);
289
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #e6e4e0), color-stop(1, #e9e7e3));
290
+ border-bottom: solid 2px #cfcdc9;
291
+ }
292
+
293
+ #editors form#coffee2js {
294
+ background: #d3e9ed;
295
+ background-color: #d3e9ed;
296
+ background-image: -moz-linear-gradient(top, #d3e9ed, #f6fafb);
297
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #d3e9ed), color-stop(1, #f6fafb));
298
+ background-color: #d3e9ed;
299
+ background-image: -moz-linear-gradient(top, #d3e9ed, #e9e7e3);
300
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #d3e9ed), color-stop(1, #e9e7e3));
301
+ border-bottom: solid 2px #bdd1d5;
302
+ }
303
+
304
+ #editors .editor,#editors .output {
305
+ opacity: 0.9;
306
+ position: absolute;
307
+ left: 10px;
308
+ top: 0;
309
+ right: 50%;
310
+ bottom: 0;
311
+ border: solid 15px #fff;
312
+ border-right-width: 5px;
313
+ background-color: #fff;
314
+ }
315
+
316
+ #editors .editor {
317
+ -moz-box-shadow: 3px 0 2px rgba(0,0,0,0.2),1px 0 0 rgba(0,0,0,0.2);
318
+ -webkit-box-shadow: 3px 0 2px rgba(0,0,0,0.2),1px 0 0 rgba(0,0,0,0.2);
319
+ -o-box-shadow: 3px 0 2px rgba(0,0,0,0.2),1px 0 0 rgba(0,0,0,0.2);
320
+ box-shadow: 3px 0 2px rgba(0,0,0,0.2),1px 0 0 rgba(0,0,0,0.2);
321
+ }
322
+
323
+ #editors .output {
324
+ -moz-box-shadow: 0 0 2px rgba(0,0,0,0.2);
325
+ -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2);
326
+ -o-box-shadow: 0 0 2px rgba(0,0,0,0.2);
327
+ box-shadow: 0 0 2px rgba(0,0,0,0.2);
328
+ opacity: 0.8;
329
+ right: 10px;
330
+ left: 50%;
331
+ }
332
+
333
+ #editors .error {
334
+ -moz-box-sizing: border-box;
335
+ -webkit-box-sizing: border-box;
336
+ -ms-box-sizing: border-box;
337
+ box-sizing: border-box;
338
+ position: absolute;
339
+ top: 20px;
340
+ left: 50%;
341
+ max-width: 40%;
342
+ padding: 5px 10px;
343
+ background: rgba(153,51,51,0.9);
344
+ color: #eee;
345
+ text-shadow: 1px 1px 0 rgba(0,0,0,0.3);
346
+ z-index: 100;
347
+ }
348
+
349
+ p.more-info {
350
+ margin: 0 0 20px 0;
351
+ padding: 0;
352
+ text-align: center;
353
+ }
354
+
355
+ p.more-info a {
356
+ display: inline-block;
357
+ background: rgba(0,0,0,0.5);
358
+ -moz-border-radius-bottomleft: 4px;
359
+ -webkit-border-bottom-left-radius: 4px;
360
+ -o-border-bottom-left-radius: 4px;
361
+ -ms-border-bottom-left-radius: 4px;
362
+ -khtml-border-bottom-left-radius: 4px;
363
+ border-bottom-left-radius: 4px;
364
+ -moz-border-radius-bottomright: 4px;
365
+ -webkit-border-bottom-right-radius: 4px;
366
+ -o-border-bottom-right-radius: 4px;
367
+ -ms-border-bottom-right-radius: 4px;
368
+ -khtml-border-bottom-right-radius: 4px;
369
+ border-bottom-right-radius: 4px;
370
+ font-family: lato,sans-serif;
371
+ text-transform: uppercase;
372
+ letter-spacing: 3px;
373
+ font-size: 7pt;
374
+ font-weight: normal;
375
+ color: #aaa;
376
+ text-shadow: 1px 1px 0 rgba(0,0,0,0.3);
377
+ padding: 5px 30px;
378
+ }
379
+
380
+ p.more-info a:hover {
381
+ background: rgba(215,125,45,0.7);
382
+ color: #fff;
383
+ }
384
+
385
+ #info {
386
+ background: #4d362d url(/images/bg-brown.jpg);
387
+ margin: 0 0 0 0;
388
+ overflow: hidden;
389
+ position: relative;
390
+ color: #eee;
391
+ text-shadow: 1px 1px 0 rgba(0,0,0,0.15);
392
+ }
393
+
394
+ #info a,#info a:visited {
395
+ color: #f7e5d5;
396
+ border-bottom: dotted 1px rgba(247,229,213,0.4);
397
+ }
398
+
399
+ #info a:hover,#info a:visited:hover {
400
+ background: rgba(0,0,0,0.2);
401
+ -moz-border-radius: 2px;
402
+ -webkit-border-radius: 2px;
403
+ -o-border-radius: 2px;
404
+ -ms-border-radius: 2px;
405
+ -khtml-border-radius: 2px;
406
+ border-radius: 2px;
407
+ }
408
+
409
+ #info h2 {
410
+ height: 66px;
411
+ text-indent: -9999px;
412
+ background: url(/images/h1.png) center 0 no-repeat;
413
+ margin: 50px 0;
414
+ padding: 0;
415
+ }
416
+
417
+ #info .logo {
418
+ margin: 90px 0 0 0;
419
+ height: 70px;
420
+ background: #eceae6;
421
+ border-top: solid 2px #253a3a;
422
+ border-bottom: solid 2px #253a3a;
423
+ text-align: center;
424
+ }
425
+
426
+ #info .logo img {
427
+ position: relative;
428
+ top: -63px;
429
+ }
430
+
431
+ #info article {
432
+ background: url(/images/bg-blue.jpg);
433
+ padding: 20px;
434
+ padding-top: 80px;
435
+ }
436
+
437
+ #info article > .c {
438
+ width: 400px;
439
+ padding-left: 200px;
440
+ margin: 0 auto;
441
+ }
442
+
443
+ #info h3 {
444
+ margin: 0;
445
+ padding: 0;
446
+ margin-left: -200px;
447
+ margin-top: 28px;
448
+ width: 170px;
449
+ float: left;
450
+ color: #d77d2d;
451
+ text-transform: uppercase;
452
+ font-family: lato;
453
+ text-align: right;
454
+ letter-spacing: 1px;
455
+ font-size: 9pt;
456
+ }
457
+
458
+ #info h3:first-child {
459
+ margin-top: 0;
460
+ }
461
+
462
+ #info h3 + p {
463
+ margin-top: 40px;
464
+ }
465
+
466
+ #info h4 {
467
+ color: #999;
468
+ border-top: solid 1px #ddd;
469
+ padding-top: 20px;
470
+ margin-top: 20px;
471
+ font-size: 1em;
472
+ }
473
+
474
+ #info code {
475
+ background: rgba(250,250,250,0.2);
476
+ border: solid 1px rgba(221,221,221,0.2);
477
+ ptopadding: 1px 4px;
478
+ }
479
+
480
+ a.github {
481
+ background-image: url(https://a248.e.akamai.net/assets.github.com/img/e6bef7a091f5f3138b8cd40bc3e114258dd68ddf/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67);
482
+ background-position: 0 0;
483
+ background-repeat: no-repeat;
484
+ display: block;
485
+ width: 150px;
486
+ height: 150px;
487
+ overflow: hidden;
488
+ position: absolute;
489
+ text-indent: -9999px;
490
+ right: 0;
491
+ top: -20px;
492
+ }
493
+
494
+