Frank Becker avatar Frank Becker committed 72bee93

1st version of booker form

Comments (0)

Files changed (67)

install/requirements.txt

 pyScss
 pytz
 milkman
-easy_thumbnails
 git+http://github.com/justinlilly/django-gencal.git#egg=django_gencal
-django-floppyforms
 gunicorn
 django-floppyforms
 django-haystack

src/booker/forms.py

+# -*- coding: utf-8 -*-
+
+"""forms of myhost booker app
+"""
+
+from datetime import datetime
+#from django import forms
+import floppyforms as forms
+from django.utils.translation import ugettext_lazy as _
+from hosts.models import Host, MyHostUser
+
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Layout, Div, Submit, HTML, Button, Row, Field
+from crispy_forms.bootstrap import AppendedText, PrependedText, FormActions
+
+from booker import models
+
+
+class DatePicker(forms.DateInput):
+    template_name = 'booker/datepicker.html'
+
+    class Media:
+        js = (
+            'js/jquery.js',
+            'js/jquery-ui.min.js',
+            )
+        css = {
+            'all': (
+                'css/jquery-ui.css',
+                )
+        }
+
+
+class BookHostForm(forms.Form):
+    """
+    Form to book a host
+    """
+
+    date_from = forms.DateField(
+        help_text = _(u"Date and Time to book from"),
+        label="",
+        widget=DatePicker,
+    )
+
+    date_to = forms.DateTimeField(
+        help_text = _(u"Date and Time to book to"),
+        label="",
+    )
+
+    priority = forms.ChoiceField(
+        label="",
+        choices = (
+            (_('high'), _(u"Highest priority.")),
+            (_('normal'), _(u"Normal priority")),
+            (_('low'), _(u"Low priority")),
+            ),
+        widget = forms.RadioSelect,
+        initial = 'normal',
+    )
+    helper = FormHelper()
+    helper.form_class = 'form-horizontal'
+    helper.layout = Layout(
+        #Field('date_from', css_class='input-xlarge'),
+        PrependedText('date_from', 'from'),
+        #Field('date_to', css_class='input-xlarge'),
+        PrependedText('date_to', 'to'),
+        Field('priority', style="background: #FAFAFA; padding: 10px;"),
+        FormActions(
+            Submit('save_form', 'Save', css_class="btn-success"),
+            Submit('cancel', 'Cancel'),
+        )
+    )
+
+class MessageForm(forms.Form):
+    text_input = forms.CharField()
+
+    date_from = forms.DateField(
+
+        help_text = u"Datum bitte",
+
+    )
+
+    textarea = forms.CharField(
+        widget = forms.Textarea(),
+    )
+
+    radio_buttons = forms.ChoiceField(
+        choices = (
+            ('option_one', "Option one is this and that be sure to include why it's great"),
+            ('option_two', "Option two can is something else and selecting it will deselect option one")
+            ),
+        widget = forms.RadioSelect,
+        initial = 'option_two',
+    )
+
+    checkboxes = forms.MultipleChoiceField(
+        choices = (
+            ('option_one', "Option one is this and that be sure to include why it's great"),
+            ('option_two', 'Option two can also be checked and included in form results'),
+            ('option_three', 'Option three can yes, you guessed it also be checked and included in form results')
+            ),
+        initial = 'option_one',
+        widget = forms.CheckboxSelectMultiple,
+        help_text = "<strong>Note:</strong> Labels surround all the options for much larger click areas and a more usable form.",
+    )
+
+    appended_text = forms.CharField(
+        help_text = "Here's more help text"
+    )
+
+    prepended_text = forms.CharField()
+
+    prepended_text_two = forms.CharField()
+
+    multicolon_select = forms.MultipleChoiceField(
+        choices = (('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5')),
+    )
+
+    # Uni-form
+    helper = FormHelper()
+    helper.form_class = 'form-horizontal'
+    helper.layout = Layout(
+        Field('text_input', css_class='input-xlarge'),
+        Field('date_from', css_class='input-xlarge'),
+        Field('textarea', rows="3", css_class='input-xlarge'),
+        'radio_buttons',
+        Field('checkboxes', style="background: #FAFAFA; padding: 10px;"),
+        AppendedText('appended_text', '.00'),
+        PrependedText('prepended_text', '<input type="checkbox" checked="checked" value="" id="" name="">', active=True),
+        PrependedText('prepended_text_two', '@'),
+        'multicolon_select',
+        FormActions(
+            Submit('save_changes', 'Save changes', css_class="btn-primary"),
+            Submit('cancel', 'Cancel'),
+        )
+    )

src/booker/templates/booker/booker_form.html

+{% load crispy_forms_tags %}
+
+
+<div class="row-fluid">
+    <div class="span8">
+        <div id="booker-form">
+            {% csrf_token %}
+            {% crispy form %}
+        </div>
+    </div>
+</div>
+

src/booker/templates/booker/datepicker.html

+{% include "floppyforms/input.html" %}
+
+<script type="text/javascript">
+    $(document).ready(function() {
+        var type = $('<input type="text" />').attr('type');
+        //var type = $('<input type="date" />').attr('type');
+        if (type == 'text') { // No HTML5 support
+            var options = {
+                dateFormat: 'yy-mm-dd'
+            };
+            $('#{{ attrs.id }}').datepicker(options);
+        }
+    });
+</script>

src/booker/templates/booker/test_form.html

+{% extends 'base.html' %}
+{% load crispy_forms_tags %}
+
+{% block main_content %}
+    {% csrf_token %}
+    {% crispy form %}
+{% endblock %}

src/booker/urls.py

+# -*- coding: utf-8 -*-
+
+"""urls of hosts app,
+"""
+from django.conf.urls import patterns, include, url
+from booker.views import index
+from hosts.views import HostDetails, get_host_names_as_json, host_details_refresh
+
+urlpatterns = patterns(
+    '',
+    url(r'book/(?P<name>[-\w]+)/$', index, name='book-host'),
+    )
+

src/booker/views.py

-# Create your views here.
+# -*- coding: utf-8 -*-
+
+"""views of myhost booker app
+"""
+
+# -*- coding: utf-8 -*-
+from django.shortcuts import render, get_object_or_404, redirect
+from forms import MessageForm
+from hosts.models import Host
+
+#def index(request):
+    # This view is missing all form handling logic for simplicity of the example
+#    return render(request, 'index.html', {'form': MessageForm()})
+
+def index(request, name=None, template_name='booker/test_form.html'):
+    """
+    bla
+    :param request:
+    :param host:
+    :param template_name:
+    :return:
+    """
+    host = get_object_or_404(Host, name=name)
+    form = MessageForm(request.POST or None)
+    if form.is_valid():
+        myhost = form.save()
+        myhost.edited_at_djangocon = True
+        myhost.save()
+        return redirect('home')
+    return render(request, template_name, {'form': form, 'host': host})

src/fabric_tapper.py

