diff --git a/.sample.env b/.sample.env index a194f48..9e3d79c 100644 --- a/.sample.env +++ b/.sample.env @@ -3,3 +3,4 @@ ASSET_HOST=localhost:3000 HOST=localhost:3000 RACK_ENV=development SECRET_KEY_BASE=development_secret +EVENTBRITE_ACCESS_TOKEN=GET_THIS_FROM_HEROKU_CONFIG diff --git a/Gemfile b/Gemfile index b23c70a..6a1ad45 100644 --- a/Gemfile +++ b/Gemfile @@ -6,21 +6,23 @@ gem "airbrake" gem "autoprefixer-rails" gem "bourbon", "~> 4.2.0" gem "coffee-rails", "~> 4.1.0" -gem "delayed_job_active_record" +gem "compass", "1.0.0.rc.1" gem "email_validator" gem "flutie" gem "high_voltage" +gem "httparty" gem "i18n-tasks" +gem "jquery-middleman" gem "jquery-rails" gem "neat", "~> 1.7.0" gem "normalize-rails", "~> 3.0.0" gem "pg" +gem "rack-contrib" gem "rails", "4.2.1" gem "recipient_interceptor" gem "refills" gem "sass-rails", "~> 5.0" gem "simple_form" -gem "title" gem "uglifier" gem "unicorn" @@ -42,6 +44,7 @@ end group :test do gem "capybara-webkit", ">= 1.2.0" + gem "climate_control" gem "database_cleaner" gem "formulaic" gem "launchy" diff --git a/Gemfile.lock b/Gemfile.lock index 7133ebc..dd67965 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -65,6 +65,9 @@ GEM capybara-webkit (1.5.1) capybara (>= 2.3.0, < 2.5.0) json + chunky_png (1.3.4) + climate_control (0.0.3) + activesupport (>= 3.0) coderay (1.1.0) coffee-rails (4.1.0) coffee-script (>= 2.2.0) @@ -74,15 +77,22 @@ GEM execjs coffee-script-source (1.9.1.1) columnize (0.9.0) + compass (1.0.0.rc.1) + chunky_png (~> 1.2) + compass-core (~> 1.0.0.rc.1) + compass-import-once (~> 1.0.5) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + sass (>= 3.3.13, < 3.5) + compass-core (1.0.3) + multi_json (~> 1.0) + sass (>= 3.3.0, < 3.5) + compass-import-once (1.0.5) + sass (>= 3.2, < 3.5) crack (0.4.2) safe_yaml (~> 1.0.0) database_cleaner (1.4.1) debug_inspector (0.0.2) - delayed_job (4.0.6) - activesupport (>= 3.0, < 5.0) - delayed_job_active_record (4.0.3) - activerecord (>= 3.0, < 5.0) - delayed_job (>= 3.0, < 4.1) diff-lcs (1.2.5) docile (1.1.5) dotenv (2.0.1) @@ -101,6 +111,7 @@ GEM factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) + ffi (1.9.8) flutie (2.0.0) formulaic (0.2.0) activesupport @@ -110,6 +121,9 @@ GEM activesupport (>= 4.1.0) high_voltage (2.3.0) highline (1.7.2) + httparty (0.13.1) + json (~> 1.8) + multi_xml (>= 0.5.2) i18n (0.7.0) i18n-tasks (0.8.3) activesupport @@ -119,6 +133,8 @@ GEM i18n term-ansicolor terminal-table + jquery-middleman (3.0.4) + thor (>= 0.14, < 2.0) jquery-rails (4.0.3) rails-dom-testing (~> 1.0) railties (>= 4.2.0) @@ -136,6 +152,7 @@ GEM mini_portile (0.6.2) minitest (5.6.1) multi_json (1.11.0) + multi_xml (0.5.5) neat (1.7.2) bourbon (>= 4.0) sass (>= 3.3) @@ -150,6 +167,8 @@ GEM pry-rails (0.3.4) pry (>= 0.9.10) rack (1.6.0) + rack-contrib (1.1.0) + rack (>= 0.9.1) rack-test (0.6.3) rack (>= 1.0) rack-timeout (0.2.4) @@ -179,6 +198,9 @@ GEM thor (>= 0.18.1, < 2.0) raindrops (0.13.0) rake (10.4.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) + ffi (>= 0.5.0) recipient_interceptor (0.1.2) mail refills (0.1.0) @@ -235,9 +257,6 @@ GEM tilt (1.4.1) timecop (0.7.3) tins (1.5.1) - title (0.0.5) - i18n - rails (>= 3.1) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (2.7.1) @@ -269,22 +288,26 @@ DEPENDENCIES bundler-audit byebug capybara-webkit (>= 1.2.0) + climate_control coffee-rails (~> 4.1.0) + compass (= 1.0.0.rc.1) database_cleaner - delayed_job_active_record dotenv-rails email_validator factory_girl_rails flutie formulaic high_voltage + httparty i18n-tasks + jquery-middleman jquery-rails launchy neat (~> 1.7.0) normalize-rails (~> 3.0.0) pg pry-rails + rack-contrib rack-timeout rails (= 4.2.1) recipient_interceptor @@ -297,7 +320,6 @@ DEPENDENCIES spring spring-commands-rspec timecop - title uglifier unicorn web-console diff --git a/Procfile b/Procfile index 7934897..9c82374 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1 @@ web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb -worker: bundle exec rake jobs:work diff --git a/README.md b/README.md index 1eef235..b49cdd7 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,33 @@ -# Railsbridgeboston dot org +RailsBridge Boston Website +========================== -## Getting Started +[![Build +Status](https://travis-ci.org/railsbridge-boston/railsbridgeboston_dot_org.svg?branch=master)](https://travis-ci.org/railsbridge-boston/railsbridgeboston_dot_org) -After you have cloned this repo, run this setup script to set up your machine -with the necessary dependencies to run and test this app: +This is the website for RailsBridge Boston, a chapter of [RailsBridge]. You can +check out the site at . This does *not* +include any curriculum content. - % ./bin/setup +RailsBridge Boston organizes workshops for women and their friends to learn +Ruby, Rails, and other web technologies. -It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up -your machine with [this script]. +[RailsBridge]: http://www.railsbridge.org -[this script]: https://github.com/thoughtbot/laptop +Running the app locally +---------------------- -After setting up, you can run the application using [foreman]: + $ ./bin/setup + $ middleman + $ open http://localhost:4567 - % foreman start +Using real event data +--------------------- -If you don't have `foreman`, see [Foreman's install instructions][foreman]. It -is [purposefully excluded from the project's `Gemfile`][exclude]. +If you'd like to work with actual Eventbrite data, you'll have to set the +`EVENTBRITE_ACCESS_TOKEN` variable to a real token in your `.env` file. -[foreman]: https://github.com/ddollar/foreman -[exclude]: https://github.com/ddollar/foreman/pull/437#issuecomment-41110407 +You can get this via `heroku config:get EVENTBRITE_ACCESS_TOKEN` if you have +Heroku access or from [Eventbrite App Management] if you have access to the +RailsBridge Boston Eventbrite account. Otherwise, ask a maintainer for access. -## Guidelines - -Use the following guides for getting things done, programming well, and -programming in style. - -* [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol) -* [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices) -* [Style](http://github.com/thoughtbot/guides/blob/master/style) +[Eventbrite App Management]: http://www.eventbrite.com/myaccount/apps/ diff --git a/app/assets/images/boston.png b/app/assets/images/boston.png new file mode 100644 index 0000000..c76afd7 Binary files /dev/null and b/app/assets/images/boston.png differ diff --git a/app/assets/images/boston_2x.png b/app/assets/images/boston_2x.png new file mode 100644 index 0000000..244921b Binary files /dev/null and b/app/assets/images/boston_2x.png differ diff --git a/app/assets/images/email.svg b/app/assets/images/email.svg new file mode 100644 index 0000000..6b58092 --- /dev/null +++ b/app/assets/images/email.svg @@ -0,0 +1 @@ +Imported Layers 3 \ No newline at end of file diff --git a/app/assets/images/gem.svg b/app/assets/images/gem.svg new file mode 100644 index 0000000..b4cc256 --- /dev/null +++ b/app/assets/images/gem.svg @@ -0,0 +1 @@ +gem diff --git a/app/assets/images/github.svg b/app/assets/images/github.svg new file mode 100644 index 0000000..0d01457 --- /dev/null +++ b/app/assets/images/github.svg @@ -0,0 +1 @@ +Imported Layers 4 diff --git a/app/assets/images/google-group.svg b/app/assets/images/google-group.svg new file mode 100644 index 0000000..b410db7 --- /dev/null +++ b/app/assets/images/google-group.svg @@ -0,0 +1 @@ +Imported Layers 2 diff --git a/app/assets/images/heart.svg b/app/assets/images/heart.svg new file mode 100644 index 0000000..5d7b032 --- /dev/null +++ b/app/assets/images/heart.svg @@ -0,0 +1 @@ +heart diff --git a/app/assets/images/play.png b/app/assets/images/play.png new file mode 100644 index 0000000..3d1dcef Binary files /dev/null and b/app/assets/images/play.png differ diff --git a/app/assets/images/reflection.png b/app/assets/images/reflection.png new file mode 100644 index 0000000..a4b267b Binary files /dev/null and b/app/assets/images/reflection.png differ diff --git a/app/assets/images/reflection_2x.png b/app/assets/images/reflection_2x.png new file mode 100644 index 0000000..627a880 Binary files /dev/null and b/app/assets/images/reflection_2x.png differ diff --git a/app/assets/images/rubygem_2x.png b/app/assets/images/rubygem_2x.png new file mode 100644 index 0000000..51fd326 Binary files /dev/null and b/app/assets/images/rubygem_2x.png differ diff --git a/app/assets/images/sponsors/actblue.png b/app/assets/images/sponsors/actblue.png new file mode 100644 index 0000000..c6f1aec Binary files /dev/null and b/app/assets/images/sponsors/actblue.png differ diff --git a/app/assets/images/sponsors/annkissam.png b/app/assets/images/sponsors/annkissam.png new file mode 100644 index 0000000..a5b994c Binary files /dev/null and b/app/assets/images/sponsors/annkissam.png differ diff --git a/app/assets/images/sponsors/cantina.jpg b/app/assets/images/sponsors/cantina.jpg new file mode 100644 index 0000000..1b165e2 Binary files /dev/null and b/app/assets/images/sponsors/cantina.jpg differ diff --git a/app/assets/images/sponsors/general_assembly.png b/app/assets/images/sponsors/general_assembly.png new file mode 100644 index 0000000..0009f9e Binary files /dev/null and b/app/assets/images/sponsors/general_assembly.png differ diff --git a/app/assets/images/sponsors/launch.png b/app/assets/images/sponsors/launch.png new file mode 100644 index 0000000..aaa971e Binary files /dev/null and b/app/assets/images/sponsors/launch.png differ diff --git a/app/assets/images/sponsors/rbm.png b/app/assets/images/sponsors/rbm.png new file mode 100644 index 0000000..80b4c13 Binary files /dev/null and b/app/assets/images/sponsors/rbm.png differ diff --git a/app/assets/images/sponsors/thoughtbot.png b/app/assets/images/sponsors/thoughtbot.png new file mode 100644 index 0000000..fda36ee Binary files /dev/null and b/app/assets/images/sponsors/thoughtbot.png differ diff --git a/app/assets/images/train.svg b/app/assets/images/train.svg new file mode 100644 index 0000000..8239310 --- /dev/null +++ b/app/assets/images/train.svg @@ -0,0 +1 @@ +Railsbridge diff --git a/app/assets/images/twitter.svg b/app/assets/images/twitter.svg new file mode 100644 index 0000000..37dacb8 --- /dev/null +++ b/app/assets/images/twitter.svg @@ -0,0 +1 @@ +Imported Layers 5 diff --git a/app/assets/images/workshop.png b/app/assets/images/workshop.png new file mode 100644 index 0000000..4851db2 Binary files /dev/null and b/app/assets/images/workshop.png differ diff --git a/app/assets/images/workshop/1.jpg b/app/assets/images/workshop/1.jpg new file mode 100644 index 0000000..080076c Binary files /dev/null and b/app/assets/images/workshop/1.jpg differ diff --git a/app/assets/images/workshop/2.jpg b/app/assets/images/workshop/2.jpg new file mode 100644 index 0000000..aef583e Binary files /dev/null and b/app/assets/images/workshop/2.jpg differ diff --git a/app/assets/images/workshop/3.jpg b/app/assets/images/workshop/3.jpg new file mode 100644 index 0000000..540a6ee Binary files /dev/null and b/app/assets/images/workshop/3.jpg differ diff --git a/app/assets/images/workshop/4.jpg b/app/assets/images/workshop/4.jpg new file mode 100644 index 0000000..af9b350 Binary files /dev/null and b/app/assets/images/workshop/4.jpg differ diff --git a/app/assets/images/workshop2.jpg b/app/assets/images/workshop2.jpg new file mode 100644 index 0000000..6caf19d Binary files /dev/null and b/app/assets/images/workshop2.jpg differ diff --git a/app/assets/images/workshop2_2x.jpg b/app/assets/images/workshop2_2x.jpg new file mode 100644 index 0000000..31f16e1 Binary files /dev/null and b/app/assets/images/workshop2_2x.jpg differ diff --git a/app/assets/images/workshop_2x.png b/app/assets/images/workshop_2x.png new file mode 100644 index 0000000..104ed4f Binary files /dev/null and b/app/assets/images/workshop_2x.png differ diff --git a/app/assets/javascripts/all.js b/app/assets/javascripts/all.js new file mode 100644 index 0000000..13dfcc5 --- /dev/null +++ b/app/assets/javascripts/all.js @@ -0,0 +1,2 @@ +//= require jquery +//= require_tree . diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 646c5ab..a707e05 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,15 +1,3 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. -// -// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details -// about supported directives. -// //= require jquery //= require jquery_ujs //= require_tree . diff --git a/app/assets/javascripts/jquery.sticky.js b/app/assets/javascripts/jquery.sticky.js new file mode 100755 index 0000000..f7c9cd4 --- /dev/null +++ b/app/assets/javascripts/jquery.sticky.js @@ -0,0 +1,170 @@ +// Sticky Plugin v1.0.0 for jQuery +// ============= +// Author: Anthony Garand +// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk) +// Improvements by Leonardo C. Daronco (daronco) +// Created: 2/14/2011 +// Date: 2/12/2012 +// Website: http://labs.anthonygarand.com/sticky +// Description: Makes an element on the page stick on the screen as you scroll +// It will only set the 'top' and 'position' of your element, you +// might need to adjust the width in some cases. + +(function($) { + var defaults = { + topSpacing: 0, + bottomSpacing: 0, + className: 'is-sticky', + wrapperClassName: 'sticky-wrapper', + center: false, + getWidthFrom: '', + responsiveWidth: false + }, + $window = $(window), + $document = $(document), + sticked = [], + windowHeight = $window.height(), + scroller = function() { + var scrollTop = $window.scrollTop(), + documentHeight = $document.height(), + dwh = documentHeight - windowHeight, + extra = (scrollTop > dwh) ? dwh - scrollTop : 0; + + for (var i = 0; i < sticked.length; i++) { + var s = sticked[i], + elementTop = s.stickyWrapper.offset().top, + etse = elementTop - s.topSpacing - extra; + + if (scrollTop <= etse) { + if (s.currentTop !== null) { + s.stickyElement + .css('position', '') + .css('top', ''); + s.stickyElement.trigger('sticky-end', [s]).parent().removeClass(s.className); + s.currentTop = null; + } + } + else { + var newTop = documentHeight - s.stickyElement.outerHeight() + - s.topSpacing - s.bottomSpacing - scrollTop - extra; + if (newTop < 0) { + newTop = newTop + s.topSpacing; + } else { + newTop = s.topSpacing; + } + if (s.currentTop != newTop) { + s.stickyElement + .css('position', 'fixed') + .css('top', newTop); + + if (typeof s.getWidthFrom !== 'undefined') { + s.stickyElement.css('width', $(s.getWidthFrom).width()); + } + + s.stickyElement.trigger('sticky-start', [s]).parent().addClass(s.className); + s.currentTop = newTop; + } + } + } + }, + resizer = function() { + windowHeight = $window.height(); + + for (var i = 0; i < sticked.length; i++) { + var s = sticked[i]; + if (typeof s.getWidthFrom !== 'undefined' && s.responsiveWidth === true) { + s.stickyElement.css('width', $(s.getWidthFrom).width()); + } + } + }, + methods = { + init: function(options) { + var o = $.extend({}, defaults, options); + return this.each(function() { + var stickyElement = $(this); + + var stickyId = stickyElement.attr('id'); + var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName + var wrapper = $('
') + .attr('id', stickyId + '-sticky-wrapper') + .addClass(o.wrapperClassName); + stickyElement.wrapAll(wrapper); + + if (o.center) { + stickyElement.parent().css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"}); + } + + if (stickyElement.css("float") == "right") { + stickyElement.css({"float":"none"}).parent().css({"float":"right"}); + } + + var stickyWrapper = stickyElement.parent(); + stickyWrapper.css('height', stickyElement.outerHeight()); + sticked.push({ + topSpacing: o.topSpacing, + bottomSpacing: o.bottomSpacing, + stickyElement: stickyElement, + currentTop: null, + stickyWrapper: stickyWrapper, + className: o.className, + getWidthFrom: o.getWidthFrom, + responsiveWidth: o.responsiveWidth + }); + }); + }, + update: scroller, + unstick: function(options) { + return this.each(function() { + var unstickyElement = $(this); + + var removeIdx = -1; + for (var i = 0; i < sticked.length; i++) + { + if (sticked[i].stickyElement.get(0) == unstickyElement.get(0)) + { + removeIdx = i; + } + } + if(removeIdx != -1) + { + sticked.splice(removeIdx,1); + unstickyElement.unwrap(); + unstickyElement.removeAttr('style'); + } + }); + } + }; + + // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): + if (window.addEventListener) { + window.addEventListener('scroll', scroller, false); + window.addEventListener('resize', resizer, false); + } else if (window.attachEvent) { + window.attachEvent('onscroll', scroller); + window.attachEvent('onresize', resizer); + } + + $.fn.sticky = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method ) { + return methods.init.apply( this, arguments ); + } else { + $.error('Method ' + method + ' does not exist on jQuery.sticky'); + } + }; + + $.fn.unstick = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method ) { + return methods.unstick.apply( this, arguments ); + } else { + $.error('Method ' + method + ' does not exist on jQuery.sticky'); + } + + }; + $(function() { + setTimeout(scroller, 0); + }); +})(jQuery); diff --git a/app/assets/javascripts/nav.js b/app/assets/javascripts/nav.js new file mode 100644 index 0000000..0178628 --- /dev/null +++ b/app/assets/javascripts/nav.js @@ -0,0 +1,7 @@ +$(document).ready(function(){ + $(".nav-toggle").click(function(e){ + $(this).toggleClass("is-on"); + $(".nav").toggleClass("is-open"); + e.preventDefault(); + }); +}); diff --git a/app/assets/javascripts/resources-nav.js b/app/assets/javascripts/resources-nav.js new file mode 100644 index 0000000..f5dbd6e --- /dev/null +++ b/app/assets/javascripts/resources-nav.js @@ -0,0 +1,12 @@ +$(document).ready(function(){ + $(".quick-find").sticky({topSpacing:50}); + + $(".resources-content section").waypoint(function() { + idName = $(this).attr("id"); + navLinks = $(".quick-find a"); + activeLink = $(".to-" + idName); + + navLinks.removeClass("active"); + activeLink.addClass("active"); + }, {offset: "35%"}); +}); diff --git a/app/assets/javascripts/video-toggle.js b/app/assets/javascripts/video-toggle.js new file mode 100644 index 0000000..f126f6e --- /dev/null +++ b/app/assets/javascripts/video-toggle.js @@ -0,0 +1,7 @@ +$(document).ready(function(){ + $(".video").click(function(e){ + $(this).toggleClass("show-video"); + $(this).find("iframe").attr("src", "http://player.vimeo.com/video/70699061?autoplay=1"); + $(".media .caption").fadeIn("slow"); + }); +}); diff --git a/app/assets/javascripts/waypoints.min.js b/app/assets/javascripts/waypoints.min.js new file mode 100755 index 0000000..b9098f8 --- /dev/null +++ b/app/assets/javascripts/waypoints.min.js @@ -0,0 +1,8 @@ +// Generated by CoffeeScript 1.6.2 +/*! +jQuery Waypoints - v2.0.5 +Copyright (c) 2011-2014 Caleb Troughton +Licensed under the MIT license. +https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt +*/ +(function(){var t=[].indexOf||function(t){for(var e=0,n=this.length;e=0;s={horizontal:{},vertical:{}};f=1;c={};u="waypoints-context-id";p="resize.waypoints";y="scroll.waypoints";v=1;w="waypoints-waypoint-ids";g="waypoint";m="waypoints";o=function(){function t(t){var e=this;this.$element=t;this.element=t[0];this.didResize=false;this.didScroll=false;this.id="context"+f++;this.oldScroll={x:t.scrollLeft(),y:t.scrollTop()};this.waypoints={horizontal:{},vertical:{}};this.element[u]=this.id;c[this.id]=this;t.bind(y,function(){var t;if(!(e.didScroll||a)){e.didScroll=true;t=function(){e.doScroll();return e.didScroll=false};return r.setTimeout(t,n[m].settings.scrollThrottle)}});t.bind(p,function(){var t;if(!e.didResize){e.didResize=true;t=function(){n[m]("refresh");return e.didResize=false};return r.setTimeout(t,n[m].settings.resizeThrottle)}})}t.prototype.doScroll=function(){var t,e=this;t={horizontal:{newScroll:this.$element.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.$element.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};if(a&&(!t.vertical.oldScroll||!t.vertical.newScroll)){n[m]("refresh")}n.each(t,function(t,r){var i,o,l;l=[];o=r.newScroll>r.oldScroll;i=o?r.forward:r.backward;n.each(e.waypoints[t],function(t,e){var n,i;if(r.oldScroll<(n=e.offset)&&n<=r.newScroll){return l.push(e)}else if(r.newScroll<(i=e.offset)&&i<=r.oldScroll){return l.push(e)}});l.sort(function(t,e){return t.offset-e.offset});if(!o){l.reverse()}return n.each(l,function(t,e){if(e.options.continuous||t===l.length-1){return e.trigger([i])}})});return this.oldScroll={x:t.horizontal.newScroll,y:t.vertical.newScroll}};t.prototype.refresh=function(){var t,e,r,i=this;r=n.isWindow(this.element);e=this.$element.offset();this.doScroll();t={horizontal:{contextOffset:r?0:e.left,contextScroll:r?0:this.oldScroll.x,contextDimension:this.$element.width(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:r?0:e.top,contextScroll:r?0:this.oldScroll.y,contextDimension:r?n[m]("viewportHeight"):this.$element.height(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};return n.each(t,function(t,e){return n.each(i.waypoints[t],function(t,r){var i,o,l,s,f;i=r.options.offset;l=r.offset;o=n.isWindow(r.element)?0:r.$element.offset()[e.offsetProp];if(n.isFunction(i)){i=i.apply(r.element)}else if(typeof i==="string"){i=parseFloat(i);if(r.options.offset.indexOf("%")>-1){i=Math.ceil(e.contextDimension*i/100)}}r.offset=o-e.contextOffset+e.contextScroll-i;if(r.options.onlyOnScroll&&l!=null||!r.enabled){return}if(l!==null&&l<(s=e.oldScroll)&&s<=r.offset){return r.trigger([e.backward])}else if(l!==null&&l>(f=e.oldScroll)&&f>=r.offset){return r.trigger([e.forward])}else if(l===null&&e.oldScroll>=r.offset){return r.trigger([e.forward])}})})};t.prototype.checkEmpty=function(){if(n.isEmptyObject(this.waypoints.horizontal)&&n.isEmptyObject(this.waypoints.vertical)){this.$element.unbind([p,y].join(" "));return delete c[this.id]}};return t}();l=function(){function t(t,e,r){var i,o;if(r.offset==="bottom-in-view"){r.offset=function(){var t;t=n[m]("viewportHeight");if(!n.isWindow(e.element)){t=e.$element.height()}return t-n(this).outerHeight()}}this.$element=t;this.element=t[0];this.axis=r.horizontal?"horizontal":"vertical";this.callback=r.handler;this.context=e;this.enabled=r.enabled;this.id="waypoints"+v++;this.offset=null;this.options=r;e.waypoints[this.axis][this.id]=this;s[this.axis][this.id]=this;i=(o=this.element[w])!=null?o:[];i.push(this.id);this.element[w]=i}t.prototype.trigger=function(t){if(!this.enabled){return}if(this.callback!=null){this.callback.apply(this.element,t)}if(this.options.triggerOnce){return this.destroy()}};t.prototype.disable=function(){return this.enabled=false};t.prototype.enable=function(){this.context.refresh();return this.enabled=true};t.prototype.destroy=function(){delete s[this.axis][this.id];delete this.context.waypoints[this.axis][this.id];return this.context.checkEmpty()};t.getWaypointsByElement=function(t){var e,r;r=t[w];if(!r){return[]}e=n.extend({},s.horizontal,s.vertical);return n.map(r,function(t){return e[t]})};return t}();d={init:function(t,e){var r;e=n.extend({},n.fn[g].defaults,e);if((r=e.handler)==null){e.handler=t}this.each(function(){var t,r,i,s;t=n(this);i=(s=e.context)!=null?s:n.fn[g].defaults.context;if(!n.isWindow(i)){i=t.closest(i)}i=n(i);r=c[i[0][u]];if(!r){r=new o(i)}return new l(t,r,e)});n[m]("refresh");return this},disable:function(){return d._invoke.call(this,"disable")},enable:function(){return d._invoke.call(this,"enable")},destroy:function(){return d._invoke.call(this,"destroy")},prev:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(e>0){return t.push(n[e-1])}})},next:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(et.oldScroll.y})},left:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset<=t.oldScroll.x})},right:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset>t.oldScroll.x})},enable:function(){return h._invoke("enable")},disable:function(){return h._invoke("disable")},destroy:function(){return h._invoke("destroy")},extendFn:function(t,e){return d[t]=e},_invoke:function(t){var e;e=n.extend({},s.vertical,s.horizontal);return n.each(e,function(e,n){n[t]();return true})},_filter:function(t,e,r){var i,o;i=c[n(t)[0][u]];if(!i){return[]}o=[];n.each(i.waypoints[e],function(t,e){if(r(i,e)){return o.push(e)}});o.sort(function(t,e){return t.offset-e.offset});return n.map(o,function(t){return t.element})}};n[m]=function(){var t,n;n=arguments[0],t=2<=arguments.length?e.call(arguments,1):[];if(h[n]){return h[n].apply(null,t)}else{return h.aggregate.call(null,n)}};n[m].settings={resizeThrottle:100,scrollThrottle:30};return i.on("load.waypoints",function(){return n[m]("refresh")})})}).call(this); \ No newline at end of file diff --git a/app/assets/stylesheets/_about.scss b/app/assets/stylesheets/_about.scss new file mode 100644 index 0000000..45c471a --- /dev/null +++ b/app/assets/stylesheets/_about.scss @@ -0,0 +1,109 @@ +.workshop-images { + @include display(flex); + @include flex-wrap(wrap); + + li { + overflow: hidden; + width: 50%; + + @include media($medium-screen) { + width: 25%; + } + } + + img { + float: left; + width: 100%; + } +} + +.empowering-women, +.promoting-diversity { + @include media($medium-screen) { + @include span-columns(5.5); + padding-top: 2em; + } +} + +.promoting-diversity { + @include media($medium-screen) { + @include omega; + @include shift(1); + } +} + +.code-of-conduct { + border-bottom: $light-border; + border-top: $light-border; + clear: both; + + .wrap { + @include media($medium-screen) { + @include column-count(2); + @include column-gap(5.75em); + } + + p { + display: inline-block; + } + } +} + +$contact-types: ( + twitter: image-url("twitter.svg"), + github: image-url("github.svg"), + email: image-url("email.svg"), + googlegroup: image-url("google-group.svg") +); + +%internal-section-grid { + ul { + @include media($medium-screen) { + @include display(flex); + } + } + + li { + margin-bottom: 1.25em; + + @include media($medium-screen) { + @include span-columns(3 of 12); + } + } +} + +.contact { + @extend %internal-section-grid; + padding-bottom: 0; + + li { + @include media($medium-screen) { + padding-top: 3em; + position: relative; + } + + &:before { + @include size(1.25em); + background-position: center center; + background-repeat: no-repeat; + background-size: 100%; + content: ""; + display: inline-block; + + @include media($medium-screen) { + @include position(absolute, 0 null null 0); + @include size(2.25em); + } + } + + @each $type, $background-url in $contact-types { + &.contact-#{$type}:before { + background-image: #{$background-url}; + } + } + } +} + +.links-out { + @extend %internal-section-grid; +} diff --git a/app/assets/stylesheets/_class-levels.scss b/app/assets/stylesheets/_class-levels.scss new file mode 100644 index 0000000..fbadb23 --- /dev/null +++ b/app/assets/stylesheets/_class-levels.scss @@ -0,0 +1,78 @@ +.class-levels { + main { + @include media($small-screen) { + margin: inherit auto; + max-width: $small-screen; + } + } + + h3 { + color: $secondary-link-color; + margin: 1em inherit; + } +} + +.levels { + position: relative; + + &::before { + @include size(2em); + background-color: $white; + border: 3px $gray-light solid; + border-radius: 50%; + color: darken($gray-light, 25); + content: "1"; + display: inline-block; + font-family: $sans-serif; + font-weight: $bold-font-weight; + line-height: 2em; + margin-bottom: 1em; + text-align: center; + + @include media($medium-screen) { + @include position(absolute, 2.65em null null -4em); + margin-bottom: 0; + } + } + + &::after { + @include media($medium-screen) { + @include position(absolute, 4em null null -2.85em); + @include size(.15em 100%); + background: lighten($gray-light, 5); + content: ""; + display: block; + z-index: $z-under; + } + } + + &:last-of-type::after { + display: none; + } + + li { + display: inline-block; + + &::before { + @include margin(null 0.5em null -0.75em); + @include size(0.25em); + background-color: $gray-light; + border-radius: 50%; + content: ""; + display: inline-block; + vertical-align: middle; + } + } +} + +$levels: "level-1", "level-2", "level-3", "level-4"; + +@each $level in $levels { + $number: index($levels, $level); + + .#{$level}::before { + border-color: lighten($gray, 50 / $number); + color: lighten($gray, 50 / $number); + content: "#{$number}"; + } +} diff --git a/app/assets/stylesheets/_donate.scss b/app/assets/stylesheets/_donate.scss new file mode 100644 index 0000000..04139c9 --- /dev/null +++ b/app/assets/stylesheets/_donate.scss @@ -0,0 +1,104 @@ +.donate, +.thanks { + background: image-url('workshop2.jpg') center top no-repeat; + + @include media($medium-screen) { + background-image: image-url('workshop2_2x.jpg'); + background-position: center -3vh; + background-size: 100% auto; + position: relative; + } + + @include media($large-screen) { + background-position: center -4vh; + } + + &::before { + @include media($small-screen) { + @include size(100% 30vh); + @include position(absolute,17vh null null 0); + background: linear-gradient(rgba($white, 0), $white); + content: ""; + display: block; + } + } + + &::after { + @include media($small-screen) { + @include position(absolute, 47vh null 0 0); + background: $white; + content: ""; + display: block; + width: 100%; + z-index: $z-under; + } + } + + h1 { + margin-bottom: 0.5em; + } + + main { + background-color: $white; + margin-bottom: 3rem; + margin-top: 19rem; + max-width: 100%; + position: relative; + + @include media($small-screen) { + background-color: transparent; + margin: 32vh auto 5rem; + max-width: em(640); + padding: 0.25em 2em; + } + + &::before { + @include position(absolute, -16rem null null 0); + @include size(100% 16rem); + background: linear-gradient(rgba($white, 0), $white); + content: ""; + display: block; + + @include media($small-screen) { + display: none; + } + } + } + + .section-title { + margin-bottom: 2em; + } +} + +.organization-cta { + margin-bottom: 3em; + + li { + @include media($small-screen) { + display: inline-block; + } + } + + .cta-prospectus { + @extend %link-callout; + } + + .cta-email { + @include button-callout($secondary-button-color); + margin: 1em inherit; + + @include media($small-screen) { + margin: 0 1em 0 inherit; + } + } +} + +.thanks main a { + @extend %link-callout; +} + +.thanks-heart { + animation: heart 2s $ease-in-out-quad infinite; + max-width: 0.5em; + vertical-align: top; +} diff --git a/app/assets/stylesheets/_global.scss b/app/assets/stylesheets/_global.scss new file mode 100644 index 0000000..806440c --- /dev/null +++ b/app/assets/stylesheets/_global.scss @@ -0,0 +1,71 @@ +html, body { + @include size(100%); +} + +main { + @include outer-container; + padding: 0 $side-padding; +} + +section { + padding: 3em 0; +} + +footer { + @include outer-container; + border-top: $light-border; + margin-top: 2em; + padding: 2em $side-padding; + + @include media($large-screen) { + padding: 2em 0; + } + + a { + color: darken($gray-light, 20); + + &:hover { + color: $orange; + } + } + + p { + color: darken($gray-light, 15); + font-family: $sans-serif; + margin-bottom: 0.5em; + + @include media($medium-screen) { + &:first-of-type { + float: left; + } + + &:last-of-type { + float: right; + } + } + } +} + +.button { + @extend %button; +} + +.caption { + color: darken($gray-light, 25); + font-size: $small-font-size; + + a { + color: darken($gray-light, 35); + + &:hover { + color: $gray; + } + } +} + +.section-title { + color: $blue; + font-weight: $thin-font-weight; + margin-bottom: 1em; + text-transform: uppercase; +} diff --git a/app/assets/stylesheets/_internal-pages.scss b/app/assets/stylesheets/_internal-pages.scss new file mode 100644 index 0000000..6306c05 --- /dev/null +++ b/app/assets/stylesheets/_internal-pages.scss @@ -0,0 +1,14 @@ +.internal { + h1 { + font-family: $serif; + font-size: em(60); + font-weight: $base-font-weight; + margin-top: .75em; + } + + main { + @include media($large-screen-up) { + padding-bottom: 4em; + } + } +} diff --git a/app/assets/stylesheets/_landing.scss b/app/assets/stylesheets/_landing.scss new file mode 100644 index 0000000..1b2458c --- /dev/null +++ b/app/assets/stylesheets/_landing.scss @@ -0,0 +1,325 @@ +.landing { + .header-bar { + @include media($medium-screen) { + display: none; + } + } + + .nav { + @include media($medium-screen) { + @include outer-container; + @include position(absolute, null 0 null 0); + @include size(100% auto); + background: transparent; + margin: 0 auto; + overflow: visible; + } + } + + .pages { + @include media($medium-screen) { + @include shift(1); + @include span-columns(10); + @include transform(translateY(0)); + border-bottom: $nav-blue-border; + top: 0; + max-width: inherit; + } + + li { + @include media($medium-screen) { + @include span-columns(2 of 10); + border: 0; + display: inline-block; + padding: $nav-large-padding; + } + } + } +} + +.hero { + @include radial-gradient(50% 114%, + circle cover, + lighten($blue, 10) 21%, + $blue 80%); + padding: 3em $side-padding; + text-align: center; + + @include media($medium-screen) { + padding: 6em $side-padding 4em; + position: relative; + } + + &::before { + @include media($medium-screen) { + @include position(fixed, 0 0 0 0); + @include size(1px 100vh); + background: $blue-light; + content: ""; + display: block; + margin: 0 auto; + z-index: $z-under; + } + } + + .boston { + background: image-url("boston.png") no-repeat center top; + background-size: 100%; + margin-bottom: 1em; + position: relative; + + @include media($medium-screen) { + @include outer-container; + background-image: image-url("boston_2x.png"); + background-position: center 4em; + background-size: 90%; + padding: 7em 0 1% 0; + } + + img { + max-width: 3rem; + + @include media($medium-screen) { + max-width: 5rem; + } + } + + .gem { + display: block; + margin: 0 auto; + max-width: 5em; + + @include media($medium-screen) { + @include position(absolute, 40% 0px null 0px); + max-width: 7em; + } + } + } + + .title { + color: $blue-light; + font-size: $large-font-size; + letter-spacing: 5px; + margin-top: 1em; + text-shadow: $text-shadow; + text-transform: uppercase; + + @include media($medium-screen) { + font-size: 2em; + margin-top: 1.5em; + } + + span { + color: $white; + display: block; + font-family: $serif; + font-size: em(40); + line-height: 1em; + margin-top: .2em; + + @include media($medium-screen) { + margin-top: .125em; + } + } + } + + .register-link { + @extend %link-callout; + color: $yellow; + + &:after { + content: "\BB"; + margin-left: .35em; + } + + &:hover { + color: lighten($yellow, 20); + } + } +} + +.upcoming, +.mailing-list { + background: $white; + padding: 3em $side-padding; +} + +.upcoming { + border-bottom: 3px $blue-light solid; + margin: auto; + + @include media($medium-screen) { + @include display(flex); + @include padding(null 2.5em); + border: 3px $blue-light solid; + border-radius: $base-border-radius; + margin: 20vh auto; + max-width: 44em; + } + + iframe { + width: 100%; + + @include media($medium-screen) { + max-width: em(300); + order: 2; + } + } +} + +.workshop { + margin: 1.5em auto 0 auto; + max-width: $small-screen; + + @include media($medium-screen) { + @include flex(1); + margin-right: 2em; + margin-top: 0; + order: 1; + } + + p { + margin: 0; + + &:first-of-type { + font-weight: $bold-font-weight; + } + } + + .register-link { + margin-top: 2em; + } +} + +.mailing-list { + margin: 0 auto; + max-width: $small-screen; + + @include media($medium-screen) { + @include outer-container; + @include padding(5em null); + border-top: 1px $blue-light solid; + } + + label { + color: $gray-light; + } + + input[type="submit"] { + @include button-callout($secondary-button-color); + } + + .text { + @include media($medium-screen) { + @include span-columns(4 of 10); + } + } + + #mc_embed_signup { + @include media($medium-screen) { + @include shift(1 of 10); + @include span-columns(5 of 10); + } + } +} + +.summary { + background-color: $gray-light; + background-image: image-url("reflection.png"), image-url("workshop.png"); + background-position: center -10px, right bottom; + background-repeat: repeat-x, no-repeat; + background-size: auto, cover; + + @include media($medium-screen) { + background-image: image-url("reflection_2x.png"), + image-url("workshop_2x.png"); + background-position: center -10px, center 25%; + background-size: 70%, cover; + } + + .wrap { + padding: 1em $side-padding; + + @include media($medium-screen) { + @include outer-container; + padding: 5em $side-padding 1em; + } + } + + .text { + margin: 0 auto 3em auto; + max-width: $small-screen; + + @include media($medium-screen) { + @include span-columns(5); + } + + .section-title { + color: $white; + margin-top: 1em; + } + + .to-about { + @extend %link-callout; + } + } + + .media { + @include media($medium-screen) { + @include shift(1); + @include span-columns(6); + } + + .video { + @include size(100% 15em); + border: 2px $base-border-color solid; + border-radius: $base-border-radius; + overflow: hidden; + position: relative; + + @include media($medium-screen) { + height: 20em; + } + + &:after { + @include position(absolute, 0 0 0 0); + @include size(6em); + @include transition; + background: image-url("play.png") 56% 51% no-repeat; + border: 4px $white solid; + border-radius: 50%; + content: ""; + display: block; + margin: auto; + } + + &:hover { + cursor: pointer; + + &:after { + background-color: $blue; + } + } + + iframe { + @include size(100%); + border: 0; + display: none; + } + + &.show-video { + &:after { + display: none; + } + + iframe { + display: block; + } + } + } + + .caption { + display: none; + } + } +} diff --git a/app/assets/stylesheets/_nav.scss b/app/assets/stylesheets/_nav.scss new file mode 100644 index 0000000..65c1433 --- /dev/null +++ b/app/assets/stylesheets/_nav.scss @@ -0,0 +1,161 @@ +header { + @include media($medium-screen-up) { + @include linear-gradient(90deg, lighten(saturate($blue, 50), 15), $blue); + } + + .outer-container { + @include media($medium-screen-up) { + @include align-items(center); + @include display(flex); + @include justify-content(space-between); + @include outer-container; + position: relative; + + &:after { + display: none; + } + } + } +} + +.header-bar { + @include media($medium-screen-down) { + @include clearfix; + background: $blue; + border-bottom: $nav-blue-border; + position: relative; + z-index: $z-header; + } +} + +.logo { + color: $blue-light; + display: inline-block; + font-family: $header-font-family; + font-weight: $base-font-weight; + letter-spacing: 3px; + padding: .65em $side-padding; + position: relative; + text-shadow: $text-shadow; + text-transform: uppercase; + + @include media($medium-screen-up) { + font-size: $large-font-size; + padding: .5em $side-padding .5em 2em; + } + + &:hover { + @include media($medium-screen-up) { + color: $base-accent-color; + + &:before { + @include animation(wiggle .25s linear); + } + } + } + + &:active, &:focus { + @include media($medium-screen-up) { + color: $white; + } + } + + &:before { + @include media($medium-screen-up) { + @include position(absolute, .5em null null 0); + @include size(1.5em); + background: image-url("gem.svg") no-repeat center center; + background-size: 100%; + content: ""; + display: inline-block; + } + } + + span { + color: $white; + font-weight: $bold-font-weight; + } +} + +.nav-toggle { + @extend %nav-links; + display: block; + float: right; + font-size: $small-font-size; + font-weight: $bold-font-weight; + padding: 1rem 1rem; + text-transform: uppercase; + + @include media($medium-screen-up) { + display: none; + } +} + +.nav { + @include transition(all .25s linear); + overflow: hidden; + z-index: $z-nav; + + @include media($medium-screen-down) { + @include position(absolute, 0px null null null); + @include size(100% 0%); + background: $blue; + } + + &.is-open { + @include media($medium-screen-down) { + @include size(100%); + } + } + + .pages { + @extend %vertical-align; + margin: 0 auto; + + @include media($medium-screen-down) { + max-width: 20em; + } + + @include media($medium-screen-up) { + @include transform(none); + } + + a { + @extend %nav-links; + display: block; + font-weight: $base-font-weight; + padding: $nav-large-padding; + text-align: center; + + @include media($medium-screen-up) { + padding: .75em 1.25em; + } + } + + li { + border-bottom: $nav-blue-border; + + @include media($medium-screen-up) { + border-bottom: 0; + display: inline-block; + } + + &.page-home { + @include media($medium-screen-up) { + display: none; + } + } + + &:last-of-type { + border: 0; + } + } + } +} + +body.about .page-about, +body.donate .page-donate, +body.resources .page-resources { + border-bottom: 4px $base-accent-color solid; +} + diff --git a/app/assets/stylesheets/_normalize.scss b/app/assets/stylesheets/_normalize.scss new file mode 100644 index 0000000..73abb76 --- /dev/null +++ b/app/assets/stylesheets/_normalize.scss @@ -0,0 +1,375 @@ +/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/* + * Prevents modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for `hidden` attribute not present in IE 8/9. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/* + * 1. Sets default font family to sans-serif. + * 2. Prevents iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Removes default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/* + * Addresses `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/* + * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, + * Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; +} + +/* + * Addresses styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/* + * Addresses styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + + +/* + * Corrects font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * Sets consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/* + * Addresses inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/* + * Prevents `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/* + * Removes border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/* + * Corrects overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/* + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Corrects font family not being inherited in all browsers. + * 2. Corrects font size not being inherited in all browsers. + * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/* + * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/* + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Corrects inability to style clickable `input` types in iOS. + * 3. Improves usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/* + * Re-set default cursor for disabled elements. + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to `content-box` in IE 8/9. + * 2. Removes excess padding in IE 8/9. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE 8/9. + * 2. Improves readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/app/assets/stylesheets/_resources.scss b/app/assets/stylesheets/_resources.scss new file mode 100644 index 0000000..b26603e --- /dev/null +++ b/app/assets/stylesheets/_resources.scss @@ -0,0 +1,63 @@ +.resources { + h1 { + margin-bottom: 1em; + } + + section { + padding-top: 0; + + @include media($medium-screen-up) { + padding-bottom: 5em; + } + + ul { + list-style-type: circle; + + @include media($medium-screen-down) { + margin-left: 1em; + } + } + } +} + +.sticky-wrapper { + display: none; + + @include media($medium-screen-up) { + display: inline-block; + float: left; + width: 25%; + } +} + +.quick-find { + padding-right: 5%; + + a { + @extend %link-callout; + color: $secondary-link-color; + + &:hover { + color: $gray; + } + + &.active { + color: $gray; + } + } + + ul { + li:first-of-type a { + padding-top: 0; + } + } +} + +.resources-content { + @include media($medium-screen-up) { + border-left: $light-border; + float: right; + padding-left: 10%; + width: 75%; + } +} diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index e701338..5b9dee6 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -1,8 +1,14 @@ -@charset "utf-8"; - -@import "normalize-rails"; -@import "bourbon"; +@import "bourbon/bourbon"; @import "base/grid-settings"; -@import "neat"; +@import "neat/neat"; +@import "normalize"; @import "base/base"; -@import "refills/flashes"; + +@import "global"; +@import "nav"; +@import "landing"; +@import "internal-pages"; +@import "about"; +@import "donate"; +@import "resources"; +@import "class-levels" diff --git a/app/assets/stylesheets/base/_animations.scss b/app/assets/stylesheets/base/_animations.scss new file mode 100644 index 0000000..186cf63 --- /dev/null +++ b/app/assets/stylesheets/base/_animations.scss @@ -0,0 +1,23 @@ +@include keyframes(wiggle) { + 0% { + transform: rotate(-15deg); + } + 80% { + transform: rotate(10deg); + } + 100% { + transform: rotate(0deg); + } +} + +@include keyframes(heart) { + 0% { + transform: translateY(0) scale(0.95); + } + 50% { + transform: translateY(-7px) scale(1); + } + 100% { + transform: translateY(0) scale(0.95); + } +} diff --git a/app/assets/stylesheets/base/_base.scss b/app/assets/stylesheets/base/_base.scss index ddc350d..a32a1f8 100644 --- a/app/assets/stylesheets/base/_base.scss +++ b/app/assets/stylesheets/base/_base.scss @@ -1,15 +1,25 @@ -// Bitters 1.0.0 +// Bitters v0.10.0 // http://bitters.bourbon.io -// Copyright 2013-2015 thoughtbot, inc. -// MIT License -@import "variables"; +// Variables +@import 'variables'; -// Neat Settings -- uncomment if using Neat -- must be imported before Neat -// @import "grid-settings"; +// Typography and Elements +@import 'typography'; +@import 'forms'; +@import 'tables'; +@import 'lists'; +@import 'buttons'; +@import 'animations'; + +// Extends +@import 'extends/button'; +@import 'extends/clearfix'; +@import 'extends/hide-text'; +@import 'extends/vertical-align'; +@import 'extends/links'; + +// Mixins +@import 'mixins/flash'; +@import 'mixins/buttons'; -@import "buttons"; -@import "forms"; -@import "lists"; -@import "tables"; -@import "typography"; diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss index f902f60..3319426 100644 --- a/app/assets/stylesheets/base/_buttons.scss +++ b/app/assets/stylesheets/base/_buttons.scss @@ -1,31 +1,10 @@ -#{$all-button-inputs}, -button { +button, +input[type="submit"] { + @extend %button; @include appearance(none); - -webkit-font-smoothing: antialiased; - background-color: $action-color; - border-radius: $base-border-radius; border: none; - color: #fff; cursor: pointer; - display: inline-block; - font-family: $base-font-family; - font-size: $base-font-size; - font-weight: 600; - line-height: 1; - padding: 0.75em 1em; - text-decoration: none; user-select: none; vertical-align: middle; white-space: nowrap; - - &:hover, - &:focus { - background-color: darken($action-color, 15%); - color: #fff; - } - - &:disabled { - cursor: not-allowed; - opacity: 0.5; - } } diff --git a/app/assets/stylesheets/base/_flashes.scss b/app/assets/stylesheets/base/_flashes.scss new file mode 100644 index 0000000..7eeddf1 --- /dev/null +++ b/app/assets/stylesheets/base/_flashes.scss @@ -0,0 +1,15 @@ +%flash-alert { + @include flash($alert-color); +} + +%flash-error { + @include flash($error-color); +} + +%flash-notice { + @include flash($notice-color); +} + +%flash-success { + @include flash($success-color); +} diff --git a/app/assets/stylesheets/base/_forms.scss b/app/assets/stylesheets/base/_forms.scss index db4a796..e710c8f 100644 --- a/app/assets/stylesheets/base/_forms.scss +++ b/app/assets/stylesheets/base/_forms.scss @@ -1,23 +1,24 @@ fieldset { - background-color: lighten($base-border-color, 10%); - border: $base-border; - margin: 0 0 $small-spacing; - padding: $base-spacing; + background: lighten($base-border-color, 10); + border: 1px solid $base-border-color; + margin: 0 0 ($base-line-height / 2) 0; + padding: $base-line-height; } input, label, select { display: block; - font-family: $base-font-family; - font-size: $base-font-size; + font-family: $form-font-family; + font-size: $form-font-size; } label { - font-weight: 600; - margin-bottom: $small-spacing / 2; + font-size: $small-font-size; + font-weight: bold; + margin-bottom: $base-line-height / 4; - &.required::after { + &.required:after { content: "*"; } @@ -26,28 +27,27 @@ label { } } +textarea, #{$all-text-inputs}, -select[multiple=multiple], -textarea { - background-color: $base-background-color; - border: $base-border; - border-radius: $base-border-radius; +select[multiple=multiple] { + @include box-sizing(border-box); + @include transition(border-color); + background-color: white; + border-radius: $form-border-radius; + border: 1px solid $form-border-color; box-shadow: $form-box-shadow; - box-sizing: border-box; - font-family: $base-font-family; - font-size: $base-font-size; - margin-bottom: $base-spacing / 2; - padding: $base-spacing / 3; - transition: border-color; + font-family: $form-font-family; + font-size: $form-font-size; + margin-bottom: $base-line-height / 2; + padding: ($base-line-height / 3) ($base-line-height / 3); width: 100%; &:hover { - border-color: darken($base-border-color, 10%); + border-color: $form-border-color-hover; } &:focus { - border-color: $action-color; - box-shadow: $form-box-shadow-focus; + border-color: $form-border-color-focus; outline: none; } } @@ -60,19 +60,19 @@ input[type="search"] { @include appearance(none); } -input[type="checkbox"], -input[type="radio"] { +input[type="checkbox"], input[type="radio"] { display: inline; - margin-right: $small-spacing / 2; + margin-right: $base-line-height / 4; } input[type="file"] { - padding-bottom: $small-spacing; + margin-bottom: $base-line-height / 2; + padding-bottom: ($base-line-height / 3); width: 100%; } select { - margin-bottom: $base-spacing; - max-width: 100%; width: auto; + max-width: 100%; + margin-bottom: $base-line-height; } diff --git a/app/assets/stylesheets/base/_grid-settings.scss b/app/assets/stylesheets/base/_grid-settings.scss index c42bdaf..a3764da 100644 --- a/app/assets/stylesheets/base/_grid-settings.scss +++ b/app/assets/stylesheets/base/_grid-settings.scss @@ -1,14 +1,16 @@ -@import "neat-helpers"; // or "../neat/neat-helpers" when not in Rails +@import '../neat/neat-helpers'; // or '../neat/neat-helpers' when not in Rails // Neat Overrides // $column: 90px; // $gutter: 30px; // $grid-columns: 12; -// $max-width: em(1088); +$max-width: rem(1088); // Neat Breakpoints -$medium-screen: em(640); -$large-screen: em(860); +$small-screen: em(540); +$medium-screen: em(860); +$large-screen: em(1100); -$medium-screen-up: new-breakpoint(min-width $medium-screen 4); -$large-screen-up: new-breakpoint(min-width $large-screen 8); +$medium-screen-down: new-breakpoint(max-width $medium-screen 4); +$medium-screen-up: new-breakpoint(min-width $medium-screen 12); +$large-screen-up: new-breakpoint(min-width $large-screen 12); diff --git a/app/assets/stylesheets/base/_lists.scss b/app/assets/stylesheets/base/_lists.scss index c989d90..4915bac 100644 --- a/app/assets/stylesheets/base/_lists.scss +++ b/app/assets/stylesheets/base/_lists.scss @@ -1,28 +1,27 @@ -ul, -ol { - list-style-type: none; +ul, ol { margin: 0; padding: 0; + list-style-type: none; &%default-ul { list-style-type: disc; - margin-bottom: $small-spacing; - padding-left: $base-spacing; + margin-bottom: $base-line-height / 2; + padding-left: $base-line-height; } &%default-ol { list-style-type: decimal; - margin-bottom: $small-spacing; - padding-left: $base-spacing; + margin-bottom: $base-line-height / 2; + padding-left: $base-line-height; } } dl { - margin-bottom: $small-spacing; + margin-bottom: $base-line-height / 2; dt { font-weight: bold; - margin-top: $small-spacing; + margin-top: $base-line-height / 2; } dd { diff --git a/app/assets/stylesheets/base/_tables.scss b/app/assets/stylesheets/base/_tables.scss index 8c5cc31..31e78f4 100644 --- a/app/assets/stylesheets/base/_tables.scss +++ b/app/assets/stylesheets/base/_tables.scss @@ -1,25 +1,22 @@ table { - @include font-feature-settings("kern", "liga", "tnum"); border-collapse: collapse; - margin: $small-spacing 0; + margin: ($base-line-height / 2) 0; table-layout: fixed; width: 100%; } th { border-bottom: 1px solid darken($base-border-color, 15%); - font-weight: 600; - padding: $small-spacing 0; + font-weight: bold; + padding: ($base-line-height / 2) 0; text-align: left; } td { - border-bottom: $base-border; - padding: $small-spacing 0; + border-bottom: 1px solid $base-border-color; + padding: ($base-line-height / 2) 0; } -tr, -td, -th { +tr, td, th { vertical-align: middle; } diff --git a/app/assets/stylesheets/base/_typography.scss b/app/assets/stylesheets/base/_typography.scss index 358559c..30858cc 100644 --- a/app/assets/stylesheets/base/_typography.scss +++ b/app/assets/stylesheets/base/_typography.scss @@ -1,55 +1,72 @@ body { - @include font-feature-settings("kern", "liga", "pnum"); -webkit-font-smoothing: antialiased; + background-color: $base-background-color; color: $base-font-color; font-family: $base-font-family; font-size: $base-font-size; - line-height: $base-line-height; + line-height: $unitless-line-height; } -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: $heading-font-family; - font-size: $base-font-size; - line-height: $heading-line-height; - margin: 0 0 $small-spacing; +h1, h2, h3, h4, h5, h6 { + font-family: $header-font-family; + line-height: $header-line-height; + margin: 0; + text-rendering: optimizeLegibility; // Fix the character spacing for headings +} + +h1 { + font-size: em(30); // 30px +} + +h2 { + font-size: em(26); // 26px } p { - margin: 0 0 $small-spacing; + margin: 0 0 1.5rem; } a { - color: $action-color; + @include transition(color 0.1s linear); + color: $base-link-color; + font-weight: $bold-font-weight; text-decoration: none; - transition: color 0.1s linear; - &:active, - &:focus, &:hover { - color: darken($action-color, 15%); + color: $hover-link-color; } - &:active, - &:focus { + &:active, &:focus { + color: $hover-link-color; outline: none; } } hr { - border-bottom: $base-border; + border-bottom: 1px solid $base-border-color; border-left: none; border-right: none; border-top: none; - margin: $base-spacing 0; + margin: $base-line-height 0; } -img, -picture { +img { margin: 0; max-width: 100%; } + +blockquote { + border-left: 2px solid $base-border-color; + color: lighten($base-font-color, 15); + margin: $base-line-height 0; + padding-left: $base-line-height / 2; +} + +cite { + color: lighten($base-font-color, 25); + font-style: italic; + + &:before { + content: '\2014 \00A0'; + } +} diff --git a/app/assets/stylesheets/base/_variables.scss b/app/assets/stylesheets/base/_variables.scss index 7594759..d4e24cc 100644 --- a/app/assets/stylesheets/base/_variables.scss +++ b/app/assets/stylesheets/base/_variables.scss @@ -1,35 +1,73 @@ // Typography -$base-font-family: $helvetica; -$heading-font-family: $base-font-family; +/////////////////////////////// +$sans-serif: "proxima-nova", $helvetica; +$serif: "adobe-garamond-pro", $georgia; +$base-font-family: $serif; +$header-font-family: $sans-serif; +$base-button-font: $sans-serif; -// Font Sizes -$base-font-size: 1em; +// Sizes +/////////////////////////////// +$base-font-size: rem(18); +$small-font-size: rem(12); +$large-font-size: rem(20); -// Line height -$base-line-height: 1.5; -$heading-line-height: 1.2; +$base-line-height: $base-font-size * 1.35; +$unitless-line-height: $base-line-height / ($base-line-height * 0 + 1); // Strip units from line-height: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#Prefer_unitless_numbers_for_line-height_values +$header-line-height: 1.25em; +$base-border-radius: em(8); -// Other Sizes -$base-border-radius: 3px; -$base-spacing: $base-line-height * 1em; -$small-spacing: $base-spacing / 2; -$base-z-index: 0; +$base-font-weight: 500; +$thin-font-weight: 300; +$bold-font-weight: 700; + +$side-padding: 12px; +$nav-large-padding: 1.5em 1em; // Colors -$blue: #477dca; -$dark-gray: #333; -$medium-gray: #999; -$light-gray: #ddd; +/////////////////////////////// +$blue: #488CDA; +$blue-dark: #3C7DCB; +$blue-light: #CCE3FF; + +$gray: #515151; +$gray-light: #E9E9E9; + +$orange: #FF5F05; +$white: white; +$yellow: #FFD609; -// Font Colors -$base-background-color: #fff; -$base-font-color: $dark-gray; -$action-color: $blue; +$base-background-color: $white; +$base-font-color: $gray; +$base-accent-color: $yellow; +$base-link-color: darken($blue, 15); +$hover-link-color: $orange; +$secondary-link-color: darken($gray-light, 10); +$base-button-color: darken($yellow, 2); +$hover-button-color: darken($base-button-color, 3); +$secondary-button-color: lighten($gray, 45); -// Border -$base-border-color: $light-gray; -$base-border: 1px solid $base-border-color; +$text-shadow: 0 1px 4px rgba(0,0,0,0.10); + +// Borders +/////////////////////////////// +$base-border-color: $gray-light; +$nav-blue-border: 2px lighten($blue, 5) solid; +$light-border: 1px $gray-light solid; // Forms -$form-box-shadow: inset 0 1px 3px rgba(#000, 0.06); -$form-box-shadow-focus: $form-box-shadow, 0 0 5px adjust-color($action-color, $lightness: -5%, $alpha: -0.3); +/////////////////////////////// +$form-border-color: $base-border-color; +$form-border-color-hover: darken($base-border-color, 10); +$form-border-color-focus: $blue; +$form-border-radius: $base-border-radius; +$form-box-shadow: inset 0 1px 3px rgba(0,0,0,0.06); +$form-font-size: $base-font-size; +$form-font-family: $base-button-font; + +// Z-index +/////////////////////////////// +$z-under: -1; +$z-header: 10; +$z-nav: $z-header - 1; +$z-rbb-title: 1; diff --git a/app/assets/stylesheets/base/extends/_button.scss b/app/assets/stylesheets/base/extends/_button.scss new file mode 100644 index 0000000..035b6e0 --- /dev/null +++ b/app/assets/stylesheets/base/extends/_button.scss @@ -0,0 +1,23 @@ +%button { + -webkit-font-smoothing: antialiased; + background-color: $base-button-color; + border-bottom: 2px darken($base-button-color, 5) solid; + border-top: 3px transparent solid; + border-radius: $base-border-radius; + color: $white; + display: inline-block; + font-family: $base-button-font; + font-size: $large-font-size; + font-weight: $bold-font-weight; + line-height: 1; + padding: .75em 1em; + text-decoration: none; + transition: all 0.25s $ease-in-out-quad; + + &:hover { + background-color: $orange; + border-bottom-color: transparent; + border-top-color: darken($orange, 8); + color: $white; + } +} diff --git a/app/assets/stylesheets/base/extends/_clearfix.scss b/app/assets/stylesheets/base/extends/_clearfix.scss new file mode 100644 index 0000000..22ac179 --- /dev/null +++ b/app/assets/stylesheets/base/extends/_clearfix.scss @@ -0,0 +1,3 @@ +%clearfix { + @include clearfix; +} diff --git a/app/assets/stylesheets/base/extends/_hide-text.scss b/app/assets/stylesheets/base/extends/_hide-text.scss new file mode 100644 index 0000000..a41a123 --- /dev/null +++ b/app/assets/stylesheets/base/extends/_hide-text.scss @@ -0,0 +1,3 @@ +%hide-text { + @include hide-text; +} diff --git a/app/assets/stylesheets/base/extends/_links.scss b/app/assets/stylesheets/base/extends/_links.scss new file mode 100644 index 0000000..2896f17 --- /dev/null +++ b/app/assets/stylesheets/base/extends/_links.scss @@ -0,0 +1,18 @@ +%nav-links { + color: $blue-light; + font-family: $sans-serif; + + &:hover { + color: white; + } + + &:active, &:focus { + color: $blue-light; + } +} + +%link-callout { + display: inline-block; + font-family: $sans-serif; + font-weight: $bold-font-weight; +} diff --git a/app/assets/stylesheets/base/extends/_vertical-align.scss b/app/assets/stylesheets/base/extends/_vertical-align.scss new file mode 100644 index 0000000..691b27a --- /dev/null +++ b/app/assets/stylesheets/base/extends/_vertical-align.scss @@ -0,0 +1,5 @@ +%vertical-align { + @include transform(translateY(-50%)); + position: relative; + top: 50%; +} diff --git a/app/assets/stylesheets/base/mixins/_buttons.scss b/app/assets/stylesheets/base/mixins/_buttons.scss new file mode 100644 index 0000000..8671f08 --- /dev/null +++ b/app/assets/stylesheets/base/mixins/_buttons.scss @@ -0,0 +1,11 @@ +@mixin button-callout($color) { + @extend %button; + background-color: $color; + border-bottom-color: darken($color, 8); + + &:hover { + background-color: $orange; + border-bottom-color: transparent; + } +} + diff --git a/app/assets/stylesheets/base/mixins/_flash.scss b/app/assets/stylesheets/base/mixins/_flash.scss new file mode 100644 index 0000000..55afd61 --- /dev/null +++ b/app/assets/stylesheets/base/mixins/_flash.scss @@ -0,0 +1,15 @@ +@mixin flash($color) { + background: $color; + color: darken($color, 60); + font-weight: bold; + margin-bottom: $base-line-height / 2; + padding: $base-line-height / 2; + + a { + color: darken($color, 70); + + &:hover { + color: darken($color, 90); + } + } +} diff --git a/app/assets/stylesheets/bourbon/_bourbon-deprecated-upcoming.scss b/app/assets/stylesheets/bourbon/_bourbon-deprecated-upcoming.scss new file mode 100644 index 0000000..f946b3b --- /dev/null +++ b/app/assets/stylesheets/bourbon/_bourbon-deprecated-upcoming.scss @@ -0,0 +1,8 @@ +//************************************************************************// +// These mixins/functions are deprecated +// They will be removed in the next MAJOR version release +//************************************************************************// +@mixin inline-block { + display: inline-block; + @warn "inline-block mixin is deprecated and will be removed in the next major version release"; +} diff --git a/app/assets/stylesheets/bourbon/_bourbon.scss b/app/assets/stylesheets/bourbon/_bourbon.scss new file mode 100644 index 0000000..eea6e21 --- /dev/null +++ b/app/assets/stylesheets/bourbon/_bourbon.scss @@ -0,0 +1,79 @@ +// Settings +@import "settings/prefixer"; +@import "settings/px-to-em"; +@import "settings/asset-pipeline"; + +// Custom Helpers +@import "helpers/convert-units"; +@import "helpers/gradient-positions-parser"; +@import "helpers/is-num"; +@import "helpers/linear-angle-parser"; +@import "helpers/linear-gradient-parser"; +@import "helpers/linear-positions-parser"; +@import "helpers/linear-side-corner-parser"; +@import "helpers/radial-arg-parser"; +@import "helpers/radial-positions-parser"; +@import "helpers/radial-gradient-parser"; +@import "helpers/render-gradients"; +@import "helpers/shape-size-stripper"; +@import "helpers/str-to-num"; + +// Custom Functions +@import "functions/assign"; +@import "functions/color-lightness"; +@import "functions/flex-grid"; +@import "functions/golden-ratio"; +@import "functions/grid-width"; +@import "functions/modular-scale"; +@import "functions/px-to-em"; +@import "functions/px-to-rem"; +@import "functions/strip-units"; +@import "functions/tint-shade"; +@import "functions/transition-property-name"; +@import "functions/unpack"; + +// CSS3 Mixins +@import "css3/animation"; +@import "css3/appearance"; +@import "css3/backface-visibility"; +@import "css3/background"; +@import "css3/background-image"; +@import "css3/border-image"; +@import "css3/border-radius"; +@import "css3/box-sizing"; +@import "css3/calc"; +@import "css3/columns"; +@import "css3/filter"; +@import "css3/flex-box"; +@import "css3/font-face"; +@import "css3/font-feature-settings"; +@import "css3/hyphens"; +@import "css3/hidpi-media-query"; +@import "css3/image-rendering"; +@import "css3/keyframes"; +@import "css3/linear-gradient"; +@import "css3/perspective"; +@import "css3/radial-gradient"; +@import "css3/transform"; +@import "css3/transition"; +@import "css3/user-select"; +@import "css3/placeholder"; + +// Addons & other mixins +@import "addons/button"; +@import "addons/clearfix"; +@import "addons/directional-values"; +@import "addons/ellipsis"; +@import "addons/font-family"; +@import "addons/hide-text"; +@import "addons/html5-input-types"; +@import "addons/position"; +@import "addons/prefixer"; +@import "addons/retina-image"; +@import "addons/size"; +@import "addons/timing-functions"; +@import "addons/triangle"; +@import "addons/word-wrap"; + +// Soon to be deprecated Mixins +@import "bourbon-deprecated-upcoming"; diff --git a/app/assets/stylesheets/bourbon/addons/_button.scss b/app/assets/stylesheets/bourbon/addons/_button.scss new file mode 100644 index 0000000..14a89e4 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_button.scss @@ -0,0 +1,374 @@ +@mixin button ($style: simple, $base-color: #4294f0, $text-size: inherit, $padding: 7px 18px) { + + @if type-of($style) == string and type-of($base-color) == color { + @include buttonstyle($style, $base-color, $text-size, $padding); + } + + @if type-of($style) == string and type-of($base-color) == number { + $padding: $text-size; + $text-size: $base-color; + $base-color: #4294f0; + + @if $padding == inherit { + $padding: 7px 18px; + } + + @include buttonstyle($style, $base-color, $text-size, $padding); + } + + @if type-of($style) == color and type-of($base-color) == color { + $base-color: $style; + $style: simple; + @include buttonstyle($style, $base-color, $text-size, $padding); + } + + @if type-of($style) == color and type-of($base-color) == number { + $padding: $text-size; + $text-size: $base-color; + $base-color: $style; + $style: simple; + + @if $padding == inherit { + $padding: 7px 18px; + } + + @include buttonstyle($style, $base-color, $text-size, $padding); + } + + @if type-of($style) == number { + $padding: $base-color; + $text-size: $style; + $base-color: #4294f0; + $style: simple; + + @if $padding == #4294f0 { + $padding: 7px 18px; + } + + @include buttonstyle($style, $base-color, $text-size, $padding); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } +} + + +// Selector Style Button +//************************************************************************// +@mixin buttonstyle($type, $b-color, $t-size, $pad) { + // Grayscale button + @if $type == simple and $b-color == grayscale($b-color) { + @include simple($b-color, true, $t-size, $pad); + } + + @if $type == shiny and $b-color == grayscale($b-color) { + @include shiny($b-color, true, $t-size, $pad); + } + + @if $type == pill and $b-color == grayscale($b-color) { + @include pill($b-color, true, $t-size, $pad); + } + + @if $type == flat and $b-color == grayscale($b-color) { + @include flat($b-color, true, $t-size, $pad); + } + + // Colored button + @if $type == simple { + @include simple($b-color, false, $t-size, $pad); + } + + @else if $type == shiny { + @include shiny($b-color, false, $t-size, $pad); + } + + @else if $type == pill { + @include pill($b-color, false, $t-size, $pad); + } + + @else if $type == flat { + @include flat($b-color, false, $t-size, $pad); + } +} + + +// Simple Button +//************************************************************************// +@mixin simple($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { + $color: hsl(0, 0, 100%); + $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%); + $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%); + $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%); + $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%); + + @if is-light($base-color) { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border: grayscale($border); + $inset-shadow: grayscale($inset-shadow); + $stop-gradient: grayscale($stop-gradient); + $text-shadow: grayscale($text-shadow); + } + + border: 1px solid $border; + border-radius: 3px; + box-shadow: inset 0 1px 0 0 $inset-shadow; + color: $color; + display: inline-block; + font-size: $textsize; + font-weight: bold; + @include linear-gradient ($base-color, $stop-gradient); + padding: $padding; + text-decoration: none; + text-shadow: 0 1px 0 $text-shadow; + background-clip: padding-box; + + &:hover:not(:disabled) { + $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%); + $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%); + $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%); + + @if $grayscale == true { + $base-color-hover: grayscale($base-color-hover); + $inset-shadow-hover: grayscale($inset-shadow-hover); + $stop-gradient-hover: grayscale($stop-gradient-hover); + } + + box-shadow: inset 0 1px 0 0 $inset-shadow-hover; + cursor: pointer; + @include linear-gradient ($base-color-hover, $stop-gradient-hover); + } + + &:active:not(:disabled), + &:focus:not(:disabled) { + $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%); + $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%); + + @if $grayscale == true { + $border-active: grayscale($border-active); + $inset-shadow-active: grayscale($inset-shadow-active); + } + + border: 1px solid $border-active; + box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active; + } +} + + +// Shiny Button +//************************************************************************// +@mixin shiny($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { + $color: hsl(0, 0, 100%); + $border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81); + $border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122); + $fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46); + $inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12); + $second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33); + $text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114); + $third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48); + + @if is-light($base-color) { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border: grayscale($border); + $border-bottom: grayscale($border-bottom); + $fourth-stop: grayscale($fourth-stop); + $inset-shadow: grayscale($inset-shadow); + $second-stop: grayscale($second-stop); + $text-shadow: grayscale($text-shadow); + $third-stop: grayscale($third-stop); + } + + border: 1px solid $border; + border-bottom: 1px solid $border-bottom; + border-radius: 5px; + box-shadow: inset 0 1px 0 0 $inset-shadow; + color: $color; + display: inline-block; + font-size: $textsize; + font-weight: bold; + @include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%); + padding: $padding; + text-align: center; + text-decoration: none; + text-shadow: 0 -1px 1px $text-shadow; + + &:hover:not(:disabled) { + $first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18); + $second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51); + $third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66); + $fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63); + + @if $grayscale == true { + $first-stop-hover: grayscale($first-stop-hover); + $second-stop-hover: grayscale($second-stop-hover); + $third-stop-hover: grayscale($third-stop-hover); + $fourth-stop-hover: grayscale($fourth-stop-hover); + } + + cursor: pointer; + @include linear-gradient(top, $first-stop-hover 0%, + $second-stop-hover 50%, + $third-stop-hover 50%, + $fourth-stop-hover 100%); + } + + &:active:not(:disabled), + &:focus:not(:disabled) { + $inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122); + + @if $grayscale == true { + $inset-shadow-active: grayscale($inset-shadow-active); + } + + box-shadow: inset 0 0 20px 0 $inset-shadow-active; + } +} + + +// Pill Button +//************************************************************************// +@mixin pill($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { + $color: hsl(0, 0, 100%); + $border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%); + $border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%); + $border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%); + $inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%); + $stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%); + $text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%); + + @if is-light($base-color) { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border-bottom: grayscale($border-bottom); + $border-sides: grayscale($border-sides); + $border-top: grayscale($border-top); + $inset-shadow: grayscale($inset-shadow); + $stop-gradient: grayscale($stop-gradient); + $text-shadow: grayscale($text-shadow); + } + + border: 1px solid $border-top; + border-color: $border-top $border-sides $border-bottom; + border-radius: 16px; + box-shadow: inset 0 1px 0 0 $inset-shadow; + color: $color; + display: inline-block; + font-size: $textsize; + font-weight: normal; + line-height: 1; + @include linear-gradient ($base-color, $stop-gradient); + padding: $padding; + text-align: center; + text-decoration: none; + text-shadow: 0 -1px 1px $text-shadow; + background-clip: padding-box; + + &:hover:not(:disabled) { + $base-color-hover: adjust-color($base-color, $lightness: -4.5%); + $border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%); + $border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%); + $border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%); + $inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%); + $stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%); + $text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%); + + @if $grayscale == true { + $base-color-hover: grayscale($base-color-hover); + $border-bottom: grayscale($border-bottom); + $border-sides: grayscale($border-sides); + $border-top: grayscale($border-top); + $inset-shadow-hover: grayscale($inset-shadow-hover); + $stop-gradient-hover: grayscale($stop-gradient-hover); + $text-shadow-hover: grayscale($text-shadow-hover); + } + + border: 1px solid $border-top; + border-color: $border-top $border-sides $border-bottom; + box-shadow: inset 0 1px 0 0 $inset-shadow-hover; + cursor: pointer; + @include linear-gradient ($base-color-hover, $stop-gradient-hover); + text-shadow: 0 -1px 1px $text-shadow-hover; + background-clip: padding-box; + } + + &:active:not(:disabled), + &:focus:not(:disabled) { + $active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%); + $border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%); + $border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%); + $inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%); + $text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%); + + @if $grayscale == true { + $active-color: grayscale($active-color); + $border-active: grayscale($border-active); + $border-bottom-active: grayscale($border-bottom-active); + $inset-shadow-active: grayscale($inset-shadow-active); + $text-shadow-active: grayscale($text-shadow-active); + } + + background: $active-color; + border: 1px solid $border-active; + border-bottom: 1px solid $border-bottom-active; + box-shadow: inset 0 0 6px 3px $inset-shadow-active; + text-shadow: 0 -1px 1px $text-shadow-active; + } +} + + + +// Flat Button +//************************************************************************// +@mixin flat($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { + $color: hsl(0, 0, 100%); + + @if is-light($base-color) { + $color: hsl(0, 0, 20%); + } + + background-color: $base-color; + border-radius: 3px; + border: none; + color: $color; + display: inline-block; + font-size: inherit; + font-weight: bold; + padding: 7px 18px; + text-decoration: none; + background-clip: padding-box; + + &:hover:not(:disabled){ + $base-color-hover: adjust-color($base-color, $saturation: 4%, $lightness: 5%); + + @if $grayscale == true { + $base-color-hover: grayscale($base-color-hover); + } + + background-color: $base-color-hover; + cursor: pointer; + } + + &:active:not(:disabled), + &:focus:not(:disabled) { + $base-color-active: adjust-color($base-color, $saturation: -4%, $lightness: -5%); + + @if $grayscale == true { + $base-color-active: grayscale($base-color-active); + } + + background-color: $base-color-active; + cursor: pointer; + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_clearfix.scss b/app/assets/stylesheets/bourbon/addons/_clearfix.scss new file mode 100644 index 0000000..783cfbc --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_clearfix.scss @@ -0,0 +1,23 @@ +// Modern micro clearfix provides an easy way to contain floats without adding additional markup. +// +// Example usage: +// +// // Contain all floats within .wrapper +// .wrapper { +// @include clearfix; +// .content, +// .sidebar { +// float : left; +// } +// } + +@mixin clearfix { + &:after { + content:""; + display:table; + clear:both; + } +} + +// Acknowledgements +// Beat *that* clearfix: [Thierry Koblentz](http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php) diff --git a/app/assets/stylesheets/bourbon/addons/_directional-values.scss b/app/assets/stylesheets/bourbon/addons/_directional-values.scss new file mode 100644 index 0000000..742f103 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_directional-values.scss @@ -0,0 +1,111 @@ +// directional-property mixins are shorthands +// for writing properties like the following +// +// @include margin(null 0 10px); +// ------ +// margin-right: 0; +// margin-bottom: 10px; +// margin-left: 0; +// +// - or - +// +// @include border-style(dotted null); +// ------ +// border-top-style: dotted; +// border-bottom-style: dotted; +// +// ------ +// +// Note: You can also use false instead of null + +@function collapse-directionals($vals) { + $output: null; + + $A: nth( $vals, 1 ); + $B: if( length($vals) < 2, $A, nth($vals, 2)); + $C: if( length($vals) < 3, $A, nth($vals, 3)); + $D: if( length($vals) < 2, $A, nth($vals, if( length($vals) < 4, 2, 4) )); + + @if $A == 0 { $A: 0 } + @if $B == 0 { $B: 0 } + @if $C == 0 { $C: 0 } + @if $D == 0 { $D: 0 } + + @if $A == $B and $A == $C and $A == $D { $output: $A } + @else if $A == $C and $B == $D { $output: $A $B } + @else if $B == $D { $output: $A $B $C } + @else { $output: $A $B $C $D } + + @return $output; +} + +@function contains-falsy($list) { + @each $item in $list { + @if not $item { + @return true; + } + } + + @return false; +} + +@mixin directional-property($pre, $suf, $vals) { + // Property Names + $top: $pre + "-top" + if($suf, "-#{$suf}", ""); + $bottom: $pre + "-bottom" + if($suf, "-#{$suf}", ""); + $left: $pre + "-left" + if($suf, "-#{$suf}", ""); + $right: $pre + "-right" + if($suf, "-#{$suf}", ""); + $all: $pre + if($suf, "-#{$suf}", ""); + + $vals: collapse-directionals($vals); + + @if contains-falsy($vals) { + @if nth($vals, 1) { #{$top}: nth($vals, 1); } + + @if length($vals) == 1 { + @if nth($vals, 1) { #{$right}: nth($vals, 1); } + } @else { + @if nth($vals, 2) { #{$right}: nth($vals, 2); } + } + + // prop: top/bottom right/left + @if length($vals) == 2 { + @if nth($vals, 1) { #{$bottom}: nth($vals, 1); } + @if nth($vals, 2) { #{$left}: nth($vals, 2); } + + // prop: top right/left bottom + } @else if length($vals) == 3 { + @if nth($vals, 3) { #{$bottom}: nth($vals, 3); } + @if nth($vals, 2) { #{$left}: nth($vals, 2); } + + // prop: top right bottom left + } @else if length($vals) == 4 { + @if nth($vals, 3) { #{$bottom}: nth($vals, 3); } + @if nth($vals, 4) { #{$left}: nth($vals, 4); } + } + + // prop: top/right/bottom/left + } @else { + #{$all}: $vals; + } +} + +@mixin margin($vals...) { + @include directional-property(margin, false, $vals...); +} + +@mixin padding($vals...) { + @include directional-property(padding, false, $vals...); +} + +@mixin border-style($vals...) { + @include directional-property(border, style, $vals...); +} + +@mixin border-color($vals...) { + @include directional-property(border, color, $vals...); +} + +@mixin border-width($vals...) { + @include directional-property(border, width, $vals...); +} diff --git a/app/assets/stylesheets/bourbon/addons/_ellipsis.scss b/app/assets/stylesheets/bourbon/addons/_ellipsis.scss new file mode 100644 index 0000000..a8ea2a4 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_ellipsis.scss @@ -0,0 +1,7 @@ +@mixin ellipsis($width: 100%) { + display: inline-block; + max-width: $width; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/app/assets/stylesheets/bourbon/addons/_font-family.scss b/app/assets/stylesheets/bourbon/addons/_font-family.scss new file mode 100644 index 0000000..31f5d9c --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_font-family.scss @@ -0,0 +1,5 @@ +$georgia: Georgia, Cambria, "Times New Roman", Times, serif; +$helvetica: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; +$lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif; +$monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace; +$verdana: Verdana, Geneva, sans-serif; diff --git a/app/assets/stylesheets/bourbon/addons/_hide-text.scss b/app/assets/stylesheets/bourbon/addons/_hide-text.scss new file mode 100644 index 0000000..fc79438 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_hide-text.scss @@ -0,0 +1,10 @@ +@mixin hide-text { + overflow: hidden; + + &:before { + content: ""; + display: block; + width: 0; + height: 100%; + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_html5-input-types.scss b/app/assets/stylesheets/bourbon/addons/_html5-input-types.scss new file mode 100644 index 0000000..9e9324a --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_html5-input-types.scss @@ -0,0 +1,86 @@ +//************************************************************************// +// Generate a variable ($all-text-inputs) with a list of all html5 +// input types that have a text-based input, excluding textarea. +// http://diveintohtml5.org/forms.html +//************************************************************************// +$inputs-list: 'input[type="email"]', + 'input[type="number"]', + 'input[type="password"]', + 'input[type="search"]', + 'input[type="tel"]', + 'input[type="text"]', + 'input[type="url"]', + + // Webkit & Gecko may change the display of these in the future + 'input[type="color"]', + 'input[type="date"]', + 'input[type="datetime"]', + 'input[type="datetime-local"]', + 'input[type="month"]', + 'input[type="time"]', + 'input[type="week"]'; + +// Bare inputs +//************************************************************************// +$all-text-inputs: assign-inputs($inputs-list); + +// Hover Pseudo-class +//************************************************************************// +$all-text-inputs-hover: assign-inputs($inputs-list, hover); + +// Focus Pseudo-class +//************************************************************************// +$all-text-inputs-focus: assign-inputs($inputs-list, focus); + + + +// You must use interpolation on the variable: +// #{$all-text-inputs} +// #{$all-text-inputs-hover} +// #{$all-text-inputs-focus} + +// Example +//************************************************************************// +// #{$all-text-inputs}, textarea { +// border: 1px solid red; +// } + + + +//************************************************************************// +// Generate a variable ($all-button-inputs) with a list of all html5 +// input types that have a button-based input, excluding button. +//************************************************************************// +$inputs-button-list: 'input[type="button"]', + 'input[type="reset"]', + 'input[type="submit"]'; + +// Bare inputs +//************************************************************************// +$all-button-inputs: assign-inputs($inputs-button-list); + +// Hover Pseudo-class +//************************************************************************// +$all-button-inputs-hover: assign-inputs($inputs-button-list, hover); + +// Focus Pseudo-class +//************************************************************************// +$all-button-inputs-focus: assign-inputs($inputs-button-list, focus); + +// Active Pseudo-class +//************************************************************************// +$all-button-inputs-active: assign-inputs($inputs-button-list, active); + + + +// You must use interpolation on the variable: +// #{$all-button-inputs} +// #{$all-button-inputs-hover} +// #{$all-button-inputs-focus} +// #{$all-button-inputs-active} + +// Example +//************************************************************************// +// #{$all-button-inputs}, button { +// border: 1px solid red; +// } diff --git a/app/assets/stylesheets/bourbon/addons/_position.scss b/app/assets/stylesheets/bourbon/addons/_position.scss new file mode 100644 index 0000000..7de7518 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_position.scss @@ -0,0 +1,32 @@ +@mixin position ($position: relative, $coordinates: null null null null) { + + @if type-of($position) == list { + $coordinates: $position; + $position: relative; + } + + $coordinates: unpack($coordinates); + + $top: nth($coordinates, 1); + $right: nth($coordinates, 2); + $bottom: nth($coordinates, 3); + $left: nth($coordinates, 4); + + position: $position; + + @if ($top and $top == auto) or (type-of($top) == number) { + top: $top; + } + + @if ($right and $right == auto) or (type-of($right) == number) { + right: $right; + } + + @if ($bottom and $bottom == auto) or (type-of($bottom) == number) { + bottom: $bottom; + } + + @if ($left and $left == auto) or (type-of($left) == number) { + left: $left; + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_prefixer.scss b/app/assets/stylesheets/bourbon/addons/_prefixer.scss new file mode 100644 index 0000000..c32f502 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_prefixer.scss @@ -0,0 +1,45 @@ +//************************************************************************// +// Example: @include prefixer(border-radius, $radii, webkit ms spec); +//************************************************************************// +// Variables located in /settings/_prefixer.scss + +@mixin prefixer ($property, $value, $prefixes) { + @each $prefix in $prefixes { + @if $prefix == webkit { + @if $prefix-for-webkit { + -webkit-#{$property}: $value; + } + } + @else if $prefix == moz { + @if $prefix-for-mozilla { + -moz-#{$property}: $value; + } + } + @else if $prefix == ms { + @if $prefix-for-microsoft { + -ms-#{$property}: $value; + } + } + @else if $prefix == o { + @if $prefix-for-opera { + -o-#{$property}: $value; + } + } + @else if $prefix == spec { + @if $prefix-for-spec { + #{$property}: $value; + } + } + @else { + @warn "Unrecognized prefix: #{$prefix}"; + } + } +} + +@mixin disable-prefix-for-all() { + $prefix-for-webkit: false !global; + $prefix-for-mozilla: false !global; + $prefix-for-microsoft: false !global; + $prefix-for-opera: false !global; + $prefix-for-spec: false !global; +} diff --git a/app/assets/stylesheets/bourbon/addons/_retina-image.scss b/app/assets/stylesheets/bourbon/addons/_retina-image.scss new file mode 100644 index 0000000..3995c19 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_retina-image.scss @@ -0,0 +1,31 @@ +@mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) { + @if $asset-pipeline { + background-image: image-url("#{$filename}.#{$extension}"); + } + @else { + background-image: url("#{$filename}.#{$extension}"); + } + + @include hidpi { + @if $asset-pipeline { + @if $retina-filename { + background-image: image-url("#{$retina-filename}.#{$extension}"); + } + @else { + background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}"); + } + } + + @else { + @if $retina-filename { + background-image: url("#{$retina-filename}.#{$extension}"); + } + @else { + background-image: url("#{$filename}#{$retina-suffix}.#{$extension}"); + } + } + + background-size: $background-size; + + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_size.scss b/app/assets/stylesheets/bourbon/addons/_size.scss new file mode 100644 index 0000000..a865379 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_size.scss @@ -0,0 +1,16 @@ +@mixin size($size) { + $height: nth($size, 1); + $width: $height; + + @if length($size) > 1 { + $height: nth($size, 2); + } + + @if $height == auto or (type-of($height) == number and not unitless($height)) { + height: $height; + } + + @if $width == auto or (type-of($width) == number and not unitless($width)) { + width: $width; + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_timing-functions.scss b/app/assets/stylesheets/bourbon/addons/_timing-functions.scss new file mode 100644 index 0000000..5ecc6f9 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_timing-functions.scss @@ -0,0 +1,32 @@ +// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie) +// Timing functions are the same as demo'ed here: http://jqueryui.com/resources/demos/effect/easing.html + +// EASE IN +$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); +$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); +$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); +$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); +$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715); +$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); +$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); +$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); + +// EASE OUT +$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); +$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000); +$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000); +$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000); +$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000); +$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000); +$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000); +$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); + +// EASE IN OUT +$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); +$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000); +$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000); +$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000); +$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); +$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000); +$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); +$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); diff --git a/app/assets/stylesheets/bourbon/addons/_triangle.scss b/app/assets/stylesheets/bourbon/addons/_triangle.scss new file mode 100644 index 0000000..573954e --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_triangle.scss @@ -0,0 +1,83 @@ +@mixin triangle ($size, $color, $direction) { + height: 0; + width: 0; + + $width: nth($size, 1); + $height: nth($size, length($size)); + + $foreground-color: nth($color, 1); + $background-color: if(length($color) == 2, nth($color, 2), transparent); + + @if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) { + + $width: $width / 2; + $height: if(length($size) > 1, $height, $height/2); + + @if $direction == up { + border-left: $width solid $background-color; + border-right: $width solid $background-color; + border-bottom: $height solid $foreground-color; + + } @else if $direction == right { + border-top: $width solid $background-color; + border-bottom: $width solid $background-color; + border-left: $height solid $foreground-color; + + } @else if $direction == down { + border-left: $width solid $background-color; + border-right: $width solid $background-color; + border-top: $height solid $foreground-color; + + } @else if $direction == left { + border-top: $width solid $background-color; + border-bottom: $width solid $background-color; + border-right: $height solid $foreground-color; + } + } + + @else if ($direction == up-right) or ($direction == up-left) { + border-top: $height solid $foreground-color; + + @if $direction == up-right { + border-left: $width solid $background-color; + + } @else if $direction == up-left { + border-right: $width solid $background-color; + } + } + + @else if ($direction == down-right) or ($direction == down-left) { + border-bottom: $height solid $foreground-color; + + @if $direction == down-right { + border-left: $width solid $background-color; + + } @else if $direction == down-left { + border-right: $width solid $background-color; + } + } + + @else if ($direction == inset-up) { + border-width: $height $width; + border-style: solid; + border-color: $background-color $background-color $foreground-color; + } + + @else if ($direction == inset-down) { + border-width: $height $width; + border-style: solid; + border-color: $foreground-color $background-color $background-color; + } + + @else if ($direction == inset-right) { + border-width: $width $height; + border-style: solid; + border-color: $background-color $background-color $background-color $foreground-color; + } + + @else if ($direction == inset-left) { + border-width: $width $height; + border-style: solid; + border-color: $background-color $foreground-color $background-color $background-color; + } +} diff --git a/app/assets/stylesheets/bourbon/addons/_word-wrap.scss b/app/assets/stylesheets/bourbon/addons/_word-wrap.scss new file mode 100644 index 0000000..9734a59 --- /dev/null +++ b/app/assets/stylesheets/bourbon/addons/_word-wrap.scss @@ -0,0 +1,8 @@ +@mixin word-wrap($wrap: break-word) { + word-wrap: $wrap; + + @if $wrap == break-word { + overflow-wrap: break-word; + word-break: break-all; + } +} diff --git a/app/assets/stylesheets/bourbon/css3/_animation.scss b/app/assets/stylesheets/bourbon/css3/_animation.scss new file mode 100644 index 0000000..08c3dbf --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_animation.scss @@ -0,0 +1,52 @@ +// http://www.w3.org/TR/css3-animations/#the-animation-name-property- +// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties. + +// Official animation shorthand property. +@mixin animation ($animations...) { + @include prefixer(animation, $animations, webkit moz spec); +} + +// Individual Animation Properties +@mixin animation-name ($names...) { + @include prefixer(animation-name, $names, webkit moz spec); +} + + +@mixin animation-duration ($times...) { + @include prefixer(animation-duration, $times, webkit moz spec); +} + + +@mixin animation-timing-function ($motions...) { +// ease | linear | ease-in | ease-out | ease-in-out + @include prefixer(animation-timing-function, $motions, webkit moz spec); +} + + +@mixin animation-iteration-count ($values...) { +// infinite | + @include prefixer(animation-iteration-count, $values, webkit moz spec); +} + + +@mixin animation-direction ($directions...) { +// normal | alternate + @include prefixer(animation-direction, $directions, webkit moz spec); +} + + +@mixin animation-play-state ($states...) { +// running | paused + @include prefixer(animation-play-state, $states, webkit moz spec); +} + + +@mixin animation-delay ($times...) { + @include prefixer(animation-delay, $times, webkit moz spec); +} + + +@mixin animation-fill-mode ($modes...) { +// none | forwards | backwards | both + @include prefixer(animation-fill-mode, $modes, webkit moz spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_appearance.scss b/app/assets/stylesheets/bourbon/css3/_appearance.scss new file mode 100644 index 0000000..3eb16e4 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_appearance.scss @@ -0,0 +1,3 @@ +@mixin appearance ($value) { + @include prefixer(appearance, $value, webkit moz ms o spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_backface-visibility.scss b/app/assets/stylesheets/bourbon/css3/_backface-visibility.scss new file mode 100644 index 0000000..1161fe6 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_backface-visibility.scss @@ -0,0 +1,6 @@ +//************************************************************************// +// Backface-visibility mixin +//************************************************************************// +@mixin backface-visibility($visibility) { + @include prefixer(backface-visibility, $visibility, webkit spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_background-image.scss b/app/assets/stylesheets/bourbon/css3/_background-image.scss new file mode 100644 index 0000000..6abe88b --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_background-image.scss @@ -0,0 +1,42 @@ +//************************************************************************// +// Background-image property for adding multiple background images with +// gradients, or for stringing multiple gradients together. +//************************************************************************// + +@mixin background-image($images...) { + $webkit-images: (); + $spec-images: (); + + @each $image in $images { + $webkit-image: (); + $spec-image: (); + + @if (type-of($image) == string) { + $url-str: str-slice($image, 0, 3); + $gradient-type: str-slice($image, 0, 6); + + @if $url-str == "url" { + $webkit-image: $image; + $spec-image: $image; + } + + @else if $gradient-type == "linear" { + $gradients: _linear-gradient-parser($image); + $webkit-image: map-get($gradients, webkit-image); + $spec-image: map-get($gradients, spec-image); + } + + @else if $gradient-type == "radial" { + $gradients: _radial-gradient-parser($image); + $webkit-image: map-get($gradients, webkit-image); + $spec-image: map-get($gradients, spec-image); + } + } + + $webkit-images: append($webkit-images, $webkit-image, comma); + $spec-images: append($spec-images, $spec-image, comma); + } + + background-image: $webkit-images; + background-image: $spec-images; +} diff --git a/app/assets/stylesheets/bourbon/css3/_background.scss b/app/assets/stylesheets/bourbon/css3/_background.scss new file mode 100644 index 0000000..9bce930 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_background.scss @@ -0,0 +1,55 @@ +//************************************************************************// +// Background property for adding multiple backgrounds using shorthand +// notation. +//************************************************************************// + +@mixin background($backgrounds...) { + $webkit-backgrounds: (); + $spec-backgrounds: (); + + @each $background in $backgrounds { + $webkit-background: (); + $spec-background: (); + $background-type: type-of($background); + + @if $background-type == string or list { + $background-str: if($background-type == list, nth($background, 1), $background); + + $url-str: str-slice($background-str, 0, 3); + $gradient-type: str-slice($background-str, 0, 6); + + @if $url-str == "url" { + $webkit-background: $background; + $spec-background: $background; + } + + @else if $gradient-type == "linear" { + $gradients: _linear-gradient-parser("#{$background}"); + $webkit-background: map-get($gradients, webkit-image); + $spec-background: map-get($gradients, spec-image); + } + + @else if $gradient-type == "radial" { + $gradients: _radial-gradient-parser("#{$background}"); + $webkit-background: map-get($gradients, webkit-image); + $spec-background: map-get($gradients, spec-image); + } + + @else { + $webkit-background: $background; + $spec-background: $background; + } + } + + @else { + $webkit-background: $background; + $spec-background: $background; + } + + $webkit-backgrounds: append($webkit-backgrounds, $webkit-background, comma); + $spec-backgrounds: append($spec-backgrounds, $spec-background, comma); + } + + background: $webkit-backgrounds; + background: $spec-backgrounds; +} diff --git a/app/assets/stylesheets/bourbon/css3/_border-image.scss b/app/assets/stylesheets/bourbon/css3/_border-image.scss new file mode 100644 index 0000000..e338c2d --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_border-image.scss @@ -0,0 +1,59 @@ +@mixin border-image($borders...) { + $webkit-borders: (); + $spec-borders: (); + + @each $border in $borders { + $webkit-border: (); + $spec-border: (); + $border-type: type-of($border); + + @if $border-type == string or list { + $border-str: if($border-type == list, nth($border, 1), $border); + + $url-str: str-slice($border-str, 0, 3); + $gradient-type: str-slice($border-str, 0, 6); + + @if $url-str == "url" { + $webkit-border: $border; + $spec-border: $border; + } + + @else if $gradient-type == "linear" { + $gradients: _linear-gradient-parser("#{$border}"); + $webkit-border: map-get($gradients, webkit-image); + $spec-border: map-get($gradients, spec-image); + } + + @else if $gradient-type == "radial" { + $gradients: _radial-gradient-parser("#{$border}"); + $webkit-border: map-get($gradients, webkit-image); + $spec-border: map-get($gradients, spec-image); + } + + @else { + $webkit-border: $border; + $spec-border: $border; + } + } + + @else { + $webkit-border: $border; + $spec-border: $border; + } + + $webkit-borders: append($webkit-borders, $webkit-border, comma); + $spec-borders: append($spec-borders, $spec-border, comma); + } + + -webkit-border-image: $webkit-borders; + border-image: $spec-borders; + border-style: solid; +} + +//Examples: +// @include border-image(url("image.png")); +// @include border-image(url("image.png") 20 stretch); +// @include border-image(linear-gradient(45deg, orange, yellow)); +// @include border-image(linear-gradient(45deg, orange, yellow) stretch); +// @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round); +// @include border-image(radial-gradient(top, cover, orange, yellow, orange)); diff --git a/app/assets/stylesheets/bourbon/css3/_border-radius.scss b/app/assets/stylesheets/bourbon/css3/_border-radius.scss new file mode 100644 index 0000000..7c17190 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_border-radius.scss @@ -0,0 +1,22 @@ +//************************************************************************// +// Shorthand Border-radius mixins +//************************************************************************// +@mixin border-top-radius($radii) { + @include prefixer(border-top-left-radius, $radii, spec); + @include prefixer(border-top-right-radius, $radii, spec); +} + +@mixin border-bottom-radius($radii) { + @include prefixer(border-bottom-left-radius, $radii, spec); + @include prefixer(border-bottom-right-radius, $radii, spec); +} + +@mixin border-left-radius($radii) { + @include prefixer(border-top-left-radius, $radii, spec); + @include prefixer(border-bottom-left-radius, $radii, spec); +} + +@mixin border-right-radius($radii) { + @include prefixer(border-top-right-radius, $radii, spec); + @include prefixer(border-bottom-right-radius, $radii, spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_box-sizing.scss b/app/assets/stylesheets/bourbon/css3/_box-sizing.scss new file mode 100644 index 0000000..f07e1d4 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_box-sizing.scss @@ -0,0 +1,4 @@ +@mixin box-sizing ($box) { +// content-box | border-box | inherit + @include prefixer(box-sizing, $box, webkit moz spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_calc.scss b/app/assets/stylesheets/bourbon/css3/_calc.scss new file mode 100644 index 0000000..94d7e4c --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_calc.scss @@ -0,0 +1,4 @@ +@mixin calc($property, $value) { + #{$property}: -webkit-calc(#{$value}); + #{$property}: calc(#{$value}); +} diff --git a/app/assets/stylesheets/bourbon/css3/_columns.scss b/app/assets/stylesheets/bourbon/css3/_columns.scss new file mode 100644 index 0000000..96f601c --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_columns.scss @@ -0,0 +1,47 @@ +@mixin columns($arg: auto) { +// || + @include prefixer(columns, $arg, webkit moz spec); +} + +@mixin column-count($int: auto) { +// auto || integer + @include prefixer(column-count, $int, webkit moz spec); +} + +@mixin column-gap($length: normal) { +// normal || length + @include prefixer(column-gap, $length, webkit moz spec); +} + +@mixin column-fill($arg: auto) { +// auto || length + @include prefixer(column-fill, $arg, webkit moz spec); +} + +@mixin column-rule($arg) { +// || || + @include prefixer(column-rule, $arg, webkit moz spec); +} + +@mixin column-rule-color($color) { + @include prefixer(column-rule-color, $color, webkit moz spec); +} + +@mixin column-rule-style($style: none) { +// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid + @include prefixer(column-rule-style, $style, webkit moz spec); +} + +@mixin column-rule-width ($width: none) { + @include prefixer(column-rule-width, $width, webkit moz spec); +} + +@mixin column-span($arg: none) { +// none || all + @include prefixer(column-span, $arg, webkit moz spec); +} + +@mixin column-width($length: auto) { +// auto || length + @include prefixer(column-width, $length, webkit moz spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_filter.scss b/app/assets/stylesheets/bourbon/css3/_filter.scss new file mode 100644 index 0000000..8560d77 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_filter.scss @@ -0,0 +1,5 @@ +@mixin filter($function: none) { + // [ + @include prefixer(perspective, $depth, webkit moz spec); +} + +@mixin perspective-origin($value: 50% 50%) { + @include prefixer(perspective-origin, $value, webkit moz spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_placeholder.scss b/app/assets/stylesheets/bourbon/css3/_placeholder.scss new file mode 100644 index 0000000..5682fd0 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_placeholder.scss @@ -0,0 +1,8 @@ +@mixin placeholder { + $placeholders: ":-webkit-input" ":-moz" "-moz" "-ms-input"; + @each $placeholder in $placeholders { + &:#{$placeholder}-placeholder { + @content; + } + } +} diff --git a/app/assets/stylesheets/bourbon/css3/_radial-gradient.scss b/app/assets/stylesheets/bourbon/css3/_radial-gradient.scss new file mode 100644 index 0000000..7a8c376 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_radial-gradient.scss @@ -0,0 +1,39 @@ +// Requires Sass 3.1+ +@mixin radial-gradient($G1, $G2, + $G3: null, $G4: null, + $G5: null, $G6: null, + $G7: null, $G8: null, + $G9: null, $G10: null, + $pos: null, + $shape-size: null, + $fallback: null) { + + $data: _radial-arg-parser($G1, $G2, $pos, $shape-size); + $G1: nth($data, 1); + $G2: nth($data, 2); + $pos: nth($data, 3); + $shape-size: nth($data, 4); + + $full: $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10; + + // Strip deprecated cover/contain for spec + $shape-size-spec: _shape-size-stripper($shape-size); + + // Set $G1 as the default fallback color + $first-color: nth($full, 1); + $fallback-color: nth($first-color, 1); + + @if (type-of($fallback) == color) or ($fallback == "transparent") { + $fallback-color: $fallback; + } + + // Add Commas and spaces + $shape-size: if($shape-size, '#{$shape-size}, ', null); + $pos: if($pos, '#{$pos}, ', null); + $pos-spec: if($pos, 'at #{$pos}', null); + $shape-size-spec: if(($shape-size-spec != ' ') and ($pos == null), '#{$shape-size-spec}, ', '#{$shape-size-spec} '); + + background-color: $fallback-color; + background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full})); + background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})"); +} diff --git a/app/assets/stylesheets/bourbon/css3/_transform.scss b/app/assets/stylesheets/bourbon/css3/_transform.scss new file mode 100644 index 0000000..8cc3596 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_transform.scss @@ -0,0 +1,15 @@ +@mixin transform($property: none) { +// none | + @include prefixer(transform, $property, webkit moz ms o spec); +} + +@mixin transform-origin($axes: 50%) { +// x-axis - left | center | right | length | % +// y-axis - top | center | bottom | length | % +// z-axis - length + @include prefixer(transform-origin, $axes, webkit moz ms o spec); +} + +@mixin transform-style ($style: flat) { + @include prefixer(transform-style, $style, webkit moz ms o spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_transition.scss b/app/assets/stylesheets/bourbon/css3/_transition.scss new file mode 100644 index 0000000..5ad4c0a --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_transition.scss @@ -0,0 +1,77 @@ +// Shorthand mixin. Supports multiple parentheses-deliminated values for each variable. +// Example: @include transition (all 2s ease-in-out); +// @include transition (opacity 1s ease-in 2s, width 2s ease-out); +// @include transition-property (transform, opacity); + +@mixin transition ($properties...) { + // Fix for vendor-prefix transform property + $needs-prefixes: false; + $webkit: (); + $moz: (); + $spec: (); + + // Create lists for vendor-prefixed transform + @each $list in $properties { + @if nth($list, 1) == "transform" { + $needs-prefixes: true; + $list1: -webkit-transform; + $list2: -moz-transform; + $list3: (); + + @each $var in $list { + $list3: join($list3, $var); + + @if $var != "transform" { + $list1: join($list1, $var); + $list2: join($list2, $var); + } + } + + $webkit: append($webkit, $list1); + $moz: append($moz, $list2); + $spec: append($spec, $list3); + } + + // Create lists for non-prefixed transition properties + @else { + $webkit: append($webkit, $list, comma); + $moz: append($moz, $list, comma); + $spec: append($spec, $list, comma); + } + } + + @if $needs-prefixes { + -webkit-transition: $webkit; + -moz-transition: $moz; + transition: $spec; + } + @else { + @if length($properties) >= 1 { + @include prefixer(transition, $properties, webkit moz spec); + } + + @else { + $properties: all 0.15s ease-out 0s; + @include prefixer(transition, $properties, webkit moz spec); + } + } +} + +@mixin transition-property ($properties...) { + -webkit-transition-property: transition-property-names($properties, 'webkit'); + -moz-transition-property: transition-property-names($properties, 'moz'); + transition-property: transition-property-names($properties, false); +} + +@mixin transition-duration ($times...) { + @include prefixer(transition-duration, $times, webkit moz spec); +} + +@mixin transition-timing-function ($motions...) { +// ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier() + @include prefixer(transition-timing-function, $motions, webkit moz spec); +} + +@mixin transition-delay ($times...) { + @include prefixer(transition-delay, $times, webkit moz spec); +} diff --git a/app/assets/stylesheets/bourbon/css3/_user-select.scss b/app/assets/stylesheets/bourbon/css3/_user-select.scss new file mode 100644 index 0000000..1380aa8 --- /dev/null +++ b/app/assets/stylesheets/bourbon/css3/_user-select.scss @@ -0,0 +1,3 @@ +@mixin user-select($arg: none) { + @include prefixer(user-select, $arg, webkit moz ms spec); +} diff --git a/app/assets/stylesheets/bourbon/functions/_assign.scss b/app/assets/stylesheets/bourbon/functions/_assign.scss new file mode 100644 index 0000000..9a1db93 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_assign.scss @@ -0,0 +1,11 @@ +@function assign-inputs($inputs, $pseudo: null) { + $list : (); + + @each $input in $inputs { + $input: unquote($input); + $input: if($pseudo, $input + ":" + $pseudo, $input); + $list: append($list, $input, comma); + } + + @return $list; +} \ No newline at end of file diff --git a/app/assets/stylesheets/bourbon/functions/_color-lightness.scss b/app/assets/stylesheets/bourbon/functions/_color-lightness.scss new file mode 100644 index 0000000..8c6df4e --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_color-lightness.scss @@ -0,0 +1,13 @@ +// Programatically determines whether a color is light or dark +// Returns a boolean +// More details here http://robots.thoughtbot.com/closer-look-color-lightness + +@function is-light($hex-color) { + $-local-red: red(rgba($hex-color, 1.0)); + $-local-green: green(rgba($hex-color, 1.0)); + $-local-blue: blue(rgba($hex-color, 1.0)); + + $-local-lightness: ($-local-red * 0.2126 + $-local-green * 0.7152 + $-local-blue * 0.0722) / 255; + + @return $-local-lightness > .6; +} diff --git a/app/assets/stylesheets/bourbon/functions/_flex-grid.scss b/app/assets/stylesheets/bourbon/functions/_flex-grid.scss new file mode 100644 index 0000000..3bbd866 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_flex-grid.scss @@ -0,0 +1,39 @@ +// Flexible grid +@function flex-grid($columns, $container-columns: $fg-max-columns) { + $width: $columns * $fg-column + ($columns - 1) * $fg-gutter; + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($width / $container-width); +} + +// Flexible gutter +@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) { + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($gutter / $container-width); +} + +// The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function. +// This function takes the fluid grid equation (target / context = result) and uses columns to help define each. +// +// The calculation presumes that your column structure will be missing the last gutter: +// +// -- column -- gutter -- column -- gutter -- column +// +// $fg-column: 60px; // Column Width +// $fg-gutter: 25px; // Gutter Width +// $fg-max-columns: 12; // Total Columns For Main Container +// +// div { +// width: flex-grid(4); // returns (315px / 995px) = 31.65829%; +// margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%; +// +// p { +// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; +// float: left; +// margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%; +// } +// +// blockquote { +// float: left; +// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; +// } +// } \ No newline at end of file diff --git a/app/assets/stylesheets/bourbon/functions/_golden-ratio.scss b/app/assets/stylesheets/bourbon/functions/_golden-ratio.scss new file mode 100644 index 0000000..463d14a --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_golden-ratio.scss @@ -0,0 +1,3 @@ +@function golden-ratio($value, $increment) { + @return modular-scale($value, $increment, $golden) +} diff --git a/app/assets/stylesheets/bourbon/functions/_grid-width.scss b/app/assets/stylesheets/bourbon/functions/_grid-width.scss new file mode 100644 index 0000000..8e63d83 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_grid-width.scss @@ -0,0 +1,13 @@ +@function grid-width($n) { + @return $n * $gw-column + ($n - 1) * $gw-gutter; +} + +// The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function. +// +// $gw-column: 100px; // Column Width +// $gw-gutter: 40px; // Gutter Width +// +// div { +// width: grid-width(4); // returns 520px; +// margin-left: $gw-gutter; // returns 40px; +// } diff --git a/app/assets/stylesheets/bourbon/functions/_modular-scale.scss b/app/assets/stylesheets/bourbon/functions/_modular-scale.scss new file mode 100644 index 0000000..afc59eb --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_modular-scale.scss @@ -0,0 +1,66 @@ +// Scaling Variables +$golden: 1.618; +$minor-second: 1.067; +$major-second: 1.125; +$minor-third: 1.2; +$major-third: 1.25; +$perfect-fourth: 1.333; +$augmented-fourth: 1.414; +$perfect-fifth: 1.5; +$minor-sixth: 1.6; +$major-sixth: 1.667; +$minor-seventh: 1.778; +$major-seventh: 1.875; +$octave: 2; +$major-tenth: 2.5; +$major-eleventh: 2.667; +$major-twelfth: 3; +$double-octave: 4; + +@function modular-scale($value, $increment, $ratio) { + $v1: nth($value, 1); + $v2: nth($value, length($value)); + $value: $v1; + + // scale $v2 to just above $v1 + @while $v2 > $v1 { + $v2: ($v2 / $ratio); // will be off-by-1 + } + @while $v2 < $v1 { + $v2: ($v2 * $ratio); // will fix off-by-1 + } + + // check AFTER scaling $v2 to prevent double-counting corner-case + $double-stranded: $v2 > $v1; + + @if $increment > 0 { + @for $i from 1 through $increment { + @if $double-stranded and ($v1 * $ratio) > $v2 { + $value: $v2; + $v2: ($v2 * $ratio); + } @else { + $v1: ($v1 * $ratio); + $value: $v1; + } + } + } + + @if $increment < 0 { + // adjust $v2 to just below $v1 + @if $double-stranded { + $v2: ($v2 / $ratio); + } + + @for $i from $increment through -1 { + @if $double-stranded and ($v1 / $ratio) < $v2 { + $value: $v2; + $v2: ($v2 / $ratio); + } @else { + $v1: ($v1 / $ratio); + $value: $v1; + } + } + } + + @return $value; +} diff --git a/app/assets/stylesheets/bourbon/functions/_px-to-em.scss b/app/assets/stylesheets/bourbon/functions/_px-to-em.scss new file mode 100644 index 0000000..4832245 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_px-to-em.scss @@ -0,0 +1,13 @@ +// Convert pixels to ems +// eg. for a relational value of 12px write em(12) when the parent is 16px +// if the parent is another value say 24px write em(12, 24) + +@function em($pxval, $base: $em-base) { + @if not unitless($pxval) { + $pxval: strip-units($pxval); + } + @if not unitless($base) { + $base: strip-units($base); + } + @return ($pxval / $base) * 1em; +} diff --git a/app/assets/stylesheets/bourbon/functions/_px-to-rem.scss b/app/assets/stylesheets/bourbon/functions/_px-to-rem.scss new file mode 100644 index 0000000..96b244e --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_px-to-rem.scss @@ -0,0 +1,15 @@ +// Convert pixels to rems +// eg. for a relational value of 12px write rem(12) +// Assumes $em-base is the font-size of + +@function rem($pxval) { + @if not unitless($pxval) { + $pxval: strip-units($pxval); + } + + $base: $em-base; + @if not unitless($base) { + $base: strip-units($base); + } + @return ($pxval / $base) * 1rem; +} diff --git a/app/assets/stylesheets/bourbon/functions/_strip-units.scss b/app/assets/stylesheets/bourbon/functions/_strip-units.scss new file mode 100644 index 0000000..6afc6e6 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_strip-units.scss @@ -0,0 +1,5 @@ +// Srtips the units from a value. e.g. 12px -> 12 + +@function strip-units($val) { + @return ($val / ($val * 0 + 1)); +} diff --git a/app/assets/stylesheets/bourbon/functions/_tint-shade.scss b/app/assets/stylesheets/bourbon/functions/_tint-shade.scss new file mode 100644 index 0000000..f717200 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_tint-shade.scss @@ -0,0 +1,9 @@ +// Add percentage of white to a color +@function tint($color, $percent){ + @return mix(white, $color, $percent); +} + +// Add percentage of black to a color +@function shade($color, $percent){ + @return mix(black, $color, $percent); +} diff --git a/app/assets/stylesheets/bourbon/functions/_transition-property-name.scss b/app/assets/stylesheets/bourbon/functions/_transition-property-name.scss new file mode 100644 index 0000000..54cd422 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_transition-property-name.scss @@ -0,0 +1,22 @@ +// Return vendor-prefixed property names if appropriate +// Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background +//************************************************************************// +@function transition-property-names($props, $vendor: false) { + $new-props: (); + + @each $prop in $props { + $new-props: append($new-props, transition-property-name($prop, $vendor), comma); + } + + @return $new-props; +} + +@function transition-property-name($prop, $vendor: false) { + // put other properties that need to be prefixed here aswell + @if $vendor and $prop == transform { + @return unquote('-'+$vendor+'-'+$prop); + } + @else { + @return $prop; + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/bourbon/functions/_unpack.scss b/app/assets/stylesheets/bourbon/functions/_unpack.scss new file mode 100644 index 0000000..3775963 --- /dev/null +++ b/app/assets/stylesheets/bourbon/functions/_unpack.scss @@ -0,0 +1,17 @@ +// Convert shorthand to the 4-value syntax + +@function unpack($shorthand) { + @if length($shorthand) == 1 { + @return nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1); + } + @else if length($shorthand) == 2 { + @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 1) nth($shorthand, 2); + } + @else if length($shorthand) == 3 { + @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 3) nth($shorthand, 2); + } + @else { + @return $shorthand; + } +} + diff --git a/app/assets/stylesheets/bourbon/helpers/_convert-units.scss b/app/assets/stylesheets/bourbon/helpers/_convert-units.scss new file mode 100644 index 0000000..3443db3 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_convert-units.scss @@ -0,0 +1,15 @@ +//************************************************************************// +// Helper function for str-to-num fn. +// Source: http://sassmeister.com/gist/9647408 +//************************************************************************// +@function _convert-units($number, $unit) { + $strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax', 'deg', 'rad', 'grad', 'turn'; + $units: 1px 1cm 1mm 1% 1ch 1pica 1in 1em 1rem 1pt 1pc 1ex 1vw 1vh 1vmin 1vmax, 1deg, 1rad, 1grad, 1turn; + $index: index($strings, $unit); + + @if not $index { + @warn "Unknown unit `#{$unit}`."; + @return false; + } + @return $number * nth($units, $index); +} diff --git a/app/assets/stylesheets/bourbon/helpers/_gradient-positions-parser.scss b/app/assets/stylesheets/bourbon/helpers/_gradient-positions-parser.scss new file mode 100644 index 0000000..07d30b6 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_gradient-positions-parser.scss @@ -0,0 +1,13 @@ +@function _gradient-positions-parser($gradient-type, $gradient-positions) { + @if $gradient-positions + and ($gradient-type == linear) + and (type-of($gradient-positions) != color) { + $gradient-positions: _linear-positions-parser($gradient-positions); + } + @else if $gradient-positions + and ($gradient-type == radial) + and (type-of($gradient-positions) != color) { + $gradient-positions: _radial-positions-parser($gradient-positions); + } + @return $gradient-positions; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_is-num.scss b/app/assets/stylesheets/bourbon/helpers/_is-num.scss new file mode 100644 index 0000000..71459e1 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_is-num.scss @@ -0,0 +1,8 @@ +//************************************************************************// +// Helper for linear-gradient-parser +//************************************************************************// +@function _is-num($char) { + $values: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 0 1 2 3 4 5 6 7 8 9; + $index: index($values, $char); + @return if($index, true, false); +} diff --git a/app/assets/stylesheets/bourbon/helpers/_linear-angle-parser.scss b/app/assets/stylesheets/bourbon/helpers/_linear-angle-parser.scss new file mode 100644 index 0000000..e0401ed --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_linear-angle-parser.scss @@ -0,0 +1,25 @@ +// Private function for linear-gradient-parser +@function _linear-angle-parser($image, $first-val, $prefix, $suffix) { + $offset: null; + $unit-short: str-slice($first-val, str-length($first-val) - 2, str-length($first-val)); + $unit-long: str-slice($first-val, str-length($first-val) - 3, str-length($first-val)); + + @if ($unit-long == "grad") or + ($unit-long == "turn") { + $offset: if($unit-long == "grad", -100grad * 3, -0.75turn); + } + + @else if ($unit-short == "deg") or + ($unit-short == "rad") { + $offset: if($unit-short == "deg", -90 * 3, 1.6rad); + } + + @if $offset { + $num: _str-to-num($first-val); + + @return ( + webkit-image: -webkit- + $prefix + ($offset - $num) + $suffix, + spec-image: $image + ); + } +} diff --git a/app/assets/stylesheets/bourbon/helpers/_linear-gradient-parser.scss b/app/assets/stylesheets/bourbon/helpers/_linear-gradient-parser.scss new file mode 100644 index 0000000..12bcdcd --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_linear-gradient-parser.scss @@ -0,0 +1,41 @@ +@function _linear-gradient-parser($image) { + $image: unquote($image); + $gradients: (); + $start: str-index($image, "("); + $end: str-index($image, ","); + $first-val: str-slice($image, $start + 1, $end - 1); + + $prefix: str-slice($image, 0, $start); + $suffix: str-slice($image, $end, str-length($image)); + + $has-multiple-vals: str-index($first-val, " "); + $has-single-position: unquote(_position-flipper($first-val) + ""); + $has-angle: _is-num(str-slice($first-val, 0, 0)); + + @if $has-multiple-vals { + $gradients: _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals); + } + + @else if $has-single-position != "" { + $pos: unquote($has-single-position + ""); + + $gradients: ( + webkit-image: -webkit- + $image, + spec-image: $prefix + "to " + $pos + $suffix + ); + } + + @else if $has-angle { + // Rotate degree for webkit + $gradients: _linear-angle-parser($image, $first-val, $prefix, $suffix); + } + + @else { + $gradients: ( + webkit-image: -webkit- + $image, + spec-image: $image + ); + } + + @return $gradients; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_linear-positions-parser.scss b/app/assets/stylesheets/bourbon/helpers/_linear-positions-parser.scss new file mode 100644 index 0000000..d26383e --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_linear-positions-parser.scss @@ -0,0 +1,61 @@ +@function _linear-positions-parser($pos) { + $type: type-of(nth($pos, 1)); + $spec: null; + $degree: null; + $side: null; + $corner: null; + $length: length($pos); + // Parse Side and corner positions + @if ($length > 1) { + @if nth($pos, 1) == "to" { // Newer syntax + $side: nth($pos, 2); + + @if $length == 2 { // eg. to top + // Swap for backwards compatability + $degree: _position-flipper(nth($pos, 2)); + } + @else if $length == 3 { // eg. to top left + $corner: nth($pos, 3); + } + } + @else if $length == 2 { // Older syntax ("top left") + $side: _position-flipper(nth($pos, 1)); + $corner: _position-flipper(nth($pos, 2)); + } + + @if ("#{$side} #{$corner}" == "left top") or ("#{$side} #{$corner}" == "top left") { + $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); + } + @else if ("#{$side} #{$corner}" == "right top") or ("#{$side} #{$corner}" == "top right") { + $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); + } + @else if ("#{$side} #{$corner}" == "right bottom") or ("#{$side} #{$corner}" == "bottom right") { + $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); + } + @else if ("#{$side} #{$corner}" == "left bottom") or ("#{$side} #{$corner}" == "bottom left") { + $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); + } + $spec: to $side $corner; + } + @else if $length == 1 { + // Swap for backwards compatability + @if $type == string { + $degree: $pos; + $spec: to _position-flipper($pos); + } + @else { + $degree: -270 - $pos; //rotate the gradient opposite from spec + $spec: $pos; + } + } + $degree: unquote($degree + ","); + $spec: unquote($spec + ","); + @return $degree $spec; +} + +@function _position-flipper($pos) { + @return if($pos == left, right, null) + if($pos == right, left, null) + if($pos == top, bottom, null) + if($pos == bottom, top, null); +} diff --git a/app/assets/stylesheets/bourbon/helpers/_linear-side-corner-parser.scss b/app/assets/stylesheets/bourbon/helpers/_linear-side-corner-parser.scss new file mode 100644 index 0000000..86ad88f --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_linear-side-corner-parser.scss @@ -0,0 +1,31 @@ +// Private function for linear-gradient-parser +@function _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals) { + $val-1: str-slice($first-val, 0, $has-multiple-vals - 1 ); + $val-2: str-slice($first-val, $has-multiple-vals + 1, str-length($first-val)); + $val-3: null; + $has-val-3: str-index($val-2, " "); + + @if $has-val-3 { + $val-3: str-slice($val-2, $has-val-3 + 1, str-length($val-2)); + $val-2: str-slice($val-2, 0, $has-val-3 - 1); + } + + $pos: _position-flipper($val-1) _position-flipper($val-2) _position-flipper($val-3); + $pos: unquote($pos + ""); + + // Use old spec for webkit + @if $val-1 == "to" { + @return ( + webkit-image: -webkit- + $prefix + $pos + $suffix, + spec-image: $image + ); + } + + // Bring the code up to spec + @else { + @return ( + webkit-image: -webkit- + $image, + spec-image: $prefix + "to " + $pos + $suffix + ); + } +} diff --git a/app/assets/stylesheets/bourbon/helpers/_radial-arg-parser.scss b/app/assets/stylesheets/bourbon/helpers/_radial-arg-parser.scss new file mode 100644 index 0000000..a3a3704 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_radial-arg-parser.scss @@ -0,0 +1,69 @@ +@function _radial-arg-parser($G1, $G2, $pos, $shape-size) { + @each $value in $G1, $G2 { + $first-val: nth($value, 1); + $pos-type: type-of($first-val); + $spec-at-index: null; + + // Determine if spec was passed to mixin + @if type-of($value) == list { + $spec-at-index: if(index($value, at), index($value, at), false); + } + @if $spec-at-index { + @if $spec-at-index > 1 { + @for $i from 1 through ($spec-at-index - 1) { + $shape-size: $shape-size nth($value, $i); + } + @for $i from ($spec-at-index + 1) through length($value) { + $pos: $pos nth($value, $i); + } + } + @else if $spec-at-index == 1 { + @for $i from ($spec-at-index + 1) through length($value) { + $pos: $pos nth($value, $i); + } + } + $G1: null; + } + + // If not spec calculate correct values + @else { + @if ($pos-type != color) or ($first-val != "transparent") { + @if ($pos-type == number) + or ($first-val == "center") + or ($first-val == "top") + or ($first-val == "right") + or ($first-val == "bottom") + or ($first-val == "left") { + + $pos: $value; + + @if $pos == $G1 { + $G1: null; + } + } + + @else if + ($first-val == "ellipse") + or ($first-val == "circle") + or ($first-val == "closest-side") + or ($first-val == "closest-corner") + or ($first-val == "farthest-side") + or ($first-val == "farthest-corner") + or ($first-val == "contain") + or ($first-val == "cover") { + + $shape-size: $value; + + @if $value == $G1 { + $G1: null; + } + + @else if $value == $G2 { + $G2: null; + } + } + } + } + } + @return $G1, $G2, $pos, $shape-size; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_radial-gradient-parser.scss b/app/assets/stylesheets/bourbon/helpers/_radial-gradient-parser.scss new file mode 100644 index 0000000..6dde50f --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_radial-gradient-parser.scss @@ -0,0 +1,50 @@ +@function _radial-gradient-parser($image) { + $image: unquote($image); + $gradients: (); + $start: str-index($image, "("); + $end: str-index($image, ","); + $first-val: str-slice($image, $start + 1, $end - 1); + + $prefix: str-slice($image, 0, $start); + $suffix: str-slice($image, $end, str-length($image)); + + $is-spec-syntax: str-index($first-val, "at"); + + @if $is-spec-syntax and $is-spec-syntax > 1 { + $keyword: str-slice($first-val, 1, $is-spec-syntax - 2); + $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val)); + $pos: append($pos, $keyword, comma); + + $gradients: ( + webkit-image: -webkit- + $prefix + $pos + $suffix, + spec-image: $image + ) + } + + @else if $is-spec-syntax == 1 { + $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val)); + + $gradients: ( + webkit-image: -webkit- + $prefix + $pos + $suffix, + spec-image: $image + ) + } + + @else if str-index($image, "cover") or str-index($image, "contain") { + @warn "Radial-gradient needs to be updated to conform to latest spec."; + + $gradients: ( + webkit-image: null, + spec-image: $image + ) + } + + @else { + $gradients: ( + webkit-image: -webkit- + $image, + spec-image: $image + ) + } + + @return $gradients; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_radial-positions-parser.scss b/app/assets/stylesheets/bourbon/helpers/_radial-positions-parser.scss new file mode 100644 index 0000000..6a5b477 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_radial-positions-parser.scss @@ -0,0 +1,18 @@ +@function _radial-positions-parser($gradient-pos) { + $shape-size: nth($gradient-pos, 1); + $pos: nth($gradient-pos, 2); + $shape-size-spec: _shape-size-stripper($shape-size); + + $pre-spec: unquote(if($pos, "#{$pos}, ", null)) + unquote(if($shape-size, "#{$shape-size},", null)); + $pos-spec: if($pos, "at #{$pos}", null); + + $spec: "#{$shape-size-spec} #{$pos-spec}"; + + // Add comma + @if ($spec != ' ') { + $spec: "#{$spec}," + } + + @return $pre-spec $spec; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_render-gradients.scss b/app/assets/stylesheets/bourbon/helpers/_render-gradients.scss new file mode 100644 index 0000000..5765676 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_render-gradients.scss @@ -0,0 +1,26 @@ +// User for linear and radial gradients within background-image or border-image properties + +@function _render-gradients($gradient-positions, $gradients, $gradient-type, $vendor: false) { + $pre-spec: null; + $spec: null; + $vendor-gradients: null; + @if $gradient-type == linear { + @if $gradient-positions { + $pre-spec: nth($gradient-positions, 1); + $spec: nth($gradient-positions, 2); + } + } + @else if $gradient-type == radial { + $pre-spec: nth($gradient-positions, 1); + $spec: nth($gradient-positions, 2); + } + + @if $vendor { + $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient(#{$pre-spec} $gradients); + } + @else if $vendor == false { + $vendor-gradients: "#{$gradient-type}-gradient(#{$spec} #{$gradients})"; + $vendor-gradients: unquote($vendor-gradients); + } + @return $vendor-gradients; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_shape-size-stripper.scss b/app/assets/stylesheets/bourbon/helpers/_shape-size-stripper.scss new file mode 100644 index 0000000..ee5eda4 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_shape-size-stripper.scss @@ -0,0 +1,10 @@ +@function _shape-size-stripper($shape-size) { + $shape-size-spec: null; + @each $value in $shape-size { + @if ($value == "cover") or ($value == "contain") { + $value: null; + } + $shape-size-spec: "#{$shape-size-spec} #{$value}"; + } + @return $shape-size-spec; +} diff --git a/app/assets/stylesheets/bourbon/helpers/_str-to-num.scss b/app/assets/stylesheets/bourbon/helpers/_str-to-num.scss new file mode 100644 index 0000000..b3d6168 --- /dev/null +++ b/app/assets/stylesheets/bourbon/helpers/_str-to-num.scss @@ -0,0 +1,50 @@ +//************************************************************************// +// Helper function for linear/radial-gradient-parsers. +// Source: http://sassmeister.com/gist/9647408 +//************************************************************************// +@function _str-to-num($string) { + // Matrices + $strings: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9'; + $numbers: 0 1 2 3 4 5 6 7 8 9; + + // Result + $result: 0; + $divider: 0; + $minus: false; + + // Looping through all characters + @for $i from 1 through str-length($string) { + $character: str-slice($string, $i, $i); + $index: index($strings, $character); + + @if $character == '-' { + $minus: true; + } + + @else if $character == '.' { + $divider: 1; + } + + @else { + @if not $index { + $result: if($minus, $result * -1, $result); + @return _convert-units($result, str-slice($string, $i)); + } + + $number: nth($numbers, $index); + + @if $divider == 0 { + $result: $result * 10; + } + + @else { + // Move the decimal dot to the left + $divider: $divider * 10; + $number: $number / $divider; + } + + $result: $result + $number; + } + } + @return if($minus, $result * -1, $result); +} diff --git a/app/assets/stylesheets/bourbon/settings/_asset-pipeline.scss b/app/assets/stylesheets/bourbon/settings/_asset-pipeline.scss new file mode 100644 index 0000000..d481a6a --- /dev/null +++ b/app/assets/stylesheets/bourbon/settings/_asset-pipeline.scss @@ -0,0 +1 @@ +$asset-pipeline: false !default; diff --git a/app/assets/stylesheets/bourbon/settings/_prefixer.scss b/app/assets/stylesheets/bourbon/settings/_prefixer.scss new file mode 100644 index 0000000..ecab49f --- /dev/null +++ b/app/assets/stylesheets/bourbon/settings/_prefixer.scss @@ -0,0 +1,6 @@ +// Variable settings for /addons/prefixer.scss +$prefix-for-webkit: true !default; +$prefix-for-mozilla: true !default; +$prefix-for-microsoft: true !default; +$prefix-for-opera: true !default; +$prefix-for-spec: true !default; // required for keyframe mixin diff --git a/app/assets/stylesheets/bourbon/settings/_px-to-em.scss b/app/assets/stylesheets/bourbon/settings/_px-to-em.scss new file mode 100644 index 0000000..f2f9a3e --- /dev/null +++ b/app/assets/stylesheets/bourbon/settings/_px-to-em.scss @@ -0,0 +1 @@ +$em-base: 16px !default; diff --git a/app/assets/stylesheets/neat/_neat-helpers.scss b/app/assets/stylesheets/neat/_neat-helpers.scss new file mode 100644 index 0000000..e915c69 --- /dev/null +++ b/app/assets/stylesheets/neat/_neat-helpers.scss @@ -0,0 +1,7 @@ +// Functions +@import "functions/private"; +@import "functions/new-breakpoint"; + +// Settings +@import "settings/grid"; +@import "settings/visual-grid"; diff --git a/app/assets/stylesheets/neat/_neat.scss b/app/assets/stylesheets/neat/_neat.scss new file mode 100644 index 0000000..e93d636 --- /dev/null +++ b/app/assets/stylesheets/neat/_neat.scss @@ -0,0 +1,21 @@ +// Bourbon Neat 1.6.0.pre +// MIT Licensed +// Copyright (c) 2012-2013 thoughtbot, inc. + +// Helpers +@import "neat-helpers"; + +// Grid +@import "grid/private"; +@import "grid/reset"; +@import "grid/grid"; +@import "grid/omega"; +@import "grid/outer-container"; +@import "grid/span-columns"; +@import "grid/row"; +@import "grid/shift"; +@import "grid/pad"; +@import "grid/fill-parent"; +@import "grid/media"; +@import "grid/to-deprecate"; +@import "grid/visual-grid"; diff --git a/app/assets/stylesheets/neat/functions/_new-breakpoint.scss b/app/assets/stylesheets/neat/functions/_new-breakpoint.scss new file mode 100644 index 0000000..a89c9ce --- /dev/null +++ b/app/assets/stylesheets/neat/functions/_new-breakpoint.scss @@ -0,0 +1,16 @@ +@function new-breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) { + + @if length($query) == 1 { + $query: $default-feature nth($query, 1) $total-columns; + } + + @else if length($query) % 2 == 0 { + $query: append($query, $total-columns); + } + + @if not belongs-to($query, $visual-grid-breakpoints) { + $visual-grid-breakpoints: append($visual-grid-breakpoints, $query, comma) !global; + } + + @return $query; +} diff --git a/app/assets/stylesheets/neat/functions/_private.scss b/app/assets/stylesheets/neat/functions/_private.scss new file mode 100644 index 0000000..6f03cfc --- /dev/null +++ b/app/assets/stylesheets/neat/functions/_private.scss @@ -0,0 +1,125 @@ +// Checks if a number is even +@function is-even($int) { + @if $int%2 == 0 { + @return true; + } + + @return false; +} + +// Checks if an element belongs to a list +@function belongs-to($tested-item, $list) { + @each $item in $list { + @if $item == $tested-item { + @return true; + } + } + + @return false; +} + +// Contains display value +@function contains-display-value($query) { + @if belongs-to(table, $query) or belongs-to(block, $query) or belongs-to(inline-block, $query) or belongs-to(inline, $query) { + @return true; + } + + @return false; +} + +// Parses the first argument of span-columns() +@function container-span($span: $span) { + @if length($span) == 3 { + $container-columns: nth($span, 3); + @return $container-columns; + } + + @else if length($span) == 2 { + $container-columns: nth($span, 2); + @return $container-columns; + } + + @else { + @return $grid-columns; + } +} + +@function container-shift($shift: $shift) { + $parent-columns: $grid-columns !global !default; + + @if length($shift) == 3 { + $container-columns: nth($shift, 3); + @return $container-columns; + } + + @else if length($shift) == 2 { + $container-columns: nth($shift, 2); + @return $container-columns; + } + + @else { + @return $parent-columns; + } +} + +// Generates a striped background +@function gradient-stops($grid-columns, $color: $visual-grid-color) { + $transparent: rgba(0,0,0,0); + + $column-width: flex-grid(1, $grid-columns); + $gutter-width: flex-gutter($grid-columns); + $column-offset: $column-width; + + $values: ($transparent 0, $color 0); + + @for $i from 1 to $grid-columns*2 { + @if is-even($i) { + $values: append($values, $transparent $column-offset, comma); + $values: append($values, $color $column-offset, comma); + $column-offset: $column-offset + $column-width; + } + + @else { + $values: append($values, $color $column-offset, comma); + $values: append($values, $transparent $column-offset, comma); + $column-offset: $column-offset + $gutter-width; + } + } + + @return $values; +} + +// Layout direction +@function get-direction($layout, $default) { + $direction: nil; + + @if $layout == LTR or $layout == RTL { + $direction: direction-from-layout($layout); + } @else { + $direction: direction-from-layout($default); + } + + @return $direction; +} + +@function direction-from-layout($layout) { + $direction: nil; + + @if $layout == LTR { + $direction: right; + } @else { + $direction: left; + } + + @return $direction; +} + +@function get-opposite-direction($direction) { + $opposite-direction: left; + + @if $direction == left { + $opposite-direction: right; + } + + @return $opposite-direction; +} diff --git a/app/assets/stylesheets/neat/grid/_fill-parent.scss b/app/assets/stylesheets/neat/grid/_fill-parent.scss new file mode 100644 index 0000000..859c977 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_fill-parent.scss @@ -0,0 +1,7 @@ +@mixin fill-parent() { + width: 100%; + + @if $border-box-sizing == false { + @include box-sizing(border-box); + } +} diff --git a/app/assets/stylesheets/neat/grid/_grid.scss b/app/assets/stylesheets/neat/grid/_grid.scss new file mode 100644 index 0000000..e074b6c --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_grid.scss @@ -0,0 +1,5 @@ +@if $border-box-sizing == true { + * { + @include box-sizing(border-box); + } +} diff --git a/app/assets/stylesheets/neat/grid/_media.scss b/app/assets/stylesheets/neat/grid/_media.scss new file mode 100644 index 0000000..bf27f70 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_media.scss @@ -0,0 +1,38 @@ +@mixin media($query:$feature $value $columns, $total-columns: $grid-columns) { + @if length($query) == 1 { + @media screen and ($default-feature: nth($query, 1)) { + $default-grid-columns: $grid-columns; + $grid-columns: $total-columns !global; + @content; + $grid-columns: $default-grid-columns !global; + } + } + + @else { + $loopTo: length($query); + $mediaQuery: 'screen and '; + $default-grid-columns: $grid-columns; + $grid-columns: $total-columns !global; + + @if length($query) % 2 != 0 { + $grid-columns: nth($query, $loopTo) !global; + $loopTo: $loopTo - 1; + } + + $i: 1; + @while $i <= $loopTo { + $mediaQuery: $mediaQuery + '(' + nth($query, $i) + ': ' + nth($query, $i + 1) + ') '; + + @if ($i + 1) != $loopTo { + $mediaQuery: $mediaQuery + 'and '; + } + + $i: $i + 2; + } + + @media #{$mediaQuery} { + @content; + $grid-columns: $default-grid-columns !global; + } + } +} diff --git a/app/assets/stylesheets/neat/grid/_omega.scss b/app/assets/stylesheets/neat/grid/_omega.scss new file mode 100644 index 0000000..c99ed6c --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_omega.scss @@ -0,0 +1,61 @@ +// Remove last element gutter +@mixin omega($query: block, $direction: default) { + $table: if(belongs-to(table, $query), true, false); + $auto: if(belongs-to(auto, $query), true, false); + + @if $direction != default { + @warn "The omega mixin will no longer take a $direction argument. To change the layout direction, use row($direction) or set $default-layout-direction instead." + } @else { + $direction: get-direction($layout-direction, $default-layout-direction); + } + + @if $table { + @warn "The omega mixin no longer removes padding in table layouts." + } + + @if length($query) == 1 { + @if $auto { + &:last-child { + margin-#{$direction}: 0; + } + } + + @else if contains-display-value($query) and $table == false { + margin-#{$direction}: 0; + } + + @else { + @include nth-child($query, $direction); + } + } + + @else if length($query) == 2 { + @if $auto { + &:last-child { + margin-#{$direction}: 0; + } + } + + @else { + @include nth-child(nth($query, 1), $direction); + } + } + + @else { + @warn "Too many arguments passed to the omega() mixin." + } +} + +@mixin nth-child($query, $direction) { + $opposite-direction: get-opposite-direction($direction); + + &:nth-child(#{$query}) { + margin-#{$direction}: 0; + } + + @if type-of($query) == number { + &:nth-child(#{$query}+1) { + clear: $opposite-direction; + } + } +} diff --git a/app/assets/stylesheets/neat/grid/_outer-container.scss b/app/assets/stylesheets/neat/grid/_outer-container.scss new file mode 100644 index 0000000..22c541f --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_outer-container.scss @@ -0,0 +1,8 @@ +@mixin outer-container { + @include clearfix; + max-width: $max-width; + margin: { + left: auto; + right: auto; + } +} diff --git a/app/assets/stylesheets/neat/grid/_pad.scss b/app/assets/stylesheets/neat/grid/_pad.scss new file mode 100644 index 0000000..3ef5d80 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_pad.scss @@ -0,0 +1,8 @@ +@mixin pad($padding: flex-gutter()) { + $padding-list: null; + @each $value in $padding { + $value: if($value == 'default', flex-gutter(), $value); + $padding-list: join($padding-list, $value); + } + padding: $padding-list; +} diff --git a/app/assets/stylesheets/neat/grid/_private.scss b/app/assets/stylesheets/neat/grid/_private.scss new file mode 100644 index 0000000..b195336 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_private.scss @@ -0,0 +1,43 @@ +$parent-columns: $grid-columns !default; +$fg-column: $column; +$fg-gutter: $gutter; +$fg-max-columns: $grid-columns; +$container-display-table: false !default; +$layout-direction: nil !default; + +@function flex-grid($columns, $container-columns: $fg-max-columns) { + $width: $columns * $fg-column + ($columns - 1) * $fg-gutter; + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($width / $container-width); +} + +@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) { + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($gutter / $container-width); +} + +@function grid-width($n) { + @return $n * $gw-column + ($n - 1) * $gw-gutter; +} + +@function get-parent-columns($columns) { + @if $columns != $grid-columns { + $parent-columns: $columns !global; + } @else { + $parent-columns: $grid-columns !global; + } + + @return $parent-columns; +} + +@function is-display-table($container-is-display-table, $display) { + $display-table: false; + + @if $container-is-display-table == true { + $display-table: true; + } @else if $display == table { + $display-table: true; + } + + @return $display-table; +} diff --git a/app/assets/stylesheets/neat/grid/_reset.scss b/app/assets/stylesheets/neat/grid/_reset.scss new file mode 100644 index 0000000..496c4a7 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_reset.scss @@ -0,0 +1,12 @@ +@mixin reset-display { + $container-display-table: false !global; +} + +@mixin reset-layout-direction { + $layout-direction: $default-layout-direction !global; +} + +@mixin reset-all { + @include reset-display; + @include reset-layout-direction; +} diff --git a/app/assets/stylesheets/neat/grid/_row.scss b/app/assets/stylesheets/neat/grid/_row.scss new file mode 100644 index 0000000..81da6d3 --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_row.scss @@ -0,0 +1,17 @@ +@mixin row($display: block, $direction: $default-layout-direction) { + @include clearfix; + $layout-direction: $direction !global; + + @if $display == table { + display: table; + @include fill-parent; + table-layout: fixed; + $container-display-table: true !global; + } + + @else { + display: block; + $container-display-table: false !global; + } +} + diff --git a/app/assets/stylesheets/neat/grid/_shift.scss b/app/assets/stylesheets/neat/grid/_shift.scss new file mode 100644 index 0000000..1d27b9b --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_shift.scss @@ -0,0 +1,16 @@ +@mixin shift($n-columns: 1) { + @include shift-in-context($n-columns); +} + +@mixin shift-in-context($shift: $columns of $container-columns) { + $n-columns: nth($shift, 1); + $parent-columns: container-shift($shift) !global; + + $direction: get-direction($layout-direction, $default-layout-direction); + $opposite-direction: get-opposite-direction($direction); + + margin-#{$opposite-direction}: $n-columns * flex-grid(1, $parent-columns) + $n-columns * flex-gutter($parent-columns); + + // Reset nesting context + $parent-columns: $grid-columns !global; +} diff --git a/app/assets/stylesheets/neat/grid/_span-columns.scss b/app/assets/stylesheets/neat/grid/_span-columns.scss new file mode 100644 index 0000000..c79193d --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_span-columns.scss @@ -0,0 +1,43 @@ +@mixin span-columns($span: $columns of $container-columns, $display: block) { + $columns: nth($span, 1); + $container-columns: container-span($span); + + // Set nesting context (used by shift()) + $parent-columns: get-parent-columns($container-columns) !global; + + $direction: get-direction($layout-direction, $default-layout-direction); + $opposite-direction: get-opposite-direction($direction); + + $display-table: is-display-table($container-display-table, $display); + + @if $display-table { + display: table-cell; + width: percentage($columns / $container-columns); + } @else { + float: #{$opposite-direction}; + + @if $display != no-display { + display: block; + } + + @if $display == collapse { + @warn "The 'collapse' argument will be deprecated. Use 'block-collapse' instead." + } + + @if $display == collapse or $display == block-collapse { + width: flex-grid($columns, $container-columns) + flex-gutter($container-columns); + + &:last-child { + width: flex-grid($columns, $container-columns); + } + + } @else { + margin-#{$direction}: flex-gutter($container-columns); + width: flex-grid($columns, $container-columns); + + &:last-child { + margin-#{$direction}: 0; + } + } + } +} diff --git a/app/assets/stylesheets/neat/grid/_to-deprecate.scss b/app/assets/stylesheets/neat/grid/_to-deprecate.scss new file mode 100644 index 0000000..d0a681f --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_to-deprecate.scss @@ -0,0 +1,57 @@ +@mixin breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) { + @warn "The breakpoint() mixin was renamed to media() in Neat 1.0. Please update your project with the new syntax before the next version bump."; + + @if length($query) == 1 { + @media screen and ($default-feature: nth($query, 1)) { + $default-grid-columns: $grid-columns; + $grid-columns: $total-columns; + @content; + $grid-columns: $default-grid-columns; + } + } + + @else if length($query) == 2 { + @media screen and (nth($query, 1): nth($query, 2)) { + $default-grid-columns: $grid-columns; + $grid-columns: $total-columns; + @content; + $grid-columns: $default-grid-columns; + } + } + + @else if length($query) == 3 { + @media screen and (nth($query, 1): nth($query, 2)) { + $default-grid-columns: $grid-columns; + $grid-columns: nth($query, 3); + @content; + $grid-columns: $default-grid-columns; + } + } + + @else if length($query) == 4 { + @media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) { + $default-grid-columns: $grid-columns; + $grid-columns: $total-columns; + @content; + $grid-columns: $default-grid-columns; + } + } + + @else if length($query) == 5 { + @media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) { + $default-grid-columns: $grid-columns; + $grid-columns: nth($query, 5); + @content; + $grid-columns: $default-grid-columns; + } + } + + @else { + @warn "Wrong number of arguments for breakpoint(). Read the documentation for more details."; + } +} + +@mixin nth-omega($nth, $display: block, $direction: default) { + @warn "The nth-omega() mixin is deprecated. Please use omega() instead."; + @include omega($nth $display, $direction); +} diff --git a/app/assets/stylesheets/neat/grid/_visual-grid.scss b/app/assets/stylesheets/neat/grid/_visual-grid.scss new file mode 100644 index 0000000..1c822fd --- /dev/null +++ b/app/assets/stylesheets/neat/grid/_visual-grid.scss @@ -0,0 +1,41 @@ +@mixin grid-column-gradient($values...) { + background-image: deprecated-webkit-gradient(linear, left top, left bottom, $values); + background-image: -webkit-linear-gradient(left, $values); + background-image: -moz-linear-gradient(left, $values); + background-image: -ms-linear-gradient(left, $values); + background-image: -o-linear-gradient(left, $values); + background-image: unquote("linear-gradient(left, #{$values})"); +} + +@if $visual-grid == true or $visual-grid == yes { + body:before { + content: ''; + display: inline-block; + @include grid-column-gradient(gradient-stops($grid-columns)); + height: 100%; + left: 0; + margin: 0 auto; + max-width: $max-width; + opacity: $visual-grid-opacity; + position: fixed; + right: 0; + width: 100%; + pointer-events: none; + + @if $visual-grid-index == back { + z-index: -1; + } + + @else if $visual-grid-index == front { + z-index: 9999; + } + + @each $breakpoint in $visual-grid-breakpoints { + @if $breakpoint != nil { + @include media($breakpoint) { + @include grid-column-gradient(gradient-stops($grid-columns)); + } + } + } + } +} diff --git a/app/assets/stylesheets/neat/settings/_grid.scss b/app/assets/stylesheets/neat/settings/_grid.scss new file mode 100644 index 0000000..f1dcda4 --- /dev/null +++ b/app/assets/stylesheets/neat/settings/_grid.scss @@ -0,0 +1,7 @@ +$column: golden-ratio(1em, 3) !default; // Column width +$gutter: golden-ratio(1em, 1) !default; // Gutter between each two columns +$grid-columns: 12 !default; // Total number of columns in the grid +$max-width: em(1088) !default; // Max-width of the outer container +$border-box-sizing: true !default; // Makes all elements have a border-box layout +$default-feature: min-width; // Default @media feature for the breakpoint() mixin +$default-layout-direction: LTR !default; diff --git a/app/assets/stylesheets/neat/settings/_visual-grid.scss b/app/assets/stylesheets/neat/settings/_visual-grid.scss new file mode 100644 index 0000000..611c2b3 --- /dev/null +++ b/app/assets/stylesheets/neat/settings/_visual-grid.scss @@ -0,0 +1,5 @@ +$visual-grid: false !default; // Display the base grid +$visual-grid-color: #EEE !default; +$visual-grid-index: back !default; // Show grid behind content (back) or overlay it over the content (front) +$visual-grid-opacity: 0.4 !default; +$visual-grid-breakpoints: () !default; diff --git a/app/controllers/homes_controller.rb b/app/controllers/homes_controller.rb new file mode 100644 index 0000000..26c83b4 --- /dev/null +++ b/app/controllers/homes_controller.rb @@ -0,0 +1,5 @@ +class HomesController < ApplicationController + def show + render :show, layout: "landing" + end +end diff --git a/app/data/links.yml b/app/data/links.yml new file mode 100644 index 0000000..96d8f14 --- /dev/null +++ b/app/data/links.yml @@ -0,0 +1,35 @@ +contacts: +- googlegroup: + type: "googlegroup" + title: "Alumni Google Group" + url: "https://groups.google.com/forum/?fromgroups#!forum/railsbridge-boston-alumni" + description: "If you graduated from or volunteered at one of our workshops, join our" +- github: + type: "github" + title: "Github" + url: "https://github.com/railsbridge-boston/railsbridge-boston/issues" + description: "Tell us how we can improve our curriculum at" +- twitter: + type: "twitter" + title: "@RailsBridgeBos" + url: "https://twitter.com/RailsBridgeBos" + description: "Follow us on Twitter," +- email: + type: "email" + title: "railsbridgeboston@gmail.com" + url: "mailto:railsbridgeboston@gmail.com" + description: "Email us directly," + +friends: +- railsbridge: + name: "RailsBridge" + url: "http://workshops.railsbridge.org/" + description: "The original San Francisco Ruby on Rails workshop that made our effort possible." +- openhatch: + name: "OpenHatch" + url: "https://openhatch.org/" + description: "Our wonderful outreach effort mentors." +- bostonrb: + name: "BostonRB" + url: "http://bostonrb.org/" + description: "The official local Ruby user group, and a wonderful community of helpful Rubyists." diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..58b859b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,13 @@ module ApplicationHelper + def mailchimp_form_url + "//railsbridgeboston.us6.list-manage.com/subscribe/post?u=1b4272afae4569dec6efb74bb&id=1ec91857a1" + end + + def venue_map_url + "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2948.1159095133034!2d-71.08135500000003!3d42.36136900000001!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89e370a423d61825%3A0x58516248462c99eb!2sMicrosoft+New+England+Research+and+Development+Center!5e0!3m2!1sen!2sus!4v1425584974378" + end + + def data_links + @data_links ||= YAML.load_file(Rails.root.join("app/data/links.yml")) + end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb new file mode 100644 index 0000000..66abd5e --- /dev/null +++ b/app/helpers/events_helper.rb @@ -0,0 +1,15 @@ +module EventsHelper + def next_event + event_manager.upcoming_event + end + + def next_event_venue + next_event.venue + end + + private + + def event_manager + Eventbrite.new + end +end diff --git a/app/views/application/_footer.html.erb b/app/views/application/_footer.html.erb new file mode 100644 index 0000000..f82226d --- /dev/null +++ b/app/views/application/_footer.html.erb @@ -0,0 +1,8 @@ +
+

