c2 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Cracker Snack Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # C2 - Command & Control
2
+
3
+ ## Note on Patches/Pull Requests
4
+
5
+ * Fork the project.
6
+ * Make your feature addition or bug fix.
7
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
8
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
9
+ * Send me a pull request. Bonus points for topic branches.
10
+
11
+ ## Copyright
12
+
13
+ Copyright (c) 2009 hexorx. See LICENSE for details.
@@ -0,0 +1,6 @@
1
+ class C2::BaseController < ApplicationController
2
+ unloadable
3
+ layout 'c2'
4
+
5
+ before_filter :authorize_c2_agent
6
+ end
@@ -0,0 +1,4 @@
1
+ class C2::Informant::AppController < C2::BaseController
2
+ def show
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ class C2::Informant::BucketsController < C2::BaseController
2
+ respond_to(:json)
3
+
4
+ def index
5
+ respond_with(@locus = C2::Informant::Locus.find(params[:locus_id]).buckets)
6
+ end
7
+
8
+ def update
9
+ respond_with(@locus = C2::Information::Locus.find(params[:locus_id]).buckets)
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ class C2::Informant::EntriesController < C2::BaseController
2
+ respond_to(:json)
3
+ before_filter :load_source
4
+
5
+ def index
6
+ @entries = @source.entries.offset(0).limit(12)
7
+ render :json => @source.entries_as_json(@entries)
8
+ end
9
+
10
+ def show
11
+ @entry = @source.entries.find(params[:id])
12
+ render :json => @source.entry_as_json(@entry)
13
+ end
14
+
15
+ def create
16
+ @entry = @source.klass.new(@source.sanitized(params))
17
+ @entry.save
18
+ render :json => @source.entry_as_json(@entry)
19
+ end
20
+
21
+ def update
22
+ @entry = @source.entries.find(params[:id])
23
+ @entry.update_attributes(@source.sanitized(params))
24
+ render :json => @source.entry_as_json(@entry)
25
+ end
26
+
27
+ protected
28
+
29
+ def load_source
30
+ @locus = C2::Informant::Locus.find(params[:locus_id])
31
+ @bucket = @locus.buckets.find(params[:bucket_id]) if params[:bucket_id]
32
+ @source = (@bucket || @locus)
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ class C2::Informant::LocusController < C2::BaseController
2
+ respond_to(:json)
3
+
4
+ def index
5
+ respond_with(@locus = C2::Informant::Locus.all.order(:class_name => :asc))
6
+ end
7
+
8
+ def update
9
+ respond_with(@locus = C2::Information::Locus.find(params[:id]))
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ class C2::Informant::Bucket
2
+ include Mongoid::Document
3
+
4
+ field :label
5
+ field :description
6
+
7
+ field :method_name
8
+
9
+ embedded_in :locus, :class_name => 'C2::Informant::Locus'
10
+
11
+ delegate :count, :to => :entries
12
+ delegate :elements, :entry_label, :sanitized, :to => :locus
13
+
14
+ validate :method_name, :presences => true, :unique => true
15
+
16
+ def label
17
+ self[:label] || self.method_name.titleize
18
+ end
19
+
20
+ def entries
21
+ return _parent.klass.all unless method_name && _parent.klass.respond_to?(method_name)
22
+ _parent.klass.try(method_name)
23
+ end
24
+
25
+ def entries_page(page=1,per=10)
26
+ entries.offset((page - 1) * per).limit(per).map do |entry|
27
+ data = elements.enabled.inject({}) do |memo, element|
28
+ memo[element.name] = entry.send(element.name) if entry.respond_to?(element.name)
29
+ memo
30
+ end
31
+ data['_id'] = entry['_id']
32
+ data['created_at'] = entry['created_at']
33
+ data['updated_at'] = entry['updated_at']
34
+ data[entry_label] = entry[entry_label]
35
+ data
36
+ end
37
+ end
38
+
39
+ def as_json(options={})
40
+ cleaned = super((options || {}).merge({
41
+ :methods => [:label, :count, :entries_page]
42
+ })).map {|k,v| [k.to_s, (v.is_a?(Numeric) ? v.to_s : v)]}
43
+ Hash[cleaned]
44
+ end
45
+ end
@@ -0,0 +1,43 @@
1
+ class C2::Informant::FormElement
2
+ include Mongoid::Document
3
+
4
+ field :tag
5
+ field :name
6
+ field :caption
7
+ field :tip
8
+
9
+ field :enabled, :type => Boolean, :default => true
10
+
11
+ embedded_in :locus, :class_name => 'C2::Informant::Locus'
12
+
13
+ scope :enabled, :where => { :enabled => true }
14
+
15
+ delegate :klass, :to => :'_parent'
16
+
17
+ def as_json(options={})
18
+ {
19
+ 'type' => 'div',
20
+ 'id' => "entry_#{name}_field",
21
+ 'class' => "field #{name}_field #{tag}",
22
+ 'elements' => [
23
+ {
24
+ 'type' => tag,
25
+ 'name' => name,
26
+ 'id' => "entry_#{name}",
27
+ 'class' => "#{name}_input #{tag}",
28
+ 'caption' => (caption || name.titleize)
29
+ },
30
+ {
31
+ 'type' => 'div',
32
+ 'class' => 'tip',
33
+ 'elements' => [
34
+ {
35
+ 'type' => 'p',
36
+ 'html' => tip
37
+ }
38
+ ]
39
+ }
40
+ ]
41
+ }
42
+ end
43
+ end
@@ -0,0 +1,105 @@
1
+ class C2::Informant::Locus
2
+ include Mongoid::Document
3
+
4
+ field :label
5
+ field :description
6
+
7
+ field :class_name
8
+
9
+ field :entry_label
10
+
11
+ embeds_many :buckets, :class_name => 'C2::Informant::Bucket'
12
+ embeds_many :elements, :class_name => 'C2::Informant::FormElement'
13
+
14
+ delegate :count, :to => :klass
15
+
16
+ validate :class_name, :presences => true, :unique => true
17
+
18
+ def label
19
+ return self[:label] || '' unless self.class_name
20
+ self[:label] ||= self.class_name.pluralize.titleize
21
+ end
22
+
23
+ def singular_label
24
+ label.to_s.singularize
25
+ end
26
+
27
+ def entry_label
28
+ return self[:entry_label] || '' unless self.class_name
29
+ self[:entry_label] ||= ([:c2_label, :entry_label, :to_label, :label, :title, :name, :email, :subject].map(&:to_s) & klass.instance_methods).first
30
+ end
31
+
32
+ def klass
33
+ @klass ||= self.class_name.classify.constantize
34
+ end
35
+
36
+ def entries
37
+ klass.all
38
+ end
39
+
40
+ def entries_page(page=1,per=10)
41
+ entries_as_json(entries.offset((page - 1) * per).limit(per))
42
+ end
43
+
44
+ def entry_as_json(entry)
45
+ data = self.elements.inject({}) do |memo, element|
46
+ memo[element.name] = entry.send(element.name) if entry.respond_to?(element.name)
47
+ memo
48
+ end
49
+ data['_id'] = entry['_id']
50
+ data[entry_label] = entry[entry_label]
51
+ data['created_at'] = entry['created_at']
52
+ data['updated_at'] = entry['updated_at']
53
+ data['errors'] = entry.errors
54
+ data
55
+ end
56
+
57
+ def entries_as_json(entries)
58
+ entries.map { |entry| self.entry_as_json(entry) }
59
+ end
60
+
61
+ def sanitized(params)
62
+ self.elements.enabled.map(&:name).inject({}) do |memo, field|
63
+ memo[field] = params[field]
64
+ memo
65
+ end
66
+ end
67
+
68
+ def hash_path
69
+ '#/locus/' + self.id.to_s
70
+ end
71
+
72
+ def entry_form_builder
73
+ {
74
+ 'action' => '#',
75
+ 'elements' => [
76
+ {
77
+ 'type' => 'div',
78
+ 'id' => 'entry-fields',
79
+ 'class' => 'fields',
80
+ 'elements' => elements.enabled.as_json(:except => ['_id', 'tag'])
81
+ },
82
+ {
83
+ 'type' => 'div',
84
+ 'class' => 'actions',
85
+ 'elements' => [
86
+ {'type' => 'submit', 'class' => 'button', 'value' => 'Save'},
87
+ {
88
+ 'type' => 'a',
89
+ 'class' => 'cancel flip-trigger',
90
+ 'href' => "#",
91
+ 'html' => 'Cancel'
92
+ }
93
+ ]
94
+ }
95
+ ]
96
+ }
97
+ end
98
+
99
+ def as_json(options={})
100
+ cleaned = super((options || {}).merge({
101
+ :methods => [:count, :buckets, :label, :singular_label, :entry_label, :entries_page, :entry_form_builder]
102
+ })).map {|k,v| [k.to_s, (v.is_a?(Numeric) ? v.to_s : v)]}
103
+ Hash[cleaned]
104
+ end
105
+ end
@@ -0,0 +1,681 @@
1
+ @import "compass/utilities";
2
+ @import "compass/css3";
3
+
4
+ /* Fonts */
5
+ @font-face {
6
+ font-family: 'Pictos';
7
+ src: url('/fonts/c2/pictos-web.eot');
8
+ src: local('☺'), url('/fonts/c2/pictos-web.woff') format('woff'),
9
+ url('/fonts/c2/pictos-web.ttf') format('truetype'),
10
+ url('/fonts/c2/pictos-web.svg#webfontIyfZbseF') format('svg');
11
+ font-weight: normal;
12
+ font-style: normal;
13
+ }
14
+
15
+ /* Text Styles */
16
+ h1, h2, h3, h4 {
17
+ @include text-shadow(rgba(255, 255, 255, 0.5));
18
+ color: #777;
19
+ }
20
+
21
+ h3 {
22
+ font-size: 13px;
23
+ line-height: 18px;
24
+ }
25
+
26
+ p { margin: 0px 0px 1.5em }
27
+
28
+ ul { list-style: none; margin: 0; padding: 0 }
29
+ a { text-decoration: none; outline: 0; }
30
+ a, .dropdown-trigger, .tool, .count {
31
+ @include transition(all, .3s, ease);
32
+ }
33
+
34
+ a.external-link::after {
35
+ content: "(open in new window)";
36
+ display: inline-block;
37
+ text-indent: -99999px;
38
+ height: 16px; width: 16px;
39
+ background: url(/images/c2/external-link.png) no-repeat center center;
40
+ margin-left: 2px;
41
+ opacity: .6;
42
+ }
43
+
44
+ dl { display: block; }
45
+
46
+ .meta {
47
+ color: #777;
48
+ font-size: 11px;
49
+ margin: 0; padding: 0;
50
+ dt, dd {
51
+ display: inline;
52
+ margin: 0;
53
+ }
54
+ }
55
+
56
+ abbr[title], dfn[title] {
57
+ border-bottom: 1px dotted;
58
+ cursor: help;
59
+ }
60
+
61
+ input[type="checkbox"], input.checkbox,
62
+ input[type="radio"], input.radio {
63
+ position: relative;
64
+ top: 0.25em;
65
+ }
66
+
67
+ input[type="checkbox"] { vertical-align: bottom }
68
+
69
+ /* Defaults */
70
+ html {
71
+ background: #101010 url(/images/c2/bg-header.png) repeat-x;
72
+ height: 100%;
73
+ }
74
+
75
+ body {
76
+ @include box-sizing(border-box);
77
+ height: 100%;
78
+ margin: 0; padding: 76px 0 0 0;
79
+ min-width: 960px;
80
+ color: #555;
81
+ font-size: 12px;
82
+ font-family: 'Helvetica Neue', sans-serif;
83
+ line-height: 1.5;
84
+ z-index: 0;
85
+ }
86
+
87
+ /* Details */
88
+ #templates { display: none; }
89
+
90
+ #wrapper {
91
+ display: table;
92
+ background: url(/images/c2/bg-body.png);
93
+ height: 100%; width: 100%;
94
+ z-index: 0;
95
+
96
+ #header-wrapper {
97
+ position: absolute;
98
+ top: 0; left: 0;
99
+ height: 76px; min-width: 960px; width: 100%;
100
+ border-bottom: 1px solid rgba(255, 255, 255, 0.5);
101
+ #header {
102
+ padding: 14px 0 0 20px;
103
+ a {
104
+ text-shadow: rgba(0, 0, 0, 0.4), 1px 1px 2px;
105
+ cursor: pointer;
106
+ color: white; opacity: .5;
107
+ font-weight: bold;
108
+ }
109
+ h1, h2 {
110
+ white-space: nowrap;
111
+ margin: 0; padding: 0 8px 0 0;
112
+ line-height: 1;
113
+ display: inline;
114
+ }
115
+ h1 {
116
+ font-size: 30px;
117
+ font-weight: normal;
118
+ a { font-weight: normal; text-shadow: none; opacity: 1; }
119
+ }
120
+ h2 {
121
+ font-size: 14px;
122
+ text-transform: uppercase;
123
+ a {
124
+ color: #8EB1D0; opacity: 1;
125
+ font-weight: normal;
126
+ text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 2px;
127
+ &.preview::after {
128
+ content: "(preview)";
129
+ display: inline-block;
130
+ text-indent: -99999px;
131
+ background: url(/images/c2/eye.png) no-repeat left center;
132
+ margin-left: 5px;
133
+ height: 15px; width: 25px;
134
+ opacity: .6;
135
+ }
136
+ &.preview:hover {
137
+ color: white;
138
+ &::after {
139
+ opacity: 1;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ .url {
145
+ line-height: 1.4;
146
+ font-weight: normal;
147
+ font-size: 11px;
148
+
149
+ a { color: #999; &::after { opacity: 0 } }
150
+ }
151
+ .links {
152
+ position: absolute;
153
+ top: 0; right: 10px;
154
+ font-size: 11px;
155
+ list-style: none;
156
+ margin: 0; padding: 0;
157
+ li { float: right; vertical-align: top; }
158
+ & > li {
159
+ & > a, & > .dropdown-trigger {
160
+ cursor: pointer;
161
+ display: block;
162
+ line-height: 26px;
163
+ text-align: left;
164
+ padding-left: 10px;
165
+ text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 2px;
166
+ color: white;
167
+ opacity: .5;
168
+ }
169
+ & > a::after {
170
+ content: "|";
171
+ display: inline-block;
172
+ width: 1px;
173
+ margin-left: 10px;
174
+ color: #555;
175
+ text-shadow: none;
176
+ }
177
+ }
178
+ .dropdown-trigger::after {
179
+ content: "↓";
180
+ display: inline-block;
181
+ text-indent: -99999px;
182
+ height: 16px; width: 16px;
183
+ margin-top: -6px; margin-left: 2px;
184
+ vertical-align: middle;
185
+ background: url('/images/c2/down-arrow.png');
186
+ }
187
+ .dropdown {
188
+ @include border-bottom-radius(5px);
189
+ @include box-shadow(rgba(0, 0, 0, 0.5), 0, 3px, 5px, 0);
190
+ background: #191919;
191
+ position: absolute;
192
+ display: none;
193
+ right: 0;
194
+ min-width: 150px;
195
+ padding: 0;
196
+ opacity: 1;
197
+ z-index: 9999;
198
+ li {
199
+ display: block;
200
+ width: 100%;
201
+ clear: both;
202
+ text-align: left;
203
+ white-space: nowrap;
204
+ background-color: rgba(255, 255, 255, 0.1);
205
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
206
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
207
+ a, .link button {
208
+ @include border-radius(0);
209
+ display: block;
210
+ line-height: 1.2;
211
+ padding: 9px 20px;
212
+ }
213
+ }
214
+ li:last-child { &, a, .link button { @include border-bottom-radius(5px); } }
215
+ }
216
+
217
+ a.back {
218
+ color: white;
219
+ opacity: 1;
220
+ &:hover { color: #8EB1D0; }
221
+ &::before {
222
+ content: "<";
223
+ background: url(/images/c2/back-light.png) no-repeat center center;
224
+ display: inline-block;
225
+ text-indent: -99999px;
226
+ height: 26px; width: 16px;
227
+ margin-right: 4px;
228
+ }
229
+ }
230
+ .active > .dropdown { display: block; }
231
+ .active .dropdown-trigger, .dropdown-trigger:hover { background: rgba(255, 255, 255, 0.05); opacity: 1; }
232
+ .dropdown li { a:hover, a.hover, a:active, a.active { @include linear-gradient(color-stops(#555, #333)); } }
233
+ }
234
+ nav {
235
+ color: #777;
236
+ position: absolute;
237
+ bottom: 15px; right: 10px;
238
+ margin: 0px;
239
+ li {
240
+ display: inline-block;
241
+ vertical-align: middle;
242
+ &.current a {
243
+ @include linear-gradient(color-stops(rgba(0, 0, 0, 0.398438), rgba(0, 0, 0, 0)));
244
+ opacity: 1;
245
+ color: white;
246
+ }
247
+ }
248
+ a {
249
+ @include border-top-radius(8px);
250
+ font-size: 18px;
251
+ opacity: 0.65;
252
+ padding: 5px 15px 10px;
253
+ }
254
+ }
255
+ a { &.active, &.current, &:hover, &:active, &:hover::after { opacity: 1; } }
256
+ }
257
+ }
258
+
259
+ #main-wrapper {
260
+ display: table-row;
261
+ height: 100%;
262
+ margin: 0; padding: 0;
263
+ vertical-align: baseline;
264
+ #sidebar-wrapper, #main-content, #aside-wrapper {
265
+ display: table-cell;
266
+ height: 100%;
267
+ margin: 0; padding: 0;
268
+ vertical-align: top;
269
+ }
270
+ #sidebar-wrapper, #aside-wrapper {
271
+ min-width: 225px; width: 22%;
272
+ }
273
+
274
+ aside, nav {
275
+ display: block;
276
+ color: #777;
277
+ border: 0; outline: 0;
278
+ margin: 0; padding: 0;
279
+ }
280
+
281
+ #sidebar-wrapper {
282
+ @include box-shadow(rgba(0, 0, 0, 0.0976562), -2px, 2px, 10px, inset);
283
+ background: #EFEFEF;
284
+ #sidebar {
285
+ dislpay: block;
286
+ min-height: 300px;
287
+ margin: 0; padding: 0;
288
+ vertical-align: baseline;
289
+ .sitemap {
290
+ a {
291
+ color: #777;
292
+ margin: 0px 10px 0px 20px;
293
+ font-style: normal;
294
+ font-variant: normal;
295
+ vertical-align: baseline;
296
+ &:hover, &.active { color: black; }
297
+ }
298
+ h3 {
299
+ text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
300
+ text-transform: uppercase;
301
+ border-top: 1px solid transparent;
302
+ margin: 0px;
303
+ font-weight: normal;
304
+ a {
305
+ display: block;
306
+ padding-bottom: 6px;
307
+ padding-top: 9px;
308
+ }
309
+ }
310
+ li { display: list-item; }
311
+ .header {
312
+ display: block;
313
+ position: relative;
314
+ border-bottom: 1px dotted rgba(0, 0, 0, 0.136719);
315
+ margin-bottom: 4.5px;
316
+ }
317
+ .tree {
318
+ dislpay: block; padding-bottom: 18px;
319
+ ul { margin: 0; }
320
+ .label { position: relative; }
321
+ .item {
322
+ .entries, .bucket {
323
+ .label {padding-left: 15px}
324
+ a.entries, a.bucket { padding-left: 20px }
325
+ a.entries { background: url(/images/c2/entries-small.png) no-repeat 0% 50%; }
326
+ a.bucket { background: url(/images/c2/categories-small.png) no-repeat 0% 50%; }
327
+ a .count {
328
+ @include border-radius(6px);
329
+ float: right;
330
+ margin-top: 1px; padding: 0px 6px ;
331
+ background: #999; color: white;
332
+ font-size: 11px;
333
+ font-style: normal;
334
+ line-height: 16px;
335
+ text-shadow: none;
336
+ }
337
+ a:hover .count { background: #555; }
338
+ .current a .count { background: white; color: #525252 }
339
+ }
340
+ }
341
+ a {
342
+ -webkit-font-smoothing: antialiased;
343
+ display: block;
344
+ font-weight: 600;
345
+ padding-bottom: 2.25px;
346
+ padding-top: 2.25px;
347
+ text-shadow: rgba(255, 255, 255, 0.496094) 1px 1px 0px;
348
+ }
349
+ }
350
+ a.section {
351
+ color: #333;
352
+ font-size: 14px;
353
+ margin-top: 4.5px;
354
+ }
355
+ .current, .current a {
356
+ background: #525252; color: white;
357
+ text-shadow: none;
358
+ }
359
+ }
360
+ }
361
+ }
362
+
363
+ #main-content {
364
+ padding: 0px;
365
+ min-width: 510px;
366
+ height: 100%;
367
+ #app-wrapper, #app { position: relative; height: 100% }
368
+ #app {
369
+ position: relative;
370
+ vertical-align: baseline;
371
+ z-index: 0;
372
+ .sheet {
373
+ @include transition(all, .5s, ease-in-out);
374
+ @include border-radius(5px);
375
+ position: absolute;
376
+ overflow: auto;
377
+ top: -5px; bottom: 0; left: 0; right: 0;
378
+ background: white;
379
+ border: 0px solid white;
380
+ border-width: 0 5px 5px 5px;
381
+ padding: 18px 20px;
382
+
383
+ &#app-front { z-index: 900; }
384
+ &#app-back { z-index: 800; }
385
+ }
386
+ &.flip {
387
+ #app-front { z-index: 900; }
388
+ #app-back { z-index: 1000; }
389
+ }
390
+ .toolbar {
391
+ position: absolute;
392
+ top: 0; right: 0;
393
+ height: 27px;
394
+ text-align: right;
395
+ line-height: 27px;
396
+ padding-right: 5px;
397
+ a {
398
+ color: #555;
399
+ height: 100%;
400
+ }
401
+ }
402
+ .header {
403
+ position: relative;
404
+ display: block;
405
+ margin: 0; padding: 0;
406
+ h1 {
407
+ margin: 0;
408
+ color: #A5A5A5;
409
+ font-size: 23px;
410
+ font-weight: 100;
411
+ line-height: 27px;
412
+ text-transform: none;
413
+ strong {
414
+ color: #555;
415
+ font-weight: normal;
416
+ }
417
+ }
418
+ }
419
+ .header::after, .actions::before {
420
+ content: '.';
421
+ display: block;
422
+ height: 1px;
423
+ margin: 6px 0px 18px;
424
+ text-indent: -99999px;
425
+ background: rgba(0, 0, 0, 0.0976562);
426
+ border: 1px solid rgba(255, 255, 255, 0.648438); border-left: 0px; border-right: 0px;
427
+ }
428
+ .field {
429
+ max-width: 100%;
430
+ margin-bottom: 18px;
431
+ label {
432
+ color: #777;
433
+ cursor: pointer;
434
+ display: block;
435
+ font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
436
+ font-size: 12px;
437
+ font-weight: bold;
438
+ line-height: 18px;
439
+ margin: 0px 0px 3px;
440
+ text-shadow: none;
441
+ text-transform: none;
442
+ }
443
+ input, textarea {
444
+ border: 1px solid #BBB;
445
+ color: #222;
446
+ font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
447
+ font-size: 16px;
448
+ font-weight: bold;
449
+ }
450
+ input, textarea, .tip {
451
+ @include box-sizing(border-box);
452
+ width: 100%;
453
+ }
454
+ input {
455
+ line-height: 1;
456
+ margin: 0px 0px 3px;
457
+ padding: 6px;
458
+ }
459
+ textarea {
460
+ height: 5em;
461
+ line-height: 22.5px;
462
+ margin: 0px;
463
+ min-height: 60px;
464
+ padding: 3px 6px;
465
+ }
466
+ &.checkbox input, &.radio input { margin-right: 5px; }
467
+
468
+ &.checkbox input, &.radio input,
469
+ &.select input, &.readonly input {
470
+ display: inline;
471
+ top: 0px;
472
+ width: auto;
473
+ }
474
+
475
+ &.checkbox label, &.radio label,
476
+ &.select label, &.readonly label {
477
+ color: #555;
478
+ display: inline;
479
+ width: auto;
480
+ }
481
+
482
+ .tip {
483
+ color: #999;
484
+ font-size: 11px;
485
+ margin: 0px 0px 18px;
486
+ }
487
+ p { margin-bottom: 0px }
488
+ }
489
+ }
490
+ .block-list {
491
+ margin-top: -9px;
492
+ .item {
493
+ position: relative;
494
+ border-bottom: 1px dotted rgba(0, 0, 0, 0.136719);
495
+ margin: 0; padding: 9px 0px;
496
+ h3 {
497
+ margin: 0;
498
+ font-size: 15px;
499
+ font-weight: normal;
500
+ a { color: #6186B7; }
501
+ }
502
+ .meta { margin-top: 9px; }
503
+ }
504
+
505
+ }
506
+ }
507
+
508
+ #aside-wrapper {
509
+ @include box-shadow(rgba(0, 0, 0, 0.0976562), 2px, 2px, 10px, inset);
510
+ background: #E8E8E8;
511
+ #aside {
512
+ padding: 20px;
513
+ .call-to-action {
514
+ .button {
515
+ display: block;
516
+ text-align: center;
517
+ strong {
518
+ @include border-radius;
519
+ @include box-sizing(border-box);
520
+ border: none; outline: none;
521
+ background: #484848 url(/images/c2/alert-overlay.png) repeat-x;
522
+ text-shadow: rgba(0, 0, 0, 0.699219) 0px 1px 2px;
523
+ color: white; cursor: pointer;
524
+ display: inline-block;
525
+ font-size: 15px;
526
+ font-weight: bold;
527
+ line-height: 1;
528
+ opacity: 0.95;
529
+ padding: 10px 20px 12px;
530
+ position: relative;
531
+ text-align: center;
532
+ text-decoration: none;
533
+ vertical-align: middle;
534
+ }
535
+ }
536
+ .button::before {
537
+ content: '+';
538
+ display: block;
539
+ height: 100px; width: 100%;
540
+ margin-bottom: 8px;
541
+ text-indent: -99999px;
542
+ }
543
+ &.new-entry .button::before{ background: url(/images/c2/new-entry.png) no-repeat 50% 50%; }
544
+ }
545
+ }
546
+ }
547
+ #footer-wrapper {
548
+ position: absolute;
549
+ bottom: 0; left: 0;
550
+ height: 10px; min-width: 960px; width: 100%;
551
+ border-top: 1px solid rgba(255, 255, 255, 0.5);
552
+ background: #101010 url(/images/c2/bg-header.png) repeat-x;
553
+ }
554
+
555
+ .actions {
556
+ .button, button, .cancel {
557
+ @include text-shadow(rgba(0, 0, 0, 0.699219), 0px, 1px, 2px);
558
+ @include box-sizing(border-box);
559
+ @include border-radius(8px);
560
+
561
+ position: relative; display: inline-block;
562
+ border: none; outline: none; cursor: pointer;
563
+ height: 36px; min-width: 95px;
564
+
565
+ font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
566
+ font-size: 15px;
567
+ font-weight: bold;
568
+ line-height: 1;
569
+ text-align: center;
570
+ text-decoration: none;
571
+ vertical-align: middle;
572
+ }
573
+ .button, button {
574
+ @include transition(all, .3s, ease);
575
+ @include linear-gradient(color-stops(#75A7D0, #6186B7 50%, #4470A1));
576
+ background-color: #4470A1; color: white;
577
+ margin-right: 10px; padding: 9px 20px;
578
+ &:hover, &.hover, &:active, &.active {
579
+ background-color: #335F90;
580
+ background-image: none;
581
+ }
582
+ }
583
+ .cancel {
584
+ background-color: #999; color: white;
585
+ margin-right: 10px; padding: 9px 20px;
586
+ opacity: 0.7;
587
+ &:hover, &.hover, &:active, &.active { opacity: 1; }
588
+ }
589
+ }
590
+ }
591
+ }
592
+
593
+ .field_with_errors {
594
+ label { position: relative ; }
595
+ .error {
596
+ color: #D63104;
597
+ display: inline-block;
598
+ margin: 0; padding: 0px 55px 0px 0px;
599
+ font-size: 12px;
600
+ font-weight: bold;
601
+ z-index: 9999;
602
+ &::before {
603
+ content: '→';
604
+ color: #999;
605
+ margin: 0px 6px;
606
+ }
607
+ &::after {
608
+ content: 'Opps!;';
609
+ background: url(/images/c2/ops.png) no-repeat 50% 50%;
610
+ display: inline-block; position: absolute;
611
+ height: 53px; width: 42px;
612
+ top: -6px; right: 10px;
613
+ text-indent: -99999px;
614
+ z-index: 1;
615
+ }
616
+ }
617
+ }
618
+
619
+ #notices {
620
+ display: block; position: absolute;
621
+ top: 0; left: 0;
622
+ margin: 0; padding: 0;
623
+ border: none;
624
+ width: 100%; min-width: 960px;
625
+ .success, .notice, .warning, .error {
626
+ @include border-radius;
627
+ display: block;
628
+ width: 490px;
629
+ margin: 10px auto; padding: 10px;
630
+ color: #333;
631
+ text-align: center;
632
+ line-height: 20px;
633
+ font-size: 16px;
634
+ font-weight: bold;
635
+ }
636
+ .success, .notice {
637
+ background: #BBFFB6;
638
+ border: 1px solid #1FDF00;
639
+ }
640
+ .warning {
641
+ background: #FFC;
642
+ border: 1px solid #FF8;
643
+ }
644
+ .error {
645
+ background: #F77;
646
+ border: 1px solid #F55;
647
+ }
648
+ }
649
+
650
+ /* Pictos */
651
+ .pictos-icon {
652
+ display: none;
653
+ font-family: 'Pictos';
654
+ font-size: 20px;
655
+ }
656
+ body.pictos-icons {
657
+ .pictos-text { display: none; }
658
+ .pictos-icon { display: block; }
659
+ }
660
+
661
+ /* Experimental */
662
+ body.lab {
663
+ #app {
664
+ .sheet {
665
+ &#app-front {
666
+ -webkit-transform: rotateY(0deg);
667
+ -webkit-transform-style: preserve-3d;
668
+ -webkit-backface-visibility: hidden;
669
+ }
670
+ &#app-back {
671
+ -webkit-transform: rotateY(180deg);
672
+ -webkit-transform-style: preserve-3d;
673
+ -webkit-backface-visibility: hidden;
674
+ }
675
+ }
676
+ &.flip {
677
+ #app-front { -webkit-transform: rotateY(180deg); }
678
+ #app-back { -webkit-transform: rotateY(0deg); }
679
+ }
680
+ }
681
+ }