+# -*- coding: utf-8 -*-
+
+"""
+Python source code - replace this with a description of the code and write
+the code below this text.
+"""
+from fabric.api import run
+from fabric.state import env
+
+__author__ = "Frank Becker <fb@alien8.de>"
+__version__ = ": 0.0 $"
+__date__ = ": YDATE $"
+__copyright__ = "Copyright (c) 2012 Frank Becker"
+__license__ = "Python"
+
+
+env.hosts = ['tapper@tapper:22',]
+env.passwords = {'tapper@tapper:22': 'tapper'}
+
+def get_tapper_hosts():
+    """
+
+    Args:
+
+
+    Returns:
+
+    """
+    cmd = 'tapper-testrun listhost -v'
+    result = run(cmd, shell=True)
+    return result
+
+
+def main():
+    print get_tapper_hosts()
+
+
+if __name__ == "__main__":
+    main()

src/hosts/tasks.py

 
 from celery.task.schedules import crontab
 from celery.decorators import periodic_task
+from celery.decorators import task
 import tools.tapper_scraper
 import tools.hwdb_scraper
 import tools.ping_hosts
 
 @periodic_task(run_every=crontab(hour="*", minute="5", day_of_week="*"))
 def update_from_tapper():
-    print "update from tapper"
+    #print "update from tapper"
     tools.tapper_scraper.main()
 
 @periodic_task(run_every=crontab(hour="*", minute="15", day_of_week="*"))
 def update_ping():
-    print "update from tapper"
+    #print "update from tapper"
     tools.ping_hosts.main()
 
+@task
+def ping_host(host):
+    """
+    Task to ping the host
+
+    :param host: host name as string
+    """
+    tools.ping_hosts.ping_and_update_host(host)
+
 def main():
     tools.hwdb_scraper.main()
     tools.tapper_scraper.main()

src/hosts/templates/hosts/generic_details.html

+<div id="host-details" class="span12 frame status status-{{ status_last_ping }}" data-refresh-url="{% url host-details-refresh name=host.name %}">
+    <h1>Host Details</h1>
+    <p></p>
+    <ul>
+        <li>
+            last update: {{ host.time_change }}
+        </li>
+        <li>
+            Hardwaredb ID:
+            <a href="http://quecksilber.amd.com/hardwaredb/index.php?head=systems&rev_id={{ host.hardware_db_id }}">
+                {{ host.hardware_db_id }}
+            </a>
+        </li>
+        <li>
+            CPUs: {{ host.cpu_number }}x {{ host.cpu_type.name }}
+        </li>
+        <li>
+            location: {{ host.location }}
+        </li>
+        <li>
+            Last ping: {{ host.time_last_ping|date:"r" }}
+        </li>
+    </ul>
+    <!-- div class="spinner"></div -->
+    <a href="#" class="btn ajax" data-method="get"
+       data-append="#host-details"
+       data-refresh="#host-details"
+       data-spinner=".spinner">
+        <i class="icon icon-check"></i>
+        update
+    </a>
+</div>

src/hosts/templates/hosts/host_detail.html

 {% load thumbnail %}
 {% load gencal %}
 
-
 {% block main_content %}
-        <div class="span3">
-            <div class="well sidebar-nav">
+    <div class="span3">
+        <div class="well sidebar-nav">
+        </div>
+    </div>
+    <div class="span9">
+    <div class="row-fluid">
+    <div class="frame">
+        <div class="span4">
+            <div class="hero-unit">
+                <h1>{{ object.name }}</h1>
             </div>
         </div>
-        <div class="span9">
-            <div class="hero-unit">
-                <div class="span4">
-                    <h1>{{ object.name }}</h1>
-                </div>
-                <div class="span5">
-                    {% if host.user.avatar %}
-                    <img src="{{ host.user.avatar|thumbnail_url:'avatar' }}" alt="">
-                    {% endif %}
-                    {{ host.user.user.first_name }}
-                    {{ host.user.user.last_name }}
-                    - {{ host.user.ldap }}
-                </div>
-                <button class="btn btn-large btn-success">Book host now</button>
-                </button>
-            </div>
-            <div class="row-fluid">
-                <div class="frame">
-                    <div class="span4">
-                        {% gencal queryset 2012 06 %}
-                    </div>
-                    <div class="span4">
-                        {% gencal queryset 2012 07 %}
-                    </div>
-                    <div class="span4">
-                        {% gencal queryset 2012 08 %}
-                    </div>
-                </div>
-            </div>
-            <div class="row-fluid">
-                <div class="span12 frame status status-{{ status_last_ping }}">
-                    <h1>Host Details</h1>
-                    <p></p>
-                    <ul>
-                        <li>
-                            last update: {{ host.time_change }}
-                        </li>
-                        <li>
-                            Hardwaredb ID:
-                            <a href="http://quecksilber.amd.com/hardwaredb/index.php?head=systems&rev_id={{ host.hardware_db_id }}">
-                                {{ host.hardware_db_id }}
-                            </a>
-                        </li>
-                        <li>
-                            CPUs: {{ host.cpu_number }}x {{ host.cpu_type.name }}
-                        </li>
-                        <li>
-                            location: {{ host.location }}
-                        </li>
-                        <li>
-                            Last ping: {{ host.time_last_ping|date:"r" }}
-                        </li>
+        <div class="span5">
+            {% if host.user.avatar %}
+                <img src="{{ host.user.avatar|thumbnail_url:'avatar' }}" alt="">
+            {% endif %}
+            {{ host.user.user.first_name }}
+            {{ host.user.user.last_name }}
+            - {{ host.user.ldap }}
+        </div>
+        <div class="span3">
+            <div class="btn-group btn-booker">
+                {% if user.is_authenticated %}
+                    <a class="btn btn-large btn-success" href="#" onclick="toggle_feature('booker-form'); return false"><i class="icon-calendar icon-white"></i>Book host</a>
+                    <a class="btn btn-large btn-success dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>
+                    <ul class="dropdown-menu">
+                        <li><a href="#"><i class="icon-pencil"></i> New</a></li>
+                        <li><a href="#"><i class="icon-pencil"></i> Edit</a></li>
+                        <li><a href="#"><i class="icon-trash"></i> Return</a></li>
                     </ul>
-                </div>
-            </div>
-            <div class="row-fluid">
-                <div class="span12 frame status status-{{ status_tapper }}">
-                    <h1>Tapper Details</h1>
-                    <p></p>
-                    {% if host.in_tapper %}
-                        {% with host.tapper as t %}
-                            <ul>
-                                <li>
-                                    Tapper ID: <a href="http://tapper/tapper/testruns/host/{{ host.name }}">{{ t.tapper_id }}</a>
-                                </li>
-                                <li>
-                                    {% if t.tapper_status != 'free' %}
-                                        Current testrun id: <a href="http://tapper/tapper/testruns/id/{{ t.tapper_status }}">{{ t.tapper_status }}</a>
-                                    {% else %}
-                                        Host is not running any tapper testrun right now
-                                    {% endif %}
-                                </li>
-                                <li>
-                                    Comment: {{ t.comment }}
-                                </li>
-                                <li>
-                                    Queues: {{ t.queues }}
-                                </li>
-                                <li>
-                                    last update: {{ t.time_last_update|date:"jS F Y H:i" }}
-                                </li>
-                            </ul>
-                        {% endwith %}
-                    {% else %}
-                        This host is not registered in Tapper.
-                    {% endif %}
-                </div>
+                    {% include "booker/booker_form.html" %}
+                {% else %}
+                    <button class="btn btn-large btn-success disabled">Book host now</button>
+                {% endif %}
             </div>
         </div>