Get in touch via + <%= link_to "email", "mailto:railsbridgeboston@gmail.com" %> + or + <%= link_to "@RailsBridgeBos", "https://twitter.com/RailsBridgeBos" %> +

+

Site design by <%= link_to "thoughtbot", "http://www.thoughtbot.com" %>

+
diff --git a/app/views/application/_header.html.erb b/app/views/application/_header.html.erb new file mode 100644 index 0000000..a7ff886 --- /dev/null +++ b/app/views/application/_header.html.erb @@ -0,0 +1,14 @@ +
+
+
+ <%= link_to "/", class: "logo" do %> + RailsBridge Bos + <% end %> + + <%= link_to "Menu", "#!", class: "nav-toggle" %> +
+ + <%= render "nav" %> +
+
+ diff --git a/app/views/application/_nav.html.erb b/app/views/application/_nav.html.erb new file mode 100644 index 0000000..52063dd --- /dev/null +++ b/app/views/application/_nav.html.erb @@ -0,0 +1,22 @@ + diff --git a/app/views/application/_title.html.erb b/app/views/application/_title.html.erb new file mode 100644 index 0000000..3770c8e --- /dev/null +++ b/app/views/application/_title.html.erb @@ -0,0 +1,5 @@ +<% if content_for?(:title) %> + <%= content_for(:title) %> - <%= t("titles.application") %> +<% else %> + <%= t("titles.application") %> +<% end %> diff --git a/app/views/application/_typekit.html.erb b/app/views/application/_typekit.html.erb new file mode 100644 index 0000000..909e0ed --- /dev/null +++ b/app/views/application/_typekit.html.erb @@ -0,0 +1,2 @@ + + diff --git a/app/views/homes/_mailchimp_form.html.erb b/app/views/homes/_mailchimp_form.html.erb new file mode 100644 index 0000000..633d2e6 --- /dev/null +++ b/app/views/homes/_mailchimp_form.html.erb @@ -0,0 +1,19 @@ +
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
diff --git a/app/views/homes/show.html.erb b/app/views/homes/show.html.erb new file mode 100644 index 0000000..150ee53 --- /dev/null +++ b/app/views/homes/show.html.erb @@ -0,0 +1,74 @@ +<% content_for :title do %> + RailsBridge Boston - Ruby and Rails workshop +<% end %> + +
+ <%= link_to "Menu", "#!", class: "nav-toggle" %> +
+<%= render "nav" %> + +
+
+ <%= image_tag "train.svg", class: "railsbridge" %> + +

