caboose-cms 0.5.15 → 0.5.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +9 -9
  2. data/app/assets/javascripts/caboose/cart2.js +98 -0
  3. data/app/assets/javascripts/caboose/model/index_table.js +82 -30
  4. data/app/assets/javascripts/caboose/model/model_binder.js +4 -4
  5. data/app/assets/stylesheets/caboose/admin.css +1 -0
  6. data/app/assets/stylesheets/caboose/admin_main.css +0 -42
  7. data/app/assets/stylesheets/caboose/cart.scss +41 -0
  8. data/app/assets/stylesheets/caboose/checkout.css.scss +2 -3
  9. data/app/assets/stylesheets/caboose/message_boxes.scss +49 -0
  10. data/app/assets/templates/caboose/cart/add_to_cart.jst.ejs +1 -1
  11. data/app/controllers/caboose/block_types_controller.rb +3 -1
  12. data/app/controllers/caboose/cart_controller.rb +30 -23
  13. data/app/controllers/caboose/checkout_controller.rb +11 -1
  14. data/app/controllers/caboose/products_controller.rb +28 -14
  15. data/app/controllers/caboose/stackable_groups_controller.rb +107 -0
  16. data/app/models/caboose/line_item.rb +20 -6
  17. data/app/models/caboose/order.rb +2 -1
  18. data/app/models/caboose/order_package.rb +103 -0
  19. data/app/models/caboose/product.rb +2 -1
  20. data/app/models/caboose/schema.rb +45 -3
  21. data/app/models/caboose/shipping_calculator.rb +101 -60
  22. data/app/models/caboose/shipping_package.rb +80 -0
  23. data/app/models/caboose/site.rb +3 -1
  24. data/app/models/caboose/stackable_group.rb +17 -0
  25. data/app/models/caboose/tax_calculator.rb +1 -2
  26. data/app/models/caboose/variant.rb +2 -5
  27. data/app/views/caboose/cart/index.html.erb +19 -6
  28. data/app/views/caboose/checkout/_cart.html.erb +49 -52
  29. data/app/views/caboose/checkout/empty.html.erb +9 -2
  30. data/app/views/caboose/checkout/step_one.html.erb +2 -3
  31. data/app/views/caboose/checkout/step_three.html.erb +28 -10
  32. data/app/views/caboose/checkout/step_two.html.erb +2 -4
  33. data/app/views/caboose/pages/admin_edit_content.html.erb +1 -1
  34. data/app/views/caboose/products/admin_index.html.erb +12 -11
  35. data/app/views/caboose/sites/admin_edit.html.erb +33 -6
  36. data/app/views/caboose/stackable_groups/admin_index.html.erb +43 -0
  37. data/config/routes.rb +15 -6
  38. data/lib/caboose/version.rb +1 -1
  39. data/lib/tasks/caboose.rake +7 -1
  40. metadata +36 -14
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmZkN2Y1OTAyYTUwNjIyM2JhYTA4MjIxMmI4NDYyNDg1OWUxNWFhMw==
4
+ MDU5MWI2YTUyYzc5NTg3NDYwOTEzYjJlMTYzMDc2ZGIwOTlkMDA2YQ==
5
5
  data.tar.gz: !binary |-
6
- YjM1NWE0ZGQyMTg5N2FjOGFjMWM3ODk0N2Q3YzZlYWZhMjE3MzFiNA==
7
- !binary "U0hBNTEy":
6
+ YWJkNTI4N2Y3YWZjYTYzYzM1NzgxNTYyYTEwZGI5NDU4ODFlNDU5YQ==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTQ5ZDYyOGRkN2ViNDlkZGYyMDQ1N2U1OTk1ZTYzMmNhYTA2NzY5YmQxNTU1
10
- NjY5YTlkNmI3OGMwMzBhNzFmMzU3ZmI2M2E1OWRlNWNjMjY5ZDQ0MzkzOWZi
11
- YmI5NDBiYzViMDVhZGY0NzdkYjg4MDQ4YmEyMjM3YTVlYzJkYzU=
9
+ ZGE2YTExNTVkNjI5YTA3N2RmM2NhYTkxNWU0NjVmZWM3MTYzN2Y3ZDE2MDIy
10
+ OGRlYTg1ZjU4OGI2OGY0N2RjMjQyZTk5YzgzNjBkMTUwMTdjOTBhMGZiNTdm
11
+ YTIwODI5NWU5NDhlZjA2OWRhNjllMmE2ODViYTcwYmY2YjRlYjE=
12
12
  data.tar.gz: !binary |-