+    </div>
+    </div>
+    <div class="row-fluid">
+        <div class="frame">
+            <div class="span4">
+                {% gencal queryset 2012 06 %}
+            </div>
+            <div class="span4">
+                {% gencal queryset 2012 07 %}
+            </div>
+            <div class="span4">
+                {% gencal queryset 2012 08 %}
+            </div>
+        </div>
+    </div>
+    <div class="row-fluid">
+        {% include "hosts/generic_details.html" %}
+    </div>
+    <div class="row-fluid">
+        {% include "hosts/tapper_details.html" %}
+    </div>
+    </div>
+
 {% endblock %}
+{% block js_bottom %}
+    <script language="JavaScript">
+        function toggle_feature (id) {
+            $('#'+id).toggle('fast');
+        };
+    </script>
+{% endblock js_bottom %}
+{% comment %}
+        // http://stackoverflow.com/questions/220767/auto-refreshing-div-with-jquery
+
+        $(function() {
+            update_generic_details = function () {
+                $("#host-details").html('Loading..');
+                $.ajax({
+                    type: 'GET',
+                    url: "{% url host-details-refresh name=host.name %}",
+                    timeout: 2000,
+                    success: function(data) {
+                        $("#host-details").html(data.html);
+                        console.log(data.html)
+                        //$(".spinner").html('');
+                        window.setTimeout(update_generic_details, 10000);
+                    },
+                    error: function (XMLHttpRequest, textStatus, errorThrown) {
+                        $("#host-details").html('Timeout contacting server..');
+                        window.setTimeout(update_generic_details, 60000);
+                    }
+                });
+            }
+        });
+        setInterval( "update_generic_details();", 60000 );  ///////// 5 seconds
+{% endcomment %}

src/hosts/templates/hosts/tapper_details.html

+<div class="span12 frame status status-{{ status_tapper }}">
+    <h1>Tapper Details</h1>
+    <p></p>
+    {% if host.in_tapper %}
+        {% with host.tapper as t %}
+            <ul>
+                <li>
+                    Tapper ID: <a href="http://tapper/tapper/testruns/host/{{ host.name }}">{{ t.tapper_id }}</a>
+                </li>
+                <li>
+                    {% if t.tapper_status != 'free' %}
+                        Current testrun id: <a href="http://tapper/tapper/testruns/id/{{ t.tapper_status }}">{{ t.tapper_status }}</a>
+                    {% else %}
+                        Host is not running any tapper testrun right now
+                    {% endif %}
+                </li>
+                <li>
+                    Comment: {{ t.comment }}
+                </li>
+                <li>
+                    Queues: {{ t.queues }}
+                </li>
+                <li>
+                    last update: {{ t.time_last_update|date:"jS F Y H:i" }}
+                </li>
+            </ul>
+        {% endwith %}
+    {% else %}
+        This host is not registered in Tapper.
+    {% endif %}
+</div>
+

src/hosts/urls.py

 """urls of hosts app,
 """
 from django.conf.urls import patterns, include, url
-from hosts.views import HostDetails, get_host_names_as_json
+from hosts.views import HostDetails, get_host_names_as_json, host_details_refresh
 
 urlpatterns = patterns(
     '',
     url(r'name/(?P<slug>[-\w]+)/$', HostDetails.as_view(), name='host-detail'),
     url(r'names/$', get_host_names_as_json, name='host-names-as-json'),
+    url(r'refresh/(?P<name>[-\w]+)/$', host_details_refresh, name='host-details-refresh'),
     )
 

src/hosts/views.py

 import json
 from django.http import HttpResponse, HttpResponseRedirect
 from django.template.context import RequestContext
+from django.shortcuts import redirect, render
+from django.template.loader import render_to_string
 from django.utils import timezone
 from django.shortcuts import render_to_response, get_object_or_404
 
 from django.views.generic import DetailView
+from booker.forms import MessageForm, BookHostForm
+from hosts import tasks
 from hosts.models import (Host, CPU, MyHostUser, Vendor, RAM, NetworkCard,
                           GraphicBoard, BIOS,)
 
         context['now'] = timezone.now()
         context['hosts'] = [e[0] for e in Host.objects.all().values_list('name')]
         context['status_last_ping'] = get_currentness(self.object.time_last_ping)
+        context['form'] = BookHostForm()
         if self.object.tapper:
             context['status_tapper'] = get_currentness(self.object.tapper.time_last_update)
         else:
 
     return HttpResponse(json.dumps(hosts), mimetype="application/json")
 
+def host_details_refresh(request, name=None):
+    """
+    Return ajax request for generic host info
+    :param request:
+    :param name: Hostname
+    :return: json
+    """
+    host = get_object_or_404(Host, name=name)
+    if request.is_ajax():
+        data = {
+            "html": render_to_string("hosts/generic_details.html", {
+                "host": host,
+                'status_last_ping': get_currentness(host.time_last_ping),
+            }, context_instance=RequestContext(request))
+        }
+        tasks.ping_host(name)
+        return HttpResponse(json.dumps(data), mimetype="application/json")
+    return render(request, "hosts/generic_details.html", {
+        "host": get_object_or_404(Host, name=name),
+        'status_last_ping': get_currentness(host.time_last_ping),
+    })

src/project/settings.py

 
 TEMPLATE_DIRS = (
     os.path.join(BASEDIR, "templates/"),
+    #os.path.join(BASEDIR, "admin_bootstrap/templates/"),
     # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
     # Always use forward slashes, even on Windows.
     # Don't forget to use absolute paths, not relative paths.
     'gencal',
     'taggit',
     'floppyforms',
-    #'crispyforms',
+    'crispy_forms',
     # myhosts modules
     'hosts',
     'booker',
 }
 
 DEFAULT_TIMEZONE = pytz.timezone('Europe/Berlin')
+
+CRISPY_TEMPLATE_PACK = 'bootstrap'

src/project/urls.py

     url(r'^admin/', include(admin.site.urls)),
 
     url(r'^hosts/', include('hosts.urls')),
+    url(r'^booker/', include('booker.urls')),
 )
 
 if settings.DEBUG:

src/templates/base.html

+{% comment %}
+TODO: add jquery ui for datepicker
+{% endcomment %}
 <!DOCTYPE html>
 {% load compress %}
 {% load i18n %}
     <meta name="keywords" content="{% page_attribute meta_keywords %}"/>
     {% endcomment %}
 