RailsBridge Boston

+ <% if next_event.url %> + <%= link_to "Register for the workshop", next_event.url, + class: "register-link", target: "_blank" %> + <% end %> +
+
+ +
+ +
+

<%= next_event.dates %>

+

<%= next_event_venue.name %>

+

<%= next_event_venue.address %>

+ <% if next_event.url %> + <%= link_to "Register for workshop", next_event.url, class: "register-link button", target: "_blank" %> + <% end %> +
+
+ +
+
+

Stay in the loop

+

Want to know about new upcoming workshops? Sign up for our announcement list and we’ll keep you updated!

+
+ + <%= render "mailchimp_form" %> +
+ +
+
+
+

What is a RailsBridge workshop?

+

+ It is a fun and free way to get started or level up with + <%= link_to "Ruby", "http://ruby-lang.org/", target: "_blank" %>, + <%= link_to "Ruby on Rails", "http://rubyonrails.org/", target: "_blank" %>, + and other web technologies. Our events focus on increasing diversity in + tech, so that people of all backgrounds can feel welcome and comfortable + in our industry. +

+ + <%= link_to "Learn more about us", "/about.html", :class => "to-about" %> +
+ +
+
+ +
+

+ <%= link_to "RailsBridge Boston Video Teaser", "http://vimeo.com/70699061" %> + from + <%= link_to "RailsBridge Boston", "http://vimeo.com/railsbridgeboston" %> + by + <%= link_to "A2V Media", "http://www.a2vmedia.com/" %> + on + <%= link_to "Vimeo", "https://vimeo.com" %>. +