13
- ZTdmZTE2NDA2MDc3NmE4NGVmOWIwZGRhZGYzOTYzN2NjMzhmY2EyZGI4MTg3
14
- YjUxM2QxNDVhZDJjYWExNzRkN2U5YjBhZmMzZWIzZmIxMjY1YWY3ZWYyOWIy
15
- MjRkMTBiYmY3YzczZGQyZGFmOTNhNDEyZjhhYjRhOGU5MjhlMjc=
13
+ NWQ2MzJiNjljYzBiYTQzZDc0YjIwYTgzMDcxMzEzMjNhMjY3ODZhNjIwNDU5
14
+ NzIwMTVmYTdhMDVlN2NlYWIyODRmMTIwMDA2NjI1MjI1NzdjZjRhZmQwODRj
15
+ NTU4MjBiYmJjMDg0NWU0MzY0ZDMwOThhMTliZjE5NWZlY2FhNmQ=
@@ -0,0 +1,98 @@
1
+
2
+ Cart = function(params) { this.init(params); };
3
+
4
+ Cart.prototype = {
5
+
6
+ order: false,
7
+
8
+ init: function(params)
9
+ {
10
+ for (var i in params)
11
+ this[i] = params[i];
12
+ this.refresh();
13
+ },
14
+
15
+ refresh: function()
16
+ {
17
+ var that = this;
18
+ $('#message').html("<p class='loading'>Getting cart...</p>");
19
+ $.ajax({
20
+ url: '/cart/items',
21
+ success: function(resp) {
22
+ that.order = resp.order;
23
+ that.print();
24
+ }
25
+ });
26
+ },
27
+
28
+ print: function()
29
+ {
30
+ var that = this;
31
+ if (!this.order || !this.order.line_items || this.order.line_items.length == 0)
32
+ {
33
+ $('#cart').html("<p class='note'>You don't have any items in your shopping cart. <a href='/products'>Continue shopping.</a></p>");
34
+ return;
35
+ }
36
+
37
+ var tbody = $('<tbody/>')
38
+ .append($('<tr/>')
39
+ .append($('<th/>').html('&nbsp'))
40
+ .append($('<th/>').html('Item'))
41
+ .append($('<th/>').html('Unit Price'))
42
+ .append($('<th/>').html('Quantity'))
43
+ .append($('<th/>').html('Subtotal'))
44
+ );
45
+
46
+ $.each(this.order.line_items, function(i, li) {
47
+ var v = li.variant;
48
+ var img = v.images ? v.images[0] : (p.featured_image ? p.featured_image : false);
49
+ console.log(img);
50
+ img = img ? $('<img/>').attr('src', img.urls.tiny) : '&nbsp;';
51
+
52
+ tbody.append($('<tr/>')
53
+ .append($('<td/>').attr('valign', 'top').append(img))
54
+ .append($('<td/>').attr('valign', 'top')
55
+ .append(v.title).append('<br/>')
56
+ .append($('<a/>').attr('href','#').html('Remove').click(function(e) { e.preventDefault(); that.remove_item(li.id); }))
57
+ )
58
+ .append($('<td/>').css('text-align', 'right').html('$' + parseFloat(v.price).toFixed(2)))
59
+ .append($('<td/>').css('text-align', 'right').append($('<div/>').attr('id', 'lineitem_' + li.id + '_quantity')))
60
+ .append($('<td/>').css('text-align', 'right').html('$' + (v.price * li.quantity).toFixed(2)))
61
+ );
62
+ });
63
+ tbody.append($('<tr/>')
64
+ .append($('<td/>').css('text-align', 'right').attr('colspan', 4).html('Subtotal'))
65
+ .append($('<td/>').css('text-align', 'right').html('$' + parseFloat(that.order.subtotal).toFixed(2)))
66
+ );
67
+ $('#cart').empty()
68
+ .append($('<table/>').append(tbody))
69
+ .append($('<p/>').addClass('controls')
70
+ .append($('<input/>').attr('type', 'button').val('Continue Shopping').click(function() { window.location = '/products'; }))
71
+ .append(' ')
72
+ .append($('<input/>').attr('type', 'button').val('Checkout').click(function() { window.location = '/checkout'; }))
73
+ );
74
+
75
+ $.each(this.order.line_items, function(i, li) {
76
+ m = new ModelBinder({
77
+ name: 'LineItem',
78
+ id: li.id,
79
+ update_url: '/cart/' + li.id,
80
+ authenticity_token: that.form_authenticity_token,
81
+ attributes: [
82
+ { name: 'quantity', nice_name: 'Qty', type: 'text', value: li.quantity, width: 50, fixed_placeholder: false, after_update: function() { that.refresh(); } }
83
+ ]
84
+ });
85
+ });
86
+ },
87
+
88
+ remove_item: function(li_id)
89
+ {
90
+ var that = this;
91
+ $.ajax({
92
+ url: '/cart/' + li_id,
93
+ type: 'delete',
94
+ success: function(resp) { that.refresh(); }
95
+ });
96
+ }
97
+
98
+ };
@@ -20,6 +20,9 @@ IndexTable.prototype = {
20
20
  // Where to send bulk deletes
21
21
  bulk_delete_url: false,
22
22
 
23
+ // When to send bulk import CSV data
24
+ bulk_import_url: false,
25
+
23
26
  // Where to post new models
24
27
  add_url: false,
25
28
 
@@ -73,8 +76,10 @@ IndexTable.prototype = {
73
76
 
74
77
  allow_bulk_edit: true,
75
78
  allow_bulk_delete: true,
76
- allow_duplicate: true,
77
- allow_advanced_edit: true,
79
+ allow_bulk_import: true,
80
+ allow_duplicate: true,
81
+ allow_advanced_edit: true,
82
+ bulk_import_fields: false,
78
83
  no_models_text: "There are no models right now.",
79
84
  new_model_text: 'New',
80
85
  new_model_fields: [{ name: 'name', nice_name: 'Name', type: 'text', width: 400 }],
@@ -236,8 +241,9 @@ IndexTable.prototype = {
236
241
  var columns = this.column_checkboxes();
237
242
  var controls = $('<p/>');
238
243
  if (this.allow_bulk_edit ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_edit' ).val('Bulk Edit' ).click(function(e) { that.bulk_edit(); })).append(' ');
239
- if (this.allow_bulk_delete ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_delete').val('Bulk Delete').click(function(e) { that.bulk_delete(); })).append(' ');
240
- if (this.allow_duplicate ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_duplicate' ).val('Duplicate' ).click(function(e) { that.duplicate(); }));
244
+ if (this.allow_bulk_delete ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_delete').val('Delete' ).click(function(e) { that.bulk_delete(); })).append(' ');
245
+ if (this.allow_duplicate ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_duplicate' ).val('Duplicate' ).click(function(e) { that.duplicate(); })).append(' ');
246
+ if (this.allow_bulk_import ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_import').val('Bulk Import').click(function(e) { that.bulk_import(); })).append(' ');
241
247
 
242
248
  $('#' + that.container).empty()
243
249
  .append($('<p/>')
@@ -465,7 +471,7 @@ IndexTable.prototype = {
465
471
  var that = this;
466
472
  if (this.model_ids.length == 0)
467
473
  {
468
- $('#message').html("<p class='note error'>Please select at least one row.</p>");
474
+ $('#' + that.container + '_message').html("<p class='note error'>Please select at least one row.</p>");
469
475
  return;
470
476
  }
471
477
  var div = $('<div/>')
@@ -475,8 +481,8 @@ IndexTable.prototype = {
475
481
  if (field.bulk_edit == true)
476
482
  div.append($('<p/>').append($('<div/>').attr('id', 'bulkmodel_1_' + field.name)));
477
483
  });
478
- div.append($('<input/>').attr('type','button').val('Finished').click(function() { $('#message').empty(); }));
479
- $('#message').empty().append(div);
484
+ div.append($('<input/>').attr('type','button').val('Finished').click(function() { $('#' + that.container + '_message').empty(); }));
485
+ $('#' + that.container + '_message').empty().append(div);
480
486
 
481
487
  var params = this.model_ids.map(function(model_id) { return 'model_ids[]=' + model_id; }).join('&');
482
488
  var attribs = [];
@@ -505,16 +511,16 @@ IndexTable.prototype = {
505
511
  var that = this;
506
512
  if (this.model_ids.length == 0)
507
513
  {
508
- $('#message').html("<p class='note error'>Please select at least one row.</p>");
514
+ $('#' + that.container + '_message').html("<p class='note error'>Please select at least one row.</p>");
509
515
  return;
510
516
  }
511
517
  if (!confirm)
512
518
  {
513
519
  var p = $('<p/>').addClass('note').addClass('warning')
514
520
  .append('Are you sure you want to delete the selected rows? ')
515
- .append($('<input/>').attr('type','button').val('Yes').click(function() { that.bulk_delete(true); }))
516
- .append($('<input/>').attr('type','button').val('No').click(function() { $('#message').empty(); }));
517
- $('#message').empty().append(p);
521
+ .append($('<input/>').attr('type','button').val('Yes').click(function() { that.bulk_delete(true); })).append(' ')
522
+ .append($('<input/>').attr('type','button').val('No').click(function() { $('#' + that.container + '_message').empty(); }));
523
+ $('#' + that.container + '_message').empty().append(p);
518
524
  return;
519
525
  }
520
526
  var params = this.model_ids.map(function(model_id) { return 'model_ids[]=' + model_id; }).join('&');
@@ -526,12 +532,59 @@ IndexTable.prototype = {
526
532
  model_ids: that.model_ids
527
533
  },
528
534
  success: function(resp) {
529
- $('#message').empty();
535
+ $('#' + that.container + '_message').empty();
530
536
  that.refresh();
531
537
  }
532
538
  });
533
539
  },
534
540
 
541
+ bulk_import: function(data, data_url)
542
+ {
543
+ var that = this;
544
+ if (!data && !data_url)
545
+ {
546
+ var div = $('<div/>').addClass('note')
547
+ .append($('<h2/>').html('Bulk Import'))
548
+ .append($('<p/>').html("Enter either the URL where CSV data can be downloaded or the CSV data.</p>"))
549
+ .append($('<p/>')
550
+ .append('CSV Data URL').append('<br />')
551
+ .append($('<input/>').attr('id', that.container + '_bulk_import_data_url').attr('placeholder', 'CSV Data URL').css('width', '100%'))
552
+ )
553
+ .append($('<p/>')
554
+ .append('CSV Data').append('<br />')
555
+ .append($('<textarea/>').attr('id', that.container + '_bulk_import_data').attr('placeholder', 'CSV Data').css('width', '100%').css('height', '150px'))
556
+ )
557
+ .append($('<p/>')
558
+ .append($('<input/>').attr('type','button').val('Cancel').click(function() { $('#' + that.container + '_message').empty(); })).append(' ')
559
+ .append($('<input/>').attr('type','button').val('Add').click(function() { that.bulk_import($('#' + that.container + '_bulk_import_data').val(), $('#' + that.container + '_bulk_import_data_url').val()); }))
560
+ );
561
+ if (that.bulk_import_fields)
562
+ div.append($('<p/>').css('font-size', '75%').html("Format: " + that.bulk_import_fields.join(', ')));
563
+
564
+ $('#' + that.container + '_message').empty().append(div);
565
+ return;
566
+ }
567
+ $('#' + that.container + '_message').empty().append("<p class='loading'>Adding...</p>");
568
+ $.ajax({
569
+ url: this.bulk_import_url,
570
+ type: 'post',
571
+ data: {
572
+ csv_data: data,
573
+ csv_data_url: data_url
574
+ },
575
+ success: function(resp) {
576
+ if (resp.error)
577
+ $('#' + that.container + '_message').html("<p class='note error'>" + resp.error + "</p>");
578
+ else
579
+ {
580
+ $('#' + that.container + '_message').html("<p class='note success'>Added successfully.</p>");
581
+ setTimeout(function() { $('#' + that.container + '_message').empty(); }, 3000);
582
+ that.refresh();
583
+ }
584
+ }
585
+ });
586
+ },
587
+
535
588
  model_for_id: function(model_id)
536
589
  {
537
590
  for (var i=0; i<this.models.length; i++)
@@ -546,13 +599,13 @@ IndexTable.prototype = {
546
599
  if (this.model_ids.length == 0)
547
600
  {
548
601
  var p = $('<p/>').addClass('note error').html("Please select a row.");
549
- $('#message').empty().append(p);
602
+ $('#' + that.container + '_message').empty().append(p);
550
603
  return;
551
604
  }
552
605
  if (this.model_ids.length > 1)
553
606
  {
554
607
  var p = $('<p/>').addClass('note error').html("Please select a single row.");
555
- $('#message').empty().append(p);
608
+ $('#' + that.container + '_message').empty().append(p);
556
609
  return;
557
610
  }
558
611
  if (!count)
@@ -561,19 +614,19 @@ IndexTable.prototype = {
561
614
  .append('How many times do you want this duplicated?')
562
615
  .append($('<input/>').attr('type', 'text').attr('id', 'count').css('width', '50'))
563
616
  .append('<br />')
564
- .append($('<input/>').attr('type', 'button').val('Cancel').click(function(e) { $('#message').empty(); })).append(' ')
617
+ .append($('<input/>').attr('type', 'button').val('Cancel').click(function(e) { $('#' + that.container + '_message').empty(); })).append(' ')
565
618
  .append($('<input/>').attr('type', 'button').val('Duplicate').click(function(e) { that.duplicate($('#count').val()); return false; }));
566
- $('#message').empty().append(p);
619
+ $('#' + that.container + '_message').empty().append(p);
567
620
  return;
568
621
  }
569
- $('#message').html("<p class='loading'>Duplicating...</p>");
622
+ $('#' + that.container + '_message').html("<p class='loading'>Duplicating...</p>");
570
623
  $.ajax({
571
624
  url: that.duplicate_url(that.model_ids[0], that),
572
625
  type: 'post',
573
626
  data: { count: count },
574
627
  success: function(resp) {
575
- if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
576
- if (resp.success) { $('#message').empty(); that.refresh(); }
628
+ if (resp.error) $('#' + that.container + '_message').html("<p class='note error'>" + resp.error + "</p>");
629
+ if (resp.success) { $('#' + that.container + '_message').empty(); that.refresh(); }
577
630
  }
578
631
  });
579
632
  },
@@ -648,8 +701,10 @@ IndexTable.prototype = {
648
701
 
649
702
  pager_params: function(h)
650
703
  {
651
- var that = this;
652
- var p = $.extend({}, this.pager.params);
704
+ var that = this;
705
+ var skip = this.pager.options && this.pager.options.skip ? this.pager.options.skip : [];
706
+ var p = {};
707
+ for (var i in this.pager.params) if (skip.indexOf(i) == -1) p[i] = this.pager.params[i];
653
708
  if (this.pager.options)
654
709
  {
655
710
  if (this.pager.options.sort) p.sort = this.pager.options.sort;
@@ -657,17 +712,14 @@ IndexTable.prototype = {
657
712
  if (this.pager.options.page) p.page = this.pager.options.page;
658
713
  }
659
714
  if (h)
660
- {
715
+ {
661
716
  for (var i in h)
662
- {
663
- //console.log('' + i + ' = ' + h[i]);
664
- //console.log(typeof(h[i]));
665
- //console.log('-------------------');
717
+ {
666
718
  if (typeof(h[i]) == 'boolean')
667
719
  p[i] = h[i] ? 1 : 0;
668
720
  else
669
721
  p[i] = h[i];
670
- }
722
+ }
671
723
  }
672
724
  return p;
673
725
  },
@@ -705,7 +757,7 @@ IndexTable.prototype = {
705
757
  form.append($('<p/>').append($('<input/>').attr('type', 'text').attr('name', f.name).attr('placeholder', f.nice_name).css('width', '' + f.width + 'px')));
706
758
  });
707
759
  form
708
- .append($('<div/>').attr('id', 'new_message'))
760
+ .append($('<div/>').attr('id', that.container + '_new_message'))
709
761
  .append($('<p>')
710
762
  .append($('<input/>').attr('type', 'button').val('Cancel').click(function(e) { $('#' + that.container + '_new_form_container').empty(); }))
711
763
  .append(' ')
@@ -721,13 +773,13 @@ IndexTable.prototype = {
721
773
  add_model: function()
722
774
  {
723
775
  var that = this;
724
- $('#new_message').html("<p class='loading'>Adding...</p>");
776
+ $('#' + that.container + '_new_message').html("<p class='loading'>Adding...</p>");
725
777
  $.ajax({
726
778
  url: this.add_url,
727
779
  type: 'post',
728
780
  data: $('#new_form').serialize(),
729
781
  success: function(resp) {
730
- if (resp.error) $('#new_message').html("<p class='note error'>" + resp.error + "</p>");
782
+ if (resp.error) $('#' + that.container + '_new_message').html("<p class='note error'>" + resp.error + "</p>");
731
783
  if (resp.redirect || resp.refresh) that.refresh();
732
784
  }
733
785
  });
@@ -126,16 +126,16 @@ ModelBinder.prototype = {
126
126
 
127
127
  control_with_id: function(id)
128
128
  {
129
- attrib = false
129
+ var control = false
130
130
  var this2 = this;
131
- $.each(this.controls, function(i, c) {
131
+ $.each(this.controls, function(i, c) {
132
132
  if (id == (this2.model.name + "_" + this2.model.id + "_" + c.attribute.name).toLowerCase())
133
133
  {
134
- attrib = c.attribute;
134
+ control = c;
135
135
  return false;
136
136
  }
137
137
  });
138
- return attrib;
138
+ return control;
139
139
  },
140
140
 
141
141
  cancel: function()
@@ -12,6 +12,7 @@
12
12
  *= require jquery-ui
13
13
  *= require caboose/fonts
14
14
  *= require caboose/caboose
15
+ *= require caboose/message_boxes
15
16
  *= require caboose/model_binder
16
17
  *= require caboose/admin_main
17
18
  *= require caboose/admin_crumbtrail
@@ -336,48 +336,6 @@ Modeljs
336
336
  line-height: 0;
337
337
  }
338
338
 
339
- /*******************************************************************************
340
- Message boxes
341
- *******************************************************************************/
342
-
343
- #content .note {
344
- padding: 20px;
345
- background: #fef49c;
346
- color: #000000;
347
- font-weight: bold;
348
- font-size: 1.4em;
349
- }
350
-
351
- #content .note_small {
352
- display: block;
353
- padding: 4px 10px;
354
- background: #fef49c;
355
- color: #000000;
356
- font-size: 1em;
357
- }
358
-
359
- #content .error {
360
- background: #9c171b;
361
- color: #ffffff;
362
- }
363
-
364
- #content .error a {
365
- color: #fff;
366
- }
367
-
368
- #content .error a:hover {
369
- color: #000;
370
- }
371
-
372
- #content .success {
373
- background: #009900;
374
- color: #ffffff;
375
- }
376
-
377
- #content .success a {
378
- color: #ffffff;
379
- }
380
-
381
339
  /*******************************************************************************
382
340
  Page Bar Generator
383
341
  *******************************************************************************/
@@ -0,0 +1,41 @@
1
+
2
+ #cart {
3
+
4
+ margin: 20px 0 10px 0;
5
+ table { border-collapse: collapse; width: 100%; }
6
+ table th { font-weight: bold; text-align: center; }
7
+ table td { border: #ccc 1px solid; padding: 10px; }
8
+
9
+ input[type="text"] {
10
+ border-color: #b9b9b9;
11
+ border-radius: 0;
12
+ border-width: 1px;
13
+ color: #565656;
14
+ font: 1em "Klinic Slab",serif;
15
+ padding: 8px 6px 6px;
16
+ text-align: right !important;
17
+ }
18
+
19
+ input[type="button"] {
20
+ background-color: #c25454;
21
+ background-position: 6px center;
22
+ background-repeat: no-repeat;
23
+ background-size: 30px auto;
24
+ border-radius: 0;
25
+ border-width: 0;
26
+ color: #fff;
27
+ cursor: pointer;
28
+ display: block-inline;
29
+ font: 20px/1em "Klinic Slab",serif;
30
+ margin-top: 20px;
31
+ padding: 8px 15px 6px 15px;
32
+ text-align: center;
33
+ text-decoration: none;
34
+ text-transform: uppercase;
35
+ }
36
+
37
+ p.controls {
38
+ text-align: right;
39
+ margin-bottom: 20px;
40
+ }
41
+ }