+      <script src="{{ STATIC_URL }}js/jquery.js"></script>
+      <script src="{{ STATIC_URL }}js/jquery-ui.min.js"></script>
+      <link href="{{ STATIC_URL }}css/jquery-ui.css" rel="stylesheet">
+
     <link href="{{ STATIC_URL }}css/bootstrap.css" rel="stylesheet">
     <link href="{{ STATIC_URL }}css/bootstrap-responsive.css" rel="stylesheet">
       {% compress css %}
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
         </a>
-        <a class="brand" href="#">MyHost</a>
+        <a class="brand" href="/">MyHost</a>
         <div class="btn-group pull-right">
           <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
             <i class="icon-user"></i>
               {% if user.is_authenticated %}
                   {{ user.username }}
               {% else %}
+                  <a href="/admin">
                   <span class="alert-error">please log in</span>
+                  </a>
               {% endif %}
             <span class="caret"></span>
           </a>
   {% comment %}
     <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
   {% endcomment %}
-  <script src="{{ STATIC_URL }}js/jquery.js"></script>
   <script src="{{ STATIC_URL }}js/bootstrap-transition.js"></script>
   <script src="{{ STATIC_URL }}js/bootstrap-typeahead.js"></script>
+  <script src="{{ STATIC_URL }}js/bootstrap-ajax.js"></script>
+  <script src="{{ STATIC_URL }}js/spin.min.js"></script>
+  <script src="{{ STATIC_URL }}js/bootstrap-dropdown.js"></script>
     {% comment %}
     <script src="{{ STATIC_URL }}js/bootstrap-carousel.js"></script>
     <script src="{{ STATIC_URL }}js/bootstrap-alert.js"></script>
     <script src="{{ STATIC_URL }}js/bootstrap-modal.js"></script>
-    <script src="{{ STATIC_URL }}js/bootstrap-dropdown.js"></script>
     <script src="{{ STATIC_URL }}js/bootstrap-scrollspy.js"></script>
     <script src="{{ STATIC_URL }}js/bootstrap-tab.js"></script>
     <script src="{{ STATIC_URL }}js/bootstrap-tooltip.js"></script>