+
+
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 3e38f12..291bee0 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -4,18 +4,19 @@ - <%# - Configure default and controller-, and view-specific titles in - config/locales/en.yml. For more see: - https://github.com/calebthompson/title#usage - %> - <%= title %> + + <%= render "title" %> <%= stylesheet_link_tag :application, media: "all" %> + <%= render "javascript" %> + <%= render "typekit" %> <%= csrf_meta_tags %> - - <%= render "flashes" -%> + + + <%= render "header" %> <%= yield %> - <%= render "javascript" %> + +<%= render "footer" %> + diff --git a/app/views/layouts/landing.html.erb b/app/views/layouts/landing.html.erb new file mode 100644 index 0000000..a63b0e5 --- /dev/null +++ b/app/views/layouts/landing.html.erb @@ -0,0 +1,19 @@ + + + + + + + + <%= render "title" %> + <%= stylesheet_link_tag :application, media: "all" %> + <%= render "javascript" %> + <%= render "typekit" %> + <%= csrf_meta_tags %> + + + + <%= yield %> + + + diff --git a/app/views/pages/about.html.erb b/app/views/pages/about.html.erb new file mode 100644 index 0000000..7553e99 --- /dev/null +++ b/app/views/pages/about.html.erb @@ -0,0 +1,60 @@ +<% content_for(:title, "About") %> +<% content_for(:page_class, "about") %> + +
    +
  • <%= image_tag "workshop/1.jpg" %>
  • +
  • <%= image_tag "workshop/2.jpg" %>
  • +
  • <%= image_tag "workshop/3.jpg" %>
  • +
  • <%= image_tag "workshop/4.jpg" %>
  • +
