Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

howdy

  • Loading branch information...
commit 81f8c4169ce23b21febe71eeb854f6351e13ae19 0 parents
@steeleforge authored
Showing with 23,319 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. +1 −0  404.html
  3. +1 −0  CNAME
  4. +3 −0  README.md
  5. +294 −0 Rakefile
  6. +117 −0 _config.yml
  7. +12 −0 _includes/JB/analytics
  8. +12 −0 _includes/JB/analytics-providers/getclicky
  9. +11 −0 _includes/JB/analytics-providers/google
  10. +37 −0 _includes/JB/categories_list
  11. +16 −0 _includes/JB/comments
  12. +13 −0 _includes/JB/comments-providers/disqus
  13. +9 −0 _includes/JB/comments-providers/facebook
  14. +6 −0 _includes/JB/comments-providers/intensedebate
  15. +6 −0 _includes/JB/comments-providers/livefyre
  16. +32 −0 _includes/JB/liquid_raw
  17. +37 −0 _includes/JB/pages_list
  18. +55 −0 _includes/JB/posts_collate
  19. +22 −0 _includes/JB/setup
  20. +8 −0 _includes/JB/sharing
  21. +33 −0 _includes/JB/tags_list
  22. +125 −0 _includes/themes/sf/default.html
  23. +28 −0 _includes/themes/sf/less/accordion.less
  24. +70 −0 _includes/themes/sf/less/alerts.less
  25. +62 −0 _includes/themes/sf/less/bootstrap.less
  26. +22 −0 _includes/themes/sf/less/breadcrumbs.less
  27. +148 −0 _includes/themes/sf/less/button-groups.less
  28. +183 −0 _includes/themes/sf/less/buttons.less
  29. +121 −0 _includes/themes/sf/less/carousel.less
  30. +18 −0 _includes/themes/sf/less/close.less
  31. +57 −0 _includes/themes/sf/less/code.less
  32. +18 −0 _includes/themes/sf/less/component-animations.less
  33. +130 −0 _includes/themes/sf/less/dropdowns.less
  34. +522 −0 _includes/themes/sf/less/forms.less
  35. +8 −0 _includes/themes/sf/less/grid.less
  36. +20 −0 _includes/themes/sf/less/hero-unit.less
  37. +32 −0 _includes/themes/sf/less/labels.less
  38. +17 −0 _includes/themes/sf/less/layouts.less
  39. +590 −0 _includes/themes/sf/less/mixins.less
  40. +83 −0 _includes/themes/sf/less/modals.less
  41. +299 −0 _includes/themes/sf/less/navbar.less
  42. +353 −0 _includes/themes/sf/less/navs.less
  43. +30 −0 _includes/themes/sf/less/pager.less
  44. +55 −0 _includes/themes/sf/less/pagination.less
  45. +49 −0 _includes/themes/sf/less/popovers.less
  46. +95 −0 _includes/themes/sf/less/progress-bars.less
  47. +126 −0 _includes/themes/sf/less/reset.less
  48. +327 −0 _includes/themes/sf/less/responsive.less
  49. +29 −0 _includes/themes/sf/less/scaffolding.less
  50. +158 −0 _includes/themes/sf/less/sprites.less
  51. +150 −0 _includes/themes/sf/less/tables.less
  52. +35 −0 _includes/themes/sf/less/thumbnails.less
  53. +35 −0 _includes/themes/sf/less/tooltip.less
  54. +218 −0 _includes/themes/sf/less/type.less
  55. +23 −0 _includes/themes/sf/less/utilities.less
  56. +107 −0 _includes/themes/sf/less/variables.less
  57. +17 −0 _includes/themes/sf/less/wells.less
  58. +10 −0 _includes/themes/sf/page.html
  59. +40 −0 _includes/themes/sf/post.html
  60. +2 −0  _includes/themes/sf/settings.yml
  61. +6 −0 _layouts/default.html
  62. +5 −0 _layouts/less
  63. +5 −0 _layouts/page.html
  64. +5 −0 _layouts/post.html
  65. +38 −0 _plugins/debug.rb
  66. +46 −0 _posts/2010-06-15-back-end-web-developers-please-step-forward.html
  67. +14 −0 _posts/2012-03-02-refresh.html
  68. +12 −0 about.html
  69. +10 −0 archive.html
  70. BIN  assets/static/front-to-back.png
  71. +643 −0 assets/themes/sf/css/bootstrap-responsive.css
  72. +4 −0 assets/themes/sf/css/bootstrap-responsive.min.css
  73. +3,682 −0 assets/themes/sf/css/bootstrap.css
  74. +632 −0 assets/themes/sf/css/bootstrap.min.css
  75. +192 −0 assets/themes/sf/css/style.css
  76. BIN  assets/themes/sf/img/404.png
  77. BIN  assets/themes/sf/img/glyphicons-halflings-white.png
  78. BIN  assets/themes/sf/img/glyphicons-halflings.png
  79. BIN  assets/themes/sf/img/logo.png
  80. BIN  assets/themes/sf/img/splash.png
  81. BIN  assets/themes/sf/img/tag.png
  82. BIN  assets/themes/sf/img/twitter.png
  83. +94 −0 assets/themes/sf/js/bootstrap-alert.js
  84. +100 −0 assets/themes/sf/js/bootstrap-button.js
  85. +157 −0 assets/themes/sf/js/bootstrap-carousel.js
  86. +136 −0 assets/themes/sf/js/bootstrap-collapse.js
  87. +92 −0 assets/themes/sf/js/bootstrap-dropdown.js
  88. +210 −0 assets/themes/sf/js/bootstrap-modal.js
  89. +95 −0 assets/themes/sf/js/bootstrap-popover.js
  90. +125 −0 assets/themes/sf/js/bootstrap-scrollspy.js
  91. +130 −0 assets/themes/sf/js/bootstrap-tab.js
  92. +270 −0 assets/themes/sf/js/bootstrap-tooltip.js
  93. +51 −0 assets/themes/sf/js/bootstrap-transition.js
  94. +271 −0 assets/themes/sf/js/bootstrap-typeahead.js
  95. +1,720 −0 assets/themes/sf/js/bootstrap.js
  96. +9,252 −0 assets/themes/sf/js/jquery.js
  97. +28 −0 atom.xml
  98. +22 −0 categories.html
  99. +46 −0 changelog.md
  100. +29 −0 index.html
  101. +8 −0 lab.html
  102. +13 −0 pages.html
  103. +8 −0 sitemap.txt
  104. +21 −0 tags.html