src/templates/css/bootstrap-responsive.css

 /*!
- * Bootstrap Responsive v2.0.4
+ * Bootstrap Responsive v2.1.0
  *
  * Copyright 2012 Twitter, Inc
  * Licensed under the Apache License v2.0
 .clearfix:before,
 .clearfix:after {
   display: table;
+  line-height: 0;
   content: "";
 }
 
 .input-block-level {
   display: block;
   width: 100%;
-  min-height: 28px;
+  min-height: 30px;
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
-      -ms-box-sizing: border-box;
           box-sizing: border-box;
 }
 
   display: none !important;
 }
 
+.visible-desktop {
+  display: inherit !important;
+}
+
+@media (min-width: 768px) and (max-width: 979px) {
+  .hidden-desktop {
+    display: inherit !important;
+  }
+  .visible-desktop {
+    display: none !important ;
+  }
+  .visible-tablet {
+    display: inherit !important;
+  }
+  .hidden-tablet {
+    display: none !important;
+  }
+}
+
 @media (max-width: 767px) {
+  .hidden-desktop {
+    display: inherit !important;
+  }
+  .visible-desktop {
+    display: none !important;
+  }
   .visible-phone {
     display: inherit !important;
   }
   .hidden-phone {
     display: none !important;
   }
-  .hidden-desktop {
-    display: inherit !important;
-  }
-  .visible-desktop {
-    display: none !important;
-  }
 }
 
-@media (min-width: 768px) and (max-width: 979px) {
-  .visible-tablet {
-    display: inherit !important;
+@media (min-width: 1200px) {
+  .row {
+    margin-left: -30px;
+    *zoom: 1;
   }
-  .hidden-tablet {
-    display: none !important;
+  .row:before,
+  .row:after {
+    display: table;
+    line-height: 0;
+    content: "";
   }
-  .hidden-desktop {
-    display: inherit !important;
+  .row:after {
+    clear: both;
   }
-  .visible-desktop {
-    display: none !important ;
+  [class*="span"] {
+    float: left;
+    margin-left: 30px;
   }
-}
-
-@media (max-width: 480px) {
-  .nav-collapse {
-    -webkit-transform: translate3d(0, 0, 0);
+  .container,
+  .navbar-static-top .container,
+  .navbar-fixed-top .container,
+  .navbar-fixed-bottom .container {
+    width: 1170px;
   }
-  .page-header h1 small {
-    display: block;
-    line-height: 18px;
+  .span12 {
+    width: 1170px;
   }
-  input[type="checkbox"],
-  input[type="radio"] {
-    border: 1px solid #ccc;
+  .span11 {
+    width: 1070px;
   }
-  .form-horizontal .control-group > label {
-    float: none;
-    width: auto;
-    padding-top: 0;
-    text-align: left;
+  .span10 {
+    width: 970px;
   }
-  .form-horizontal .controls {
-    margin-left: 0;
+  .span9 {
+    width: 870px;
   }
-  .form-horizontal .control-list {
-    padding-top: 0;
+  .span8 {
+    width: 770px;
   }
-  .form-horizontal .form-actions {
-    padding-right: 10px;
-    padding-left: 10px;
+  .span7 {
+    width: 670px;
   }
-  .modal {
-    position: absolute;
-    top: 10px;
-    right: 10px;
-    left: 10px;
-    width: auto;
-    margin: 0;
+  .span6 {
+    width: 570px;
   }
-  .modal.fade.in {
-    top: auto;
+  .span5 {
+    width: 470px;
   }
-  .modal-header .close {
-    padding: 10px;
-    margin: -10px;
+  .span4 {
+    width: 370px;
   }
-  .carousel-caption {
-    position: static;
+  .span3 {
+    width: 270px;
   }
-}
-
-@media (max-width: 767px) {
-  body {
-    padding-right: 20px;
-    padding-left: 20px;
+  .span2 {
+    width: 170px;
   }
-  .navbar-fixed-top,
-  .navbar-fixed-bottom {
-    margin-right: -20px;
-    margin-left: -20px;
+  .span1 {
+    width: 70px;
   }
-  .container-fluid {
-    padding: 0;
+  .offset12 {
+    margin-left: 1230px;
   }
-  .dl-horizontal dt {
-    float: none;
-    width: auto;
-    clear: none;
-    text-align: left;
+  .offset11 {
+    margin-left: 1130px;
   }
-  .dl-horizontal dd {
-    margin-left: 0;
+  .offset10 {
+    margin-left: 1030px;
   }
-  .container {
-    width: auto;
+  .offset9 {
+    margin-left: 930px;
+  }
+  .offset8 {
+    margin-left: 830px;
+  }
+  .offset7 {
+    margin-left: 730px;
+  }
+  .offset6 {
+    margin-left: 630px;
+  }
+  .offset5 {
+    margin-left: 530px;
+  }
+  .offset4 {
+    margin-left: 430px;
+  }
+  .offset3 {
+    margin-left: 330px;
+  }
+  .offset2 {
+    margin-left: 230px;
+  }
+  .offset1 {
+    margin-left: 130px;
   }
   .row-fluid {
     width: 100%;
+    *zoom: 1;
   }
-  .row,
-  .thumbnails {
+  .row-fluid:before,
+  .row-fluid:after {
+    display: table;
+    line-height: 0;
+    content: "";
+  }
+  .row-fluid:after {
+    clear: both;
+  }
+  .row-fluid [class*="span"] {
+    display: block;
+    float: left;
+    width: 100%;
+    min-height: 30px;
+    margin-left: 2.564102564102564%;
+    *margin-left: 2.5109110747408616%;
+    -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+            box-sizing: border-box;
+  }
+  .row-fluid [class*="span"]:first-child {
     margin-left: 0;
   }
-  [class*="span"],
-  .row-fluid [class*="span"] {
-    display: block;
-    float: none;
-    width: auto;
+  .row-fluid .span12 {
+    width: 100%;
+    *width: 99.94680851063829%;
+  }
+  .row-fluid .span11 {
+    width: 91.45299145299145%;
+    *width: 91.39979996362975%;
+  }
+  .row-fluid .span10 {
+    width: 82.90598290598291%;
+    *width: 82.8527914166212%;
+  }
+  .row-fluid .span9 {
+    width: 74.35897435897436%;
+    *width: 74.30578286961266%;
+  }
+  .row-fluid .span8 {
+    width: 65.81196581196582%;
+    *width: 65.75877432260411%;
+  }
+  .row-fluid .span7 {
+    width: 57.26495726495726%;
+    *width: 57.21176577559556%;
+  }
+  .row-fluid .span6 {
+    width: 48.717948717948715%;
+    *width: 48.664757228587014%;
+  }
+  .row-fluid .span5 {
+    width: 40.17094017094017%;
+    *width: 40.11774868157847%;
+  }
+  .row-fluid .span4 {
+    width: 31.623931623931625%;
+    *width: 31.570740134569924%;
+  }
+  .row-fluid .span3 {
+    width: 23.076923076923077%;
+    *width: 23.023731587561375%;
+  }
+  .row-fluid .span2 {
+    width: 14.52991452991453%;
+    *width: 14.476723040552828%;
+  }
+  .row-fluid .span1 {
+    width: 5.982905982905983%;
+    *width: 5.929714493544281%;
+  }
+  .row-fluid .offset12 {
+    margin-left: 105.12820512820512%;
+    *margin-left: 105.02182214948171%;
+  }
+  .row-fluid .offset12:first-child {
+    margin-left: 102.56410256410257%;
+    *margin-left: 102.45771958537915%;
+  }
+  .row-fluid .offset11 {
+    margin-left: 96.58119658119658%;
+    *margin-left: 96.47481360247316%;
+  }
+  .row-fluid .offset11:first-child {
+    margin-left: 94.01709401709402%;
+    *margin-left: 93.91071103837061%;
+  }
+  .row-fluid .offset10 {
+    margin-left: 88.03418803418803%;
+    *margin-left: 87.92780505546462%;
+  }
+  .row-fluid .offset10:first-child {
+    margin-left: 85.47008547008548%;
+    *margin-left: 85.36370249136206%;
+  }
+  .row-fluid .offset9 {
+    margin-left: 79.48717948717949%;
+    *margin-left: 79.38079650845607%;
+  }
+  .row-fluid .offset9:first-child {
+    margin-left: 76.92307692307693%;
+    *margin-left: 76.81669394435352%;
+  }
+  .row-fluid .offset8 {
+    margin-left: 70.94017094017094%;
+    *margin-left: 70.83378796144753%;
+  }
+  .row-fluid .offset8:first-child {
+    margin-left: 68.37606837606839%;
+    *margin-left: 68.26968539734497%;
+  }
+  .row-fluid .offset7 {
+    margin-left: 62.393162393162385%;
+    *margin-left: 62.28677941443899%;
+  }
+  .row-fluid .offset7:first-child {
+    margin-left: 59.82905982905982%;
+    *margin-left: 59.72267685033642%;
+  }
+  .row-fluid .offset6 {
+    margin-left: 53.84615384615384%;
+    *margin-left: 53.739770867430444%;
+  }
+  .row-fluid .offset6:first-child {
+    margin-left: 51.28205128205128%;
+    *margin-left: 51.175668303327875%;
+  }
+  .row-fluid .offset5 {
+    margin-left: 45.299145299145295%;
+    *margin-left: 45.1927623204219%;
+  }
+  .row-fluid .offset5:first-child {
+    margin-left: 42.73504273504273%;
+    *margin-left: 42.62865975631933%;
+  }
+  .row-fluid .offset4 {
+    margin-left: 36.75213675213675%;
+    *margin-left: 36.645753773413354%;
+  }
+  .row-fluid .offset4:first-child {
+    margin-left: 34.18803418803419%;
+    *margin-left: 34.081651209310785%;
+  }
+  .row-fluid .offset3 {
+    margin-left: 28.205128205128204%;
+    *margin-left: 28.0987452264048%;
+  }
+  .row-fluid .offset3:first-child {
+    margin-left: 25.641025641025642%;
+    *margin-left: 25.53464266230224%;
+  }
+  .row-fluid .offset2 {
+    margin-left: 19.65811965811966%;
+    *margin-left: 19.551736679396257%;
+  }
+  .row-fluid .offset2:first-child {
+    margin-left: 17.094017094017094%;
+    *margin-left: 16.98763411529369%;
+  }
+  .row-fluid .offset1 {
+    margin-left: 11.11111111111111%;
+    *margin-left: 11.004728132387708%;
+  }
+  .row-fluid .offset1:first-child {
+    margin-left: 8.547008547008547%;
+    *margin-left: 8.440625568285142%;
+  }
+  input,
+  textarea,
+  .uneditable-input {
     margin-left: 0;
   }
-  .input-large,
-  .input-xlarge,
-  .input-xxlarge,
-  input[class*="span"],
-  select[class*="span"],
-  textarea[class*="span"],
-  .uneditable-input {
-    display: block;
-    width: 100%;
-    min-height: 28px;
-    -webkit-box-sizing: border-box;
-       -moz-box-sizing: border-box;
-        -ms-box-sizing: border-box;
-            box-sizing: border-box;
+  .controls-row [class*="span"] + [class*="span"] {
+    margin-left: 30px;
   }
-  .input-prepend input,
-  .input-append input,
-  .input-prepend input[class*="span"],
-  .input-append input[class*="span"] {
-    display: inline-block;
-    width: auto;
+  input.span12,
+  textarea.span12,
+  .uneditable-input.span12 {
+    width: 1156px;
+  }
+  input.span11,
+  textarea.span11,
+  .uneditable-input.span11 {
+    width: 1056px;
+  }
+  input.span10,
+  textarea.span10,
+  .uneditable-input.span10 {
+    width: 956px;
+  }
+  input.span9,
+  textarea.span9,
+  .uneditable-input.span9 {
+    width: 856px;
+  }
+  input.span8,
+  textarea.span8,
+  .uneditable-input.span8 {
+    width: 756px;
+  }
+  input.span7,
+  textarea.span7,
+  .uneditable-input.span7 {
+    width: 656px;
+  }
+  input.span6,
+  textarea.span6,
+  .uneditable-input.span6 {
+    width: 556px;
+  }
+  input.span5,
+  textarea.span5,
+  .uneditable-input.span5 {
+    width: 456px;
+  }
+  input.span4,
+  textarea.span4,
+  .uneditable-input.span4 {
+    width: 356px;
+  }
+  input.span3,
+  textarea.span3,
+  .uneditable-input.span3 {
+    width: 256px;
+  }
+  input.span2,
+  textarea.span2,
+  .uneditable-input.span2 {
+    width: 156px;
+  }
+  input.span1,
+  textarea.span1,
+  .uneditable-input.span1 {
+    width: 56px;
+  }
+  .thumbnails {
+    margin-left: -30px;
+  }
+  .thumbnails > li {
+    margin-left: 30px;
+  }
+  .row-fluid .thumbnails {
+    margin-left: 0;
   }
 }
 
   .row:before,
   .row:after {
     display: table;
+    line-height: 0;
     content: "";
   }
   .row:after {
     margin-left: 20px;
   }
   .container,
+  .navbar-static-top .container,
   .navbar-fixed-top .container,
   .navbar-fixed-bottom .container {
     width: 724px;
   .row-fluid:before,
   .row-fluid:after {
     display: table;
+    line-height: 0;
     content: "";
   }
   .row-fluid:after {
     display: block;
     float: left;
     width: 100%;
-    min-height: 28px;
-    margin-left: 2.762430939%;
-    *margin-left: 2.7124309390000003%;
+    min-height: 30px;
+    margin-left: 2.7624309392265194%;
+    *margin-left: 2.709239449864817%;
     -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
-        -ms-box-sizing: border-box;
-            box-sizing: border-box;
-  }
-  .row-fluid [class*="span"]:first-child {
-    margin-left: 0;
-  }
-  .row-fluid .span12 {
-    width: 99.999999993%;
-    *width: 99.949999993%;
-  }
-  .row-fluid .span11 {
-    width: 91.436464082%;
-    *width: 91.386464082%;
-  }
-  .row-fluid .span10 {
-    width: 82.87292817100001%;
-    *width: 82.82292817100002%;
-  }
-  .row-fluid .span9 {
-    width: 74.30939226%;
-    *width: 74.25939226%;
-  }
-  .row-fluid .span8 {
-    width: 65.74585634900001%;
-    *width: 65.69585634900001%;
-  }
-  .row-fluid .span7 {
-    width: 57.182320438000005%;
-    *width: 57.13232043800001%;
-  }
-  .row-fluid .span6 {
-    width: 48.618784527%;
-    *width: 48.568784527000005%;
-  }
-  .row-fluid .span5 {
-    width: 40.055248616%;
-    *width: 40.005248616%;
-  }
-  .row-fluid .span4 {
-    width: 31.491712705%;
-    *width: 31.441712705%;
-  }
-  .row-fluid .span3 {
-    width: 22.928176794%;
-    *width: 22.878176793999998%;
-  }
-  .row-fluid .span2 {
-    width: 14.364640883%;
-    *width: 14.314640883%;
-  }
-  .row-fluid .span1 {
-    width: 5.801104972%;
-    *width: 5.751104972%;
-  }
-  input,
-  textarea,
-  .uneditable-input {
-    margin-left: 0;
-  }
-  input.span12,
-  textarea.span12,
-  .uneditable-input.span12 {
-    width: 714px;
-  }
-  input.span11,
-  textarea.span11,
-  .uneditable-input.span11 {
-    width: 652px;
-  }
-  input.span10,
-  textarea.span10,
-  .uneditable-input.span10 {
-    width: 590px;
-  }
-  input.span9,
-  textarea.span9,
-  .uneditable-input.span9 {
-    width: 528px;
-  }
-  input.span8,
-  textarea.span8,
-  .uneditable-input.span8 {
-    width: 466px;
-  }
-  input.span7,
-  textarea.span7,
-  .uneditable-input.span7 {
-    width: 404px;
-  }
-  input.span6,
-  textarea.span6,
-  .uneditable-input.span6 {
-    width: 342px;
-  }
-  input.span5,
-  textarea.span5,
-  .uneditable-input.span5 {
-    width: 280px;
-  }
-  input.span4,
-  textarea.span4,
-  .uneditable-input.span4 {
-    width: 218px;
-  }
-  input.span3,
-  textarea.span3,
-  .uneditable-input.span3 {
-    width: 156px;
-  }
-  input.span2,
-  textarea.span2,
-  .uneditable-input.span2 {
-    width: 94px;
-  }
-  input.span1,
-  textarea.span1,
-  .uneditable-input.span1 {
-    width: 32px;
-  }
-}
-
-@media (min-width: 1200px) {
-  .row {
-    margin-left: -30px;
-    *zoom: 1;
-  }
-  .row:before,
-  .row:after {
-    display: table;
-    content: "";
-  }
-  .row:after {
-    clear: both;
-  }
-  [class*="span"] {
-    float: left;
-    margin-left: 30px;
-  }
-  .container,
-  .navbar-fixed-top .container,
-  .navbar-fixed-bottom .container {
-    width: 1170px;
-  }
-  .span12 {
-    width: 1170px;
-  }
-  .span11 {
-    width: 1070px;
-  }
-  .span10 {
-    width: 970px;
-  }
-  .span9 {
-    width: 870px;
-  }
-  .span8 {
-    width: 770px;
-  }
-  .span7 {
-    width: 670px;
-  }
-  .span6 {
-    width: 570px;
-  }
-  .span5 {
-    width: 470px;
-  }
-  .span4 {
-    width: 370px;
-  }
-  .span3 {
-    width: 270px;
-  }
-  .span2 {
-    width: 170px;
-  }
-  .span1 {
-    width: 70px;
-  }
-  .offset12 {
-    margin-left: 1230px;
-  }
-  .offset11 {
-    margin-left: 1130px;
-  }
-  .offset10 {
-    margin-left: 1030px;
-  }
-  .offset9 {
-    margin-left: 930px;
-  }
-  .offset8 {
-    margin-left: 830px;
-  }
-  .offset7 {
-    margin-left: 730px;
-  }
-  .offset6 {
-    margin-left: 630px;
-  }
-  .offset5 {
-    margin-left: 530px;
-  }
-  .offset4 {
-    margin-left: 430px;
-  }
-  .offset3 {
-    margin-left: 330px;
-  }
-  .offset2 {
-    margin-left: 230px;
-  }
-  .offset1 {
-    margin-left: 130px;
-  }
-  .row-fluid {
-    width: 100%;
-    *zoom: 1;
-  }
-  .row-fluid:before,
-  .row-fluid:after {
-    display: table;
-    content: "";
-  }
-  .row-fluid:after {
-    clear: both;
-  }
-  .row-fluid [class*="span"] {
-    display: block;
-    float: left;
-    width: 100%;
-    min-height: 28px;
-    margin-left: 2.564102564%;
-    *margin-left: 2.5141025640000003%;
-    -webkit-box-sizing: border-box;
-       -moz-box-sizing: border-box;
-        -ms-box-sizing: border-box;
             box-sizing: border-box;
   }
   .row-fluid [class*="span"]:first-child {
   }
   .row-fluid .span12 {
     width: 100%;
-    *width: 99.95%;
+    *width: 99.94680851063829%;
   }
   .row-fluid .span11 {
-    width: 91.45299145300001%;
-    *width: 91.40299145300001%;
+    width: 91.43646408839778%;
+    *width: 91.38327259903608%;
   }
   .row-fluid .span10 {
-    width: 82.905982906%;
-    *width: 82.85598290600001%;
+    width: 82.87292817679558%;
+    *width: 82.81973668743387%;
   }
   .row-fluid .span9 {
-    width: 74.358974359%;
-    *width: 74.308974359%;
+    width: 74.30939226519337%;
+    *width: 74.25620077583166%;
   }
   .row-fluid .span8 {
-    width: 65.81196581200001%;
-    *width: 65.76196581200001%;
+    width: 65.74585635359117%;
+    *width: 65.69266486422946%;
   }
   .row-fluid .span7 {
-    width: 57.264957265%;
-    *width: 57.214957265%;
+    width: 57.18232044198895%;
+    *width: 57.12912895262725%;
   }
   .row-fluid .span6 {
-    width: 48.717948718%;
-    *width: 48.667948718000005%;
+    width: 48.61878453038674%;
+    *width: 48.56559304102504%;
   }
   .row-fluid .span5 {
-    width: 40.170940171000005%;
-    *width: 40.12094017100001%;
+    width: 40.05524861878453%;
+    *width: 40.00205712942283%;
   }
   .row-fluid .span4 {
-    width: 31.623931624%;
-    *width: 31.573931624%;
+    width: 31.491712707182323%;
+    *width: 31.43852121782062%;
   }
   .row-fluid .span3 {
-    width: 23.076923077%;
-    *width: 23.026923077%;
+    width: 22.92817679558011%;
+    *width: 22.87498530621841%;
   }
   .row-fluid .span2 {
-    width: 14.529914530000001%;
-    *width: 14.47991453%;
+    width: 14.3646408839779%;
+    *width: 14.311449394616199%;
   }
   .row-fluid .span1 {
-    width: 5.982905983%;
-    *width: 5.932905983%;
+    width: 5.801104972375691%;
+    *width: 5.747913483013988%;
+  }
+  .row-fluid .offset12 {
+    margin-left: 105.52486187845304%;
+    *margin-left: 105.41847889972962%;
+  }
+  .row-fluid .offset12:first-child {
+    margin-left: 102.76243093922652%;
+    *margin-left: 102.6560479605031%;
+  }
+  .row-fluid .offset11 {
+    margin-left: 96.96132596685082%;
+    *margin-left: 96.8549429881274%;
+  }
+  .row-fluid .offset11:first-child {
+    margin-left: 94.1988950276243%;
+    *margin-left: 94.09251204890089%;
+  }
+  .row-fluid .offset10 {
+    margin-left: 88.39779005524862%;
+    *margin-left: 88.2914070765252%;
+  }
+  .row-fluid .offset10:first-child {
+    margin-left: 85.6353591160221%;
+    *margin-left: 85.52897613729868%;
+  }
+  .row-fluid .offset9 {
+    margin-left: 79.8342541436464%;
+    *margin-left: 79.72787116492299%;
+  }
+  .row-fluid .offset9:first-child {
+    margin-left: 77.07182320441989%;
+    *margin-left: 76.96544022569647%;
+  }
+  .row-fluid .offset8 {
+    margin-left: 71.2707182320442%;
+    *margin-left: 71.16433525332079%;
+  }
+  .row-fluid .offset8:first-child {
+    margin-left: 68.50828729281768%;
+    *margin-left: 68.40190431409427%;
+  }
+  .row-fluid .offset7 {
+    margin-left: 62.70718232044199%;
+    *margin-left: 62.600799341718584%;
+  }
+  .row-fluid .offset7:first-child {
+    margin-left: 59.94475138121547%;
+    *margin-left: 59.838368402492065%;
+  }
+  .row-fluid .offset6 {
+    margin-left: 54.14364640883978%;
+    *margin-left: 54.037263430116376%;
+  }
+  .row-fluid .offset6:first-child {
+    margin-left: 51.38121546961326%;
+    *margin-left: 51.27483249088986%;
+  }
+  .row-fluid .offset5 {
+    margin-left: 45.58011049723757%;
+    *margin-left: 45.47372751851417%;
+  }
+  .row-fluid .offset5:first-child {
+    margin-left: 42.81767955801105%;
+    *margin-left: 42.71129657928765%;
+  }
+  .row-fluid .offset4 {
+    margin-left: 37.01657458563536%;
+    *margin-left: 36.91019160691196%;
+  }
+  .row-fluid .offset4:first-child {
+    margin-left: 34.25414364640884%;
+    *margin-left: 34.14776066768544%;
+  }
+  .row-fluid .offset3 {
+    margin-left: 28.45303867403315%;
+    *margin-left: 28.346655695309746%;
+  }
+  .row-fluid .offset3:first-child {
+    margin-left: 25.69060773480663%;
+    *margin-left: 25.584224756083227%;
+  }
+  .row-fluid .offset2 {
+    margin-left: 19.88950276243094%;
+    *margin-left: 19.783119783707537%;
+  }
+  .row-fluid .offset2:first-child {
+    margin-left: 17.12707182320442%;
+    *margin-left: 17.02068884448102%;
+  }
+  .row-fluid .offset1 {
+    margin-left: 11.32596685082873%;
+    *margin-left: 11.219583872105325%;
+  }
+  .row-fluid .offset1:first-child {
+    margin-left: 8.56353591160221%;
+    *margin-left: 8.457152932878806%;
   }
   input,
   textarea,
   .uneditable-input {
     margin-left: 0;
   }
+  .controls-row [class*="span"] + [class*="span"] {
+    margin-left: 20px;
+  }
   input.span12,
   textarea.span12,
   .uneditable-input.span12 {
-    width: 1160px;
+    width: 710px;
   }
   input.span11,
   textarea.span11,
   .uneditable-input.span11 {
-    width: 1060px;
+    width: 648px;
   }
   input.span10,
   textarea.span10,
   .uneditable-input.span10 {
-    width: 960px;
+    width: 586px;
   }
   input.span9,
   textarea.span9,
   .uneditable-input.span9 {
-    width: 860px;
+    width: 524px;
   }
   input.span8,
   textarea.span8,
   .uneditable-input.span8 {
-    width: 760px;
+    width: 462px;
   }
   input.span7,
   textarea.span7,
   .uneditable-input.span7 {
-    width: 660px;
+    width: 400px;
   }
   input.span6,
   textarea.span6,
   .uneditable-input.span6 {
-    width: 560px;
+    width: 338px;
   }
   input.span5,
   textarea.span5,
   .uneditable-input.span5 {
-    width: 460px;
+    width: 276px;
   }
   input.span4,
   textarea.span4,
   .uneditable-input.span4 {
-    width: 360px;
+    width: 214px;
   }
   input.span3,
   textarea.span3,
   .uneditable-input.span3 {
-    width: 260px;
+    width: 152px;
   }
   input.span2,
   textarea.span2,
   .uneditable-input.span2 {
-    width: 160px;
+    width: 90px;
   }
   input.span1,
   textarea.span1,
   .uneditable-input.span1 {
-    width: 60px;
+    width: 28px;
   }
+}
+
+@media (max-width: 767px) {
+  body {
+    padding-right: 20px;
+    padding-left: 20px;
+  }
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    margin-right: -20px;
+    margin-left: -20px;
+  }
+  .container-fluid {
+    padding: 0;
+  }
+  .dl-horizontal dt {
+    float: none;
+    width: auto;
+    clear: none;
+    text-align: left;
+  }
+  .dl-horizontal dd {
+    margin-left: 0;
+  }
+  .container {
+    width: auto;
+  }
+  .row-fluid {
+    width: 100%;
+  }
+  .row,
   .thumbnails {
-    margin-left: -30px;
+    margin-left: 0;
   }
   .thumbnails > li {
-    margin-left: 30px;
+    float: none;
+    margin-left: 0;
   }
-  .row-fluid .thumbnails {
+  [class*="span"],
+  .row-fluid [class*="span"] {
+    display: block;
+    float: none;
+    width: auto;
     margin-left: 0;
   }
+  .span12,
+  .row-fluid .span12 {
+    width: 100%;
+    -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+            box-sizing: border-box;
+  }
+  .input-large,
+  .input-xlarge,
+  .input-xxlarge,
+  input[class*="span"],
+  select[class*="span"],
+  textarea[class*="span"],
+  .uneditable-input {
+    display: block;
+    width: 100%;
+    min-height: 30px;
+    -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+            box-sizing: border-box;
+  }
+  .input-prepend input,
+  .input-append input,
+  .input-prepend input[class*="span"],
+  .input-append input[class*="span"] {
+    display: inline-block;
+    width: auto;
+  }
+  .modal {
+    position: fixed;
+    top: 20px;
+    right: 20px;
+    left: 20px;
+    width: auto;
+    margin: 0;
+  }
+  .modal.fade.in {
+    top: auto;
+  }
+}
+
+@media (max-width: 480px) {
+  .nav-collapse {
+    -webkit-transform: translate3d(0, 0, 0);
+  }
+  .page-header h1 small {
+    display: block;
+    line-height: 20px;
+  }
+  input[type="checkbox"],
+  input[type="radio"] {
+    border: 1px solid #ccc;
+  }
+  .form-horizontal .control-group > label {
+    float: none;
+    width: auto;
+    padding-top: 0;
+    text-align: left;
+  }
+  .form-horizontal .controls {
+    margin-left: 0;
+  }
+  .form-horizontal .control-list {
+    padding-top: 0;
+  }
+  .form-horizontal .form-actions {
+    padding-right: 10px;
+    padding-left: 10px;
+  }
+  .modal {
+    top: 10px;
+    right: 10px;
+    left: 10px;
+  }
+  .modal-header .close {
+    padding: 10px;
+    margin: -10px;
+  }
+  .carousel-caption {
+    position: static;
+  }
 }
 
 @media (max-width: 979px) {
     position: static;
   }
   .navbar-fixed-top {
-    margin-bottom: 18px;
+    margin-bottom: 20px;
   }
   .navbar-fixed-bottom {
-    margin-top: 18px;
+    margin-top: 20px;
   }
   .navbar-fixed-top .navbar-inner,
   .navbar-fixed-bottom .navbar-inner {
   }
   .nav-collapse .nav {
     float: none;
-    margin: 0 0 9px;
+    margin: 0 0 10px;
   }
   .nav-collapse .nav > li {
     float: none;
     display: none;
   }
   .nav-collapse .nav .nav-header {
-    color: #999999;
+    color: #555555;
     text-shadow: none;
   }
   .nav-collapse .nav > li > a,
   .nav-collapse .dropdown-menu a {
-    padding: 6px 15px;
+    padding: 9px 15px;
     font-weight: bold;
-    color: #999999;
+    color: #555555;
     -webkit-border-radius: 3px;
        -moz-border-radius: 3px;
             border-radius: 3px;
   }
   .nav-collapse .nav > li > a:hover,
   .nav-collapse .dropdown-menu a:hover {
-    background-color: #222222;
+    background-color: #f2f2f2;
+  }
+  .navbar-inverse .nav-collapse .nav > li > a:hover,
+  .navbar-inverse .nav-collapse .dropdown-menu a:hover {
+    background-color: #111111;
   }
   .nav-collapse.in .btn-group {
     padding: 0;
   .nav-collapse .navbar-form,
   .nav-collapse .navbar-search {
     float: none;
-    padding: 9px 15px;
-    margin: 9px 0;
-    border-top: 1px solid #222222;
-    border-bottom: 1px solid #222222;
+    padding: 10px 15px;
+    margin: 10px 0;
+    border-top: 1px solid #f2f2f2;
+    border-bottom: 1px solid #f2f2f2;
     -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
        -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
             box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);

src/templates/css/bootstrap.css

 /*!
- * Bootstrap v2.0.4
+ * Bootstrap v2.1.0
  *
  * Copyright 2012 Twitter, Inc
  * Licensed under the Apache License v2.0
 }
 
 img {
+  height: auto;
   max-width: 100%;
   vertical-align: middle;
   border: 0;
 .clearfix:before,
 .clearfix:after {
   display: table;
+  line-height: 0;
   content: "";
 }
 
 .input-block-level {
   display: block;
   width: 100%;
-  min-height: 28px;
+  min-height: 30px;
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
-      -ms-box-sizing: border-box;
           box-sizing: border-box;
 }
 
 body {
   margin: 0;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  line-height: 18px;
+  font-size: 14px;
+  line-height: 20px;
   color: #333333;
   background-color: #ffffff;
 }
   text-decoration: underline;
 }
 
+.img-rounded {
+  -webkit-border-radius: 6px;
+     -moz-border-radius: 6px;
+          border-radius: 6px;
+}
+
+.img-polaroid {
+  padding: 4px;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.img-circle {
+  -webkit-border-radius: 500px;
+     -moz-border-radius: 500px;
+          border-radius: 500px;
+}
+
 .row {
   ma