+ +
+

About

+ +
+

Empowering Women with Ruby

+

Do you dream of someday writing software that helps people and improves the world?

+

Led by an all-volunteer team of seasoned, enthusiastic Ruby and Rails developers, the workshop introduces women of all backgrounds to the concepts, tools, and techniques of Ruby and Rails development. Our audience is those with no or little programming experience.

+

We welcome you to the Boston Ruby community. Whatever your goal is in learning to program, we hope to connect you with the tools to take the next step.

+
+ +
+

Promoting Diversity

+

The Boston software scene needs more women. So this workshop is for women and their guests. You should identify as a woman, or be the male guest of a woman who is attending.

+

We support mothers who want to code. We will provide childcare to those who need it. Please let us know if you want to use these services on the application form.

+
+ +
+

Code of Conduct

+
+

RailsBridge Boston is dedicated to providing a harassment-free experience for everyone regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion.

+

We will not tolerate harassment of workshop participants in any form, be it verbal comments (said aloud or typed into a backchannel), imagery, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of lectures, inappropriate physical contact, and unwelcome sexual attention.

+

Workshop participants violating these rules may be sanctioned or expelled from the event at the discretion of the organizers.

+

If you are being harassed, see someone else being harassed, or have any other concerns on-site please contact one of the workshop organizers or teaching assistants immediately.