10 .gitignore
@@ -0,0 +1,10 @@
+_site/*
+_theme_packages/*
+
+Thumbs.db
+.DS_Store
+
+!.gitkeep
+
+.rbenv-version
+.rvmrc
1  404.html
@@ -0,0 +1 @@
+<img src="/assets/themes/sf/img/404.png">
1  CNAME
@@ -0,0 +1 @@
+steeleforge.com
3  README.md
@@ -0,0 +1,3 @@
+# SteeleForge
+
+Powered by Jekyll-Bootstrap <http://jekyllbootstrap.com> and Twitter Bootstrap <http://twitter.github.com/bootstrap>
294 Rakefile
@@ -0,0 +1,294 @@
+require "rubygems"
+require 'rake'
+require 'yaml'
+
+SOURCE = "."
+CONFIG = {
+ 'version' => "0.2.0",
+ 'themes' => File.join(SOURCE, "_includes", "themes"),
+ 'layouts' => File.join(SOURCE, "_layouts"),
+ 'posts' => File.join(SOURCE, "_posts"),
+ 'post_ext' => "md",
+ 'theme_package_version' => "0.1.0"
+}
+
+# Path configuration helper
+module JB
+ class Path
+ SOURCE = "."
+ Paths = {
+ :layouts => "_layouts",
+ :themes => "_includes/themes",
+ :theme_assets => "assets/themes",
+ :theme_packages => "_theme_packages",
+ :posts => "_posts"
+ }
+
+ def self.base
+ SOURCE
+ end
+
+ # build a path relative to configured path settings.
+ def self.build(path, opts = {})
+ opts[:root] ||= SOURCE
+ path = "#{opts[:root]}/#{Paths[path.to_sym]}/#{opts[:node]}".split("/")
+ path.compact!
+ File.__send__ :join, path
+ end
+
+ end #Path
+end #JB
+
+# Usage: rake post title="A Title"
+desc "Begin a new post in #{CONFIG['posts']}"
+task :post do
+ abort("rake aborted: '#{CONFIG['posts']}' directory not found.") unless FileTest.directory?(CONFIG['posts'])
+ title = ENV["title"] || "new-post"
+ slug = title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
+ filename = File.join(CONFIG['posts'], "#{Time.now.strftime('%Y-%m-%d')}-#{slug}.#{CONFIG['post_ext']}")
+ if File.exist?(filename)
+ abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+ end
+
+ puts "Creating new post: #{filename}"
+ open(filename, 'w') do |post|
+ post.puts "---"
+ post.puts "layout: post"
+ post.puts "title: \"#{title.gsub(/-/,' ')}\""
+ post.puts "category: "
+ post.puts "tags: []"
+ post.puts "---"
+ post.puts "{% include JB/setup %}"
+ end
+end # task :post
+
+# Usage: rake page name="about.html"
+# You can also specify a sub-directory path.
+# If you don't specify a file extention we create an index.html at the path specified
+desc "Create a new page."
+task :page do
+ name = ENV["name"] || "new-page.md"
+ filename = File.join(SOURCE, "#{name}")
+ filename = File.join(filename, "index.html") if File.extname(filename) == ""
+ title = File.basename(filename, File.extname(filename)).gsub(/[\W\_]/, " ").gsub(/\b\w/){$&.upcase}
+ if File.exist?(filename)
+ abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+ end
+
+ mkdir_p File.dirname(filename)
+ puts "Creating new page: #{filename}"
+ open(filename, 'w') do |post|
+ post.puts "---"
+ post.puts "layout: page"
+ post.puts "title: \"#{title}\""
+ post.puts "---"
+ post.puts "{% include JB/setup %}"
+ end
+end # task :page
+
+desc "Launch preview environment"
+task :preview do
+ system "jekyll --auto --server"
+end # task :preview
+
+# Public: Alias - Maintains backwards compatability for theme switching.
+task :switch_theme => "theme:switch"
+
+namespace :theme do
+
+ # Public: Switch from one theme to another for your blog.
+ #
+ # name - String, Required. name of the theme you want to switch to.
+ # The the theme must be installed into your JB framework.
+ #
+ # Examples
+ #
+ # rake theme:switch name="the-program"
+ #
+ # Returns Success/failure messages.
+ desc "Switch between Jekyll-bootstrap themes."
+ task :switch do
+ theme_name = ENV["name"].to_s
+ theme_path = File.join(CONFIG['themes'], theme_name)
+ settings_file = File.join(theme_path, "settings.yml")
+ non_layout_files = ["settings.yml"]
+
+ abort("rake aborted: name cannot be blank") if theme_name.empty?
+ abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path)
+ abort("rake aborted: '#{CONFIG['layouts']}' directory not found.") unless FileTest.directory?(CONFIG['layouts'])
+
+ Dir.glob("#{theme_path}/*") do |filename|
+ next if non_layout_files.include?(File.basename(filename).downcase)
+ puts "Generating '#{theme_name}' layout: #{File.basename(filename)}"
+
+ open(File.join(CONFIG['layouts'], File.basename(filename)), 'w') do |page|
+ if File.basename(filename, ".html").downcase == "default"
+ page.puts "---"
+ page.puts File.read(settings_file) if File.exist?(settings_file)
+ page.puts "---"
+ else
+ page.puts "---"
+ page.puts "layout: default"
+ page.puts "---"
+ end
+ page.puts "{% include JB/setup %}"
+ page.puts "{% include themes/#{theme_name}/#{File.basename(filename)} %}"
+ end
+ end
+
+ puts "=> Theme successfully switched!"
+ puts "=> Reload your web-page to check it out =)"
+ end # task :switch
+
+ # Public: Install a theme using the theme packager.
+ # Version 0.1.0 simple 1:1 file matching.
+ #
+ # git - String, Optional path to the git repository of the theme to be installed.
+ # name - String, Optional name of the theme you want to install.
+ # Passing name requires that the theme package already exist.
+ #
+ # Examples
+ #
+ # rake theme:install git="https://github.com/jekyllbootstrap/theme-twitter.git"
+ # rake theme:install name="cool-theme"
+ #
+ # Returns Success/failure messages.
+ desc "Install theme"
+ task :install do
+ if ENV["git"]
+ manifest = theme_from_git_url(ENV["git"])
+ name = manifest["name"]
+ else
+ name = ENV["name"].to_s.downcase
+ end
+
+ packaged_theme_path = JB::Path.build(:theme_packages, :node => name)
+
+ abort("rake aborted!
+ => ERROR: 'name' cannot be blank") if name.empty?
+ abort("rake aborted!
+ => ERROR: '#{packaged_theme_path}' directory not found.
+ => Installable themes can be added via git. You can find some here: http://github.com/jekyllbootstrap
+ => To download+install run: `rake theme:install git='[PUBLIC-CLONE-URL]'`
+ => example : rake theme:install git='git@github.com:jekyllbootstrap/theme-the-program.git'
+ ") unless FileTest.directory?(packaged_theme_path)
+
+ manifest = verify_manifest(packaged_theme_path)
+
+ # Get relative paths to packaged theme files
+ # Exclude directories as they'll be recursively created. Exclude meta-data files.
+ packaged_theme_files = []
+ FileUtils.cd(packaged_theme_path) {
+ Dir.glob("**/*.*") { |f|
+ next if ( FileTest.directory?(f) || f =~ /^(manifest|readme|packager)/i )
+ packaged_theme_files << f
+ }
+ }
+
+ # Mirror each file into the framework making sure to prompt if already exists.
+ packaged_theme_files.each do |filename|
+ file_install_path = File.join(JB::Path.base, filename)
+ if File.exist? file_install_path
+ next if ask("#{file_install_path} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+ else
+ mkdir_p File.dirname(file_install_path)
+ cp_r File.join(packaged_theme_path, filename), file_install_path
+ end
+ end
+
+ puts "=> #{name} theme has been installed!"
+ puts "=> ---"
+ if ask("=> Want to switch themes now?", ['y', 'n']) == 'y'
+ system("rake switch_theme name='#{name}'")
+ end
+ end
+
+ # Public: Package a theme using the theme packager.
+ # The theme must be structured using valid JB API.
+ # In other words packaging is essentially the reverse of installing.
+ #
+ # name - String, Required name of the theme you want to package.
+ #
+ # Examples
+ #
+ # rake theme:package name="twitter"
+ #
+ # Returns Success/failure messages.
+ desc "Package theme"
+ task :package do
+ name = ENV["name"].to_s.downcase
+ theme_path = JB::Path.build(:themes, :node => name)
+ asset_path = JB::Path.build(:theme_assets, :node => name)
+
+ abort("rake aborted: name cannot be blank") if name.empty?
+ abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path)
+ abort("rake aborted: '#{asset_path}' directory not found.") unless FileTest.directory?(asset_path)
+
+ ## Mirror theme's template directory (_includes)
+ packaged_theme_path = JB::Path.build(:themes, :root => JB::Path.build(:theme_packages, :node => name))
+ mkdir_p packaged_theme_path
+ cp_r theme_path, packaged_theme_path
+
+ ## Mirror theme's asset directory
+ packaged_theme_assets_path = JB::Path.build(:theme_assets, :root => JB::Path.build(:theme_packages, :node => name))
+ mkdir_p packaged_theme_assets_path
+ cp_r asset_path, packaged_theme_assets_path
+
+ ## Log packager version
+ packager = {"packager" => {"version" => CONFIG["theme_package_version"].to_s } }
+ open(JB::Path.build(:theme_packages, :node => "#{name}/packager.yml"), "w") do |page|
+ page.puts packager.to_yaml
+ end
+
+ puts "=> '#{name}' theme is packaged and available at: #{JB::Path.build(:theme_packages, :node => name)}"
+ end
+
+end # end namespace :theme
+
+# Internal: Download and process a theme from a git url.
+# Notice we don't know the name of the theme until we look it up in the manifest.
+# So we'll have to change the folder name once we get the name.
+#
+# url - String, Required url to git repository.
+#
+# Returns theme manifest hash
+def theme_from_git_url(url)
+ tmp_path = JB::Path.build(:theme_packages, :node => "_tmp")
+ system("git clone #{url} #{tmp_path}")
+ manifest = verify_manifest(tmp_path)
+ new_path = JB::Path.build(:theme_packages, :node => manifest["name"])
+ if File.exist?(new_path) && ask("=> #{new_path} theme package already exists. Override?", ['y', 'n']) == 'n'
+ remove_dir(tmp_path)
+ abort("rake aborted: '#{manifest["name"]}' already exists as theme package.")
+ end
+
+ remove_dir(new_path) if File.exist?(new_path)
+ mv(tmp_path, new_path)
+ manifest
+end
+
+# Internal: Process theme package manifest file.
+#
+# theme_path - String, Required. File path to theme package.
+#
+# Returns theme manifest hash
+def verify_manifest(theme_path)
+ manifest = File.join(theme_path, "manifest.yml")
+ abort("rake aborted: repo must contain valid manifest.yml") unless File.exist? manifest
+ manifest = YAML.load_file(manifest)
+ manifest
+end
+
+def ask(message, valid_options)
+ if valid_options
+ answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
+ else
+ answer = get_stdin(message)
+ end
+ answer
+end
+
+def get_stdin(message)
+ print message
+ STDIN.gets.chomp
+end
117 _config.yml
@@ -0,0 +1,117 @@
+# This is the default format.
+# For more see: https://github.com/mojombo/jekyll/wiki/Permalinks
+permalink: /:categories/:year/:month/:day/:title
+
+exclude: [".rvmrc", ".rbenv-version", "README.md", "Rakefile", "changelog.md"]
+auto: true
+pygments: true
+
+# Themes are encouraged to use these universal variables
+# so be sure to set them if your theme uses them.
+#
+title : steeleforge
+tagline:
+author :
+ name : David Steele
+ email : david@steeleforge.com
+ github : steeleforge
+ twitter : davidsteele
+ feedburner :
+
+# The production_url is only used when full-domain names are needed
+# such as sitemap.txt
+# Most places will/should use BASE_PATH to make the urls
+#
+# If you have set a CNAME (pages.github.com) set your custom domain here.
+# Else if you are pushing to username.github.com, replace with your username.
+# Finally if you are pushing to a GitHub project page, include the project name at the end.
+#
+production_url : http://steeleforge.com
+
+# All Jekyll-Bootstrap specific configurations are namespaced into this hash
+#
+JB :
+ version : 0.2.8
+
+ # All links will be namespaced by BASE_PATH if defined.
+ # Links in your website should always be prefixed with {{BASE_PATH}}
+ # however this value will be dynamically changed depending on your deployment situation.
+ #
+ # CNAME (http://yourcustomdomain.com)
+ # DO NOT SET BASE_PATH
+ # (urls will be prefixed with "/" and work relatively)
+ #
+ # GitHub Pages (http://username.github.com)
+ # DO NOT SET BASE_PATH
+ # (urls will be prefixed with "/" and work relatively)
+ #
+ # GitHub Project Pages (http://username.github.com/project-name)
+ #
+ # A GitHub Project site exists in the `gh-pages` branch of one of your repositories.
+ # REQUIRED! Set BASE_PATH to: http://username.github.com/project-name
+ #
+ # CAUTION:
+ # - When in Localhost, your site will run from root "/" regardless of BASE_PATH
+ # - Only the following values are falsy: ["", null, false]
+ # - When setting BASE_PATH it must be a valid url.
+ # This means always setting the protocol (http|https) or prefixing with "/"
+ BASE_PATH : false
+
+ # By default, the asset_path is automatically defined relative to BASE_PATH plus the enabled theme.
+ # ex: [BASE_PATH]/assets/themes/[THEME-NAME]
+ #
+ # Override this by defining an absolute path to assets here.
+ # ex:
+ # http://s3.amazonaws.com/yoursite/themes/watermelon
+ # /assets
+ #
+ ASSET_PATH : false
+
+ # These paths are to the main pages Jekyll-Bootstrap ships with.
+ # Some JB helpers refer to these paths; change theme here if needed.
+ #
+ archive_path: /archive.html
+ categories_path : /categories.html
+ tags_path : /tags.html
+
+ # Settings for comments helper
+ # Set 'provider' to the comment provider you want to use.
+ # Set 'provider' to false to turn commenting off globally.
+ #
+ comments :
+ provider : disqus
+ disqus :
+ short_name : steeleforge
+
+ # Settings for analytics helper
+ # Set 'provider' to the analytics provider you want to use.
+ # Set 'provider' to false to turn analytics off globally.
+ #
+ analytics :
+ provider : google
+ google :
+ tracking_id : 'UA-8037814-1'
+ getclicky :
+ site_id :
+ mixpanel :
+ token : '_MIXPANEL_TOKEN_'
+
+ # Settings for sharing helper.
+ # Sharing is for things like tweet, plusone, like, reddit buttons etc.
+ # Set 'provider' to the sharing provider you want to use.
+ # Set 'provider' to false to turn sharing off globally.
+ #
+ sharing :
+ provider : false
+
+ # Settings for all other include helpers can be defined by creating
+ # a hash with key named for the given helper. ex:
+ #
+ # pages_list :
+ # provider : "custom"
+ #
+ # Setting any helper's provider to 'custom' will bypass the helper code
+ # and include your custom code. Your custom file must be defined at:
+ # ./_includes/custom/[HELPER]
+ # where [HELPER] is the name of the helper you are overriding.
+
12 _includes/JB/analytics
@@ -0,0 +1,12 @@
+{% if site.safe and site.JB.analytics.provider and page.JB.analytics != false %}
+
+{% case site.JB.analytics.provider %}
+{% when "google" %}
+ {% include JB/analytics-providers/google %}
+{% when "getclicky" %}
+ {% include JB/analytics-providers/getclicky %}
+{% when "custom" %}
+ {% include custom/analytics %}
+{% endcase %}
+
+{% endif %}
12 _includes/JB/analytics-providers/getclicky
@@ -0,0 +1,12 @@
+<script type="text/javascript">
+var clicky_site_ids = clicky_site_ids || [];
+clicky_site_ids.push({{ site.JB.analytics.getclicky.site_id }});
+(function() {
+ var s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.async = true;
+ s.src = '//static.getclicky.com/js';
+ ( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( s );
+})();
+</script>
+<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/{{ site.JB.analytics.getclicky.site_id }}ns.gif" /></p></noscript>
11 _includes/JB/analytics-providers/google
@@ -0,0 +1,11 @@
+<script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', '{{ site.JB.analytics.google.tracking_id }}']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+</script>
37 _includes/JB/categories_list
@@ -0,0 +1,37 @@
+{% comment %}<!--
+The categories_list include is a listing helper for categories.
+Usage:
+ 1) assign the 'categories_list' variable to a valid array of tags.
+ 2) include JB/categories_list
+ example:
+ <ul>
+ {% assign categories_list = site.categories %}
+ {% include JB/categories_list %}
+ </ul>
+
+ Notes:
+ Categories can be either a Hash of Category objects (hashes) or an Array of category-names (strings).
+ The encapsulating 'if' statement checks whether categories_list is a Hash or Array.
+ site.categories is a Hash while page.categories is an array.
+
+ This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.categories_list.provider == "custom" %}
+ {% include custom/categories_list %}
+{% else %}
+ {% if categories_list.first[0] == null %}
+ {% for category in categories_list %}
+ <li><a href="{{ BASE_PATH }}{{ site.JB.categories_path }}#{{ category }}-ref">
+ {{ category | join: "/" }} <span>{{ site.categories[category].size }}</span>
+ </a></li>
+ {% endfor %}
+ {% else %}
+ {% for category in categories_list %}
+ <li><a href="{{ BASE_PATH }}{{ site.JB.categories_path }}#{{ category[0] }}-ref">
+ {{ category[0] | join: "/" }} <span>{{ category[1].size }}</span>
+ </a></li>
+ {% endfor %}
+ {% endif %}
+{% endif %}
+{% assign categories_list = nil %}
16 _includes/JB/comments
@@ -0,0 +1,16 @@
+{% if site.JB.comments.provider and page.JB.comments != false %}
+
+{% case site.JB.comments.provider %}
+{% when "disqus" %}
+ {% include JB/comments-providers/disqus %}
+{% when "livefyre" %}
+ {% include JB/comments-providers/livefyre %}
+{% when "intensedebate" %}
+ {% include JB/comments-providers/intensedebate %}
+{% when "facebook" %}
+ {% include JB/comments-providers/facebook %}
+{% when "custom" %}
+ {% include custom/comments %}
+{% endcase %}
+
+{% endif %}
13 _includes/JB/comments-providers/disqus
@@ -0,0 +1,13 @@
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+ {% if site.safe == false %}var disqus_developer = 1;{% endif %}
+ var disqus_shortname = '{{ site.JB.comments.disqus.short_name }}'; // required: replace example with your forum shortname
+ /* * * DON'T EDIT BELOW THIS LINE * * */
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
9 _includes/JB/comments-providers/facebook
@@ -0,0 +1,9 @@
+<div id="fb-root"></div>
+<script>(function(d, s, id) {
+ var js, fjs = d.getElementsByTagName(s)[0];
+ if (d.getElementById(id)) return;
+ js = d.createElement(s); js.id = id;
+ js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId={{ site.JB.comments.facebook.appid }}";
+ fjs.parentNode.insertBefore(js, fjs);
+}(document, 'script', 'facebook-jssdk'));</script>
+<div class="fb-comments" data-href="{{ site.production_url }}" data-num-posts="{{ site.JB.comments.facebook.num_posts }}" data-width="{{ site.JB.comments.facebook.width }}" data-colorscheme="{{ site.JB.comments.facebook.colorscheme }}"></div>
6 _includes/JB/comments-providers/intensedebate
@@ -0,0 +1,6 @@
+<script>
+var idcomments_acct = '{{ site.JB.comments.intensedebate.account }}';
+var idcomments_post_id;
+var idcomments_post_url;
+</script>
+<script type="text/javascript" src="http://www.intensedebate.com/js/genericLinkWrapperV2.js"></script>
6 _includes/JB/comments-providers/livefyre
@@ -0,0 +1,6 @@
+<script type='text/javascript' src='http://zor.livefyre.com/wjs/v1.0/javascripts/livefyre_init.js'></script>
+<script type='text/javascript'>
+ var fyre = LF({
+ site_id: {{ site.JB.comments.livefyre.site_id }}
+ });
+</script>
32 _includes/JB/liquid_raw
@@ -0,0 +1,32 @@
+{% comment%}<!--
+The liquid_raw helper is a way to display raw liquid code, as opposed to parsing it.
+Normally you'd use Liquid's built in 'raw' tag.
+The problem is GitHub Jekyll does not support the current Liquid release.
+GitHub Jekyll supports the deprecated 'literal' tag.
+Using one will break the other if you plan to deploy to GitHub pages.
+ see: https://github.com/mojombo/jekyll/issues/425
+
+Since I don't want to mess with Liquid versions, I'll just rewrite the way I
+intend to give liquid examples. It's not an elegant by any means:
+
+Usage:
+ 1) Define a 'text' variable with the block of liquid code you intend to display.
+ 2) Pass the text variable to include JB/liquid_raw
+
+ example:
+ {% capture text %}|.% for tag in tags_list %.|
+ <li><a href="|.{ site.var.tags_path }.||.{ tag[0] }.|-ref">|.{ tag[0] }.| <span>|.{tag[1].size}.|</span></a></li>
+ |.% endfor %.|
+
+ |.% assign tags_list = null %.|{% endcapture %}
+ {% include JB/liquid_raw %}
+
+ As seen here, you must use "|." and ".|" as opening and closing brackets.
+-->{% endcomment%}
+
+{% if site.JB.liquid_raw.provider == "custom" %}
+ {% include custom/liquid_raw %}
+{% else %}
+ <pre><code>{{text | replace:"|.", "&#123;" | replace:".|", "&#125;" | replace:">", "&gt;" | replace:"<", "&lt;" }}</code></pre>
+{% endif %}
+{% assign text = nil %}
37 _includes/JB/pages_list
@@ -0,0 +1,37 @@
+{% comment %}<!--
+The pages_list include is a listing helper.
+Usage:
+ 1) assign the 'pages_list' variable to a valid array of pages or posts.
+ 2) include JB/pages_list
+ example:
+ <ul>
+ {% assign pages_list = site.pages %}
+ {% include JB/pages_list %}
+ </ul>
+
+ Grouping: (optional):
+ assign the 'group' variable to constrain the list to only pages/posts
+ in the given group. Note you must define the group manually in the page/post
+ meta-data to use this feature.
+ Grouping is mainly helpful for non-post pages.
+ If you want to group posts, it's easier/better to tag them, then pass the tagged posts array.
+ i.e. site.tags.cool_tag (this returns an array of posts tagged: cool_tag)
+
+ This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.pages_list.provider == "custom" %}
+ {% include custom/pages_list %}
+{% else %}
+ {% for node in pages_list %}
+ {% if group == null or group == node.group %}
+ {% if page.url == node.url %}
+ <li class="active"><a href="{{ BASE_PATH }}{{node.url}}" class="active">{{node.title}}</a></li>
+ {% else %}
+ <li><a href="{{ BASE_PATH }}{{node.url}}">{{node.title}}</a></li>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+{% endif %}
+{% assign pages_list = nil %}
+{% assign group = nil %}
55 _includes/JB/posts_collate
@@ -0,0 +1,55 @@
+{% comment %}<!--
+Collate_posts helper. Collated posts by year and month.
+Usage:
+ 1) assign the 'posts_collate' variable to a valid array of posts.
+ 2) include JB/posts_collate
+ example:
+ {% assign posts_collate = site.posts %}
+ {% include JB/posts_collate %}
+
+ Ordering:
+ Posts are displayed in reverse chronological order.
+ For normal chronological order:
+ 1) Change the for loop to this:
+ => 'for post in site.posts reversed'
+ 2) Next make sure to change 'post.previous.date' to:
+ => 'post.next.date'
+
+-->{% endcomment %}
+
+{% if site.JB.posts_collate.provider == "custom" %}
+ {% include custom/posts_collate %}
+{% else %}
+ {% for post in posts_collate %}
+ {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
+ {% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %}
+ {% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
+ {% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %}
+
+ {% if forloop.first %}
+ <h2>{{this_year}}</h2>
+ <h3>{{this_month}}</h3>
+ <ul>
+ {% endif %}
+
+ <li><span>{{ post.date | date: "%B %e, %Y" }}</span> &raquo; <a href="{{ BASE_PATH }}{{ post.url }}">{{ post.title }}</a></li>
+
+ {% if forloop.last %}
+ </ul>
+ {% else %}
+ {% if this_year != next_year %}
+ </ul>
+ <h2>{{next_year}}</h2>
+ <h3>{{next_month}}</h3>
+ <ul>
+ {% else %}
+ {% if this_month != next_month %}
+ </ul>
+ <h3>{{next_month}}</h3>
+ <ul>
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+{% endif %}
+{% assign posts_collate = nil %}
22 _includes/JB/setup
@@ -0,0 +1,22 @@
+{% capture jbcache %}
+ <!--
+ - Dynamically set liquid variables for working with URLs/paths
+ -->
+ {% if site.JB.setup.provider == "custom" %}
+ {% include custom/setup %}
+ {% else %}
+ {% if site.safe and site.JB.BASE_PATH and site.JB.BASE_PATH != '' %}
+ {% assign BASE_PATH = site.JB.BASE_PATH %}
+ {% assign HOME_PATH = site.JB.BASE_PATH %}
+ {% else %}
+ {% assign BASE_PATH = nil %}
+ {% assign HOME_PATH = "/" %}
+ {% endif %}
+
+ {% if site.JB.ASSET_PATH %}
+ {% assign ASSET_PATH = site.JB.ASSET_PATH %}
+ {% else %}
+ {% capture ASSET_PATH %}{{ BASE_PATH }}/assets/themes/{{ page.theme.name }}{% endcapture %}
+ {% endif %}
+ {% endif %}
+{% endcapture %}{% assign jbcache = nil %}
8 _includes/JB/sharing
@@ -0,0 +1,8 @@
+{% if site.safe and site.JB.sharing.provider and page.JB.sharing != false %}
+
+{% case site.JB.sharing.provider %}
+{% when "custom" %}
+ {% include custom/sharing %}
+{% endcase %}
+
+{% endif %}
33 _includes/JB/tags_list
@@ -0,0 +1,33 @@
+{% comment %}<!--
+The tags_list include is a listing helper for tags.
+Usage:
+ 1) assign the 'tags_list' variable to a valid array of tags.
+ 2) include JB/tags_list
+ example:
+ <ul>
+ {% assign tags_list = site.tags %}
+ {% include JB/tags_list %}
+ </ul>
+
+ Notes:
+ Tags can be either a Hash of tag objects (hashes) or an Array of tag-names (strings).
+ The encapsulating 'if' statement checks whether tags_list is a Hash or Array.
+ site.tags is a Hash while page.tags is an array.
+
+ This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.tags_list.provider == "custom" %}
+ {% include custom/tags_list %}
+{% else %}
+ {% if tags_list.first[0] == null %}
+ {% for tag in tags_list %}
+ <li><a href="{{ BASE_PATH }}{{ site.JB.tags_path }}#{{ tag }}-ref">{{ tag }} <span>{{ site.tags[tag].size }}</span></a></li>
+ {% endfor %}
+ {% else %}
+ {% for tag in tags_list %}
+ <li><a href="{{ BASE_PATH }}{{ site.JB.tags_path }}#{{ tag[0] }}-ref">{{ tag[0] }} <span>{{ tag[1].size }}</span></a></li>
+ {% endfor %}
+ {% endif %}
+{% endif %}
+{% assign tags_list = nil %}
125 _includes/themes/sf/default.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>{{ page.title }} - {{ site.title }}</title>
+ {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="author" content="{{ site.author.name }}">
+
+ <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
+ <!--[if lt IE 9]>
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+
+ <!-- Le styles -->
+ <link href="{{ ASSET_PATH }}/css/bootstrap.min.css" rel="stylesheet">
+ <link href="{{ ASSET_PATH }}/css/bootstrap-responsive.min.css" rel="stylesheet">
+ <link href="{{ ASSET_PATH }}/css/style.css?body=1" rel="stylesheet" type="text/css" media="all">
+ </head>
+
+ <body>
+ <div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container-fluid">
+ <a class="brand-logo" href="{{ HOME_PATH }}">
+ <img src="{{ ASSET_PATH }}/img/logo.png" alt="{{ site.title }}" title="{{ site.title }}"/>
+ </a>
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </a>
+ <a class="brand" href="{{ HOME_PATH }}">
+ {{ site.title }}
+ </a>
+ <div class="nav-collapse">
+ <ul class="nav">
+ {% assign pages_list = site.pages %}
+ {% assign group = 'navigation' %}
+ {% include JB/pages_list %}
+ </ul>
+ </div><!--/.nav-collapse -->
+ <div class="nav pull-right">
+ <a href="https://twitter.com/davidsteele" class="twitter-follow-button" data-show-count="false">Follow @davidsteele</a>
+<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+ </div>
+ </div>
+ </div><!--/.navbar-inner-->
+ </div>
+
+ <div class="container-fluid">
+ <div class="row-fluid">
+ <div class="span2">
+ <div class="well">
+ <ul class="nav nav-pills nav-stacked">
+ <li class="nav-header">Essays</li>
+ {% assign pages_list = site.pages %}
+ {% assign group = 'essays' %}
+ {% include JB/pages_list %}
+ </ul>
+ </div><!--/.well -->
+
+ <script charset="utf-8" src="http://widgets.twimg.com/j/2/widget.js"></script>
+ <script>
+ new TWTR.Widget({
+ version: 2,
+ type: 'profile',
+ rpp: 4,
+ interval: 30000,
+ width: 'auto',
+ height: 200,
+ theme: {
+ shell: {
+ background: '#fff',
+ color: '#78b'
+ },
+ tweets: {
+ background: '#fff',
+ color: '#555',
+ links: '#78b'
+ }
+ },
+ features: {
+ scrollbar: true,
+ loop: false,
+ live: true,
+ behavior: 'all'
+ }
+ }).render().setUser('davidsteele').start();
+ </script>
+ </div><!--/span-->
+
+ <div class="span10">
+ <div class="content">
+ {{ content }}
+ </div>
+ </div><!--/span-->
+ </div><!-- /row -->
+ </div> <!-- /container -->
+
+
+ <hr/>
+ <footer>
+ <p>&copy; 2012 - david steele</p>
+ </footer>
+
+ {% include JB/analytics %}
+
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
+ <script src="{{ ASSET_PATH }}/js/bootstrap.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-dropdown.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-transition.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-alert.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-modal.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-dropdown.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-scrollspy.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-tab.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-tooltip.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-popover.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-button.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-collapse.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-carousel.js"></script>
+ <script src="{{ ASSET_PATH }}/js/bootstrap-typeahead.js"></script>
+ </body>
+</html>
28 _includes/themes/sf/less/accordion.less
@@ -0,0 +1,28 @@
+// ACCORDION
+// ---------
+
+
+// Parent container
+.accordion {
+ margin-bottom: @baseLineHeight;
+}
+
+// Group == heading + body
+.accordion-group {
+ margin-bottom: 2px;
+ border: 1px solid #e5e5e5;
+ .border-radius(4px);
+}
+.accordion-heading {
+ border-bottom: 0;
+}
+.accordion-heading .accordion-toggle {
+ display: block;
+ padding: 8px 15px;
+}
+
+// Inner needs the styles because you can't animate properly with any styles on the element
+.accordion-inner {
+ padding: 9px 15px;
+ border-top: 1px solid #e5e5e5;
+}
70 _includes/themes/sf/less/alerts.less
@@ -0,0 +1,70 @@
+// ALERT STYLES
+// ------------
+
+// Base alert styles
+.alert {
+ padding: 8px 35px 8px 14px;
+ margin-bottom: @baseLineHeight;
+ text-shadow: 0 1px 0 rgba(255,255,255,.5);
+ background-color: @warningBackground;
+ border: 1px solid @warningBorder;
+ .border-radius(4px);
+}
+.alert,
+.alert-heading {
+ color: @warningText;
+}
+
+// Adjust close link position
+.alert .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ line-height: 18px;
+}
+
+// Alternate styles
+// ----------------
+
+.alert-success {
+ background-color: @successBackground;
+ border-color: @successBorder;
+}
+.alert-success,
+.alert-success .alert-heading {
+ color: @successText;
+}
+.alert-danger,
+.alert-error {
+ background-color: @errorBackground;
+ border-color: @errorBorder;
+}
+.alert-danger,
+.alert-error,
+.alert-danger .alert-heading,
+.alert-error .alert-heading {
+ color: @errorText;
+}
+.alert-info {
+ background-color: @infoBackground;
+ border-color: @infoBorder;
+}
+.alert-info,
+.alert-info .alert-heading {
+ color: @infoText;
+}
+
+
+// Block alerts
+// ------------------------
+.alert-block {
+ padding-top: 14px;
+ padding-bottom: 14px;
+}
+.alert-block > p,
+.alert-block > ul {
+ margin-bottom: 0;
+}
+.alert-block p + p {
+ margin-top: 5px;
+}
62 _includes/themes/sf/less/bootstrap.less
@@ -0,0 +1,62 @@
+/*!
+ * Bootstrap v2.0.1
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+// CSS Reset
+@import "reset.less";
+
+// Core variables and mixins
+@import "variables.less"; // Modify this for custom colors, font-sizes, etc
+@import "mixins.less";
+
+// Grid system and page structure
+@import "scaffolding.less";
+@import "grid.less";
+@import "layouts.less";
+
+// Base CSS
+@import "type.less";
+@import "code.less";
+@import "forms.less";
+@import "tables.less";
+
+// Components: common
+@import "sprites.less";
+@import "dropdowns.less";
+@import "wells.less";
+@import "component-animations.less";
+@import "close.less";
+
+// Components: Buttons & Alerts
+@import "buttons.less";
+@import "button-groups.less";
+@import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
+
+// Components: Nav
+@import "navs.less";
+@import "navbar.less";
+@import "breadcrumbs.less";
+@import "pagination.less";
+@import "pager.less";
+
+// Components: Popovers
+@import "modals.less";
+@import "tooltip.less";
+@import "popovers.less";
+
+// Components: Misc
+@import "thumbnails.less";
+@import "labels.less";
+@import "progress-bars.less";
+@import "accordion.less";
+@import "carousel.less";
+@import "hero-unit.less";
+
+// Utility classes
+@import "utilities.less"; // Has to be last to override when necessary
22 _includes/themes/sf/less/breadcrumbs.less
@@ -0,0 +1,22 @@
+// BREADCRUMBS
+// -----------
+
+.breadcrumb {
+ padding: 7px 14px;
+ margin: 0 0 @baseLineHeight;
+ #gradient > .vertical(@white, #f5f5f5);
+ border: 1px solid #ddd;
+ .border-radius(3px);
+ .box-shadow(inset 0 1px 0 @white);
+ li {
+ display: inline-block;
+ text-shadow: 0 1px 0 @white;
+ }
+ .divider {
+ padding: 0 5px;
+ color: @grayLight;
+ }
+ .active a {
+ color: @grayDark;
+ }
+}
148 _includes/themes/sf/less/button-groups.less
@@ -0,0 +1,148 @@
+// BUTTON GROUPS
+// -------------
+
+
+// Make the div behave like a button
+.btn-group {
+ position: relative;
+ .clearfix(); // clears the floated buttons
+ .ie7-restore-left-whitespace();
+}
+
+// Space out series of button groups
+.btn-group + .btn-group {
+ margin-left: 5px;
+}
+
+// Optional: Group multiple button groups together for a toolbar
+.btn-toolbar {
+ margin-top: @baseLineHeight / 2;
+ margin-bottom: @baseLineHeight / 2;
+ .btn-group {
+ display: inline-block;
+ .ie7-inline-block();
+ }
+}
+
+// Float them, remove border radius, then re-add to first and last elements
+.btn-group .btn {
+ position: relative;
+ float: left;
+ margin-left: -1px;
+ .border-radius(0);
+}
+// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
+.btn-group .btn:first-child {
+ margin-left: 0;
+ -webkit-border-top-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+ border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ border-bottom-left-radius: 4px;
+}
+.btn-group .btn:last-child,
+.btn-group .dropdown-toggle {
+ -webkit-border-top-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+ border-bottom-right-radius: 4px;
+}
+// Reset corners for large buttons
+.btn-group .btn.large:first-child {
+ margin-left: 0;
+ -webkit-border-top-left-radius: 6px;
+ -moz-border-radius-topleft: 6px;
+ border-top-left-radius: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ border-bottom-left-radius: 6px;
+}
+.btn-group .btn.large:last-child,
+.btn-group .large.dropdown-toggle {
+ -webkit-border-top-right-radius: 6px;
+ -moz-border-radius-topright: 6px;
+ border-top-right-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ -moz-border-radius-bottomright: 6px;
+ border-bottom-right-radius: 6px;
+}
+
+// On hover/focus/active, bring the proper btn to front
+.btn-group .btn:hover,
+.btn-group .btn:focus,
+.btn-group .btn:active,
+.btn-group .btn.active {
+ z-index: 2;
+}
+
+// On active and open, don't show outline
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+
+
+// Split button dropdowns
+// ----------------------
+
+// Give the line between buttons some depth
+.btn-group .dropdown-toggle {
+ padding-left: 8px;
+ padding-right: 8px;
+ @shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
+ .box-shadow(@shadow);
+ *padding-top: 5px;
+ *padding-bottom: 5px;
+}
+
+.btn-group.open {
+ // IE7's z-index only goes to the nearest positioned ancestor, which would
+ // make the menu appear below buttons that appeared later on the page
+ *z-index: @zindexDropdown;
+
+ // Reposition menu on open and round all corners
+ .dropdown-menu {
+ display: block;
+ margin-top: 1px;
+ .border-radius(5px);
+ }
+
+ .dropdown-toggle {
+ background-image: none;
+ @shadow: inset 0 1px 6px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
+ .box-shadow(@shadow);
+ }
+}
+
+// Reposition the caret
+.btn .caret {
+ margin-top: 7px;
+ margin-left: 0;
+}
+.btn:hover .caret,
+.open.btn-group .caret {
+ .opacity(100);
+}
+
+
+// Account for other colors
+.btn-primary,
+.btn-danger,
+.btn-info,
+.btn-success,
+.btn-inverse {
+ .caret {
+ border-top-color: @white;
+ .opacity(75);
+ }
+}
+
+// Small button dropdowns
+.btn-small .caret {
+ margin-top: 4px;
+}
+
183 _includes/themes/sf/less/buttons.less
@@ -0,0 +1,183 @@
+// BUTTON STYLES
+// -------------
+
+
+// Base styles
+// --------------------------------------------------
+
+// Core
+.btn {
+ display: inline-block;
+ padding: 4px 10px 4px;
+ margin-bottom: 0; // For input.btn
+ font-size: @baseFontSize;
+ line-height: @baseLineHeight;
+ color: @grayDark;
+ text-align: center;
+ text-shadow: 0 1px 1px rgba(255,255,255,.75);
+ vertical-align: middle;
+ .buttonBackground(@white, darken(@white, 10%));
+ border: 1px solid #ccc;
+ border-bottom-color: #bbb;
+ .border-radius(4px);
+ @shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
+ .box-shadow(@shadow);
+ cursor: pointer;
+
+ // Give IE7 some love
+ .reset-filter();
+ .ie7-restore-left-whitespace();
+}
+
+// Hover state
+.btn:hover {
+ color: @grayDark;
+ text-decoration: none;
+ background-color: darken(@white, 10%);
+ background-position: 0 -15px;
+
+ // transition is only when going to hover, otherwise the background
+ // behind the gradient (there for IE<=9 fallback) gets mismatched
+ .transition(background-position .1s linear);
+}
+
+// Focus state for keyboard and accessibility
+.btn:focus {
+ .tab-focus();
+}
+
+// Active state
+.btn.active,
+.btn:active {
+ background-image: none;
+ @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
+ .box-shadow(@shadow);
+ background-color: darken(@white, 10%);
+ background-color: darken(@white, 15%) e("\9");
+ outline: 0;
+}
+
+// Disabled state
+.btn.disabled,
+.btn[disabled] {
+ cursor: default;
+ background-image: none;
+ background-color: darken(@white, 10%);
+ .opacity(65);
+ .box-shadow(none);
+}
+
+
+// Button Sizes
+// --------------------------------------------------
+
+// Large
+.btn-large {
+ padding: 9px 14px;
+ font-size: @baseFontSize + 2px;
+ line-height: normal;
+ .border-radius(5px);
+}
+.btn-large [class^="icon-"] {
+ margin-top: 1px;
+}
+
+// Small
+.btn-small {
+ padding: 5px 9px;
+ font-size: @baseFontSize - 2px;
+ line-height: @baseLineHeight - 2px;
+}
+.btn-small [class^="icon-"] {
+ margin-top: -1px;
+}
+
+// Mini
+.btn-mini {
+ padding: 2px 6px;
+ font-size: @baseFontSize - 2px;
+ line-height: @baseLineHeight - 4px;
+}
+
+
+// Alternate buttons
+// --------------------------------------------------
+
+// Set text color
+// -------------------------
+.btn-primary,
+.btn-primary:hover,
+.btn-warning,
+.btn-warning:hover,
+.btn-danger,
+.btn-danger:hover,
+.btn-success,
+.btn-success:hover,
+.btn-info,
+.btn-info:hover,
+.btn-inverse,
+.btn-inverse:hover {
+ text-shadow: 0 -1px 0 rgba(0,0,0,.25);
+ color: @white;
+}
+// Provide *some* extra contrast for those who can get it
+.btn-primary.active,
+.btn-warning.active,
+.btn-danger.active,
+.btn-success.active,
+.btn-info.active,
+.btn-dark.active {
+ color: rgba(255,255,255,.75);
+}
+
+// Set the backgrounds
+// -------------------------
+.btn-primary {
+ .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20));
+}
+// Warning appears are orange
+.btn-warning {
+ .buttonBackground(lighten(@orange, 15%), @orange);
+}
+// Danger and error appear as red
+.btn-danger {
+ .buttonBackground(#ee5f5b, #bd362f);
+}
+// Success appears as green
+.btn-success {
+ .buttonBackground(#62c462, #51a351);
+}
+// Info appears as a neutral blue
+.btn-info {
+ .buttonBackground(#5bc0de, #2f96b4);
+}
+// Inverse appears as dark gray
+.btn-inverse {
+ .buttonBackground(#454545, #262626);
+}
+
+
+// Cross-browser Jank
+// --------------------------------------------------
+
+button.btn,
+input[type="submit"].btn {
+
+ // Firefox 3.6 only I believe
+ &::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+ }
+
+ // IE7 has some default padding on button controls
+ *padding-top: 2px;
+ *padding-bottom: 2px;
+ &.large {
+ *padding-top: 7px;
+ *padding-bottom: 7px;
+ }
+ &.small {
+ *padding-top: 3px;
+ *padding-bottom: 3px;
+ }
+}
121 _includes/themes/sf/less/carousel.less
@@ -0,0 +1,121 @@
+// CAROUSEL
+// --------
+
+.carousel {
+ position: relative;
+ margin-bottom: @baseLineHeight;
+ line-height: 1;
+}
+
+.carousel-inner {
+ overflow: hidden;
+ width: 100%;
+ position: relative;
+}
+
+.carousel {
+
+ .item {
+ display: none;
+ position: relative;
+ .transition(.6s ease-in-out left);
+ }
+
+ // Account for jankitude on images
+ .item > img {
+ display: block;
+ line-height: 1;
+ }
+
+ .active,
+ .next,
+ .prev { display: block; }
+
+ .active {
+ left: 0;
+ }
+
+ .next,
+ .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ .next {
+ left: 100%;
+ }
+ .prev {
+ left: -100%;
+ }
+ .next.left,
+ .prev.right {
+ left: 0;
+ }
+
+ .active.left {
+ left: -100%;
+ }
+ .active.right {
+ left: 100%;
+ }
+
+}
+
+// Left/right controls for nav
+// ---------------------------
+
+.carousel-control {
+ position: absolute;
+ top: 40%;
+ left: 15px;
+ width: 40px;
+ height: 40px;
+ margin-top: -20px;
+ font-size: 60px;
+ font-weight: 100;
+ line-height: 30px;
+ color: @white;
+ text-align: center;
+ background: @grayDarker;
+ border: 3px solid @white;
+ .border-radius(23px);
+ .opacity(50);
+
+ // we can't have this transition here
+ // because webkit cancels the carousel
+ // animation if you trip this while
+ // in the middle of another animation
+ // ;_;
+ // .transition(opacity .2s linear);
+
+ // Reposition the right one
+ &.right {
+ left: auto;
+ right: 15px;
+ }
+
+ // Hover state
+ &:hover {
+ color: @white;
+ text-decoration: none;
+ .opacity(90);
+ }
+}
+
+// Caption for text below images
+// -----------------------------
+
+.carousel-caption {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ padding: 10px 15px 5px;
+ background: @grayDark;
+ background: rgba(0,0,0,.75);
+}
+.carousel-caption h4,
+.carousel-caption p {
+ color: @white;
+}
18 _includes/themes/sf/less/close.less
@@ -0,0 +1,18 @@
+// CLOSE ICONS
+// -----------
+
+.close {
+ float: right;
+ font-size: 20px;
+ font-weight: bold;
+ line-height: @baseLineHeight;
+ color: @black;
+ text-shadow: 0 1px 0 rgba(255,255,255,1);
+ .opacity(20);
+ &:hover {
+ color: @black;
+ text-decoration: none;
+ .opacity(40);
+ cursor: pointer;
+ }
+}
57 _includes/themes/sf/less/code.less
@@ -0,0 +1,57 @@
+// Code.less
+// Code typography styles for the <code> and <pre> elements
+// --------------------------------------------------------
+
+// Inline and block code styles
+code,
+pre {
+ padding: 0 3px 2px;
+ #font > #family > .monospace;
+ font-size: @baseFontSize - 1;
+ color: @grayDark;
+ .border-radius(3px);
+}
+
+// Inline code
+code {
+ padding: 3px 4px;
+ color: #d14;
+ background-color: #f7f7f9;
+ border: 1px solid #e1e1e8;
+}
+
+// Blocks of code
+pre {
+ display: block;
+ padding: (@baseLineHeight - 1) / 2;
+ margin: 0 0 @baseLineHeight / 2;
+ font-size: 12px;
+ line-height: @baseLineHeight;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc; // fallback for IE7-8
+ border: 1px solid rgba(0,0,0,.15);
+ .border-radius(4px);
+ white-space: pre;
+ white-space: pre-wrap;
+ word-break: break-all;
+ word-wrap: break-word;
+
+ // Make prettyprint styles more spaced out for readability
+ &.prettyprint {
+ margin-bottom: @baseLineHeight;
+ }
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ padding: 0;
+ color: inherit;
+ background-color: transparent;
+ border: 0;
+ }
+}
+
+// Enable scrollable blocks of code
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
18 _includes/themes/sf/less/component-animations.less
@@ -0,0 +1,18 @@
+// COMPONENT ANIMATIONS
+// --------------------
+
+.fade {
+ .transition(opacity .15s linear);
+ opacity: 0;
+ &.in {
+ opacity: 1;
+ }
+}
+
+.collapse {
+ .transition(height .35s ease);
+ position:relative;
+ overflow:hidden;
+ height: 0;
+ &.in { height: auto; }
+}
130 _includes/themes/sf/less/dropdowns.less
@@ -0,0 +1,130 @@
+// DROPDOWN MENUS
+// --------------
+
+// Use the .menu class on any <li> element within the topbar or ul.tabs and you'll get some superfancy dropdowns
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle {
+ // The caret makes the toggle a bit too tall in IE7
+ *margin-bottom: -3px;
+}
+.dropdown-toggle:active,
+.open .dropdown-toggle {
+ outline: 0;
+}
+// Dropdown arrow/caret
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ text-indent: -99999px;
+ // IE7 won't do the border trick if there's a text indent, but it doesn't
+ // do the content that text-indent is hiding, either, so we're ok.
+ *text-indent: 0;
+ vertical-align: top;
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 4px solid @black;
+ .opacity(30);
+ content: "\2193";
+}
+.dropdown .caret {
+ margin-top: 8px;
+ margin-left: 2px;
+}
+.dropdown:hover .caret,
+.open.dropdown .caret {
+ .opacity(100);
+}
+// The dropdown menu (ul)
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: @zindexDropdown;
+ float: left;
+ display: none; // none by default, but block on "open" of the menu
+ min-width: 160px;
+ _width: 160px;
+ padding: 4px 0;
+ margin: 0; // override default ul
+ list-style: none;
+ background-color: @white;
+ border-color: #ccc;
+ border-color: rgba(0,0,0,.2);
+ border-style: solid;
+ border-width: 1px;
+ .border-radius(0 0 5px 5px);
+ .box-shadow(0 5px 10px rgba(0,0,0,.2));
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+ *border-right-width: 2px;
+ *border-bottom-width: 2px;
+
+ // Allow for dropdowns to go bottom up (aka, dropup-menu)
+ &.bottom-up {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+ }
+
+ // Dividers (basically an hr) within the dropdown
+ .divider {
+ height: 1px;
+ margin: 5px 1px;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ border-bottom: 1px solid @white;
+
+ // IE7 needs a set width since we gave a height. Restricting just
+ // to IE7 to keep the 1px left/right space in other browsers.
+ // It is unclear where IE is getting the extra space that we need
+ // to negative-margin away, but so it goes.
+ *width: 100%;
+ *margin: -5px 0 5px;
+ }
+
+ // Links within the dropdown menu
+ a {
+ display: block;
+ padding: 3px 15px;
+ clear: both;
+ font-weight: normal;
+ line-height: @baseLineHeight;
+ color: @gray;
+ white-space: nowrap;
+ }
+}
+
+// Hover state
+.dropdown-menu li > a:hover,
+.dropdown-menu .active > a,
+.dropdown-menu .active > a:hover {
+ color: @white;
+ text-decoration: none;
+ background-color: @linkColor;
+}
+
+// Open state for the dropdown
+.dropdown.open {
+ // IE7's z-index only goes to the nearest positioned ancestor, which would
+ // make the menu appear below buttons that appeared later on the page
+ *z-index: @zindexDropdown;
+
+ .dropdown-toggle {
+ color: @white;
+ background: #ccc;
+ background: rgba(0,0,0,.3);
+ }
+ .dropdown-menu {
+ display: block;
+ }
+}
+
+// Typeahead
+.typeahead {
+ margin-top: 2px; // give it some space to breathe
+ .border-radius(4px);
+}
522 _includes/themes/sf/less/forms.less
@@ -0,0 +1,522 @@
+// Forms.less
+// Base styles for various input types, form layouts, and states
+// -------------------------------------------------------------
+
+
+// GENERAL STYLES
+// --------------
+
+// Make all forms have space below them
+form {
+ margin: 0 0 @baseLineHeight;
+}
+
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+// Groups of fields with labels on top (legends)
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: @baseLineHeight * 1.5;
+ font-size: @baseFontSize * 1.5;
+ line-height: @baseLineHeight * 2;
+ color: @grayDark;
+ border: 0;
+ border-bottom: 1px solid #eee;
+
+ // Small
+ small {
+ font-size: @baseLineHeight * .75;
+ color: @grayLight;
+ }
+}
+
+// Set font for forms
+label,
+input,
+button,
+select,
+textarea {
+ #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here
+}
+input,
+button,
+select,
+textarea {
+ #font > #family > .sans-serif(); // And only set font-family here for those that need it (note the missing label element)
+}
+
+// Identify controls by their labels
+label {
+ display: block;
+ margin-bottom: 5px;
+ color: @grayDark;
+}
+
+// Inputs, Textareas, Selects
+input,
+textarea,
+select,
+.uneditable-input {
+ display: inline-block;
+ width: 210px;
+ height: @baseLineHeight;
+ padding: 4px;
+ margin-bottom: 9px;
+ font-size: @baseFontSize;
+ line-height: @baseLineHeight;
+ color: @gray;
+ border: 1px solid #ccc;
+ .border-radius(3px);
+}
+.uneditable-textarea {
+ width: auto;
+ height: auto;
+}
+
+// Inputs within a label
+label input,
+label textarea,
+label select {
+ display: block;
+}
+
+// Mini reset for unique input types
+input[type="image"],
+input[type="checkbox"],
+input[type="radio"] {
+ width: auto;
+ height: auto;
+ padding: 0;
+ margin: 3px 0;
+ *margin-top: 0; /* IE7 */
+ line-height: normal;
+ cursor: pointer;
+ .border-radius(0);
+ border: 0 \9; /* IE9 and down */
+}
+input[type="image"] {
+ border: 0;
+}
+
+// Reset the file input to browser defaults
+input[type="file"] {
+ width: auto;
+ padding: initial;
+ line-height: initial;
+ border: initial;
+ background-color: @white;
+ background-color: initial;
+ .box-shadow(none);
+}
+
+// Help out input buttons
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ width: auto;
+ height: auto;
+}
+
+// Set the height of select and file controls to match text inputs
+select,
+input[type="file"] {
+ height: 28px; /* In IE7, the height of the select element cannot be changed by height, only font-size */
+ *margin-top: 4px; /* For IE7, add top margin to align select with labels */
+ line-height: 28px;
+}
+
+// Reset line-height for IE
+input[type="file"] {
+ line-height: 18px \9;
+}
+
+// Chrome on Linux and Mobile Safari need background-color
+select {
+ width: 220px; // default input width + 10px of padding that doesn't get applied
+ background-color: @white;
+}
+
+// Make multiple select elements height not fixed
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+// Remove shadow from image inputs
+input[type="image"] {
+ .box-shadow(none);
+}
+
+// Make textarea height behave
+textarea {
+ height: auto;
+}
+
+// Hidden inputs
+input[type="hidden"] {
+ display: none;
+}
+
+
+
+// CHECKBOXES & RADIOS
+// -------------------
+
+// Indent the labels to position radios/checkboxes as hanging
+.radio,
+.checkbox {
+ padding-left: 18px;
+}
+.radio input[type="radio"],
+.checkbox input[type="checkbox"] {
+ float: left;
+ margin-left: -18px;
+}
+
+// Move the options list down to align with labels
+.controls > .radio:first-child,
+.controls > .checkbox:first-child {
+ padding-top: 5px; // has to be padding because margin collaspes
+}
+
+// Radios and checkboxes on same line
+// TODO v3: Convert .inline to .control-inline
+.radio.inline,
+.checkbox.inline {
+ display: inline-block;
+ padding-top: 5px;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+.radio.inline + .radio.inline,
+.checkbox.inline + .checkbox.inline {
+ margin-left: 10px; // space out consecutive inline controls
+}
+
+
+
+// FOCUS STATE
+// -----------
+
+input,
+textarea {
+ .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
+ @transition: border linear .2s, box-shadow linear .2s;
+ .transition(@transition);
+}
+input:focus,
+textarea:focus {
+ border-color: rgba(82,168,236,.8);
+ @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
+ .box-shadow(@shadow);
+ outline: 0;
+ outline: thin dotted \9; /* IE6-9 */
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus,
+select:focus {
+ .box-shadow(none); // override for file inputs
+ .tab-focus();
+}
+
+
+
+// INPUT SIZES
+// -----------
+
+// General classes for quick sizes
+.input-mini { width: 60px; }
+.input-small { width: 90px; }
+.input-medium { width: 150px; }
+.input-large { width: 210px; }
+.input-xlarge { width: 270px; }
+.input-xxlarge { width: 530px; }
+
+// Grid style input sizes
+input[class*="span"],
+select[class*="span"],
+textarea[class*="span"],
+.uneditable-input {
+ float: none;
+ margin-left: 0;
+}
+
+
+
+// GRID SIZING FOR INPUTS
+// ----------------------
+
+#inputGridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth);
+
+
+
+
+// DISABLED STATE
+// --------------
+
+// Disabled and read-only inputs
+input[disabled],
+select[disabled],
+textarea[disabled],
+input[readonly],
+select[readonly],
+textarea[readonly] {
+ background-color: #f5f5f5;
+ border-color: #ddd;
+ cursor: not-allowed;
+}
+
+
+
+
+// FORM FIELD FEEDBACK STATES
+// --------------------------
+
+// Warning
+.control-group.warning {
+ .formFieldState(@warningText, @warningText, @warningBackground);
+}
+// Error
+.control-group.error {
+ .formFieldState(@errorText, @errorText, @errorBackground);
+}
+// Success
+.control-group.success {
+ .formFieldState(@successText, @successText, @successBackground);
+}
+
+// HTML5 invalid states
+// Shares styles with the .control-group.error above
+input:focus:required:invalid,
+textarea:focus:required:invalid,
+select:focus:required:invalid {
+ color: #b94a48;
+ border-color: #ee5f5b;
+ &:focus {
+ border-color: darken(#ee5f5b, 10%);
+ .box-shadow(0 0 6px lighten(#ee5f5b, 20%));
+ }
+}
+
+
+
+// FORM ACTIONS
+// ------------
+
+.form-actions {
+ padding: (@baseLineHeight - 1) 20px @baseLineHeight;
+ margin-top: @baseLineHeight;
+ margin-bottom: @baseLineHeight;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+}
+
+// For text that needs to appear as an input but should not be an input
+.uneditable-input {
+ display: block;
+ background-color: @white;
+ border-color: #eee;
+ .box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
+ cursor: not-allowed;
+}
+
+// Placeholder text gets special styles; can't be bundled together though for some reason
+.placeholder(@grayLight);
+
+
+
+// HELP TEXT
+// ---------
+
+.help-block {
+ display: block; // account for any element using help-block
+ margin-top: 5px;
+ margin-bottom: 0;
+ color: @grayLight;
+}
+
+.help-inline {
+ display: inline-block;
+ .ie7-inline-block();
+ margin-bottom: 9px;
+ vertical-align: middle;
+ padding-left: 5px;
+}
+
+
+
+// INPUT GROUPS
+// ------------
+
+// Allow us to put symbols and text within the input field for a cleaner look
+.input-prepend,
+.input-append {
+ margin-bottom: 5px;
+ .clearfix(); // Clear the float to prevent wrapping
+ input,
+ .uneditable-input {
+ .border-radius(0 3px 3px 0);
+ &:focus {
+ position: relative;
+ z-index: 2;
+ }
+ }
+ .uneditable-input {
+ border-left-color: #ccc;
+ }
+ .add-on {
+ float: left;
+ display: block;
+ width: auto;
+ min-width: 16px;
+ height: @baseLineHeight;
+ margin-right: -1px;
+ padding: 4px 5px;
+ font-weight: normal;
+ line-height: @baseLineHeight;
+ color: @grayLight;
+ text-align: center;
+ text-shadow: 0 1px 0 @white;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ .border-radius(3px 0 0 3px);
+ }
+ .active {
+ background-color: lighten(@green, 30);
+ border-color: @green;
+ }
+}
+.input-prepend {
+ .add-on {
+ *margin-top: 1px; /* IE6-7 */
+ }
+}
+.input-append {
+ input,
+ .uneditable-input {
+ float: left;
+ .border-radius(3px 0 0 3px);
+ }
+ .uneditable-input {
+ border-left-color: #eee;
+ border-right-color: #ccc;
+ }
+ .add-on {
+ margin-right: 0;
+ margin-left: -1px;
+ .border-radius(0 3px 3px 0);
+ }
+ input:first-child {
+ // In IE7, having a hasLayout container (from clearfix's zoom:1) can make the first input
+ // inherit the sum of its ancestors' margins.
+ *margin-left: -160px;
+
+ &+.add-on {
+ *margin-left: -21px;
+ }
+ }
+}
+
+
+
+// SEARCH FORM
+// -----------
+
+.search-query {
+ padding-left: 14px;
+ padding-right: 14px;
+ margin-bottom: 0; // remove the default margin on all inputs
+ .border-radius(14px);
+}
+
+
+
+// HORIZONTAL & VERTICAL FORMS
+// ---------------------------
+
+// Common properties
+// -----------------
+
+.form-search,
+.form-inline,
+.form-horizontal {
+ input,
+ textarea,
+ select,
+ .help-inline,