+
+
+ +
+

Contact

+
    + <% data_links["contacts"].each do |contact| %> +
  • "> + <%= contact["description"] %> + <%= link_to contact["title"], contact["url"] %> +
  • + <% end %> +
+
+ + +
diff --git a/app/views/pages/class-levels.html.erb b/app/views/pages/class-levels.html.erb new file mode 100644 index 0000000..ec1fe11 --- /dev/null +++ b/app/views/pages/class-levels.html.erb @@ -0,0 +1,48 @@ +<% content_for(:title, "Class Levels") %> +<% content_for(:page_class, "class-levels") %> + +
+

Class Levels

+ +

Below is a list of class levels. Pick the one that best describes your + current experience level when you register for our workshop.

+ +
+

Totally New to Programming

+
    +
  • You have little to no experience with the terminal or a graphical IDE.
  • +
  • You might have done a little bit with HTML or CSS, but not necessarily.
  • +
  • You're unfamiliar with terms like methods, arrays, lists, hashes, or dictionaries.
  • +
+
+ +
+

Somewhat New to Programming

+
    +
  • You may have used the terminal a little — to change directories, for instance.
  • +
  • You might have done an online programming tutorial or two.
  • +
  • You don't have a lot of experience with Rails.
  • +
  • You know what a method is.
  • +
  • You aren't totally clear on how a request gets from the browser to your app.
  • +
+
+ +
+

Some Rails Experience

+
    +
  • You're comfortable using the terminal, but not necessarily a Power User.
  • +
  • You have a general understanding of a Rails app's structure, perhaps from a prior workshop or tutorial.
  • +
  • You know how to define a method in Ruby.
  • +
  • You have a decent handle on Ruby arrays and hashes.
  • +
+
+ +
+

Other Programming Experience

+
    +
  • You're proficient in another language and understand general programming concepts, like collections and scope.
  • +
  • You're new to Ruby and Rails
  • +
  • You might be familiar with version control and basic web architecture
  • +
+
+
diff --git a/app/views/pages/donate.html.erb b/app/views/pages/donate.html.erb new file mode 100644 index 0000000..283049b --- /dev/null +++ b/app/views/pages/donate.html.erb @@ -0,0 +1,30 @@ +<% content_for(:title, "Donate") %> +<% content_for(:page_class, "donate") %> + +
+

Donate

+ +

+ RailsBridge is run entirely on donations of money, time, and expertise. +

+ +

+ If your company or organization can help us make tech more welcoming and more diverse, we'd love your help. We're always looking for sponsors to help cover the cost of food and drinks for the workshop. +

+ + + +

+ If you'd like to contribute as an individual, you can do so via PayPal. +

+ + +
diff --git a/app/views/pages/resources.html.erb b/app/views/pages/resources.html.erb new file mode 100644 index 0000000..d18847e --- /dev/null +++ b/app/views/pages/resources.html.erb @@ -0,0 +1,84 @@ +<% content_for(:title, "Resources") %> +<% content_for(:page_class, "resources") %> + +
+

Resources

+ + + +
+
+

Community

+

RailsBridge Boston <%= link_to "Alumni Google Group", "https://groups.google.com/forum/#!forum/railsbridge-boston-alumni" %> is for all participants, TAs, and supporters of RailsBridge Boston.

+

The <%= link_to "Boston Ruby Group", "http://bostonrb.org/" %> organizes <%= link_to "monthly presentations", "http://bostonrb.org/calendar" %> and <%= link_to "project night", "http://bostonrb.org/project_night" %>. Project night always has a few volunteers available specifically to help others.

+

<%= link_to "Boston Ruby Women", "http://www.meetup.com/Boston-Ruby-Women/" %> is a monthly Meetup for women who use Ruby.

+

The Ruby community welcomes you.

+
+ +
+

Install your tools

+

It's customary to install Ruby on your own laptop, and we debated for a long time before using a virtual machine. You can continue to use the RailsBridge virtual machine if you wish, but we encourage you to have your own set of tools. + <%= link_to "The Ruby site offers several options on its installation page", "https://www.ruby-lang.org/en/installation" %>.

+
+ +
+

Learning sequence

+

+ For a quick review of what we learned today, watch + <%= link_to "Ruby in 100 Minutes", "http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html" %>. +

+

Once you've got Ruby basics down, the best way to learn is to make a practice project. Projects take you off the smooth path of a tutorial and out into the exciting wild lands. Pick a problem you care about. Start small and spiral out.

+

Ruby on Rails is a web framework, that is, a set of libraries and tools to make a dynamic website. Come to the RailsBridge Rails workshop to learn more. If you want to get started on your own, thoughtbot's <%= link_to "Ruby Learning Trail", "https://learn.thoughtbot.com/ruby" %> maps out the route.

+
+ +
+

Tutorials

+

There's a wealth of tutorials and resources for learning Ruby and Rails. Here are the ones we recommend starting with.

+
    +
  • <%= link_to "Ruby Koans", "http://rubykoans.com/" %> are a set of puzzles that “walk you along the path to enlightenment in order to learn Ruby. The goal is to learn the Ruby language, syntax, structure, and some common functions and libraries.”
  • +
  • <%= link_to "Code Wars", "http://www.codewars.com/" %> is an online set of puzzles.
  • +
  • <%= link_to "Learn to Program", "http://pine.fm/LearnToProgram/" %> by Chris Pine is a good starting place for new programmers.
  • +
  • <%= link_to "Programming Ruby", "http://ruby-doc.com/docs/ProgrammingRuby/" %>, a.k.a. “the Pickaxe Book”, is one of the most popular Ruby books.
  • +
  • Why not find study buddies on the <%= link_to "alumni group", "https://groups.google.com/forum/#!forum/railsbridge-boston-alumni" %>?
  • +
+
+ +
+

Classes

+
    +
  • <%= link_to "Girl Develop It", "http://www.girldevelopit.com/chapters/boston" %> offers low-cost classes in programming and web design.
  • +
  • Check community programs like the Cambridge Center for Adult Education.
  • +
+
+ +
+

Bootcamps

+

Bootcamps are intensive full-time programs. There are several in our area.

+
    +
  • <%= link_to "General Assembly", "https://generalassemb.ly/boston" %>
  • +
  • <%= link_to "Launch Academy", "http://www.launchacademy.com/" %>
  • +
  • <%= link_to "Startup Institute", "http://startupinstitute.com/boston" %>
  • +
+
+ +
+

Online classes

+
    +
  • <%= link_to "thoughtbot Upcase", "http://upcase.com/" %>
  • +
  • <%= link_to "Thinkful", "http://thinkful.com/" %>
  • +
  • <%= link_to "Pragmatic Programmers video series", "http://pragmaticstudio.com/ruby" %>
  • +
  • <%= link_to "Firehose Weekend Virtual Classes", "http://www.firehoseweekend.com/" %>
  • +
+
+
+
diff --git a/app/views/pages/thanks.html.erb b/app/views/pages/thanks.html.erb new file mode 100644 index 0000000..64288f0 --- /dev/null +++ b/app/views/pages/thanks.html.erb @@ -0,0 +1,12 @@ +<%= content_for(:title, "Thank you!") %> + +
+

+ Thanks! + <%= image_tag "heart.svg", class: "thanks-heart" %> +

+

+ Thank you for your support. Every little bit counts to help us work towards our initiative and keep these workshops running. +

+ <%= link_to "Back to homepage", "/" %> +
diff --git a/bin/setup b/bin/setup index afe9811..aa1d067 100755 --- a/bin/setup +++ b/bin/setup @@ -31,6 +31,8 @@ if ! command -v foreman > /dev/null; then printf 'See https://github.com/ddollar/foreman for install instructions.\n' fi -# Only if this isn't CI -# if [ -z "$CI" ]; then -# fi +if [ -z "$CI" ]; then + # Set up staging and production git remotes + git remote add staging git@heroku.com:railsbridge-boston-staging.git || true + git remote add production git@heroku.com:railsbridge-boston.git || true +fi diff --git a/config/application.rb b/config/application.rb index 4d9a84c..0e78646 100644 --- a/config/application.rb +++ b/config/application.rb @@ -29,22 +29,11 @@ class Application < Rails::Application generate.view_specs false end - config.action_controller.action_on_unpermitted_parameters = :raise - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. - - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' + config.autoload_paths += %W(#{config.root}/lib) - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de + config.action_controller.action_on_unpermitted_parameters = :raise # Do not swallow errors in after_commit/after_rollback callbacks. config.active_record.raise_in_transactional_callbacks = true - - config.active_job.queue_adapter = :delayed_job end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 07c3f6e..a31f37a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,4 +16,4 @@ en: "%B %d" titles: - application: Railsbridgeboston dot org + application: RailsBridge Boston diff --git a/config/routes.rb b/config/routes.rb index 1daf9a4..858a0f8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,2 +1,3 @@ Rails.application.routes.draw do + root "homes#show" end diff --git a/lib/eventbrite.rb b/lib/eventbrite.rb new file mode 100644 index 0000000..4143af5 --- /dev/null +++ b/lib/eventbrite.rb @@ -0,0 +1,62 @@ +require "httparty" +require_relative "eventbrite/event" +require_relative "eventbrite/null_event" + +class Eventbrite + include HTTParty + + base_uri "https://www.eventbriteapi.com/v3" + + def upcoming_event + event_list.first + end + + private + + def event_list + if user_events_response.success? && !events_from_response.empty? + events_from_response.map do |event| + Eventbrite::Event.new(event) + end + else + [Eventbrite::NullEvent.new] + end + end + + def events_from_response + user_events_response["events"] + end + + def user_events_response + self.class.get( + events_owned_by_user_api_url, + query: credentials.merge(event_criteria) + ) + end + + def events_owned_by_user_api_url + "/users/#{user_id}/owned_events/" + end + + def user_id + if user_response.success? + user_response["id"] + end + end + + def user_response + self.class.get(user_profile_api_url, query: credentials) + end + + def user_profile_api_url + "/users/me" + end + + def credentials + { token: ENV.fetch("EVENTBRITE_ACCESS_TOKEN") } + end + + def event_criteria + { status: "live" } + end +end diff --git a/lib/eventbrite/event.rb b/lib/eventbrite/event.rb new file mode 100644 index 0000000..1c23e22 --- /dev/null +++ b/lib/eventbrite/event.rb @@ -0,0 +1,40 @@ +require_relative "venue" + +class Eventbrite + class Event + def initialize(details) + @details = details + end + + def title + details["name"]["text"] + end + + def dates + [ + Date.parse(start_date).strftime("%B %e"), + Date.parse(end_date).strftime("%e, %Y") + ].join(" & ") + end + + def url + details["url"] + end + + def venue + Eventbrite::Venue.new(details["venue"]) + end + + private + + attr_reader :details + + def start_date + details["start"]["local"] + end + + def end_date + details["end"]["local"] + end + end +end diff --git a/lib/eventbrite/null_event.rb b/lib/eventbrite/null_event.rb new file mode 100644 index 0000000..1e8fe7b --- /dev/null +++ b/lib/eventbrite/null_event.rb @@ -0,0 +1,26 @@ +class Eventbrite + class NullEvent + def title + nil + end + + def description + "There are no upcoming workshops." + end + + def dates + nil + end + + def url + nil + end + + def venue + OpenStruct.new( + name: nil, + address: nil + ) + end + end +end diff --git a/lib/eventbrite/venue.rb b/lib/eventbrite/venue.rb new file mode 100644 index 0000000..a45f94f --- /dev/null +++ b/lib/eventbrite/venue.rb @@ -0,0 +1,35 @@ +class Eventbrite + class Venue + def initialize(details) + @details = details + end + + def name + details["name"] ||= "Location TBD" + end + + def address + [ + street_and_city, + address_details["postal_code"] + ].compact.reject(&:empty?).join(" ") + end + + private + + attr_reader :details + + def street_and_city + [ + address_details["address_1"], + address_details["address_2"], + address_details["city"], + address_details["region"], + ].compact.reject(&:empty?).join(", ") + end + + def address_details + details["address"] ||= {} + end + end +end diff --git a/public/favicon.ico b/public/favicon.ico index e69de29..a71511e 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/sponsorship_prospectus.pdf b/public/sponsorship_prospectus.pdf new file mode 100644 index 0000000..60673eb Binary files /dev/null and b/public/sponsorship_prospectus.pdf differ