*/
40 | }
41 | })
42 |
--------------------------------------------------------------------------------
/test/test_utils.js:
--------------------------------------------------------------------------------
1 |
2 | var expect = require('expect.js')
3 | , utils = require('../lib/utils')
4 |
5 | describe('linkProfiles', function () {
6 | it('should find a profile', function () {
7 | expect(utils.linkProfiles('@jaredly')).to.equal('@jaredly')
8 | })
9 | it('should ignore non-profiles', function () {
10 | var text = 'no profiles here or out@there.'
11 | expect(utils.linkProfiles(text)).to.equal(text)
12 | })
13 | it('should find one at the start of a pre', function () {
14 | expect(utils.linkProfiles('@jaredly man')).to.equal('
@jaredly man')
15 | })
16 | })
17 |
18 | describe('teaser', function () {
19 | it('should work for a simple case', function () {
20 | var line = 'here is a sentence that goes for a little while. But then it gets longer and longer. And eventually we get past 140 characters. It kind of takes a while.'
21 | , shorter = 'here is a sentence that goes for a little while. But then it gets longer and longer. And eventually we get past 140 characters. It kind of…'
22 | expect(utils.teaser(line)).to.equal(shorter);
23 | })
24 | })
25 |
26 | /*
27 | describe('fixTrailingMarkdown', function () {
28 | it('should preserve valid markdown', function () {
29 | var samples = [
30 | '*one*',
31 | '**two**',
32 | '_three_ *four* something*here.',
33 | 'some `url`s'
34 | ]
35 | })
36 | })
37 | */
38 |
39 |
--------------------------------------------------------------------------------
/web/bootstrap/less/alerts.less:
--------------------------------------------------------------------------------
1 | //
2 | // Alerts
3 | // --------------------------------------------------
4 |
5 |
6 | // Base styles
7 | // -------------------------
8 |
9 | .alert {
10 | padding: @alert-padding;
11 | margin-bottom: @line-height-computed;
12 | border: 1px solid transparent;
13 | border-radius: @alert-border-radius;
14 |
15 | // Headings for larger alerts
16 | h4 {
17 | margin-top: 0;
18 | // Specified for the h4 to prevent conflicts of changing @headings-color
19 | color: inherit;
20 | }
21 | // Provide class for links that match alerts
22 | .alert-link {
23 | font-weight: @alert-link-font-weight;
24 | }
25 |
26 | // Improve alignment and spacing of inner content
27 | > p,
28 | > ul {
29 | margin-bottom: 0;
30 | }
31 | > p + p {
32 | margin-top: 5px;
33 | }
34 | }
35 |
36 | // Dismissable alerts
37 | //
38 | // Expand the right padding and account for the close button's positioning.
39 |
40 | .alert-dismissable {
41 | padding-right: (@alert-padding + 20);
42 |
43 | // Adjust close link position
44 | .close {
45 | position: relative;
46 | top: -2px;
47 | right: -21px;
48 | color: inherit;
49 | }
50 | }
51 |
52 | // Alternate styles
53 | //
54 | // Generate contextual modifier classes for colorizing the alert.
55 |
56 | .alert-success {
57 | .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);
58 | }
59 | .alert-info {
60 | .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);
61 | }
62 | .alert-warning {
63 | .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);
64 | }
65 | .alert-danger {
66 | .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);
67 | }
68 |
--------------------------------------------------------------------------------
/lib/pages/all-issues.js:
--------------------------------------------------------------------------------
1 | var d = React.DOM
2 | , Issue = require('../components/issue')
3 | , Pager = require('../components/pager')
4 |
5 | /*
6 | * Display all the issues, with paging.
7 | *
8 | * Child components:
9 | * - Pager
10 | * - list of 'Issue's
11 | */
12 | module.exports = React.createClass({
13 | displayName: 'AllIssues',
14 | getDefaultProps: function () {
15 | return {
16 | start: 0,
17 | issues: [],
18 | issueHref: function () {},
19 | onPage: function () {
20 | console.error('parent component must manage page state')
21 | }
22 | }
23 | },
24 | render: function () {
25 | var props = {className: 'page all-issues-page'}
26 | /*
27 | if (this.props.start >= this.props.issues.length) {
28 | return d.div(props, 'No issues here')
29 | }
30 | */
31 | var issues = this.props.issues.slice(this.props.start, this.props.start + 25)
32 | , message = false
33 | if (!issues.length) {
34 | message = d.h4({className:'no-issues'}, this.props.loading ? 'Loading...' : 'No Issues')
35 | }
36 | return d.div(
37 | props,
38 | Pager({
39 | step: 25,
40 | at: this.props.start,
41 | max: this.props.issues.length,
42 | onPage: this.props.onPage
43 | }),
44 | message,
45 | d.ul(
46 | {
47 | className: 'issue-list'
48 | },
49 | issues.map(function (issue) {
50 | return d.li({className: 'issue-list__item'}, Issue({
51 | href: this.props.issueHref(issue.id),
52 | model: issue,
53 | key: issue.id
54 | }))
55 | }.bind(this))
56 | ),
57 | Pager({
58 | step: 25,
59 | at: this.props.start,
60 | max: this.props.issues.length,
61 | onPage: this.props.onPage
62 | })
63 | )
64 | }
65 | })
66 |
67 |
--------------------------------------------------------------------------------
/lib/components/repo-input.js:
--------------------------------------------------------------------------------
1 |
2 | var d = React.DOM
3 |
4 | /**
5 | * An input box + load button.
6 | * Validates the input.
7 | * Used by ../view.js
8 | */
9 | var RepoInput = module.exports = React.createClass({
10 | getDefaultProps: function () {
11 | return {
12 | initialValue: 'jaredly/github-issues',
13 | onChange: function () {}
14 | }
15 | },
16 | getInitialState: function () {
17 | return {
18 | value: ''
19 | }
20 | },
21 | onChange: function (e) {
22 | var value = e.target.value
23 | if (value === this.props.initialValue) value = ''
24 | this.setState({value: value})
25 | },
26 | onKeyDown: function (e) {
27 | // on return
28 | if (e.keyCode === 13) {
29 | if (this.canSubmit()) {
30 | e.preventDefault()
31 | e.stopPropagation()
32 | this.submit()
33 | }
34 | }
35 | },
36 | submit: function () {
37 | this.props.onChange(this.state.value)
38 | this.setState({value: ''})
39 | },
40 | canSubmit: function () {
41 | if (this.state.value.trim() === this.props.initialValue.trim()) {
42 | return false
43 | }
44 | var parts = this.state.value.trim().split('/')
45 | if (parts.length !== 2) return false
46 | if (parts[0].length === 0 || parts[1].length === 0) {
47 | return false
48 | }
49 | return true
50 | },
51 | render: function () {
52 | var disabled = !this.canSubmit()
53 | return d.div(
54 | {className: 'repo-input'},
55 | this.props.title ? d.span({className: 'repo-input__title'}, this.props.title) : false,
56 | d.input({
57 | placeholder: 'owner/repo',
58 | onKeyDown: this.onKeyDown,
59 | value: this.state.value || this.props.initialValue,
60 | onChange: this.onChange
61 | }),
62 | d.button({
63 | disabled: disabled,
64 | onClick: disabled ? null : this.submit
65 | }, 'load')
66 | )
67 | }
68 | })
69 |
70 |
--------------------------------------------------------------------------------
/web/bootstrap/less/progress-bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Progress bars
3 | // --------------------------------------------------
4 |
5 |
6 | // Bar animations
7 | // -------------------------
8 |
9 | // WebKit
10 | @-webkit-keyframes progress-bar-stripes {
11 | from { background-position: 40px 0; }
12 | to { background-position: 0 0; }
13 | }
14 |
15 | // Spec and IE10+
16 | @keyframes progress-bar-stripes {
17 | from { background-position: 40px 0; }
18 | to { background-position: 0 0; }
19 | }
20 |
21 |
22 |
23 | // Bar itself
24 | // -------------------------
25 |
26 | // Outer container
27 | .progress {
28 | overflow: hidden;
29 | height: @line-height-computed;
30 | margin-bottom: @line-height-computed;
31 | background-color: @progress-bg;
32 | border-radius: @border-radius-base;
33 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
34 | }
35 |
36 | // Bar of progress
37 | .progress-bar {
38 | float: left;
39 | width: 0%;
40 | height: 100%;
41 | font-size: @font-size-small;
42 | line-height: @line-height-computed;
43 | color: @progress-bar-color;
44 | text-align: center;
45 | background-color: @progress-bar-bg;
46 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
47 | .transition(width .6s ease);
48 | }
49 |
50 | // Striped bars
51 | .progress-striped .progress-bar {
52 | #gradient > .striped();
53 | background-size: 40px 40px;
54 | }
55 |
56 | // Call animation for the active one
57 | .progress.active .progress-bar {
58 | .animation(progress-bar-stripes 2s linear infinite);
59 | }
60 |
61 |
62 |
63 | // Variations
64 | // -------------------------
65 |
66 | .progress-bar-success {
67 | .progress-bar-variant(@progress-bar-success-bg);
68 | }
69 |
70 | .progress-bar-info {
71 | .progress-bar-variant(@progress-bar-info-bg);
72 | }
73 |
74 | .progress-bar-warning {
75 | .progress-bar-variant(@progress-bar-warning-bg);
76 | }
77 |
78 | .progress-bar-danger {
79 | .progress-bar-variant(@progress-bar-danger-bg);
80 | }
81 |
--------------------------------------------------------------------------------
/lib/components/comments.js:
--------------------------------------------------------------------------------
1 |
2 | var Comment = require('./comment')
3 | , d = React.DOM
4 |
5 | /*
6 | * Loads the comments from github.
7 | *
8 | * Child components:
9 | * - list of 'Comment's
10 | */
11 | var Comments = module.exports = React.createClass({
12 | // react api
13 | getDefaultProps: function () {
14 | return {
15 | url: null,
16 | count: 0
17 | }
18 | },
19 | getInitialState: function () {
20 | return {
21 | comments: [],
22 | loading: false,
23 | error: false
24 | }
25 | },
26 | componentWillMount: function () {
27 | if (this.props.url) this.load()
28 | },
29 | componentDidUpdate: function (oldprops, oldstate) {
30 | if (oldprops.url !== this.props.url) this.load()
31 | },
32 |
33 | // loading data
34 | load: function () {
35 | if (this.props.count === 0) {
36 | this.setState({error: false, comments: []})
37 | return // no comments to load
38 | }
39 | // XXX I don't handle cancelling a request that may still be in
40 | // progress...
41 | this.setState({error: false, loading: true, comments: []})
42 | $.get(this.props.url, this.gotData, 'json').fail(this.fail)
43 | },
44 | gotData: function (data) {
45 | this.setState({comments: data, loading: false, error: false})
46 | },
47 | fail: function (reason) {
48 | console.error('Comment load fail', this.props.url, reason)
49 | this.setState({error: reason || true, loading: false})
50 | },
51 |
52 | render: function () {
53 | if (this.state.error) {
54 | return d.div({className: 'comments'}, 'Failed to load comments!')
55 | }
56 | if (this.state.loading) {
57 | return d.div({className: 'comments loading'}, 'Loading ' + this.props.count + ' comments...')
58 | }
59 | if (!this.state.comments.length) {
60 | return d.div({className: 'comments'})
61 | }
62 | return d.ul(
63 | {className: 'comments'},
64 | this.state.comments.map(function (comment) {
65 | return Comment({
66 | model: comment,
67 | key: comment.id
68 | })
69 | })
70 | )
71 | }
72 | })
73 |
--------------------------------------------------------------------------------
/web/bootstrap/less/grid.less:
--------------------------------------------------------------------------------
1 | //
2 | // Grid system
3 | // --------------------------------------------------
4 |
5 | // Set the container width, and override it for fixed navbars in media queries
6 | .container {
7 | .container-fixed();
8 |
9 | @media (min-width: @screen-sm) {
10 | width: @container-sm;
11 | }
12 | @media (min-width: @screen-md) {
13 | width: @container-md;
14 | }
15 | @media (min-width: @screen-lg-min) {
16 | width: @container-lg;
17 | }
18 | }
19 |
20 | // mobile first defaults
21 | .row {
22 | .make-row();
23 | }
24 |
25 | // Common styles for small and large grid columns
26 | .make-grid-columns();
27 |
28 |
29 | // Extra small grid
30 | //
31 | // Columns, offsets, pushes, and pulls for extra small devices like
32 | // smartphones.
33 |
34 | .make-grid-columns-float(xs);
35 | .make-grid(@grid-columns, xs, width);
36 | .make-grid(@grid-columns, xs, pull);
37 | .make-grid(@grid-columns, xs, push);
38 | .make-grid(@grid-columns, xs, offset);
39 |
40 |
41 | // Small grid
42 | //
43 | // Columns, offsets, pushes, and pulls for the small device range, from phones
44 | // to tablets.
45 |
46 | @media (min-width: @screen-sm-min) {
47 | .make-grid-columns-float(sm);
48 | .make-grid(@grid-columns, sm, width);
49 | .make-grid(@grid-columns, sm, pull);
50 | .make-grid(@grid-columns, sm, push);
51 | .make-grid(@grid-columns, sm, offset);
52 | }
53 |
54 |
55 | // Medium grid
56 | //
57 | // Columns, offsets, pushes, and pulls for the desktop device range.
58 |
59 | @media (min-width: @screen-md-min) {
60 | .make-grid-columns-float(md);
61 | .make-grid(@grid-columns, md, width);
62 | .make-grid(@grid-columns, md, pull);
63 | .make-grid(@grid-columns, md, push);
64 | .make-grid(@grid-columns, md, offset);
65 | }
66 |
67 |
68 | // Large grid
69 | //
70 | // Columns, offsets, pushes, and pulls for the large desktop device range.
71 |
72 | @media (min-width: @screen-lg-min) {
73 | .make-grid-columns-float(lg);
74 | .make-grid(@grid-columns, lg, width);
75 | .make-grid(@grid-columns, lg, pull);
76 | .make-grid(@grid-columns, lg, push);
77 | .make-grid(@grid-columns, lg, offset);
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/lib/pages/issue.js:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 | var Comments = require('../components/comments')
3 | , Labels = require('../components/labels')
4 | , RecentTime = require('../components/recent-time')
5 | , utils = require('../utils')
6 |
7 | var Issue = module.exports = React.createClass({
8 | getDefaultProps: function () {
9 | return {
10 | issue: null
11 | }
12 | },
13 | render: function () {
14 | if (!this.props.issue) {
15 | return (
16 | React.DOM.div( {className:"page issue-page"},
17 | React.DOM.h1(null, this.props.loading ? 'Loading...' : 'Issue not found'),
18 | React.DOM.a( {className:"issue-page__back", href:this.props.backLink}, "Back")
19 | )
20 | )
21 | }
22 | var issue = this.props.issue
23 | , user = issue.user
24 |
25 | return (
26 | React.DOM.div( {className:"page issue-page"},
27 | React.DOM.header( {className:"issue-page__header"},
28 | React.DOM.h4( {className:"issue-header__main"},
29 | React.DOM.span( {className:"issue-page__state issue-state issue-state--" + issue.state},
30 | issue.state/* TODO capitalize? */
31 | ),
32 | React.DOM.a( {className:"issue-page__back", href:this.props.backLink}, "Back"),
33 | React.DOM.a( {href:issue.html_url, className:"issue-page__header__title"}, '#' + issue.number + ' ' + issue.title)
34 | ),
35 | React.DOM.div( {className:"issue-header__sub"},
36 | Labels( {className:"issue-header__labels", labels:issue.labels}),
37 | React.DOM.a( {className:"issue-page__user", href:user.html_url},
38 | React.DOM.img( {className:"user__avatar",
39 | src:user.avatar_url}),
40 | React.DOM.span( {className:"user__login user__login--avatar-left"}, user.login)
41 | ),
42 | RecentTime( {className:"issue__time", time:issue.created_at})
43 | )
44 | ),
45 | React.DOM.section( {className:"issue-page__body"},
46 | utils.processBody(issue.body)
47 | ),
48 | Comments( {url:issue.comments_url, count:issue.comments})
49 | )
50 | )
51 | }
52 | })
53 |
--------------------------------------------------------------------------------
/web/bootstrap/less/print.less:
--------------------------------------------------------------------------------
1 | //
2 | // Basic print styles
3 | // --------------------------------------------------
4 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css
5 |
6 | @media print {
7 |
8 | * {
9 | text-shadow: none !important;
10 | color: #000 !important; // Black prints faster: h5bp.com/s
11 | background: transparent !important;
12 | box-shadow: none !important;
13 | }
14 |
15 | a,
16 | a:visited {
17 | text-decoration: underline;
18 | }
19 |
20 | a[href]:after {
21 | content: " (" attr(href) ")";
22 | }
23 |
24 | abbr[title]:after {
25 | content: " (" attr(title) ")";
26 | }
27 |
28 | // Don't show links for images, or javascript/internal links
29 | a[href^="javascript:"]:after,
30 | a[href^="#"]:after {
31 | content: "";
32 | }
33 |
34 | pre,
35 | blockquote {
36 | border: 1px solid #999;
37 | page-break-inside: avoid;
38 | }
39 |
40 | thead {
41 | display: table-header-group; // h5bp.com/t
42 | }
43 |
44 | tr,
45 | img {
46 | page-break-inside: avoid;
47 | }
48 |
49 | img {
50 | max-width: 100% !important;
51 | }
52 |
53 | @page {
54 | margin: 2cm .5cm;
55 | }
56 |
57 | p,
58 | h2,
59 | h3 {
60 | orphans: 3;
61 | widows: 3;
62 | }
63 |
64 | h2,
65 | h3 {
66 | page-break-after: avoid;
67 | }
68 |
69 | // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245
70 | // Once fixed, we can just straight up remove this.
71 | select {
72 | background: #fff !important;
73 | }
74 |
75 | // Bootstrap components
76 | .navbar {
77 | display: none;
78 | }
79 | .table {
80 | td,
81 | th {
82 | background-color: #fff !important;
83 | }
84 | }
85 | .btn,
86 | .dropup > .btn {
87 | > .caret {
88 | border-top-color: #000 !important;
89 | }
90 | }
91 | .label {
92 | border: 1px solid #000;
93 | }
94 |
95 | .table {
96 | border-collapse: collapse !important;
97 | }
98 | .table-bordered {
99 | th,
100 | td {
101 | border: 1px solid #ddd !important;
102 | }
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/web/bootstrap/less/pagination.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pagination (multiple pages)
3 | // --------------------------------------------------
4 | .pagination {
5 | display: inline-block;
6 | padding-left: 0;
7 | margin: @line-height-computed 0;
8 | border-radius: @border-radius-base;
9 |
10 | > li {
11 | display: inline; // Remove list-style and block-level defaults
12 | > a,
13 | > span {
14 | position: relative;
15 | float: left; // Collapse white-space
16 | padding: @padding-base-vertical @padding-base-horizontal;
17 | line-height: @line-height-base;
18 | text-decoration: none;
19 | background-color: @pagination-bg;
20 | border: 1px solid @pagination-border;
21 | margin-left: -1px;
22 | }
23 | &:first-child {
24 | > a,
25 | > span {
26 | margin-left: 0;
27 | .border-left-radius(@border-radius-base);
28 | }
29 | }
30 | &:last-child {
31 | > a,
32 | > span {
33 | .border-right-radius(@border-radius-base);
34 | }
35 | }
36 | }
37 |
38 | > li > a,
39 | > li > span {
40 | &:hover,
41 | &:focus {
42 | background-color: @pagination-hover-bg;
43 | }
44 | }
45 |
46 | > .active > a,
47 | > .active > span {
48 | &,
49 | &:hover,
50 | &:focus {
51 | z-index: 2;
52 | color: @pagination-active-color;
53 | background-color: @pagination-active-bg;
54 | border-color: @pagination-active-bg;
55 | cursor: default;
56 | }
57 | }
58 |
59 | > .disabled {
60 | > span,
61 | > span:hover,
62 | > span:focus,
63 | > a,
64 | > a:hover,
65 | > a:focus {
66 | color: @pagination-disabled-color;
67 | background-color: @pagination-bg;
68 | border-color: @pagination-border;
69 | cursor: not-allowed;
70 | }
71 | }
72 | }
73 |
74 | // Sizing
75 | // --------------------------------------------------
76 |
77 | // Large
78 | .pagination-lg {
79 | .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);
80 | }
81 |
82 | // Small
83 | .pagination-sm {
84 | .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);
85 | }
86 |
--------------------------------------------------------------------------------
/lib/pages/issue.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 | var Comments = require('../components/comments')
3 | , Labels = require('../components/labels')
4 | , RecentTime = require('../components/recent-time')
5 | , utils = require('../utils')
6 |
7 | /**
8 | * Display a single issue
9 | *
10 | * Child components:
11 | * - RecentTime (display time in a "2 hours ago" fashion)
12 | * - Comments (load & display the comments)
13 | */
14 | var Issue = module.exports = React.createClass({
15 | getDefaultProps: function () {
16 | return {
17 | issue: null
18 | }
19 | },
20 | render: function () {
21 | if (!this.props.issue) {
22 | return (
23 |
24 |
{this.props.loading ? 'Loading...' : 'Issue not found'}
25 |
Back
26 |
27 | )
28 | }
29 | var issue = this.props.issue
30 | , user = issue.user
31 |
32 | return (
33 |
34 |
52 |
53 | {utils.processBody(issue.body)}
54 |
55 |
56 |
57 | )
58 | }
59 | })
60 |
--------------------------------------------------------------------------------
/web/bootstrap/less/list-group.less:
--------------------------------------------------------------------------------
1 | //
2 | // List groups
3 | // --------------------------------------------------
4 |
5 | // Base class
6 | //
7 | // Easily usable on , , or .
8 | .list-group {
9 | // No need to set list-style: none; since .list-group-item is block level
10 | margin-bottom: 20px;
11 | padding-left: 0; // reset padding because ul and ol
12 | }
13 |
14 | // Individual list items
15 | // -------------------------
16 |
17 | .list-group-item {
18 | position: relative;
19 | display: block;
20 | padding: 10px 15px;
21 | // Place the border on the list items and negative margin up for better styling
22 | margin-bottom: -1px;
23 | background-color: @list-group-bg;
24 | border: 1px solid @list-group-border;
25 |
26 | // Round the first and last items
27 | &:first-child {
28 | .border-top-radius(@list-group-border-radius);
29 | }
30 | &:last-child {
31 | margin-bottom: 0;
32 | .border-bottom-radius(@list-group-border-radius);
33 | }
34 |
35 | // Align badges within list items
36 | > .badge {
37 | float: right;
38 | }
39 | > .badge + .badge {
40 | margin-right: 5px;
41 | }
42 | }
43 |
44 | // Linked list items
45 | a.list-group-item {
46 | color: @list-group-link-color;
47 |
48 | .list-group-item-heading {
49 | color: @list-group-link-heading-color;
50 | }
51 |
52 | // Hover state
53 | &:hover,
54 | &:focus {
55 | text-decoration: none;
56 | background-color: @list-group-hover-bg;
57 | }
58 |
59 | // Active class on item itself, not parent
60 | &.active,
61 | &.active:hover,
62 | &.active:focus {
63 | z-index: 2; // Place active items above their siblings for proper border styling
64 | color: @list-group-active-color;
65 | background-color: @list-group-active-bg;
66 | border-color: @list-group-active-border;
67 |
68 | // Force color to inherit for custom content
69 | .list-group-item-heading {
70 | color: inherit;
71 | }
72 | .list-group-item-text {
73 | color: lighten(@list-group-active-bg, 40%);
74 | }
75 | }
76 | }
77 |
78 | // Custom content options
79 | // -------------------------
80 |
81 | .list-group-item-heading {
82 | margin-top: 0;
83 | margin-bottom: 5px;
84 | }
85 | .list-group-item-text {
86 | margin-bottom: 0;
87 | line-height: 1.3;
88 | }
89 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 | # Github issues viewer
3 |
4 | This is a viewer of github issues that is entirely client-side. It
5 | demonstrates one way of building a slightly-more-than-trivial app with
6 | [facebook's React framework](http://facebook.github.io/react).
7 |
8 | All requests to the github api are anonymous, so they cap it at 60
9 | requests/hour.
10 |
11 | [View the live example.](http://jaredly.github.io/github-issues-viewer)
12 |
13 | [](http://jaredly.github.io/github-issues-viewer)
14 |
15 | # Components
16 |
17 | - App *fetches models*
18 | - RepoInput
19 | - View *manages routing*
20 | - AllIssuesPage
21 | - Pager
22 | - Issue
23 | - IssuePage
24 | - RecentTime
25 | - Comments
26 | - Comment
27 | - RecentTime
28 |
29 |
30 | Technologies used:
31 |
32 | - [React](http://facebook.github.io/react) for the views
33 | - [Backbone](http://backbonejs.org) (mostly for routing... no mutable models here)
34 | - [Bootstrap](http://twbs.github.io/bootstrap) for some styling
35 | - [Component(1)](http://github.com/component/component) for packaging
36 | - [LessCSS](http://lesscss.org) for css processing
37 | - [FontAwesome](http://fontawesome.io) for icons
38 |
39 | ## Known Issues
40 |
41 | ### The Teaser
42 |
43 | On the main page, the teaser of the issue body can break markdown sytax,
44 | resulting in awkward-looking `` ```some code here`` or `**bold but not` at the
45 | end of the teaser.
46 |
47 | I thought about (and started implementing) an ad-hoc fix but then stopped,
48 | because it was dirtly and incomplete. The real solution would be to translate
49 | the raw text into a markdown syntax tree, and then grab the first x chunks
50 | from there. A project for another time. I couldn't find a lib on npm to do it,
51 | but if you know of one, please open an issue or pr.
52 |
53 | ### Anonymous API usage cap
54 |
55 | It might be interesting to look into auth w/ github...not sure if that's
56 | possible in a backend-less app.
57 |
58 | ### Not yet implemented things
59 |
60 | - auto-linking to referenced issues
61 | - auto-linking to commits, comments, etc
62 | - probably a few other things
63 |
64 | ## Building
65 |
66 | ```
67 | npm install -g react-tools component less
68 | make
69 | google-chrome web/index.html
70 | ```
71 |
72 | ## Hacking
73 |
74 | ```
75 | npm install -g jshint mocha
76 | make test
77 | ```
78 |
79 | ## License
80 |
81 | Apache v2
82 |
83 | Contribution and Comments are welcome.
84 |
--------------------------------------------------------------------------------
/web/bootstrap/less/scaffolding.less:
--------------------------------------------------------------------------------
1 | //
2 | // Scaffolding
3 | // --------------------------------------------------
4 |
5 |
6 | // Reset the box-sizing
7 |
8 | *,
9 | *:before,
10 | *:after {
11 | .box-sizing(border-box);
12 | }
13 |
14 |
15 | // Body reset
16 |
17 | html {
18 | font-size: 62.5%;
19 | -webkit-tap-highlight-color: rgba(0,0,0,0);
20 | }
21 |
22 | body {
23 | font-family: @font-family-base;
24 | font-size: @font-size-base;
25 | line-height: @line-height-base;
26 | color: @text-color;
27 | background-color: @body-bg;
28 | }
29 |
30 | // Reset fonts for relevant elements
31 | input,
32 | button,
33 | select,
34 | textarea {
35 | font-family: inherit;
36 | font-size: inherit;
37 | line-height: inherit;
38 | }
39 |
40 |
41 | // Links
42 |
43 | a {
44 | color: @link-color;
45 | text-decoration: none;
46 |
47 | &:hover,
48 | &:focus {
49 | color: @link-hover-color;
50 | text-decoration: underline;
51 | }
52 |
53 | &:focus {
54 | .tab-focus();
55 | }
56 | }
57 |
58 |
59 | // Images
60 |
61 | img {
62 | vertical-align: middle;
63 | }
64 |
65 | // Responsive images (ensure images don't scale beyond their parents)
66 | .img-responsive {
67 | .img-responsive();
68 | }
69 |
70 | // Rounded corners
71 | .img-rounded {
72 | border-radius: @border-radius-large;
73 | }
74 |
75 | // Image thumbnails
76 | //
77 | // Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
78 | .img-thumbnail {
79 | padding: @thumbnail-padding;
80 | line-height: @line-height-base;
81 | background-color: @thumbnail-bg;
82 | border: 1px solid @thumbnail-border;
83 | border-radius: @thumbnail-border-radius;
84 | .transition(all .2s ease-in-out);
85 |
86 | // Keep them at most 100% wide
87 | .img-responsive(inline-block);
88 | }
89 |
90 | // Perfect circle
91 | .img-circle {
92 | border-radius: 50%; // set radius in percents
93 | }
94 |
95 |
96 | // Horizontal rules
97 |
98 | hr {
99 | margin-top: @line-height-computed;
100 | margin-bottom: @line-height-computed;
101 | border: 0;
102 | border-top: 1px solid @hr-border;
103 | }
104 |
105 |
106 | // Only display content to screen readers
107 | //
108 | // See: http://a11yproject.com/posts/how-to-hide-content/
109 |
110 | .sr-only {
111 | position: absolute;
112 | width: 1px;
113 | height: 1px;
114 | margin: -1px;
115 | padding: 0;
116 | overflow: hidden;
117 | clip: rect(0,0,0,0);
118 | border: 0;
119 | }
120 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 |
2 | var marked = require('marked')
3 |
4 | module.exports = {
5 | linkProfiles: linkProfiles,
6 | teaserProcessed: teaserProcessed,
7 | processBody: processBody,
8 | teaser: teaser
9 | }
10 |
11 | /*
12 | * Convert to markdown, link @mentions to their user profiles.
13 | */
14 | function processBody(text) {
15 | return React.DOM.span({
16 | dangerouslySetInnerHTML: {
17 | __html: linkProfiles(marked(text, {gfm: true}))
18 | }
19 | })
20 | }
21 |
22 | function linkProfiles(text) {
23 | var rep = '$1
@$2'
24 | return text.replace(/(^|\s|>)@([a-zA-Z_-]{2,})/g, rep)
25 | }
26 |
27 | function teaserProcessed(text, maxlen) {
28 | return processBody(teaser(text, maxlen))
29 | }
30 |
31 | /**
32 | * Get a teaser, of max length maxlen (default 140) characters.
33 | */
34 | function teaser(text, maxlen) {
35 | var end = 0
36 | , white = /\s/
37 | , match = text.slice(end).match(white)
38 | , next
39 | maxlen = maxlen || 140
40 | if (text.length <= maxlen) return text
41 | if (!match) {
42 | return text.slice(0, maxlen) // give up
43 | }
44 | next = {start: match.index, end: match.index + match[0].length}
45 | while (end + next.start < maxlen) {
46 | end += next.end;
47 | match = text.slice(end).match(white)
48 | if (!match) {
49 | next = {start: text.length - end, end: text.length - end}
50 | } else {
51 | next = {start: match.index, end: match.index + match[0].length}
52 | }
53 | }
54 | // TODO: return fixTrailingMarkdown(text.slice(0, end).trim())
55 | return text.slice(0, end).trim() + '…'
56 | }
57 |
58 | /*
59 | * Not going to bother with this for the moment. It's an interesting problem
60 | * to solve, definitely. But it probably makes most sense to actually parse
61 | * the markdown to a syntax tree or something, and death with things on a
62 | * higher level. regex-style is dirty here.
63 | */
64 | /*
65 | function startsMarkdownExpression(text, index, len) {
66 | len = len || 1
67 | if (index === 0 || index === -1 || index >= text.length - len) {
68 | return false
69 | }
70 | // XXX: maybe use \B instead of \S? or \w?
71 | return text[index - 1].match(/\s/) && text[index + len].match(/\S/)
72 | }
73 |
74 | function fixTrailingMarkdownEx(text, ex) {
75 | var index = text.lastIndexOf(ex)
76 | if (startsMarkdownExpression(text, index, ex.length)) {
77 | return text.slice(0, index).trim()
78 | }
79 | return text
80 | }
81 |
82 | function fixTrailingMarkdown(text) {
83 | var exs = ['`', '**', '__', '*', '_']
84 | for (var i=0; i
npages - this.props.maxPages) {
32 | left = npages - this.props.maxPages
33 | }
34 | for (var i=left; i this.props.maxPages) {
48 | return this.somePages()
49 | }
50 | for (var i=0; i= this.props.max) canNext = false
67 | return d.div(
68 | { className: 'mypager' },
69 | d.button({
70 | className: 'mypager__button mypager__button--start' + (canPrev ? '' : ' disabled'),
71 | onClick: canPrev ? this.props.onPage.bind(null, 0) : null,
72 | disabled: !canPrev
73 | }),
74 | d.button({
75 | className: 'mypager__button mypager__button--prev' + (canPrev ? '' : ' disabled'),
76 | onClick: canPrev ? this.props.onPage.bind(null, prev) : null,
77 | disabled: !canPrev
78 | }),
79 | this.pages(),
80 | d.button({
81 | className: 'mypager__button mypager__button--next' + (canNext ? '' : ' disabled'),
82 | onClick: canNext ? this.props.onPage.bind(null, next) : null,
83 | disabled: !canNext
84 | }),
85 | d.button({
86 | className: 'mypager__button mypager__button--end' + (canNext ? '' : ' disabled'),
87 | onClick: canNext ? this.props.onPage.bind(null, lastPage) : null,
88 | disabled: !canNext
89 | }),
90 | this.props.onLoadMore ? d.button({
91 | className: 'mypager__load-more',
92 | onClick: this.props.onLoadMore
93 | }, 'Load more') : false
94 | )
95 | }
96 | })
97 |
98 |
--------------------------------------------------------------------------------
/web/bootstrap/less/modals.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // --------------------------------------------------
4 |
5 | // .modal-open - body class for killing the scroll
6 | // .modal - container to scroll within
7 | // .modal-dialog - positioning shell for the actual modal
8 | // .modal-content - actual modal w/ bg and corners and shit
9 |
10 | // Kill the scroll on the body
11 | .modal-open {
12 | overflow: hidden;
13 | }
14 |
15 | // Container that the modal scrolls within
16 | .modal {
17 | display: none;
18 | overflow: auto;
19 | overflow-y: scroll;
20 | position: fixed;
21 | top: 0;
22 | right: 0;
23 | bottom: 0;
24 | left: 0;
25 | z-index: @zindex-modal-background;
26 |
27 | // When fading in the modal, animate it to slide down
28 | &.fade .modal-dialog {
29 | .translate(0, -25%);
30 | .transition-transform(~"0.3s ease-out");
31 | }
32 | &.in .modal-dialog { .translate(0, 0)}
33 | }
34 |
35 | // Shell div to position the modal with bottom padding
36 | .modal-dialog {
37 | position: relative;
38 | width: auto;
39 | margin: 10px;
40 | z-index: (@zindex-modal-background + 10);
41 | }
42 |
43 | // Actual modal
44 | .modal-content {
45 | position: relative;
46 | background-color: @modal-content-bg;
47 | border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
48 | border: 1px solid @modal-content-border-color;
49 | border-radius: @border-radius-large;
50 | .box-shadow(0 3px 9px rgba(0,0,0,.5));
51 | background-clip: padding-box;
52 | // Remove focus outline from opened modal
53 | outline: none;
54 | }
55 |
56 | // Modal background
57 | .modal-backdrop {
58 | position: fixed;
59 | top: 0;
60 | right: 0;
61 | bottom: 0;
62 | left: 0;
63 | z-index: (@zindex-modal-background - 10);
64 | background-color: @modal-backdrop-bg;
65 | // Fade for backdrop
66 | &.fade { .opacity(0); }
67 | &.in { .opacity(.5); }
68 | }
69 |
70 | // Modal header
71 | // Top section of the modal w/ title and dismiss
72 | .modal-header {
73 | padding: @modal-title-padding;
74 | border-bottom: 1px solid @modal-header-border-color;
75 | min-height: (@modal-title-padding + @modal-title-line-height);
76 | }
77 | // Close icon
78 | .modal-header .close {
79 | margin-top: -2px;
80 | }
81 |
82 | // Title text within header
83 | .modal-title {
84 | margin: 0;
85 | line-height: @modal-title-line-height;
86 | }
87 |
88 | // Modal body
89 | // Where all modal content resides (sibling of .modal-header and .modal-footer)
90 | .modal-body {
91 | position: relative;
92 | padding: @modal-inner-padding;
93 | }
94 |
95 | // Footer (for actions)
96 | .modal-footer {
97 | margin-top: 15px;
98 | padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;
99 | text-align: right; // right align buttons
100 | border-top: 1px solid @modal-footer-border-color;
101 | .clearfix(); // clear it in case folks use .pull-* classes on buttons
102 |
103 | // Properly space out buttons
104 | .btn + .btn {
105 | margin-left: 5px;
106 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
107 | }
108 | // but override that for button groups
109 | .btn-group .btn + .btn {
110 | margin-left: -1px;
111 | }
112 | // and override it for block buttons as well
113 | .btn-block + .btn-block {
114 | margin-left: 0;
115 | }
116 | }
117 |
118 | // Scale up the modal
119 | @media screen and (min-width: @screen-sm-min) {
120 |
121 | .modal-dialog {
122 | width: 600px;
123 | margin: 30px auto;
124 | }
125 | .modal-content {
126 | .box-shadow(0 5px 15px rgba(0,0,0,.5));
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/web/bootstrap/less/popovers.less:
--------------------------------------------------------------------------------
1 | //
2 | // Popovers
3 | // --------------------------------------------------
4 |
5 |
6 | .popover {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | z-index: @zindex-popover;
11 | display: none;
12 | max-width: @popover-max-width;
13 | padding: 1px;
14 | text-align: left; // Reset given new insertion method
15 | background-color: @popover-bg;
16 | background-clip: padding-box;
17 | border: 1px solid @popover-fallback-border-color;
18 | border: 1px solid @popover-border-color;
19 | border-radius: @border-radius-large;
20 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
21 |
22 | // Overrides for proper insertion
23 | white-space: normal;
24 |
25 | // Offset the popover to account for the popover arrow
26 | &.top { margin-top: -10px; }
27 | &.right { margin-left: 10px; }
28 | &.bottom { margin-top: 10px; }
29 | &.left { margin-left: -10px; }
30 | }
31 |
32 | .popover-title {
33 | margin: 0; // reset heading margin
34 | padding: 8px 14px;
35 | font-size: @font-size-base;
36 | font-weight: normal;
37 | line-height: 18px;
38 | background-color: @popover-title-bg;
39 | border-bottom: 1px solid darken(@popover-title-bg, 5%);
40 | border-radius: 5px 5px 0 0;
41 | }
42 |
43 | .popover-content {
44 | padding: 9px 14px;
45 | }
46 |
47 | // Arrows
48 | //
49 | // .arrow is outer, .arrow:after is inner
50 |
51 | .popover .arrow {
52 | &,
53 | &:after {
54 | position: absolute;
55 | display: block;
56 | width: 0;
57 | height: 0;
58 | border-color: transparent;
59 | border-style: solid;
60 | }
61 | }
62 | .popover .arrow {
63 | border-width: @popover-arrow-outer-width;
64 | }
65 | .popover .arrow:after {
66 | border-width: @popover-arrow-width;
67 | content: "";
68 | }
69 |
70 | .popover {
71 | &.top .arrow {
72 | left: 50%;
73 | margin-left: -@popover-arrow-outer-width;
74 | border-bottom-width: 0;
75 | border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback
76 | border-top-color: @popover-arrow-outer-color;
77 | bottom: -@popover-arrow-outer-width;
78 | &:after {
79 | content: " ";
80 | bottom: 1px;
81 | margin-left: -@popover-arrow-width;
82 | border-bottom-width: 0;
83 | border-top-color: @popover-arrow-color;
84 | }
85 | }
86 | &.right .arrow {
87 | top: 50%;
88 | left: -@popover-arrow-outer-width;
89 | margin-top: -@popover-arrow-outer-width;
90 | border-left-width: 0;
91 | border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback
92 | border-right-color: @popover-arrow-outer-color;
93 | &:after {
94 | content: " ";
95 | left: 1px;
96 | bottom: -@popover-arrow-width;
97 | border-left-width: 0;
98 | border-right-color: @popover-arrow-color;
99 | }
100 | }
101 | &.bottom .arrow {
102 | left: 50%;
103 | margin-left: -@popover-arrow-outer-width;
104 | border-top-width: 0;
105 | border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback
106 | border-bottom-color: @popover-arrow-outer-color;
107 | top: -@popover-arrow-outer-width;
108 | &:after {
109 | content: " ";
110 | top: 1px;
111 | margin-left: -@popover-arrow-width;
112 | border-top-width: 0;
113 | border-bottom-color: @popover-arrow-color;
114 | }
115 | }
116 |
117 | &.left .arrow {
118 | top: 50%;
119 | right: -@popover-arrow-outer-width;
120 | margin-top: -@popover-arrow-outer-width;
121 | border-right-width: 0;
122 | border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback
123 | border-left-color: @popover-arrow-outer-color;
124 | &:after {
125 | content: " ";
126 | right: 1px;
127 | border-right-width: 0;
128 | border-left-color: @popover-arrow-color;
129 | bottom: -@popover-arrow-width;
130 | }
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/web/bootstrap/less/input-groups.less:
--------------------------------------------------------------------------------
1 | //
2 | // Input groups
3 | // --------------------------------------------------
4 |
5 | // Base styles
6 | // -------------------------
7 | .input-group {
8 | position: relative; // For dropdowns
9 | display: table;
10 | border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table
11 |
12 | // Undo padding and float of grid classes
13 | &[class*="col-"] {
14 | float: none;
15 | padding-left: 0;
16 | padding-right: 0;
17 | }
18 |
19 | .form-control {
20 | width: 100%;
21 | margin-bottom: 0;
22 | }
23 | }
24 |
25 | // Sizing options
26 | //
27 | // Remix the default form control sizing classes into new ones for easier
28 | // manipulation.
29 |
30 | .input-group-lg > .form-control,
31 | .input-group-lg > .input-group-addon,
32 | .input-group-lg > .input-group-btn > .btn { .input-lg(); }
33 | .input-group-sm > .form-control,
34 | .input-group-sm > .input-group-addon,
35 | .input-group-sm > .input-group-btn > .btn { .input-sm(); }
36 |
37 |
38 | // Display as table-cell
39 | // -------------------------
40 | .input-group-addon,
41 | .input-group-btn,
42 | .input-group .form-control {
43 | display: table-cell;
44 |
45 | &:not(:first-child):not(:last-child) {
46 | border-radius: 0;
47 | }
48 | }
49 | // Addon and addon wrapper for buttons
50 | .input-group-addon,
51 | .input-group-btn {
52 | width: 1%;
53 | white-space: nowrap;
54 | vertical-align: middle; // Match the inputs
55 | }
56 |
57 | // Text input groups
58 | // -------------------------
59 | .input-group-addon {
60 | padding: @padding-base-vertical @padding-base-horizontal;
61 | font-size: @font-size-base;
62 | font-weight: normal;
63 | line-height: 1;
64 | color: @input-color;
65 | text-align: center;
66 | background-color: @input-group-addon-bg;
67 | border: 1px solid @input-group-addon-border-color;
68 | border-radius: @border-radius-base;
69 |
70 | // Sizing
71 | &.input-sm {
72 | padding: @padding-small-vertical @padding-small-horizontal;
73 | font-size: @font-size-small;
74 | border-radius: @border-radius-small;
75 | }
76 | &.input-lg {
77 | padding: @padding-large-vertical @padding-large-horizontal;
78 | font-size: @font-size-large;
79 | border-radius: @border-radius-large;
80 | }
81 |
82 | // Nuke default margins from checkboxes and radios to vertically center within.
83 | input[type="radio"],
84 | input[type="checkbox"] {
85 | margin-top: 0;
86 | }
87 | }
88 |
89 | // Reset rounded corners
90 | .input-group .form-control:first-child,
91 | .input-group-addon:first-child,
92 | .input-group-btn:first-child > .btn,
93 | .input-group-btn:first-child > .dropdown-toggle,
94 | .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {
95 | .border-right-radius(0);
96 | }
97 | .input-group-addon:first-child {
98 | border-right: 0;
99 | }
100 | .input-group .form-control:last-child,
101 | .input-group-addon:last-child,
102 | .input-group-btn:last-child > .btn,
103 | .input-group-btn:last-child > .dropdown-toggle,
104 | .input-group-btn:first-child > .btn:not(:first-child) {
105 | .border-left-radius(0);
106 | }
107 | .input-group-addon:last-child {
108 | border-left: 0;
109 | }
110 |
111 | // Button input groups
112 | // -------------------------
113 | .input-group-btn {
114 | position: relative;
115 | white-space: nowrap;
116 |
117 | // Negative margin to only have a 1px border between the two
118 | &:first-child > .btn {
119 | margin-right: -1px;
120 | }
121 | &:last-child > .btn {
122 | margin-left: -1px;
123 | }
124 | }
125 | .input-group-btn > .btn {
126 | position: relative;
127 | // Jankily prevent input button groups from wrapping
128 | + .btn {
129 | margin-left: -4px;
130 | }
131 | // Bring the "active" button to the front
132 | &:hover,
133 | &:active {
134 | z-index: 2;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/web/bootstrap/less/buttons.less:
--------------------------------------------------------------------------------
1 | //
2 | // Buttons
3 | // --------------------------------------------------
4 |
5 |
6 | // Base styles
7 | // --------------------------------------------------
8 |
9 | .btn {
10 | display: inline-block;
11 | margin-bottom: 0; // For input.btn
12 | font-weight: @btn-font-weight;
13 | text-align: center;
14 | vertical-align: middle;
15 | cursor: pointer;
16 | background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
17 | border: 1px solid transparent;
18 | white-space: nowrap;
19 | .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
20 | .user-select(none);
21 |
22 | &:focus {
23 | .tab-focus();
24 | }
25 |
26 | &:hover,
27 | &:focus {
28 | color: @btn-default-color;
29 | text-decoration: none;
30 | }
31 |
32 | &:active,
33 | &.active {
34 | outline: 0;
35 | background-image: none;
36 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
37 | }
38 |
39 | &.disabled,
40 | &[disabled],
41 | fieldset[disabled] & {
42 | cursor: not-allowed;
43 | pointer-events: none; // Future-proof disabling of clicks
44 | .opacity(.65);
45 | .box-shadow(none);
46 | }
47 | }
48 |
49 |
50 | // Alternate buttons
51 | // --------------------------------------------------
52 |
53 | .btn-default {
54 | .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
55 | }
56 | .btn-primary {
57 | .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
58 | }
59 | // Warning appears as orange
60 | .btn-warning {
61 | .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);
62 | }
63 | // Danger and error appear as red
64 | .btn-danger {
65 | .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);
66 | }
67 | // Success appears as green
68 | .btn-success {
69 | .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);
70 | }
71 | // Info appears as blue-green
72 | .btn-info {
73 | .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);
74 | }
75 |
76 |
77 | // Link buttons
78 | // -------------------------
79 |
80 | // Make a button look and behave like a link
81 | .btn-link {
82 | color: @link-color;
83 | font-weight: normal;
84 | cursor: pointer;
85 | border-radius: 0;
86 |
87 | &,
88 | &:active,
89 | &[disabled],
90 | fieldset[disabled] & {
91 | background-color: transparent;
92 | .box-shadow(none);
93 | }
94 | &,
95 | &:hover,
96 | &:focus,
97 | &:active {
98 | border-color: transparent;
99 | }
100 | &:hover,
101 | &:focus {
102 | color: @link-hover-color;
103 | text-decoration: underline;
104 | background-color: transparent;
105 | }
106 | &[disabled],
107 | fieldset[disabled] & {
108 | &:hover,
109 | &:focus {
110 | color: @btn-link-disabled-color;
111 | text-decoration: none;
112 | }
113 | }
114 | }
115 |
116 |
117 | // Button Sizes
118 | // --------------------------------------------------
119 |
120 | .btn-lg {
121 | // line-height: ensure even-numbered height of button next to large input
122 | .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
123 | }
124 | .btn-sm {
125 | // line-height: ensure proper height of button next to small input
126 | .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
127 | }
128 | .btn-xs {
129 | .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
130 | }
131 |
132 |
133 | // Block button
134 | // --------------------------------------------------
135 |
136 | .btn-block {
137 | display: block;
138 | width: 100%;
139 | padding-left: 0;
140 | padding-right: 0;
141 | }
142 |
143 | // Vertically space out multiple block buttons
144 | .btn-block + .btn-block {
145 | margin-top: 5px;
146 | }
147 |
148 | // Specificity overrides
149 | input[type="submit"],
150 | input[type="reset"],
151 | input[type="button"] {
152 | &.btn-block {
153 | width: 100%;
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/lib/view.js:
--------------------------------------------------------------------------------
1 | var Backbone = require('backbone')
2 | , d = React.DOM
3 |
4 | , AppRouter = require('./router')
5 |
6 | , AllIssuesPage = require('./pages/all-issues')
7 | , IssuePage = require('./pages/issue')
8 |
9 | /*
10 | * The main view
11 | *
12 | * Pretty much just in charge of routing. See router.js for the spec.
13 | *
14 | * Child components:
15 | * - AllIssuesPage (view the list of issues)
16 | * - IssuePage (view one issue)
17 | *
18 | */
19 | var View = module.exports = React.createClass({
20 | // react stuff
21 | getDefaultProps: function () {
22 | return {
23 | repo: 'rails/rails',
24 | issues: []
25 | }
26 | },
27 | getInitialState: function () {
28 | return {
29 | page: 'allIssues',
30 | start: 0,
31 | issue: false,
32 | }
33 | },
34 | componentWillMount: function () {
35 | var that = this
36 | this.router = new AppRouter();
37 | this.router.on('route:allIssues', this.allIssues)
38 | this.router.on('route:issue', this.navIssue)
39 | this.router.on('default', function () {
40 | that.goHome()
41 | })
42 |
43 | },
44 | componentDidMount: function () {
45 | Backbone.history.start();
46 | },
47 | /*
48 | componentWillReceiveProps: function (props) {
49 | if (props.repo !== this.props.repo) {
50 | this.goHome(props.repo)
51 | }
52 | },
53 | */
54 | componentDidUpdate: function (props, state) {
55 | if (props.repo !== this.props.repo) {
56 | if (Backbone.history.fragment.indexOf(this.props.repo) === 0) return
57 | this.goHome()
58 | }
59 | },
60 |
61 | // routing
62 | checkRepoChange: function (owner, repo) {
63 | var name = owner + '/' + repo
64 | if (name === this.props.repo) return
65 | this.props.setRepo(name)
66 | return true
67 | },
68 | allIssues: function (owner, repo, start) {
69 | this.checkRepoChange(owner, repo)
70 | var num = start ? parseInt(start) : 0
71 | if (isNaN(num)) {
72 | return this.goHome()
73 | }
74 | this.setState({
75 | page: 'allIssues',
76 | start: num
77 | })
78 | },
79 | navIssue: function (owner, repo, issue) {
80 | this.checkRepoChange(owner, repo)
81 | issue = parseInt(issue)
82 | if (isNaN(issue)) {
83 | return this.goHome()
84 | }
85 | this.setState({
86 | page: 'issue',
87 | issue: issue
88 | })
89 | },
90 | goHome: function (repo) {
91 | this.router.navigate(repo || this.props.repo, {trigger: true})
92 | },
93 |
94 | // child callbacks
95 | onPage: function (start) {
96 | this.router.navigate(this.props.repo + '/' + start, {trigger: true})
97 | },
98 | issueHref: function (issue) {
99 | return '#' + this.props.repo + '/issue/' + issue
100 | },
101 |
102 | getMessage: function () {
103 | if (this.state.error) {
104 | if (this.state.error === 'Forbidden') {
105 | return "Github API imposes a 60 req/hour limit, and it looks like you've gone over."
106 | }
107 | return 'Failed to fetch issues! Does the repo exist?'
108 | }
109 | if (this.state.loading) return 'loading...'
110 | },
111 |
112 | getIssue: function (issues) {
113 | issues = issues || this.props.issues
114 | for (var i=0; i li > a {
61 | display: block;
62 | padding: 3px 20px;
63 | clear: both;
64 | font-weight: normal;
65 | line-height: @line-height-base;
66 | color: @dropdown-link-color;
67 | white-space: nowrap; // prevent links from randomly breaking onto new lines
68 | }
69 | }
70 |
71 | // Hover/Focus state
72 | .dropdown-menu > li > a {
73 | &:hover,
74 | &:focus {
75 | text-decoration: none;
76 | color: @dropdown-link-hover-color;
77 | background-color: @dropdown-link-hover-bg;
78 | }
79 | }
80 |
81 | // Active state
82 | .dropdown-menu > .active > a {
83 | &,
84 | &:hover,
85 | &:focus {
86 | color: @dropdown-link-active-color;
87 | text-decoration: none;
88 | outline: 0;
89 | background-color: @dropdown-link-active-bg;
90 | }
91 | }
92 |
93 | // Disabled state
94 | //
95 | // Gray out text and ensure the hover/focus state remains gray
96 |
97 | .dropdown-menu > .disabled > a {
98 | &,
99 | &:hover,
100 | &:focus {
101 | color: @dropdown-link-disabled-color;
102 | }
103 | }
104 | // Nuke hover/focus effects
105 | .dropdown-menu > .disabled > a {
106 | &:hover,
107 | &:focus {
108 | text-decoration: none;
109 | background-color: transparent;
110 | background-image: none; // Remove CSS gradient
111 | .reset-filter();
112 | cursor: not-allowed;
113 | }
114 | }
115 |
116 | // Open state for the dropdown
117 | .open {
118 | // Show the menu
119 | > .dropdown-menu {
120 | display: block;
121 | }
122 |
123 | // Remove the outline when :focus is triggered
124 | > a {
125 | outline: 0;
126 | }
127 | }
128 |
129 | // Dropdown section headers
130 | .dropdown-header {
131 | display: block;
132 | padding: 3px 20px;
133 | font-size: @font-size-small;
134 | line-height: @line-height-base;
135 | color: @dropdown-header-color;
136 | }
137 |
138 | // Backdrop to catch body clicks on mobile, etc.
139 | .dropdown-backdrop {
140 | position: fixed;
141 | left: 0;
142 | right: 0;
143 | bottom: 0;
144 | top: 0;
145 | z-index: @zindex-dropdown - 10;
146 | }
147 |
148 | // Right aligned dropdowns
149 | .pull-right > .dropdown-menu {
150 | right: 0;
151 | left: auto;
152 | }
153 |
154 | // Allow for dropdowns to go bottom up (aka, dropup-menu)
155 | //
156 | // Just add .dropup after the standard .dropdown class and you're set, bro.
157 | // TODO: abstract this so that the navbar fixed styles are not placed here?
158 |
159 | .dropup,
160 | .navbar-fixed-bottom .dropdown {
161 | // Reverse the caret
162 | .caret {
163 | border-top: 0;
164 | border-bottom: @caret-width-base solid;
165 | content: "";
166 | }
167 | // Different positioning for bottom up menu
168 | .dropdown-menu {
169 | top: auto;
170 | bottom: 100%;
171 | margin-bottom: 1px;
172 | }
173 | }
174 |
175 |
176 | // Component alignment
177 | //
178 | // Reiterate per navbar.less and the modified component alignment there.
179 |
180 | @media (min-width: @grid-float-breakpoint) {
181 | .navbar-right {
182 | .dropdown-menu {
183 | .pull-right > .dropdown-menu();
184 | }
185 | }
186 | }
187 |
188 |
--------------------------------------------------------------------------------
/web/bootstrap/less/panels.less:
--------------------------------------------------------------------------------
1 | //
2 | // Panels
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .panel {
8 | margin-bottom: @line-height-computed;
9 | background-color: @panel-bg;
10 | border: 1px solid transparent;
11 | border-radius: @panel-border-radius;
12 | .box-shadow(0 1px 1px rgba(0,0,0,.05));
13 | }
14 |
15 | // Panel contents
16 | .panel-body {
17 | padding: 15px;
18 | .clearfix();
19 | }
20 |
21 |
22 | // List groups in panels
23 | //
24 | // By default, space out list group content from panel headings to account for
25 | // any kind of custom content between the two.
26 |
27 | .panel {
28 | > .list-group {
29 | margin-bottom: 0;
30 |
31 | .list-group-item {
32 | border-width: 1px 0;
33 |
34 | // Remove border radius for top one
35 | &:first-child {
36 | .border-top-radius(0);
37 | }
38 | // But keep it for the last one
39 | &:last-child {
40 | border-bottom: 0;
41 | }
42 | }
43 | }
44 | }
45 | // Collapse space between when there's no additional content.
46 | .panel-heading + .list-group {
47 | .list-group-item:first-child {
48 | border-top-width: 0;
49 | }
50 | }
51 |
52 |
53 | // Tables in panels
54 | //
55 | // Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
56 | // watch it go full width.
57 |
58 | .panel {
59 | > .table,
60 | > .table-responsive > .table {
61 | margin-bottom: 0;
62 | }
63 | > .panel-body + .table,
64 | > .panel-body + .table-responsive {
65 | border-top: 1px solid @table-border-color;
66 | }
67 | > .table > tbody:first-child th,
68 | > .table > tbody:first-child td {
69 | border-top: 0;
70 | }
71 | > .table-bordered,
72 | > .table-responsive > .table-bordered {
73 | border: 0;
74 | > thead,
75 | > tbody,
76 | > tfoot {
77 | > tr {
78 | > th:first-child,
79 | > td:first-child {
80 | border-left: 0;
81 | }
82 | > th:last-child,
83 | > td:last-child {
84 | border-right: 0;
85 | }
86 |
87 | &:last-child > th,
88 | &:last-child > td {
89 | border-bottom: 0;
90 | }
91 | }
92 | }
93 | }
94 | > .table-responsive {
95 | border: 0;
96 | margin-bottom: 0;
97 | }
98 | }
99 |
100 |
101 | // Optional heading
102 | .panel-heading {
103 | padding: 10px 15px;
104 | border-bottom: 1px solid transparent;
105 | .border-top-radius(@panel-border-radius - 1);
106 |
107 | > .dropdown .dropdown-toggle {
108 | color: inherit;
109 | }
110 | }
111 |
112 | // Within heading, strip any `h*` tag of it's default margins for spacing.
113 | .panel-title {
114 | margin-top: 0;
115 | margin-bottom: 0;
116 | font-size: ceil((@font-size-base * 1.125));
117 | color: inherit;
118 |
119 | > a {
120 | color: inherit;
121 | }
122 | }
123 |
124 | // Optional footer (stays gray in every modifier class)
125 | .panel-footer {
126 | padding: 10px 15px;
127 | background-color: @panel-footer-bg;
128 | border-top: 1px solid @panel-inner-border;
129 | .border-bottom-radius(@panel-border-radius - 1);
130 | }
131 |
132 |
133 | // Collapsable panels (aka, accordion)
134 | //
135 | // Wrap a series of panels in `.panel-group` to turn them into an accordion with
136 | // the help of our collapse JavaScript plugin.
137 |
138 | .panel-group {
139 | // Tighten up margin so it's only between panels
140 | .panel {
141 | margin-bottom: 0;
142 | border-radius: @panel-border-radius;
143 | overflow: hidden; // crop contents when collapsed
144 | + .panel {
145 | margin-top: 5px;
146 | }
147 | }
148 |
149 | .panel-heading {
150 | border-bottom: 0;
151 | + .panel-collapse .panel-body {
152 | border-top: 1px solid @panel-inner-border;
153 | }
154 | }
155 | .panel-footer {
156 | border-top: 0;
157 | + .panel-collapse .panel-body {
158 | border-bottom: 1px solid @panel-inner-border;
159 | }
160 | }
161 | }
162 |
163 |
164 | // Contextual variations
165 | .panel-default {
166 | .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);
167 | }
168 | .panel-primary {
169 | .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);
170 | }
171 | .panel-success {
172 | .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);
173 | }
174 | .panel-warning {
175 | .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);
176 | }
177 | .panel-danger {
178 | .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);
179 | }
180 | .panel-info {
181 | .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);
182 | }
183 |
--------------------------------------------------------------------------------
/web/bootstrap/less/tables.less:
--------------------------------------------------------------------------------
1 | //
2 | // Tables
3 | // --------------------------------------------------
4 |
5 |
6 | table {
7 | max-width: 100%;
8 | background-color: @table-bg;
9 | }
10 | th {
11 | text-align: left;
12 | }
13 |
14 |
15 | // Baseline styles
16 |
17 | .table {
18 | width: 100%;
19 | margin-bottom: @line-height-computed;
20 | // Cells
21 | > thead,
22 | > tbody,
23 | > tfoot {
24 | > tr {
25 | > th,
26 | > td {
27 | padding: @table-cell-padding;
28 | line-height: @line-height-base;
29 | vertical-align: top;
30 | border-top: 1px solid @table-border-color;
31 | }
32 | }
33 | }
34 | // Bottom align for column headings
35 | > thead > tr > th {
36 | vertical-align: bottom;
37 | border-bottom: 2px solid @table-border-color;
38 | }
39 | // Remove top border from thead by default
40 | > caption + thead,
41 | > colgroup + thead,
42 | > thead:first-child {
43 | > tr:first-child {
44 | > th,
45 | > td {
46 | border-top: 0;
47 | }
48 | }
49 | }
50 | // Account for multiple tbody instances
51 | > tbody + tbody {
52 | border-top: 2px solid @table-border-color;
53 | }
54 |
55 | // Nesting
56 | .table {
57 | background-color: @body-bg;
58 | }
59 | }
60 |
61 |
62 | // Condensed table w/ half padding
63 |
64 | .table-condensed {
65 | > thead,
66 | > tbody,
67 | > tfoot {
68 | > tr {
69 | > th,
70 | > td {
71 | padding: @table-condensed-cell-padding;
72 | }
73 | }
74 | }
75 | }
76 |
77 |
78 | // Bordered version
79 | //
80 | // Add borders all around the table and between all the columns.
81 |
82 | .table-bordered {
83 | border: 1px solid @table-border-color;
84 | > thead,
85 | > tbody,
86 | > tfoot {
87 | > tr {
88 | > th,
89 | > td {
90 | border: 1px solid @table-border-color;
91 | }
92 | }
93 | }
94 | > thead > tr {
95 | > th,
96 | > td {
97 | border-bottom-width: 2px;
98 | }
99 | }
100 | }
101 |
102 |
103 | // Zebra-striping
104 | //
105 | // Default zebra-stripe styles (alternating gray and transparent backgrounds)
106 |
107 | .table-striped {
108 | > tbody > tr:nth-child(odd) {
109 | > td,
110 | > th {
111 | background-color: @table-bg-accent;
112 | }
113 | }
114 | }
115 |
116 |
117 | // Hover effect
118 | //
119 | // Placed here since it has to come after the potential zebra striping
120 |
121 | .table-hover {
122 | > tbody > tr:hover {
123 | > td,
124 | > th {
125 | background-color: @table-bg-hover;
126 | }
127 | }
128 | }
129 |
130 |
131 | // Table cell sizing
132 | //
133 | // Reset default table behavior
134 |
135 | table col[class*="col-"] {
136 | position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)
137 | float: none;
138 | display: table-column;
139 | }
140 | table {
141 | td,
142 | th {
143 | &[class*="col-"] {
144 | float: none;
145 | display: table-cell;
146 | }
147 | }
148 | }
149 |
150 |
151 | // Table backgrounds
152 | //
153 | // Exact selectors below required to override `.table-striped` and prevent
154 | // inheritance to nested tables.
155 |
156 | // Generate the contextual variants
157 | .table-row-variant(active; @table-bg-active);
158 | .table-row-variant(success; @state-success-bg);
159 | .table-row-variant(danger; @state-danger-bg);
160 | .table-row-variant(warning; @state-warning-bg);
161 |
162 |
163 | // Responsive tables
164 | //
165 | // Wrap your tables in `.table-responsive` and we'll make them mobile friendly
166 | // by enabling horizontal scrolling. Only applies <768px. Everything above that
167 | // will display normally.
168 |
169 | @media (max-width: @screen-xs-max) {
170 | .table-responsive {
171 | width: 100%;
172 | margin-bottom: (@line-height-computed * 0.75);
173 | overflow-y: hidden;
174 | overflow-x: scroll;
175 | -ms-overflow-style: -ms-autohiding-scrollbar;
176 | border: 1px solid @table-border-color;
177 | -webkit-overflow-scrolling: touch;
178 |
179 | // Tighten up spacing
180 | > .table {
181 | margin-bottom: 0;
182 |
183 | // Ensure the content doesn't wrap
184 | > thead,
185 | > tbody,
186 | > tfoot {
187 | > tr {
188 | > th,
189 | > td {
190 | white-space: nowrap;
191 | }
192 | }
193 | }
194 | }
195 |
196 | // Special overrides for the bordered tables
197 | > .table-bordered {
198 | border: 0;
199 |
200 | // Nuke the appropriate borders so that the parent can handle them
201 | > thead,
202 | > tbody,
203 | > tfoot {
204 | > tr {
205 | > th:first-child,
206 | > td:first-child {
207 | border-left: 0;
208 | }
209 | > th:last-child,
210 | > td:last-child {
211 | border-right: 0;
212 | }
213 | }
214 | }
215 |
216 | // Only nuke the last row's bottom-border in `tbody` and `tfoot` since
217 | // chances are there will be only one `tr` in a `thead` and that would
218 | // remove the border altogether.
219 | > tbody,
220 | > tfoot {
221 | > tr:last-child {
222 | > th,
223 | > td {
224 | border-bottom: 0;
225 | }
226 | }
227 | }
228 |
229 | }
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/web/bootstrap/less/carousel.less:
--------------------------------------------------------------------------------
1 | //
2 | // Carousel
3 | // --------------------------------------------------
4 |
5 |
6 | // Wrapper for the slide container and indicators
7 | .carousel {
8 | position: relative;
9 | }
10 |
11 | .carousel-inner {
12 | position: relative;
13 | overflow: hidden;
14 | width: 100%;
15 |
16 | > .item {
17 | display: none;
18 | position: relative;
19 | .transition(.6s ease-in-out left);
20 |
21 | // Account for jankitude on images
22 | > img,
23 | > a > img {
24 | .img-responsive();
25 | line-height: 1;
26 | }
27 | }
28 |
29 | > .active,
30 | > .next,
31 | > .prev { display: block; }
32 |
33 | > .active {
34 | left: 0;
35 | }
36 |
37 | > .next,
38 | > .prev {
39 | position: absolute;
40 | top: 0;
41 | width: 100%;
42 | }
43 |
44 | > .next {
45 | left: 100%;
46 | }
47 | > .prev {
48 | left: -100%;
49 | }
50 | > .next.left,
51 | > .prev.right {
52 | left: 0;
53 | }
54 |
55 | > .active.left {
56 | left: -100%;
57 | }
58 | > .active.right {
59 | left: 100%;
60 | }
61 |
62 | }
63 |
64 | // Left/right controls for nav
65 | // ---------------------------
66 |
67 | .carousel-control {
68 | position: absolute;
69 | top: 0;
70 | left: 0;
71 | bottom: 0;
72 | width: @carousel-control-width;
73 | .opacity(@carousel-control-opacity);
74 | font-size: @carousel-control-font-size;
75 | color: @carousel-control-color;
76 | text-align: center;
77 | text-shadow: @carousel-text-shadow;
78 | // We can't have this transition here because WebKit cancels the carousel
79 | // animation if you trip this while in the middle of another animation.
80 |
81 | // Set gradients for backgrounds
82 | &.left {
83 | #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));
84 | }
85 | &.right {
86 | left: auto;
87 | right: 0;
88 | #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));
89 | }
90 |
91 | // Hover/focus state
92 | &:hover,
93 | &:focus {
94 | outline: none;
95 | color: @carousel-control-color;
96 | text-decoration: none;
97 | .opacity(.9);
98 | }
99 |
100 | // Toggles
101 | .icon-prev,
102 | .icon-next,
103 | .glyphicon-chevron-left,
104 | .glyphicon-chevron-right {
105 | position: absolute;
106 | top: 50%;
107 | z-index: 5;
108 | display: inline-block;
109 | }
110 | .icon-prev,
111 | .glyphicon-chevron-left {
112 | left: 50%;
113 | }
114 | .icon-next,
115 | .glyphicon-chevron-right {
116 | right: 50%;
117 | }
118 | .icon-prev,
119 | .icon-next {
120 | width: 20px;
121 | height: 20px;
122 | margin-top: -10px;
123 | margin-left: -10px;
124 | font-family: serif;
125 | }
126 |
127 | .icon-prev {
128 | &:before {
129 | content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
130 | }
131 | }
132 | .icon-next {
133 | &:before {
134 | content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
135 | }
136 | }
137 | }
138 |
139 | // Optional indicator pips
140 | //
141 | // Add an unordered list with the following class and add a list item for each
142 | // slide your carousel holds.
143 |
144 | .carousel-indicators {
145 | position: absolute;
146 | bottom: 10px;
147 | left: 50%;
148 | z-index: 15;
149 | width: 60%;
150 | margin-left: -30%;
151 | padding-left: 0;
152 | list-style: none;
153 | text-align: center;
154 |
155 | li {
156 | display: inline-block;
157 | width: 10px;
158 | height: 10px;
159 | margin: 1px;
160 | text-indent: -999px;
161 | border: 1px solid @carousel-indicator-border-color;
162 | border-radius: 10px;
163 | cursor: pointer;
164 |
165 | // IE8-9 hack for event handling
166 | //
167 | // Internet Explorer 8-9 does not support clicks on elements without a set
168 | // `background-color`. We cannot use `filter` since that's not viewed as a
169 | // background color by the browser. Thus, a hack is needed.
170 | //
171 | // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
172 | // set alpha transparency for the best results possible.
173 | background-color: #000 \9; // IE8
174 | background-color: rgba(0,0,0,0); // IE9
175 | }
176 | .active {
177 | margin: 0;
178 | width: 12px;
179 | height: 12px;
180 | background-color: @carousel-indicator-active-bg;
181 | }
182 | }
183 |
184 | // Optional captions
185 | // -----------------------------
186 | // Hidden by default for smaller viewports
187 | .carousel-caption {
188 | position: absolute;
189 | left: 15%;
190 | right: 15%;
191 | bottom: 20px;
192 | z-index: 10;
193 | padding-top: 20px;
194 | padding-bottom: 20px;
195 | color: @carousel-caption-color;
196 | text-align: center;
197 | text-shadow: @carousel-text-shadow;
198 | & .btn {
199 | text-shadow: none; // No shadow for button elements in carousel-caption
200 | }
201 | }
202 |
203 |
204 | // Scale up controls for tablets and up
205 | @media screen and (min-width: @screen-sm-min) {
206 |
207 | // Scale up the controls a smidge
208 | .carousel-control {
209 | .glyphicons-chevron-left,
210 | .glyphicons-chevron-right,
211 | .icon-prev,
212 | .icon-next {
213 | width: 30px;
214 | height: 30px;
215 | margin-top: -15px;
216 | margin-left: -15px;
217 | font-size: 30px;
218 | }
219 | }
220 |
221 | // Show and left align the captions
222 | .carousel-caption {
223 | left: 20%;
224 | right: 20%;
225 | padding-bottom: 30px;
226 | }
227 |
228 | // Move up the indicators
229 | .carousel-indicators {
230 | bottom: 20px;
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/web/bootstrap/less/responsive-utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // IE10 in Windows (Phone) 8
7 | //
8 | // Support for responsive views via media queries is kind of borked in IE10, for
9 | // Surface/desktop in split view and for Windows Phone 8. This particular fix
10 | // must be accompanied by a snippet of JavaScript to sniff the user agent and
11 | // apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at
12 | // our Getting Started page for more information on this bug.
13 | //
14 | // For more information, see the following:
15 | //
16 | // Issue: https://github.com/twbs/bootstrap/issues/10497
17 | // Docs: http://getbootstrap.com/getting-started/#browsers
18 | // Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
19 |
20 | @-ms-viewport {
21 | width: device-width;
22 | }
23 |
24 |
25 | // Visibility utilities
26 |
27 | .visible-xs {
28 | .responsive-invisibility();
29 | @media (max-width: @screen-xs-max) {
30 | .responsive-visibility();
31 | }
32 | &.visible-sm {
33 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
34 | .responsive-visibility();
35 | }
36 | }
37 | &.visible-md {
38 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
39 | .responsive-visibility();
40 | }
41 | }
42 | &.visible-lg {
43 | @media (min-width: @screen-lg-min) {
44 | .responsive-visibility();
45 | }
46 | }
47 | }
48 | .visible-sm {
49 | .responsive-invisibility();
50 | &.visible-xs {
51 | @media (max-width: @screen-xs-max) {
52 | .responsive-visibility();
53 | }
54 | }
55 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
56 | .responsive-visibility();
57 | }
58 | &.visible-md {
59 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
60 | .responsive-visibility();
61 | }
62 | }
63 | &.visible-lg {
64 | @media (min-width: @screen-lg-min) {
65 | .responsive-visibility();
66 | }
67 | }
68 | }
69 | .visible-md {
70 | .responsive-invisibility();
71 | &.visible-xs {
72 | @media (max-width: @screen-xs-max) {
73 | .responsive-visibility();
74 | }
75 | }
76 | &.visible-sm {
77 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
78 | .responsive-visibility();
79 | }
80 | }
81 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
82 | .responsive-visibility();
83 | }
84 | &.visible-lg {
85 | @media (min-width: @screen-lg-min) {
86 | .responsive-visibility();
87 | }
88 | }
89 | }
90 | .visible-lg {
91 | .responsive-invisibility();
92 | &.visible-xs {
93 | @media (max-width: @screen-xs-max) {
94 | .responsive-visibility();
95 | }
96 | }
97 | &.visible-sm {
98 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
99 | .responsive-visibility();
100 | }
101 | }
102 | &.visible-md {
103 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
104 | .responsive-visibility();
105 | }
106 | }
107 | @media (min-width: @screen-lg-min) {
108 | .responsive-visibility();
109 | }
110 | }
111 |
112 | .hidden-xs {
113 | .responsive-visibility();
114 | @media (max-width: @screen-xs-max) {
115 | .responsive-invisibility();
116 | }
117 | &.hidden-sm {
118 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
119 | .responsive-invisibility();
120 | }
121 | }
122 | &.hidden-md {
123 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
124 | .responsive-invisibility();
125 | }
126 | }
127 | &.hidden-lg {
128 | @media (min-width: @screen-lg-min) {
129 | .responsive-invisibility();
130 | }
131 | }
132 | }
133 | .hidden-sm {
134 | .responsive-visibility();
135 | &.hidden-xs {
136 | @media (max-width: @screen-xs-max) {
137 | .responsive-invisibility();
138 | }
139 | }
140 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
141 | .responsive-invisibility();
142 | }
143 | &.hidden-md {
144 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
145 | .responsive-invisibility();
146 | }
147 | }
148 | &.hidden-lg {
149 | @media (min-width: @screen-lg-min) {
150 | .responsive-invisibility();
151 | }
152 | }
153 | }
154 | .hidden-md {
155 | .responsive-visibility();
156 | &.hidden-xs {
157 | @media (max-width: @screen-xs-max) {
158 | .responsive-invisibility();
159 | }
160 | }
161 | &.hidden-sm {
162 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
163 | .responsive-invisibility();
164 | }
165 | }
166 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
167 | .responsive-invisibility();
168 | }
169 | &.hidden-lg {
170 | @media (min-width: @screen-lg-min) {
171 | .responsive-invisibility();
172 | }
173 | }
174 | }
175 | .hidden-lg {
176 | .responsive-visibility();
177 | &.hidden-xs {
178 | @media (max-width: @screen-xs-max) {
179 | .responsive-invisibility();
180 | }
181 | }
182 | &.hidden-sm {
183 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
184 | .responsive-invisibility();
185 | }
186 | }
187 | &.hidden-md {
188 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
189 | .responsive-invisibility();
190 | }
191 | }
192 | @media (min-width: @screen-lg-min) {
193 | .responsive-invisibility();
194 | }
195 | }
196 |
197 | // Print utilities
198 | .visible-print {
199 | .responsive-invisibility();
200 | }
201 |
202 | @media print {
203 | .visible-print {
204 | .responsive-visibility();
205 | }
206 | .hidden-print {
207 | .responsive-invisibility();
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/web/bootstrap/less/button-groups.less:
--------------------------------------------------------------------------------
1 | //
2 | // Button groups
3 | // --------------------------------------------------
4 |
5 | // Make the div behave like a button
6 | .btn-group,
7 | .btn-group-vertical {
8 | position: relative;
9 | display: inline-block;
10 | vertical-align: middle; // match .btn alignment given font-size hack above
11 | > .btn {
12 | position: relative;
13 | float: left;
14 | // Bring the "active" button to the front
15 | &:hover,
16 | &:focus,
17 | &:active,
18 | &.active {
19 | z-index: 2;
20 | }
21 | &:focus {
22 | // Remove focus outline when dropdown JS adds it after closing the menu
23 | outline: none;
24 | }
25 | }
26 | }
27 |
28 | // Prevent double borders when buttons are next to each other
29 | .btn-group {
30 | .btn + .btn,
31 | .btn + .btn-group,
32 | .btn-group + .btn,
33 | .btn-group + .btn-group {
34 | margin-left: -1px;
35 | }
36 | }
37 |
38 | // Optional: Group multiple button groups together for a toolbar
39 | .btn-toolbar {
40 | .clearfix();
41 |
42 | .btn-group {
43 | float: left;
44 | }
45 | // Space out series of button groups
46 | > .btn,
47 | > .btn-group {
48 | + .btn,
49 | + .btn-group {
50 | margin-left: 5px;
51 | }
52 | }
53 | }
54 |
55 | .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
56 | border-radius: 0;
57 | }
58 |
59 | // 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
60 | .btn-group > .btn:first-child {
61 | margin-left: 0;
62 | &:not(:last-child):not(.dropdown-toggle) {
63 | .border-right-radius(0);
64 | }
65 | }
66 | // Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
67 | .btn-group > .btn:last-child:not(:first-child),
68 | .btn-group > .dropdown-toggle:not(:first-child) {
69 | .border-left-radius(0);
70 | }
71 |
72 | // Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
73 | .btn-group > .btn-group {
74 | float: left;
75 | }
76 | .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
77 | border-radius: 0;
78 | }
79 | .btn-group > .btn-group:first-child {
80 | > .btn:last-child,
81 | > .dropdown-toggle {
82 | .border-right-radius(0);
83 | }
84 | }
85 | .btn-group > .btn-group:last-child > .btn:first-child {
86 | .border-left-radius(0);
87 | }
88 |
89 | // On active and open, don't show outline
90 | .btn-group .dropdown-toggle:active,
91 | .btn-group.open .dropdown-toggle {
92 | outline: 0;
93 | }
94 |
95 |
96 | // Sizing
97 | //
98 | // Remix the default button sizing classes into new ones for easier manipulation.
99 |
100 | .btn-group-xs > .btn { .btn-xs(); }
101 | .btn-group-sm > .btn { .btn-sm(); }
102 | .btn-group-lg > .btn { .btn-lg(); }
103 |
104 |
105 | // Split button dropdowns
106 | // ----------------------
107 |
108 | // Give the line between buttons some depth
109 | .btn-group > .btn + .dropdown-toggle {
110 | padding-left: 8px;
111 | padding-right: 8px;
112 | }
113 | .btn-group > .btn-lg + .dropdown-toggle {
114 | padding-left: 12px;
115 | padding-right: 12px;
116 | }
117 |
118 | // The clickable button for toggling the menu
119 | // Remove the gradient and set the same inset shadow as the :active state
120 | .btn-group.open .dropdown-toggle {
121 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
122 |
123 | // Show no shadow for `.btn-link` since it has no other button styles.
124 | &.btn-link {
125 | .box-shadow(none);
126 | }
127 | }
128 |
129 |
130 | // Reposition the caret
131 | .btn .caret {
132 | margin-left: 0;
133 | }
134 | // Carets in other button sizes
135 | .btn-lg .caret {
136 | border-width: @caret-width-large @caret-width-large 0;
137 | border-bottom-width: 0;
138 | }
139 | // Upside down carets for .dropup
140 | .dropup .btn-lg .caret {
141 | border-width: 0 @caret-width-large @caret-width-large;
142 | }
143 |
144 |
145 | // Vertical button groups
146 | // ----------------------
147 |
148 | .btn-group-vertical {
149 | > .btn,
150 | > .btn-group,
151 | > .btn-group > .btn {
152 | display: block;
153 | float: none;
154 | width: 100%;
155 | max-width: 100%;
156 | }
157 |
158 | // Clear floats so dropdown menus can be properly placed
159 | > .btn-group {
160 | .clearfix();
161 | > .btn {
162 | float: none;
163 | }
164 | }
165 |
166 | > .btn + .btn,
167 | > .btn + .btn-group,
168 | > .btn-group + .btn,
169 | > .btn-group + .btn-group {
170 | margin-top: -1px;
171 | margin-left: 0;
172 | }
173 | }
174 |
175 | .btn-group-vertical > .btn {
176 | &:not(:first-child):not(:last-child) {
177 | border-radius: 0;
178 | }
179 | &:first-child:not(:last-child) {
180 | border-top-right-radius: @border-radius-base;
181 | .border-bottom-radius(0);
182 | }
183 | &:last-child:not(:first-child) {
184 | border-bottom-left-radius: @border-radius-base;
185 | .border-top-radius(0);
186 | }
187 | }
188 | .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
189 | border-radius: 0;
190 | }
191 | .btn-group-vertical > .btn-group:first-child {
192 | > .btn:last-child,
193 | > .dropdown-toggle {
194 | .border-bottom-radius(0);
195 | }
196 | }
197 | .btn-group-vertical > .btn-group:last-child > .btn:first-child {
198 | .border-top-radius(0);
199 | }
200 |
201 |
202 |
203 | // Justified button groups
204 | // ----------------------
205 |
206 | .btn-group-justified {
207 | display: table;
208 | width: 100%;
209 | table-layout: fixed;
210 | border-collapse: separate;
211 | > .btn,
212 | > .btn-group {
213 | float: none;
214 | display: table-cell;
215 | width: 1%;
216 | }
217 | > .btn-group .btn {
218 | width: 100%;
219 | }
220 | }
221 |
222 |
223 | // Checkbox and radio options
224 | [data-toggle="buttons"] > .btn > input[type="radio"],
225 | [data-toggle="buttons"] > .btn > input[type="checkbox"] {
226 | display: none;
227 | }
228 |
--------------------------------------------------------------------------------
/web/bootstrap/less/navs.less:
--------------------------------------------------------------------------------
1 | //
2 | // Navs
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | // --------------------------------------------------
8 |
9 | .nav {
10 | margin-bottom: 0;
11 | padding-left: 0; // Override default ul/ol
12 | list-style: none;
13 | .clearfix();
14 |
15 | > li {
16 | position: relative;
17 | display: block;
18 |
19 | > a {
20 | position: relative;
21 | display: block;
22 | padding: @nav-link-padding;
23 | &:hover,
24 | &:focus {
25 | text-decoration: none;
26 | background-color: @nav-link-hover-bg;
27 | }
28 | }
29 |
30 | // Disabled state sets text to gray and nukes hover/tab effects
31 | &.disabled > a {
32 | color: @nav-disabled-link-color;
33 |
34 | &:hover,
35 | &:focus {
36 | color: @nav-disabled-link-hover-color;
37 | text-decoration: none;
38 | background-color: transparent;
39 | cursor: not-allowed;
40 | }
41 | }
42 | }
43 |
44 | // Open dropdowns
45 | .open > a {
46 | &,
47 | &:hover,
48 | &:focus {
49 | background-color: @nav-link-hover-bg;
50 | border-color: @link-color;
51 | }
52 | }
53 |
54 | // Nav dividers (deprecated with v3.0.1)
55 | //
56 | // This should have been removed in v3 with the dropping of `.nav-list`, but
57 | // we missed it. We don't currently support this anywhere, but in the interest
58 | // of maintaining backward compatibility in case you use it, it's deprecated.
59 | .nav-divider {
60 | .nav-divider();
61 | }
62 |
63 | // Prevent IE8 from misplacing imgs
64 | //
65 | // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989
66 | > li > a > img {
67 | max-width: none;
68 | }
69 | }
70 |
71 |
72 | // Tabs
73 | // -------------------------
74 |
75 | // Give the tabs something to sit on
76 | .nav-tabs {
77 | border-bottom: 1px solid @nav-tabs-border-color;
78 | > li {
79 | float: left;
80 | // Make the list-items overlay the bottom border
81 | margin-bottom: -1px;
82 |
83 | // Actual tabs (as links)
84 | > a {
85 | margin-right: 2px;
86 | line-height: @line-height-base;
87 | border: 1px solid transparent;
88 | border-radius: @border-radius-base @border-radius-base 0 0;
89 | &:hover {
90 | border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;
91 | }
92 | }
93 |
94 | // Active state, and it's :hover to override normal :hover
95 | &.active > a {
96 | &,
97 | &:hover,
98 | &:focus {
99 | color: @nav-tabs-active-link-hover-color;
100 | background-color: @nav-tabs-active-link-hover-bg;
101 | border: 1px solid @nav-tabs-active-link-hover-border-color;
102 | border-bottom-color: transparent;
103 | cursor: default;
104 | }
105 | }
106 | }
107 | // pulling this in mainly for less shorthand
108 | &.nav-justified {
109 | .nav-justified();
110 | .nav-tabs-justified();
111 | }
112 | }
113 |
114 |
115 | // Pills
116 | // -------------------------
117 | .nav-pills {
118 | > li {
119 | float: left;
120 |
121 | // Links rendered as pills
122 | > a {
123 | border-radius: @nav-pills-border-radius;
124 | }
125 | + li {
126 | margin-left: 2px;
127 | }
128 |
129 | // Active state
130 | &.active > a {
131 | &,
132 | &:hover,
133 | &:focus {
134 | color: @nav-pills-active-link-hover-color;
135 | background-color: @nav-pills-active-link-hover-bg;
136 | }
137 | }
138 | }
139 | }
140 |
141 |
142 | // Stacked pills
143 | .nav-stacked {
144 | > li {
145 | float: none;
146 | + li {
147 | margin-top: 2px;
148 | margin-left: 0; // no need for this gap between nav items
149 | }
150 | }
151 | }
152 |
153 |
154 | // Nav variations
155 | // --------------------------------------------------
156 |
157 | // Justified nav links
158 | // -------------------------
159 |
160 | .nav-justified {
161 | width: 100%;
162 |
163 | > li {
164 | float: none;
165 | > a {
166 | text-align: center;
167 | margin-bottom: 5px;
168 | }
169 | }
170 |
171 | > .dropdown .dropdown-menu {
172 | top: auto;
173 | left: auto;
174 | }
175 |
176 | @media (min-width: @screen-sm-min) {
177 | > li {
178 | display: table-cell;
179 | width: 1%;
180 | > a {
181 | margin-bottom: 0;
182 | }
183 | }
184 | }
185 | }
186 |
187 | // Move borders to anchors instead of bottom of list
188 | //
189 | // Mixin for adding on top the shared `.nav-justified` styles for our tabs
190 | .nav-tabs-justified {
191 | border-bottom: 0;
192 |
193 | > li > a {
194 | // Override margin from .nav-tabs
195 | margin-right: 0;
196 | border-radius: @border-radius-base;
197 | }
198 |
199 | > .active > a,
200 | > .active > a:hover,
201 | > .active > a:focus {
202 | border: 1px solid @nav-tabs-justified-link-border-color;
203 | }
204 |
205 | @media (min-width: @screen-sm-min) {
206 | > li > a {
207 | border-bottom: 1px solid @nav-tabs-justified-link-border-color;
208 | border-radius: @border-radius-base @border-radius-base 0 0;
209 | }
210 | > .active > a,
211 | > .active > a:hover,
212 | > .active > a:focus {
213 | border-bottom-color: @nav-tabs-justified-active-link-border-color;
214 | }
215 | }
216 | }
217 |
218 |
219 | // Tabbable tabs
220 | // -------------------------
221 |
222 | // Hide tabbable panes to start, show them when `.active`
223 | .tab-content {
224 | > .tab-pane {
225 | display: none;
226 | }
227 | > .active {
228 | display: block;
229 | }
230 | }
231 |
232 |
233 | // Dropdowns
234 | // -------------------------
235 |
236 | // Specific dropdowns
237 | .nav-tabs .dropdown-menu {
238 | // make dropdown border overlap tab border
239 | margin-top: -1px;
240 | // Remove the top rounded corners here since there is a hard edge above the menu
241 | .border-top-radius(0);
242 | }
243 |
--------------------------------------------------------------------------------
/web/bootstrap/less/type.less:
--------------------------------------------------------------------------------
1 | //
2 | // Typography
3 | // --------------------------------------------------
4 |
5 |
6 | // Headings
7 | // -------------------------
8 |
9 | h1, h2, h3, h4, h5, h6,
10 | .h1, .h2, .h3, .h4, .h5, .h6 {
11 | font-family: @headings-font-family;
12 | font-weight: @headings-font-weight;
13 | line-height: @headings-line-height;
14 | color: @headings-color;
15 |
16 | small,
17 | .small {
18 | font-weight: normal;
19 | line-height: 1;
20 | color: @headings-small-color;
21 | }
22 | }
23 |
24 | h1,
25 | h2,
26 | h3 {
27 | margin-top: @line-height-computed;
28 | margin-bottom: (@line-height-computed / 2);
29 |
30 | small,
31 | .small {
32 | font-size: 65%;
33 | }
34 | }
35 | h4,
36 | h5,
37 | h6 {
38 | margin-top: (@line-height-computed / 2);
39 | margin-bottom: (@line-height-computed / 2);
40 |
41 | small,
42 | .small {
43 | font-size: 75%;
44 | }
45 | }
46 |
47 | h1, .h1 { font-size: @font-size-h1; }
48 | h2, .h2 { font-size: @font-size-h2; }
49 | h3, .h3 { font-size: @font-size-h3; }
50 | h4, .h4 { font-size: @font-size-h4; }
51 | h5, .h5 { font-size: @font-size-h5; }
52 | h6, .h6 { font-size: @font-size-h6; }
53 |
54 |
55 | // Body text
56 | // -------------------------
57 |
58 | p {
59 | margin: 0 0 (@line-height-computed / 2);
60 | }
61 |
62 | .lead {
63 | margin-bottom: @line-height-computed;
64 | font-size: floor(@font-size-base * 1.15);
65 | font-weight: 200;
66 | line-height: 1.4;
67 |
68 | @media (min-width: @screen-sm-min) {
69 | font-size: (@font-size-base * 1.5);
70 | }
71 | }
72 |
73 |
74 | // Emphasis & misc
75 | // -------------------------
76 |
77 | // Ex: 14px base font * 85% = about 12px
78 | small,
79 | .small { font-size: 85%; }
80 |
81 | // Undo browser default styling
82 | cite { font-style: normal; }
83 |
84 | // Contextual emphasis
85 | .text-muted {
86 | color: @text-muted;
87 | }
88 | .text-primary {
89 | color: @brand-primary;
90 | &:hover {
91 | color: darken(@brand-primary, 10%);
92 | }
93 | }
94 | .text-warning {
95 | color: @state-warning-text;
96 | &:hover {
97 | color: darken(@state-warning-text, 10%);
98 | }
99 | }
100 | .text-danger {
101 | color: @state-danger-text;
102 | &:hover {
103 | color: darken(@state-danger-text, 10%);
104 | }
105 | }
106 | .text-success {
107 | color: @state-success-text;
108 | &:hover {
109 | color: darken(@state-success-text, 10%);
110 | }
111 | }
112 | .text-info {
113 | color: @state-info-text;
114 | &:hover {
115 | color: darken(@state-info-text, 10%);
116 | }
117 | }
118 |
119 | // Alignment
120 | .text-left { text-align: left; }
121 | .text-right { text-align: right; }
122 | .text-center { text-align: center; }
123 |
124 |
125 | // Page header
126 | // -------------------------
127 |
128 | .page-header {
129 | padding-bottom: ((@line-height-computed / 2) - 1);
130 | margin: (@line-height-computed * 2) 0 @line-height-computed;
131 | border-bottom: 1px solid @page-header-border-color;
132 | }
133 |
134 |
135 | // Lists
136 | // --------------------------------------------------
137 |
138 | // Unordered and Ordered lists
139 | ul,
140 | ol {
141 | margin-top: 0;
142 | margin-bottom: (@line-height-computed / 2);
143 | ul,
144 | ol {
145 | margin-bottom: 0;
146 | }
147 | }
148 |
149 | // List options
150 |
151 | // Unstyled keeps list items block level, just removes default browser padding and list-style
152 | .list-unstyled {
153 | padding-left: 0;
154 | list-style: none;
155 | }
156 |
157 | // Inline turns list items into inline-block
158 | .list-inline {
159 | .list-unstyled();
160 |
161 | > li {
162 | display: inline-block;
163 | padding-left: 5px;
164 | padding-right: 5px;
165 |
166 | &:first-child {
167 | padding-left: 0;
168 | }
169 | }
170 | }
171 |
172 | // Description Lists
173 | dl {
174 | margin-top: 0; // Remove browser default
175 | margin-bottom: @line-height-computed;
176 | }
177 | dt,
178 | dd {
179 | line-height: @line-height-base;
180 | }
181 | dt {
182 | font-weight: bold;
183 | }
184 | dd {
185 | margin-left: 0; // Undo browser default
186 | }
187 |
188 | // Horizontal description lists
189 | //
190 | // Defaults to being stacked without any of the below styles applied, until the
191 | // grid breakpoint is reached (default of ~768px).
192 |
193 | @media (min-width: @grid-float-breakpoint) {
194 | .dl-horizontal {
195 | dt {
196 | float: left;
197 | width: (@component-offset-horizontal - 20);
198 | clear: left;
199 | text-align: right;
200 | .text-overflow();
201 | }
202 | dd {
203 | margin-left: @component-offset-horizontal;
204 | .clearfix(); // Clear the floated `dt` if an empty `dd` is present
205 | }
206 | }
207 | }
208 |
209 | // MISC
210 | // ----
211 |
212 | // Abbreviations and acronyms
213 | abbr[title],
214 | // Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
215 | abbr[data-original-title] {
216 | cursor: help;
217 | border-bottom: 1px dotted @abbr-border-color;
218 | }
219 | .initialism {
220 | font-size: 90%;
221 | text-transform: uppercase;
222 | }
223 |
224 | // Blockquotes
225 | blockquote {
226 | padding: (@line-height-computed / 2) @line-height-computed;
227 | margin: 0 0 @line-height-computed;
228 | border-left: 5px solid @blockquote-border-color;
229 | p {
230 | font-size: (@font-size-base * 1.25);
231 | font-weight: 300;
232 | line-height: 1.25;
233 | }
234 | p:last-child {
235 | margin-bottom: 0;
236 | }
237 | small,
238 | .small {
239 | display: block;
240 | line-height: @line-height-base;
241 | color: @blockquote-small-color;
242 | &:before {
243 | content: '\2014 \00A0'; // EM DASH, NBSP
244 | }
245 | }
246 |
247 | // Float right with text-align: right
248 | &.pull-right {
249 | padding-right: 15px;
250 | padding-left: 0;
251 | border-right: 5px solid @blockquote-border-color;
252 | border-left: 0;
253 | p,
254 | small,
255 | .small {
256 | text-align: right;
257 | }
258 | small,
259 | .small {
260 | &:before {
261 | content: '';
262 | }
263 | &:after {
264 | content: '\00A0 \2014'; // NBSP, EM DASH
265 | }
266 | }
267 | }
268 | }
269 |
270 | // Quotes
271 | blockquote:before,
272 | blockquote:after {
273 | content: "";
274 | }
275 |
276 | // Addresses
277 | address {
278 | margin-bottom: @line-height-computed;
279 | font-style: normal;
280 | line-height: @line-height-base;
281 | }
282 |
--------------------------------------------------------------------------------
/web/bootstrap/less/theme.less:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // Load core variables and mixins
4 | // --------------------------------------------------
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 |
9 |
10 |
11 | //
12 | // Buttons
13 | // --------------------------------------------------
14 |
15 | // Common styles
16 | .btn-default,
17 | .btn-primary,
18 | .btn-success,
19 | .btn-info,
20 | .btn-warning,
21 | .btn-danger {
22 | text-shadow: 0 -1px 0 rgba(0,0,0,.2);
23 | @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);
24 | .box-shadow(@shadow);
25 |
26 | // Reset the shadow
27 | &:active,
28 | &.active {
29 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
30 | }
31 | }
32 |
33 | // Mixin for generating new styles
34 | .btn-styles(@btn-color: #555) {
35 | #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));
36 | .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners
37 | background-repeat: repeat-x;
38 | border-color: darken(@btn-color, 14%);
39 |
40 | &:hover,
41 | &:focus {
42 | background-color: darken(@btn-color, 12%);
43 | background-position: 0 -15px;
44 | }
45 |
46 | &:active,
47 | &.active {
48 | background-color: darken(@btn-color, 12%);
49 | border-color: darken(@btn-color, 14%);
50 | }
51 | }
52 |
53 | // Common styles
54 | .btn {
55 | // Remove the gradient for the pressed/active state
56 | &:active,
57 | &.active {
58 | background-image: none;
59 | }
60 | }
61 |
62 | // Apply the mixin to the buttons
63 | .btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }
64 | .btn-primary { .btn-styles(@btn-primary-bg); }
65 | .btn-success { .btn-styles(@btn-success-bg); }
66 | .btn-warning { .btn-styles(@btn-warning-bg); }
67 | .btn-danger { .btn-styles(@btn-danger-bg); }
68 | .btn-info { .btn-styles(@btn-info-bg); }
69 |
70 |
71 |
72 | //
73 | // Images
74 | // --------------------------------------------------
75 |
76 | .thumbnail,
77 | .img-thumbnail {
78 | .box-shadow(0 1px 2px rgba(0,0,0,.075));
79 | }
80 |
81 |
82 |
83 | //
84 | // Dropdowns
85 | // --------------------------------------------------
86 |
87 | .dropdown-menu > li > a:hover,
88 | .dropdown-menu > li > a:focus {
89 | #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));
90 | background-color: darken(@dropdown-link-hover-bg, 5%);
91 | }
92 | .dropdown-menu > .active > a,
93 | .dropdown-menu > .active > a:hover,
94 | .dropdown-menu > .active > a:focus {
95 | #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));
96 | background-color: darken(@dropdown-link-active-bg, 5%);
97 | }
98 |
99 |
100 |
101 | //
102 | // Navbar
103 | // --------------------------------------------------
104 |
105 | // Default navbar
106 | .navbar-default {
107 | #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);
108 | .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered
109 | border-radius: @navbar-border-radius;
110 | @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);
111 | .box-shadow(@shadow);
112 |
113 | .navbar-nav > .active > a {
114 | #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));
115 | .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));
116 | }
117 | }
118 | .navbar-brand,
119 | .navbar-nav > li > a {
120 | text-shadow: 0 1px 0 rgba(255,255,255,.25);
121 | }
122 |
123 | // Inverted navbar
124 | .navbar-inverse {
125 | #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);
126 | .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered
127 |
128 | .navbar-nav > .active > a {
129 | #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));
130 | .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));
131 | }
132 |
133 | .navbar-brand,
134 | .navbar-nav > li > a {
135 | text-shadow: 0 -1px 0 rgba(0,0,0,.25);
136 | }
137 | }
138 |
139 | // Undo rounded corners in static and fixed navbars
140 | .navbar-static-top,
141 | .navbar-fixed-top,
142 | .navbar-fixed-bottom {
143 | border-radius: 0;
144 | }
145 |
146 |
147 |
148 | //
149 | // Alerts
150 | // --------------------------------------------------
151 |
152 | // Common styles
153 | .alert {
154 | text-shadow: 0 1px 0 rgba(255,255,255,.2);
155 | @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);
156 | .box-shadow(@shadow);
157 | }
158 |
159 | // Mixin for generating new styles
160 | .alert-styles(@color) {
161 | #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));
162 | border-color: darken(@color, 15%);
163 | }
164 |
165 | // Apply the mixin to the alerts
166 | .alert-success { .alert-styles(@alert-success-bg); }
167 | .alert-info { .alert-styles(@alert-info-bg); }
168 | .alert-warning { .alert-styles(@alert-warning-bg); }
169 | .alert-danger { .alert-styles(@alert-danger-bg); }
170 |
171 |
172 |
173 | //
174 | // Progress bars
175 | // --------------------------------------------------
176 |
177 | // Give the progress background some depth
178 | .progress {
179 | #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)
180 | }
181 |
182 | // Mixin for generating new styles
183 | .progress-bar-styles(@color) {
184 | #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));
185 | }
186 |
187 | // Apply the mixin to the progress bars
188 | .progress-bar { .progress-bar-styles(@progress-bar-bg); }
189 | .progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }
190 | .progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }
191 | .progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }
192 | .progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }
193 |
194 |
195 |
196 | //
197 | // List groups
198 | // --------------------------------------------------
199 |
200 | .list-group {
201 | border-radius: @border-radius-base;
202 | .box-shadow(0 1px 2px rgba(0,0,0,.075));
203 | }
204 | .list-group-item.active,
205 | .list-group-item.active:hover,
206 | .list-group-item.active:focus {
207 | text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);
208 | #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));
209 | border-color: darken(@list-group-active-border, 7.5%);
210 | }
211 |
212 |
213 |
214 | //
215 | // Panels
216 | // --------------------------------------------------
217 |
218 | // Common styles
219 | .panel {
220 | .box-shadow(0 1px 2px rgba(0,0,0,.05));
221 | }
222 |
223 | // Mixin for generating new styles
224 | .panel-heading-styles(@color) {
225 | #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));
226 | }
227 |
228 | // Apply the mixin to the panel headings only
229 | .panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }
230 | .panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }
231 | .panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }
232 | .panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }
233 | .panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }
234 | .panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }
235 |
236 |
237 |
238 | //
239 | // Wells
240 | // --------------------------------------------------
241 |
242 | .well {
243 | #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);
244 | border-color: darken(@well-bg, 10%);
245 | @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);
246 | .box-shadow(@shadow);
247 | }
248 |
--------------------------------------------------------------------------------
/web/bootstrap/less/normalize.less:
--------------------------------------------------------------------------------
1 | /*! normalize.css v2.1.3 | MIT License | git.io/normalize */
2 |
3 | // ==========================================================================
4 | // HTML5 display definitions
5 | // ==========================================================================
6 |
7 | //
8 | // Correct `block` display not defined in IE 8/9.
9 | //
10 |
11 | article,
12 | aside,
13 | details,
14 | figcaption,
15 | figure,
16 | footer,
17 | header,
18 | hgroup,
19 | main,
20 | nav,
21 | section,
22 | summary {
23 | display: block;
24 | }
25 |
26 | //
27 | // Correct `inline-block` display not defined in IE 8/9.
28 | //
29 |
30 | audio,
31 | canvas,
32 | video {
33 | display: inline-block;
34 | }
35 |
36 | //
37 | // Prevent modern browsers from displaying `audio` without controls.
38 | // Remove excess height in iOS 5 devices.
39 | //
40 |
41 | audio:not([controls]) {
42 | display: none;
43 | height: 0;
44 | }
45 |
46 | //
47 | // Address `[hidden]` styling not present in IE 8/9.
48 | // Hide the `template` element in IE, Safari, and Firefox < 22.
49 | //
50 |
51 | [hidden],
52 | template {
53 | display: none;
54 | }
55 |
56 | // ==========================================================================
57 | // Base
58 | // ==========================================================================
59 |
60 | //
61 | // 1. Set default font family to sans-serif.
62 | // 2. Prevent iOS text size adjust after orientation change, without disabling
63 | // user zoom.
64 | //
65 |
66 | html {
67 | font-family: sans-serif; // 1
68 | -ms-text-size-adjust: 100%; // 2
69 | -webkit-text-size-adjust: 100%; // 2
70 | }
71 |
72 | //
73 | // Remove default margin.
74 | //
75 |
76 | body {
77 | margin: 0;
78 | }
79 |
80 | // ==========================================================================
81 | // Links
82 | // ==========================================================================
83 |
84 | //
85 | // Remove the gray background color from active links in IE 10.
86 | //
87 |
88 | a {
89 | background: transparent;
90 | }
91 |
92 | //
93 | // Address `outline` inconsistency between Chrome and other browsers.
94 | //
95 |
96 | a:focus {
97 | outline: thin dotted;
98 | }
99 |
100 | //
101 | // Improve readability when focused and also mouse hovered in all browsers.
102 | //
103 |
104 | a:active,
105 | a:hover {
106 | outline: 0;
107 | }
108 |
109 | // ==========================================================================
110 | // Typography
111 | // ==========================================================================
112 |
113 | //
114 | // Address variable `h1` font-size and margin within `section` and `article`
115 | // contexts in Firefox 4+, Safari 5, and Chrome.
116 | //
117 |
118 | h1 {
119 | font-size: 2em;
120 | margin: 0.67em 0;
121 | }
122 |
123 | //
124 | // Address styling not present in IE 8/9, Safari 5, and Chrome.
125 | //
126 |
127 | abbr[title] {
128 | border-bottom: 1px dotted;
129 | }
130 |
131 | //
132 | // Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
133 | //
134 |
135 | b,
136 | strong {
137 | font-weight: bold;
138 | }
139 |
140 | //
141 | // Address styling not present in Safari 5 and Chrome.
142 | //
143 |
144 | dfn {
145 | font-style: italic;
146 | }
147 |
148 | //
149 | // Address differences between Firefox and other browsers.
150 | //
151 |
152 | hr {
153 | -moz-box-sizing: content-box;
154 | box-sizing: content-box;
155 | height: 0;
156 | }
157 |
158 | //
159 | // Address styling not present in IE 8/9.
160 | //
161 |
162 | mark {
163 | background: #ff0;
164 | color: #000;
165 | }
166 |
167 | //
168 | // Correct font family set oddly in Safari 5 and Chrome.
169 | //
170 |
171 | code,
172 | kbd,
173 | pre,
174 | samp {
175 | font-family: monospace, serif;
176 | font-size: 1em;
177 | }
178 |
179 | //
180 | // Improve readability of pre-formatted text in all browsers.
181 | //
182 |
183 | pre {
184 | white-space: pre-wrap;
185 | }
186 |
187 | //
188 | // Set consistent quote types.
189 | //
190 |
191 | q {
192 | quotes: "\201C" "\201D" "\2018" "\2019";
193 | }
194 |
195 | //
196 | // Address inconsistent and variable font size in all browsers.
197 | //
198 |
199 | small {
200 | font-size: 80%;
201 | }
202 |
203 | //
204 | // Prevent `sub` and `sup` affecting `line-height` in all browsers.
205 | //
206 |
207 | sub,
208 | sup {
209 | font-size: 75%;
210 | line-height: 0;
211 | position: relative;
212 | vertical-align: baseline;
213 | }
214 |
215 | sup {
216 | top: -0.5em;
217 | }
218 |
219 | sub {
220 | bottom: -0.25em;
221 | }
222 |
223 | // ==========================================================================
224 | // Embedded content
225 | // ==========================================================================
226 |
227 | //
228 | // Remove border when inside `a` element in IE 8/9.
229 | //
230 |
231 | img {
232 | border: 0;
233 | }
234 |
235 | //
236 | // Correct overflow displayed oddly in IE 9.
237 | //
238 |
239 | svg:not(:root) {
240 | overflow: hidden;
241 | }
242 |
243 | // ==========================================================================
244 | // Figures
245 | // ==========================================================================
246 |
247 | //
248 | // Address margin not present in IE 8/9 and Safari 5.
249 | //
250 |
251 | figure {
252 | margin: 0;
253 | }
254 |
255 | // ==========================================================================
256 | // Forms
257 | // ==========================================================================
258 |
259 | //
260 | // Define consistent border, margin, and padding.
261 | //
262 |
263 | fieldset {
264 | border: 1px solid #c0c0c0;
265 | margin: 0 2px;
266 | padding: 0.35em 0.625em 0.75em;
267 | }
268 |
269 | //
270 | // 1. Correct `color` not being inherited in IE 8/9.
271 | // 2. Remove padding so people aren't caught out if they zero out fieldsets.
272 | //
273 |
274 | legend {
275 | border: 0; // 1
276 | padding: 0; // 2
277 | }
278 |
279 | //
280 | // 1. Correct font family not being inherited in all browsers.
281 | // 2. Correct font size not being inherited in all browsers.
282 | // 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
283 | //
284 |
285 | button,
286 | input,
287 | select,
288 | textarea {
289 | font-family: inherit; // 1
290 | font-size: 100%; // 2
291 | margin: 0; // 3
292 | }
293 |
294 | //
295 | // Address Firefox 4+ setting `line-height` on `input` using `!important` in
296 | // the UA stylesheet.
297 | //
298 |
299 | button,
300 | input {
301 | line-height: normal;
302 | }
303 |
304 | //
305 | // Address inconsistent `text-transform` inheritance for `button` and `select`.
306 | // All other form control elements do not inherit `text-transform` values.
307 | // Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
308 | // Correct `select` style inheritance in Firefox 4+ and Opera.
309 | //
310 |
311 | button,
312 | select {
313 | text-transform: none;
314 | }
315 |
316 | //
317 | // 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
318 | // and `video` controls.
319 | // 2. Correct inability to style clickable `input` types in iOS.
320 | // 3. Improve usability and consistency of cursor style between image-type
321 | // `input` and others.
322 | //
323 |
324 | button,
325 | html input[type="button"], // 1
326 | input[type="reset"],
327 | input[type="submit"] {
328 | -webkit-appearance: button; // 2
329 | cursor: pointer; // 3
330 | }
331 |
332 | //
333 | // Re-set default cursor for disabled elements.
334 | //
335 |
336 | button[disabled],
337 | html input[disabled] {
338 | cursor: default;
339 | }
340 |
341 | //
342 | // 1. Address box sizing set to `content-box` in IE 8/9/10.
343 | // 2. Remove excess padding in IE 8/9/10.
344 | //
345 |
346 | input[type="checkbox"],
347 | input[type="radio"] {
348 | box-sizing: border-box; // 1
349 | padding: 0; // 2
350 | }
351 |
352 | //
353 | // 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
354 | // 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
355 | // (include `-moz` to future-proof).
356 | //
357 |
358 | input[type="search"] {
359 | -webkit-appearance: textfield; // 1
360 | -moz-box-sizing: content-box;
361 | -webkit-box-sizing: content-box; // 2
362 | box-sizing: content-box;
363 | }
364 |
365 | //
366 | // Remove inner padding and search cancel button in Safari 5 and Chrome
367 | // on OS X.
368 | //
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | //
376 | // Remove inner padding and border in Firefox 4+.
377 | //
378 |
379 | button::-moz-focus-inner,
380 | input::-moz-focus-inner {
381 | border: 0;
382 | padding: 0;
383 | }
384 |
385 | //
386 | // 1. Remove default vertical scrollbar in IE 8/9.
387 | // 2. Improve readability and alignment in all browsers.
388 | //
389 |
390 | textarea {
391 | overflow: auto; // 1
392 | vertical-align: top; // 2
393 | }
394 |
395 | // ==========================================================================
396 | // Tables
397 | // ==========================================================================
398 |
399 | //
400 | // Remove most spacing between table cells.
401 | //
402 |
403 | table {
404 | border-collapse: collapse;
405 | border-spacing: 0;
406 | }
407 |
--------------------------------------------------------------------------------
/web/bootstrap/less/forms.less:
--------------------------------------------------------------------------------
1 | //
2 | // Forms
3 | // --------------------------------------------------
4 |
5 |
6 | // Normalize non-controls
7 | //
8 | // Restyle and baseline non-control form elements.
9 |
10 | fieldset {
11 | padding: 0;
12 | margin: 0;
13 | border: 0;
14 | }
15 |
16 | legend {
17 | display: block;
18 | width: 100%;
19 | padding: 0;
20 | margin-bottom: @line-height-computed;
21 | font-size: (@font-size-base * 1.5);
22 | line-height: inherit;
23 | color: @legend-color;
24 | border: 0;
25 | border-bottom: 1px solid @legend-border-color;
26 | }
27 |
28 | label {
29 | display: inline-block;
30 | margin-bottom: 5px;
31 | font-weight: bold;
32 | }
33 |
34 |
35 | // Normalize form controls
36 |
37 | // Override content-box in Normalize (* isn't specific enough)
38 | input[type="search"] {
39 | .box-sizing(border-box);
40 | }
41 |
42 | // Position radios and checkboxes better
43 | input[type="radio"],
44 | input[type="checkbox"] {
45 | margin: 4px 0 0;
46 | margin-top: 1px \9; /* IE8-9 */
47 | line-height: normal;
48 | }
49 |
50 | // Set the height of select and file controls to match text inputs
51 | input[type="file"] {
52 | display: block;
53 | }
54 |
55 | // Make multiple select elements height not fixed
56 | select[multiple],
57 | select[size] {
58 | height: auto;
59 | }
60 |
61 | // Fix optgroup Firefox bug per https://github.com/twbs/bootstrap/issues/7611
62 | select optgroup {
63 | font-size: inherit;
64 | font-style: inherit;
65 | font-family: inherit;
66 | }
67 |
68 | // Focus for select, file, radio, and checkbox
69 | input[type="file"]:focus,
70 | input[type="radio"]:focus,
71 | input[type="checkbox"]:focus {
72 | .tab-focus();
73 | }
74 |
75 | // Fix for Chrome number input
76 | // Setting certain font-sizes causes the `I` bar to appear on hover of the bottom increment button.
77 | // See https://github.com/twbs/bootstrap/issues/8350 for more.
78 | input[type="number"] {
79 | &::-webkit-outer-spin-button,
80 | &::-webkit-inner-spin-button {
81 | height: auto;
82 | }
83 | }
84 |
85 | // Adjust output element
86 | output {
87 | display: block;
88 | padding-top: (@padding-base-vertical + 1);
89 | font-size: @font-size-base;
90 | line-height: @line-height-base;
91 | color: @input-color;
92 | vertical-align: middle;
93 | }
94 |
95 |
96 | // Common form controls
97 | //
98 | // Shared size and type resets for form controls. Apply `.form-control` to any
99 | // of the following form controls:
100 | //
101 | // select
102 | // textarea
103 | // input[type="text"]
104 | // input[type="password"]
105 | // input[type="datetime"]
106 | // input[type="datetime-local"]
107 | // input[type="date"]
108 | // input[type="month"]
109 | // input[type="time"]
110 | // input[type="week"]
111 | // input[type="number"]
112 | // input[type="email"]
113 | // input[type="url"]
114 | // input[type="search"]
115 | // input[type="tel"]
116 | // input[type="color"]
117 |
118 | .form-control {
119 | display: block;
120 | width: 100%;
121 | height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
122 | padding: @padding-base-vertical @padding-base-horizontal;
123 | font-size: @font-size-base;
124 | line-height: @line-height-base;
125 | color: @input-color;
126 | vertical-align: middle;
127 | background-color: @input-bg;
128 | background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
129 | border: 1px solid @input-border;
130 | border-radius: @input-border-radius;
131 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
132 | .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");
133 |
134 | // Customize the `:focus` state to imitate native WebKit styles.
135 | .form-control-focus();
136 |
137 | // Placeholder
138 | //
139 | // Placeholder text gets special styles because when browsers invalidate entire
140 | // lines if it doesn't understand a selector/
141 | .placeholder();
142 |
143 | // Disabled and read-only inputs
144 | // Note: HTML5 says that controls under a fieldset > legend:first-child won't
145 | // be disabled if the fieldset is disabled. Due to implementation difficulty,
146 | // we don't honor that edge case; we style them as disabled anyway.
147 | &[disabled],
148 | &[readonly],
149 | fieldset[disabled] & {
150 | cursor: not-allowed;
151 | background-color: @input-bg-disabled;
152 | }
153 |
154 | // Reset height for `textarea`s
155 | textarea& {
156 | height: auto;
157 | }
158 | }
159 |
160 |
161 | // Form groups
162 | //
163 | // Designed to help with the organization and spacing of vertical forms. For
164 | // horizontal forms, use the predefined grid classes.
165 |
166 | .form-group {
167 | margin-bottom: 15px;
168 | }
169 |
170 |
171 | // Checkboxes and radios
172 | //
173 | // Indent the labels to position radios/checkboxes as hanging controls.
174 |
175 | .radio,
176 | .checkbox {
177 | display: block;
178 | min-height: @line-height-computed; // clear the floating input if there is no label text
179 | margin-top: 10px;
180 | margin-bottom: 10px;
181 | padding-left: 20px;
182 | vertical-align: middle;
183 | label {
184 | display: inline;
185 | margin-bottom: 0;
186 | font-weight: normal;
187 | cursor: pointer;
188 | }
189 | }
190 | .radio input[type="radio"],
191 | .radio-inline input[type="radio"],
192 | .checkbox input[type="checkbox"],
193 | .checkbox-inline input[type="checkbox"] {
194 | float: left;
195 | margin-left: -20px;
196 | }
197 | .radio + .radio,
198 | .checkbox + .checkbox {
199 | margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
200 | }
201 |
202 | // Radios and checkboxes on same line
203 | .radio-inline,
204 | .checkbox-inline {
205 | display: inline-block;
206 | padding-left: 20px;
207 | margin-bottom: 0;
208 | vertical-align: middle;
209 | font-weight: normal;
210 | cursor: pointer;
211 | }
212 | .radio-inline + .radio-inline,
213 | .checkbox-inline + .checkbox-inline {
214 | margin-top: 0;
215 | margin-left: 10px; // space out consecutive inline controls
216 | }
217 |
218 | // Apply same disabled cursor tweak as for inputs
219 | //
220 | // Note: Neither radios nor checkboxes can be readonly.
221 | input[type="radio"],
222 | input[type="checkbox"],
223 | .radio,
224 | .radio-inline,
225 | .checkbox,
226 | .checkbox-inline {
227 | &[disabled],
228 | fieldset[disabled] & {
229 | cursor: not-allowed;
230 | }
231 | }
232 |
233 | // Form control sizing
234 | .input-sm {
235 | .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
236 | }
237 |
238 | .input-lg {
239 | .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
240 | }
241 |
242 |
243 | // Form control feedback states
244 | //
245 | // Apply contextual and semantic states to individual form controls.
246 |
247 | // Warning
248 | .has-warning {
249 | .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
250 | }
251 | // Error
252 | .has-error {
253 | .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
254 | }
255 | // Success
256 | .has-success {
257 | .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
258 | }
259 |
260 |
261 | // Static form control text
262 | //
263 | // Apply class to a `p` element to make any string of text align with labels in
264 | // a horizontal form layout.
265 |
266 | .form-control-static {
267 | margin-bottom: 0; // Remove default margin from `p`
268 | }
269 |
270 |
271 | // Help text
272 | //
273 | // Apply to any element you wish to create light text for placement immediately
274 | // below a form control. Use for general help, formatting, or instructional text.
275 |
276 | .help-block {
277 | display: block; // account for any element using help-block
278 | margin-top: 5px;
279 | margin-bottom: 10px;
280 | color: lighten(@text-color, 25%); // lighten the text some for contrast
281 | }
282 |
283 |
284 |
285 | // Inline forms
286 | //
287 | // Make forms appear inline(-block) by adding the `.form-inline` class. Inline
288 | // forms begin stacked on extra small (mobile) devices and then go inline when
289 | // viewports reach <768px.
290 | //
291 | // Requires wrapping inputs and labels with `.form-group` for proper display of
292 | // default HTML form controls and our custom form controls (e.g., input groups).
293 | //
294 | // Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
295 |
296 | .form-inline {
297 |
298 | // Kick in the inline
299 | @media (min-width: @screen-sm) {
300 | // Inline-block all the things for "inline"
301 | .form-group {
302 | display: inline-block;
303 | margin-bottom: 0;
304 | vertical-align: middle;
305 | }
306 |
307 | // In navbar-form, allow folks to *not* use `.form-group`
308 | .form-control {
309 | display: inline-block;
310 | }
311 |
312 | // Override `width: 100%;` when not within a `.form-group`
313 | select.form-control {
314 | width: auto;
315 | }
316 |
317 | // Remove default margin on radios/checkboxes that were used for stacking, and
318 | // then undo the floating of radios and checkboxes to match (which also avoids
319 | // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
320 | .radio,
321 | .checkbox {
322 | display: inline-block;
323 | margin-top: 0;
324 | margin-bottom: 0;
325 | padding-left: 0;
326 | }
327 | .radio input[type="radio"],
328 | .checkbox input[type="checkbox"] {
329 | float: none;
330 | margin-left: 0;
331 | }
332 | }
333 | }
334 |
335 |
336 | // Horizontal forms
337 | //
338 | // Horizontal forms are built on grid classes and allow you to create forms with
339 | // labels on the left and inputs on the right.
340 |
341 | .form-horizontal {
342 |
343 | // Consistent vertical alignment of labels, radios, and checkboxes
344 | .control-label,
345 | .radio,
346 | .checkbox,
347 | .radio-inline,
348 | .checkbox-inline {
349 | margin-top: 0;
350 | margin-bottom: 0;
351 | padding-top: (@padding-base-vertical + 1); // Default padding plus a border
352 | }
353 | // Account for padding we're adding to ensure the alignment and of help text
354 | // and other content below items
355 | .radio,
356 | .checkbox {
357 | min-height: @line-height-computed + (@padding-base-vertical + 1);
358 | }
359 |
360 | // Make form groups behave like rows
361 | .form-group {
362 | .make-row();
363 | }
364 |
365 | .form-control-static {
366 | padding-top: (@padding-base-vertical + 1);
367 | }
368 |
369 | // Only right align form labels here when the columns stop stacking
370 | @media (min-width: @screen-sm-min) {
371 | .control-label {
372 | text-align: right;
373 | }
374 | }
375 | }
376 |
--------------------------------------------------------------------------------
/web/font-awesome/less/variables.less:
--------------------------------------------------------------------------------
1 | // Variables
2 | // --------------------------
3 |
4 | @fa-font-path: "../fonts";
5 | //@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts"; // for referencing Bootstrap CDN font files directly
6 | @fa-css-prefix: fa;
7 | @fa-version: "4.0.3";
8 | @fa-border-color: #eee;
9 | @fa-inverse: #fff;
10 | @fa-li-width: (30em / 14);
11 |
12 | @fa-var-glass: "\f000";
13 | @fa-var-music: "\f001";
14 | @fa-var-search: "\f002";
15 | @fa-var-envelope-o: "\f003";
16 | @fa-var-heart: "\f004";
17 | @fa-var-star: "\f005";
18 | @fa-var-star-o: "\f006";
19 | @fa-var-user: "\f007";
20 | @fa-var-film: "\f008";
21 | @fa-var-th-large: "\f009";
22 | @fa-var-th: "\f00a";
23 | @fa-var-th-list: "\f00b";
24 | @fa-var-check: "\f00c";
25 | @fa-var-times: "\f00d";
26 | @fa-var-search-plus: "\f00e";
27 | @fa-var-search-minus: "\f010";
28 | @fa-var-power-off: "\f011";
29 | @fa-var-signal: "\f012";
30 | @fa-var-cog: "\f013";
31 | @fa-var-trash-o: "\f014";
32 | @fa-var-home: "\f015";
33 | @fa-var-file-o: "\f016";
34 | @fa-var-clock-o: "\f017";
35 | @fa-var-road: "\f018";
36 | @fa-var-download: "\f019";
37 | @fa-var-arrow-circle-o-down: "\f01a";
38 | @fa-var-arrow-circle-o-up: "\f01b";
39 | @fa-var-inbox: "\f01c";
40 | @fa-var-play-circle-o: "\f01d";
41 | @fa-var-repeat: "\f01e";
42 | @fa-var-refresh: "\f021";
43 | @fa-var-list-alt: "\f022";
44 | @fa-var-lock: "\f023";
45 | @fa-var-flag: "\f024";
46 | @fa-var-headphones: "\f025";
47 | @fa-var-volume-off: "\f026";
48 | @fa-var-volume-down: "\f027";
49 | @fa-var-volume-up: "\f028";
50 | @fa-var-qrcode: "\f029";
51 | @fa-var-barcode: "\f02a";
52 | @fa-var-tag: "\f02b";
53 | @fa-var-tags: "\f02c";
54 | @fa-var-book: "\f02d";
55 | @fa-var-bookmark: "\f02e";
56 | @fa-var-print: "\f02f";
57 | @fa-var-camera: "\f030";
58 | @fa-var-font: "\f031";
59 | @fa-var-bold: "\f032";
60 | @fa-var-italic: "\f033";
61 | @fa-var-text-height: "\f034";
62 | @fa-var-text-width: "\f035";
63 | @fa-var-align-left: "\f036";
64 | @fa-var-align-center: "\f037";
65 | @fa-var-align-right: "\f038";
66 | @fa-var-align-justify: "\f039";
67 | @fa-var-list: "\f03a";
68 | @fa-var-outdent: "\f03b";
69 | @fa-var-indent: "\f03c";
70 | @fa-var-video-camera: "\f03d";
71 | @fa-var-picture-o: "\f03e";
72 | @fa-var-pencil: "\f040";
73 | @fa-var-map-marker: "\f041";
74 | @fa-var-adjust: "\f042";
75 | @fa-var-tint: "\f043";
76 | @fa-var-pencil-square-o: "\f044";
77 | @fa-var-share-square-o: "\f045";
78 | @fa-var-check-square-o: "\f046";
79 | @fa-var-arrows: "\f047";
80 | @fa-var-step-backward: "\f048";
81 | @fa-var-fast-backward: "\f049";
82 | @fa-var-backward: "\f04a";
83 | @fa-var-play: "\f04b";
84 | @fa-var-pause: "\f04c";
85 | @fa-var-stop: "\f04d";
86 | @fa-var-forward: "\f04e";
87 | @fa-var-fast-forward: "\f050";
88 | @fa-var-step-forward: "\f051";
89 | @fa-var-eject: "\f052";
90 | @fa-var-chevron-left: "\f053";
91 | @fa-var-chevron-right: "\f054";
92 | @fa-var-plus-circle: "\f055";
93 | @fa-var-minus-circle: "\f056";
94 | @fa-var-times-circle: "\f057";
95 | @fa-var-check-circle: "\f058";
96 | @fa-var-question-circle: "\f059";
97 | @fa-var-info-circle: "\f05a";
98 | @fa-var-crosshairs: "\f05b";
99 | @fa-var-times-circle-o: "\f05c";
100 | @fa-var-check-circle-o: "\f05d";
101 | @fa-var-ban: "\f05e";
102 | @fa-var-arrow-left: "\f060";
103 | @fa-var-arrow-right: "\f061";
104 | @fa-var-arrow-up: "\f062";
105 | @fa-var-arrow-down: "\f063";
106 | @fa-var-share: "\f064";
107 | @fa-var-expand: "\f065";
108 | @fa-var-compress: "\f066";
109 | @fa-var-plus: "\f067";
110 | @fa-var-minus: "\f068";
111 | @fa-var-asterisk: "\f069";
112 | @fa-var-exclamation-circle: "\f06a";
113 | @fa-var-gift: "\f06b";
114 | @fa-var-leaf: "\f06c";
115 | @fa-var-fire: "\f06d";
116 | @fa-var-eye: "\f06e";
117 | @fa-var-eye-slash: "\f070";
118 | @fa-var-exclamation-triangle: "\f071";
119 | @fa-var-plane: "\f072";
120 | @fa-var-calendar: "\f073";
121 | @fa-var-random: "\f074";
122 | @fa-var-comment: "\f075";
123 | @fa-var-magnet: "\f076";
124 | @fa-var-chevron-up: "\f077";
125 | @fa-var-chevron-down: "\f078";
126 | @fa-var-retweet: "\f079";
127 | @fa-var-shopping-cart: "\f07a";
128 | @fa-var-folder: "\f07b";
129 | @fa-var-folder-open: "\f07c";
130 | @fa-var-arrows-v: "\f07d";
131 | @fa-var-arrows-h: "\f07e";
132 | @fa-var-bar-chart-o: "\f080";
133 | @fa-var-twitter-square: "\f081";
134 | @fa-var-facebook-square: "\f082";
135 | @fa-var-camera-retro: "\f083";
136 | @fa-var-key: "\f084";
137 | @fa-var-cogs: "\f085";
138 | @fa-var-comments: "\f086";
139 | @fa-var-thumbs-o-up: "\f087";
140 | @fa-var-thumbs-o-down: "\f088";
141 | @fa-var-star-half: "\f089";
142 | @fa-var-heart-o: "\f08a";
143 | @fa-var-sign-out: "\f08b";
144 | @fa-var-linkedin-square: "\f08c";
145 | @fa-var-thumb-tack: "\f08d";
146 | @fa-var-external-link: "\f08e";
147 | @fa-var-sign-in: "\f090";
148 | @fa-var-trophy: "\f091";
149 | @fa-var-github-square: "\f092";
150 | @fa-var-upload: "\f093";
151 | @fa-var-lemon-o: "\f094";
152 | @fa-var-phone: "\f095";
153 | @fa-var-square-o: "\f096";
154 | @fa-var-bookmark-o: "\f097";
155 | @fa-var-phone-square: "\f098";
156 | @fa-var-twitter: "\f099";
157 | @fa-var-facebook: "\f09a";
158 | @fa-var-github: "\f09b";
159 | @fa-var-unlock: "\f09c";
160 | @fa-var-credit-card: "\f09d";
161 | @fa-var-rss: "\f09e";
162 | @fa-var-hdd-o: "\f0a0";
163 | @fa-var-bullhorn: "\f0a1";
164 | @fa-var-bell: "\f0f3";
165 | @fa-var-certificate: "\f0a3";
166 | @fa-var-hand-o-right: "\f0a4";
167 | @fa-var-hand-o-left: "\f0a5";
168 | @fa-var-hand-o-up: "\f0a6";
169 | @fa-var-hand-o-down: "\f0a7";
170 | @fa-var-arrow-circle-left: "\f0a8";
171 | @fa-var-arrow-circle-right: "\f0a9";
172 | @fa-var-arrow-circle-up: "\f0aa";
173 | @fa-var-arrow-circle-down: "\f0ab";
174 | @fa-var-globe: "\f0ac";
175 | @fa-var-wrench: "\f0ad";
176 | @fa-var-tasks: "\f0ae";
177 | @fa-var-filter: "\f0b0";
178 | @fa-var-briefcase: "\f0b1";
179 | @fa-var-arrows-alt: "\f0b2";
180 | @fa-var-users: "\f0c0";
181 | @fa-var-link: "\f0c1";
182 | @fa-var-cloud: "\f0c2";
183 | @fa-var-flask: "\f0c3";
184 | @fa-var-scissors: "\f0c4";
185 | @fa-var-files-o: "\f0c5";
186 | @fa-var-paperclip: "\f0c6";
187 | @fa-var-floppy-o: "\f0c7";
188 | @fa-var-square: "\f0c8";
189 | @fa-var-bars: "\f0c9";
190 | @fa-var-list-ul: "\f0ca";
191 | @fa-var-list-ol: "\f0cb";
192 | @fa-var-strikethrough: "\f0cc";
193 | @fa-var-underline: "\f0cd";
194 | @fa-var-table: "\f0ce";
195 | @fa-var-magic: "\f0d0";
196 | @fa-var-truck: "\f0d1";
197 | @fa-var-pinterest: "\f0d2";
198 | @fa-var-pinterest-square: "\f0d3";
199 | @fa-var-google-plus-square: "\f0d4";
200 | @fa-var-google-plus: "\f0d5";
201 | @fa-var-money: "\f0d6";
202 | @fa-var-caret-down: "\f0d7";
203 | @fa-var-caret-up: "\f0d8";
204 | @fa-var-caret-left: "\f0d9";
205 | @fa-var-caret-right: "\f0da";
206 | @fa-var-columns: "\f0db";
207 | @fa-var-sort: "\f0dc";
208 | @fa-var-sort-asc: "\f0dd";
209 | @fa-var-sort-desc: "\f0de";
210 | @fa-var-envelope: "\f0e0";
211 | @fa-var-linkedin: "\f0e1";
212 | @fa-var-undo: "\f0e2";
213 | @fa-var-gavel: "\f0e3";
214 | @fa-var-tachometer: "\f0e4";
215 | @fa-var-comment-o: "\f0e5";
216 | @fa-var-comments-o: "\f0e6";
217 | @fa-var-bolt: "\f0e7";
218 | @fa-var-sitemap: "\f0e8";
219 | @fa-var-umbrella: "\f0e9";
220 | @fa-var-clipboard: "\f0ea";
221 | @fa-var-lightbulb-o: "\f0eb";
222 | @fa-var-exchange: "\f0ec";
223 | @fa-var-cloud-download: "\f0ed";
224 | @fa-var-cloud-upload: "\f0ee";
225 | @fa-var-user-md: "\f0f0";
226 | @fa-var-stethoscope: "\f0f1";
227 | @fa-var-suitcase: "\f0f2";
228 | @fa-var-bell-o: "\f0a2";
229 | @fa-var-coffee: "\f0f4";
230 | @fa-var-cutlery: "\f0f5";
231 | @fa-var-file-text-o: "\f0f6";
232 | @fa-var-building-o: "\f0f7";
233 | @fa-var-hospital-o: "\f0f8";
234 | @fa-var-ambulance: "\f0f9";
235 | @fa-var-medkit: "\f0fa";
236 | @fa-var-fighter-jet: "\f0fb";
237 | @fa-var-beer: "\f0fc";
238 | @fa-var-h-square: "\f0fd";
239 | @fa-var-plus-square: "\f0fe";
240 | @fa-var-angle-double-left: "\f100";
241 | @fa-var-angle-double-right: "\f101";
242 | @fa-var-angle-double-up: "\f102";
243 | @fa-var-angle-double-down: "\f103";
244 | @fa-var-angle-left: "\f104";
245 | @fa-var-angle-right: "\f105";
246 | @fa-var-angle-up: "\f106";
247 | @fa-var-angle-down: "\f107";
248 | @fa-var-desktop: "\f108";
249 | @fa-var-laptop: "\f109";
250 | @fa-var-tablet: "\f10a";
251 | @fa-var-mobile: "\f10b";
252 | @fa-var-circle-o: "\f10c";
253 | @fa-var-quote-left: "\f10d";
254 | @fa-var-quote-right: "\f10e";
255 | @fa-var-spinner: "\f110";
256 | @fa-var-circle: "\f111";
257 | @fa-var-reply: "\f112";
258 | @fa-var-github-alt: "\f113";
259 | @fa-var-folder-o: "\f114";
260 | @fa-var-folder-open-o: "\f115";
261 | @fa-var-smile-o: "\f118";
262 | @fa-var-frown-o: "\f119";
263 | @fa-var-meh-o: "\f11a";
264 | @fa-var-gamepad: "\f11b";
265 | @fa-var-keyboard-o: "\f11c";
266 | @fa-var-flag-o: "\f11d";
267 | @fa-var-flag-checkered: "\f11e";
268 | @fa-var-terminal: "\f120";
269 | @fa-var-code: "\f121";
270 | @fa-var-reply-all: "\f122";
271 | @fa-var-mail-reply-all: "\f122";
272 | @fa-var-star-half-o: "\f123";
273 | @fa-var-location-arrow: "\f124";
274 | @fa-var-crop: "\f125";
275 | @fa-var-code-fork: "\f126";
276 | @fa-var-chain-broken: "\f127";
277 | @fa-var-question: "\f128";
278 | @fa-var-info: "\f129";
279 | @fa-var-exclamation: "\f12a";
280 | @fa-var-superscript: "\f12b";
281 | @fa-var-subscript: "\f12c";
282 | @fa-var-eraser: "\f12d";
283 | @fa-var-puzzle-piece: "\f12e";
284 | @fa-var-microphone: "\f130";
285 | @fa-var-microphone-slash: "\f131";
286 | @fa-var-shield: "\f132";
287 | @fa-var-calendar-o: "\f133";
288 | @fa-var-fire-extinguisher: "\f134";
289 | @fa-var-rocket: "\f135";
290 | @fa-var-maxcdn: "\f136";
291 | @fa-var-chevron-circle-left: "\f137";
292 | @fa-var-chevron-circle-right: "\f138";
293 | @fa-var-chevron-circle-up: "\f139";
294 | @fa-var-chevron-circle-down: "\f13a";
295 | @fa-var-html5: "\f13b";
296 | @fa-var-css3: "\f13c";
297 | @fa-var-anchor: "\f13d";
298 | @fa-var-unlock-alt: "\f13e";
299 | @fa-var-bullseye: "\f140";
300 | @fa-var-ellipsis-h: "\f141";
301 | @fa-var-ellipsis-v: "\f142";
302 | @fa-var-rss-square: "\f143";
303 | @fa-var-play-circle: "\f144";
304 | @fa-var-ticket: "\f145";
305 | @fa-var-minus-square: "\f146";
306 | @fa-var-minus-square-o: "\f147";
307 | @fa-var-level-up: "\f148";
308 | @fa-var-level-down: "\f149";
309 | @fa-var-check-square: "\f14a";
310 | @fa-var-pencil-square: "\f14b";
311 | @fa-var-external-link-square: "\f14c";
312 | @fa-var-share-square: "\f14d";
313 | @fa-var-compass: "\f14e";
314 | @fa-var-caret-square-o-down: "\f150";
315 | @fa-var-caret-square-o-up: "\f151";
316 | @fa-var-caret-square-o-right: "\f152";
317 | @fa-var-eur: "\f153";
318 | @fa-var-gbp: "\f154";
319 | @fa-var-usd: "\f155";
320 | @fa-var-inr: "\f156";
321 | @fa-var-jpy: "\f157";
322 | @fa-var-rub: "\f158";
323 | @fa-var-krw: "\f159";
324 | @fa-var-btc: "\f15a";
325 | @fa-var-file: "\f15b";
326 | @fa-var-file-text: "\f15c";
327 | @fa-var-sort-alpha-asc: "\f15d";
328 | @fa-var-sort-alpha-desc: "\f15e";
329 | @fa-var-sort-amount-asc: "\f160";
330 | @fa-var-sort-amount-desc: "\f161";
331 | @fa-var-sort-numeric-asc: "\f162";
332 | @fa-var-sort-numeric-desc: "\f163";
333 | @fa-var-thumbs-up: "\f164";
334 | @fa-var-thumbs-down: "\f165";
335 | @fa-var-youtube-square: "\f166";
336 | @fa-var-youtube: "\f167";
337 | @fa-var-xing: "\f168";
338 | @fa-var-xing-square: "\f169";
339 | @fa-var-youtube-play: "\f16a";
340 | @fa-var-dropbox: "\f16b";
341 | @fa-var-stack-overflow: "\f16c";
342 | @fa-var-instagram: "\f16d";
343 | @fa-var-flickr: "\f16e";
344 | @fa-var-adn: "\f170";
345 | @fa-var-bitbucket: "\f171";
346 | @fa-var-bitbucket-square: "\f172";
347 | @fa-var-tumblr: "\f173";
348 | @fa-var-tumblr-square: "\f174";
349 | @fa-var-long-arrow-down: "\f175";
350 | @fa-var-long-arrow-up: "\f176";
351 | @fa-var-long-arrow-left: "\f177";
352 | @fa-var-long-arrow-right: "\f178";
353 | @fa-var-apple: "\f179";
354 | @fa-var-windows: "\f17a";
355 | @fa-var-android: "\f17b";
356 | @fa-var-linux: "\f17c";
357 | @fa-var-dribbble: "\f17d";
358 | @fa-var-skype: "\f17e";
359 | @fa-var-foursquare: "\f180";
360 | @fa-var-trello: "\f181";
361 | @fa-var-female: "\f182";
362 | @fa-var-male: "\f183";
363 | @fa-var-gittip: "\f184";
364 | @fa-var-sun-o: "\f185";
365 | @fa-var-moon-o: "\f186";
366 | @fa-var-archive: "\f187";
367 | @fa-var-bug: "\f188";
368 | @fa-var-vk: "\f189";
369 | @fa-var-weibo: "\f18a";
370 | @fa-var-renren: "\f18b";
371 | @fa-var-pagelines: "\f18c";
372 | @fa-var-stack-exchange: "\f18d";
373 | @fa-var-arrow-circle-o-right: "\f18e";
374 | @fa-var-arrow-circle-o-left: "\f190";
375 | @fa-var-caret-square-o-left: "\f191";
376 | @fa-var-dot-circle-o: "\f192";
377 | @fa-var-wheelchair: "\f193";
378 | @fa-var-vimeo-square: "\f194";
379 | @fa-var-try: "\f195";
380 | @fa-var-plus-square-o: "\f196";
381 |
382 |
--------------------------------------------------------------------------------
/web/font-awesome/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | // Variables
2 | // --------------------------
3 |
4 | $fa-font-path: "../fonts" !default;
5 | //$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts" !default; // for referencing Bootstrap CDN font files directly
6 | $fa-css-prefix: fa !default;
7 | $fa-version: "4.0.3" !default;
8 | $fa-border-color: #eee !default;
9 | $fa-inverse: #fff !default;
10 | $fa-li-width: (30em / 14) !default;
11 |
12 | $fa-var-glass: "\f000";
13 | $fa-var-music: "\f001";
14 | $fa-var-search: "\f002";
15 | $fa-var-envelope-o: "\f003";
16 | $fa-var-heart: "\f004";
17 | $fa-var-star: "\f005";
18 | $fa-var-star-o: "\f006";
19 | $fa-var-user: "\f007";
20 | $fa-var-film: "\f008";
21 | $fa-var-th-large: "\f009";
22 | $fa-var-th: "\f00a";
23 | $fa-var-th-list: "\f00b";
24 | $fa-var-check: "\f00c";
25 | $fa-var-times: "\f00d";
26 | $fa-var-search-plus: "\f00e";
27 | $fa-var-search-minus: "\f010";
28 | $fa-var-power-off: "\f011";
29 | $fa-var-signal: "\f012";
30 | $fa-var-cog: "\f013";
31 | $fa-var-trash-o: "\f014";
32 | $fa-var-home: "\f015";
33 | $fa-var-file-o: "\f016";
34 | $fa-var-clock-o: "\f017";
35 | $fa-var-road: "\f018";
36 | $fa-var-download: "\f019";
37 | $fa-var-arrow-circle-o-down: "\f01a";
38 | $fa-var-arrow-circle-o-up: "\f01b";
39 | $fa-var-inbox: "\f01c";
40 | $fa-var-play-circle-o: "\f01d";
41 | $fa-var-repeat: "\f01e";
42 | $fa-var-refresh: "\f021";
43 | $fa-var-list-alt: "\f022";
44 | $fa-var-lock: "\f023";
45 | $fa-var-flag: "\f024";
46 | $fa-var-headphones: "\f025";
47 | $fa-var-volume-off: "\f026";
48 | $fa-var-volume-down: "\f027";
49 | $fa-var-volume-up: "\f028";
50 | $fa-var-qrcode: "\f029";
51 | $fa-var-barcode: "\f02a";
52 | $fa-var-tag: "\f02b";
53 | $fa-var-tags: "\f02c";
54 | $fa-var-book: "\f02d";
55 | $fa-var-bookmark: "\f02e";
56 | $fa-var-print: "\f02f";
57 | $fa-var-camera: "\f030";
58 | $fa-var-font: "\f031";
59 | $fa-var-bold: "\f032";
60 | $fa-var-italic: "\f033";
61 | $fa-var-text-height: "\f034";
62 | $fa-var-text-width: "\f035";
63 | $fa-var-align-left: "\f036";
64 | $fa-var-align-center: "\f037";
65 | $fa-var-align-right: "\f038";
66 | $fa-var-align-justify: "\f039";
67 | $fa-var-list: "\f03a";
68 | $fa-var-outdent: "\f03b";
69 | $fa-var-indent: "\f03c";
70 | $fa-var-video-camera: "\f03d";
71 | $fa-var-picture-o: "\f03e";
72 | $fa-var-pencil: "\f040";
73 | $fa-var-map-marker: "\f041";
74 | $fa-var-adjust: "\f042";
75 | $fa-var-tint: "\f043";
76 | $fa-var-pencil-square-o: "\f044";
77 | $fa-var-share-square-o: "\f045";
78 | $fa-var-check-square-o: "\f046";
79 | $fa-var-arrows: "\f047";
80 | $fa-var-step-backward: "\f048";
81 | $fa-var-fast-backward: "\f049";
82 | $fa-var-backward: "\f04a";
83 | $fa-var-play: "\f04b";
84 | $fa-var-pause: "\f04c";
85 | $fa-var-stop: "\f04d";
86 | $fa-var-forward: "\f04e";
87 | $fa-var-fast-forward: "\f050";
88 | $fa-var-step-forward: "\f051";
89 | $fa-var-eject: "\f052";
90 | $fa-var-chevron-left: "\f053";
91 | $fa-var-chevron-right: "\f054";
92 | $fa-var-plus-circle: "\f055";
93 | $fa-var-minus-circle: "\f056";
94 | $fa-var-times-circle: "\f057";
95 | $fa-var-check-circle: "\f058";
96 | $fa-var-question-circle: "\f059";
97 | $fa-var-info-circle: "\f05a";
98 | $fa-var-crosshairs: "\f05b";
99 | $fa-var-times-circle-o: "\f05c";
100 | $fa-var-check-circle-o: "\f05d";
101 | $fa-var-ban: "\f05e";
102 | $fa-var-arrow-left: "\f060";
103 | $fa-var-arrow-right: "\f061";
104 | $fa-var-arrow-up: "\f062";
105 | $fa-var-arrow-down: "\f063";
106 | $fa-var-share: "\f064";
107 | $fa-var-expand: "\f065";
108 | $fa-var-compress: "\f066";
109 | $fa-var-plus: "\f067";
110 | $fa-var-minus: "\f068";
111 | $fa-var-asterisk: "\f069";
112 | $fa-var-exclamation-circle: "\f06a";
113 | $fa-var-gift: "\f06b";
114 | $fa-var-leaf: "\f06c";
115 | $fa-var-fire: "\f06d";
116 | $fa-var-eye: "\f06e";
117 | $fa-var-eye-slash: "\f070";
118 | $fa-var-exclamation-triangle: "\f071";
119 | $fa-var-plane: "\f072";
120 | $fa-var-calendar: "\f073";
121 | $fa-var-random: "\f074";
122 | $fa-var-comment: "\f075";
123 | $fa-var-magnet: "\f076";
124 | $fa-var-chevron-up: "\f077";
125 | $fa-var-chevron-down: "\f078";
126 | $fa-var-retweet: "\f079";
127 | $fa-var-shopping-cart: "\f07a";
128 | $fa-var-folder: "\f07b";
129 | $fa-var-folder-open: "\f07c";
130 | $fa-var-arrows-v: "\f07d";
131 | $fa-var-arrows-h: "\f07e";
132 | $fa-var-bar-chart-o: "\f080";
133 | $fa-var-twitter-square: "\f081";
134 | $fa-var-facebook-square: "\f082";
135 | $fa-var-camera-retro: "\f083";
136 | $fa-var-key: "\f084";
137 | $fa-var-cogs: "\f085";
138 | $fa-var-comments: "\f086";
139 | $fa-var-thumbs-o-up: "\f087";
140 | $fa-var-thumbs-o-down: "\f088";
141 | $fa-var-star-half: "\f089";
142 | $fa-var-heart-o: "\f08a";
143 | $fa-var-sign-out: "\f08b";
144 | $fa-var-linkedin-square: "\f08c";
145 | $fa-var-thumb-tack: "\f08d";
146 | $fa-var-external-link: "\f08e";
147 | $fa-var-sign-in: "\f090";
148 | $fa-var-trophy: "\f091";
149 | $fa-var-github-square: "\f092";
150 | $fa-var-upload: "\f093";
151 | $fa-var-lemon-o: "\f094";
152 | $fa-var-phone: "\f095";
153 | $fa-var-square-o: "\f096";
154 | $fa-var-bookmark-o: "\f097";
155 | $fa-var-phone-square: "\f098";
156 | $fa-var-twitter: "\f099";
157 | $fa-var-facebook: "\f09a";
158 | $fa-var-github: "\f09b";
159 | $fa-var-unlock: "\f09c";
160 | $fa-var-credit-card: "\f09d";
161 | $fa-var-rss: "\f09e";
162 | $fa-var-hdd-o: "\f0a0";
163 | $fa-var-bullhorn: "\f0a1";
164 | $fa-var-bell: "\f0f3";
165 | $fa-var-certificate: "\f0a3";
166 | $fa-var-hand-o-right: "\f0a4";
167 | $fa-var-hand-o-left: "\f0a5";
168 | $fa-var-hand-o-up: "\f0a6";
169 | $fa-var-hand-o-down: "\f0a7";
170 | $fa-var-arrow-circle-left: "\f0a8";
171 | $fa-var-arrow-circle-right: "\f0a9";
172 | $fa-var-arrow-circle-up: "\f0aa";
173 | $fa-var-arrow-circle-down: "\f0ab";
174 | $fa-var-globe: "\f0ac";
175 | $fa-var-wrench: "\f0ad";
176 | $fa-var-tasks: "\f0ae";
177 | $fa-var-filter: "\f0b0";
178 | $fa-var-briefcase: "\f0b1";
179 | $fa-var-arrows-alt: "\f0b2";
180 | $fa-var-users: "\f0c0";
181 | $fa-var-link: "\f0c1";
182 | $fa-var-cloud: "\f0c2";
183 | $fa-var-flask: "\f0c3";
184 | $fa-var-scissors: "\f0c4";
185 | $fa-var-files-o: "\f0c5";
186 | $fa-var-paperclip: "\f0c6";
187 | $fa-var-floppy-o: "\f0c7";
188 | $fa-var-square: "\f0c8";
189 | $fa-var-bars: "\f0c9";
190 | $fa-var-list-ul: "\f0ca";
191 | $fa-var-list-ol: "\f0cb";
192 | $fa-var-strikethrough: "\f0cc";
193 | $fa-var-underline: "\f0cd";
194 | $fa-var-table: "\f0ce";
195 | $fa-var-magic: "\f0d0";
196 | $fa-var-truck: "\f0d1";
197 | $fa-var-pinterest: "\f0d2";
198 | $fa-var-pinterest-square: "\f0d3";
199 | $fa-var-google-plus-square: "\f0d4";
200 | $fa-var-google-plus: "\f0d5";
201 | $fa-var-money: "\f0d6";
202 | $fa-var-caret-down: "\f0d7";
203 | $fa-var-caret-up: "\f0d8";
204 | $fa-var-caret-left: "\f0d9";
205 | $fa-var-caret-right: "\f0da";
206 | $fa-var-columns: "\f0db";
207 | $fa-var-sort: "\f0dc";
208 | $fa-var-sort-asc: "\f0dd";
209 | $fa-var-sort-desc: "\f0de";
210 | $fa-var-envelope: "\f0e0";
211 | $fa-var-linkedin: "\f0e1";
212 | $fa-var-undo: "\f0e2";
213 | $fa-var-gavel: "\f0e3";
214 | $fa-var-tachometer: "\f0e4";
215 | $fa-var-comment-o: "\f0e5";
216 | $fa-var-comments-o: "\f0e6";
217 | $fa-var-bolt: "\f0e7";
218 | $fa-var-sitemap: "\f0e8";
219 | $fa-var-umbrella: "\f0e9";
220 | $fa-var-clipboard: "\f0ea";
221 | $fa-var-lightbulb-o: "\f0eb";
222 | $fa-var-exchange: "\f0ec";
223 | $fa-var-cloud-download: "\f0ed";
224 | $fa-var-cloud-upload: "\f0ee";
225 | $fa-var-user-md: "\f0f0";
226 | $fa-var-stethoscope: "\f0f1";
227 | $fa-var-suitcase: "\f0f2";
228 | $fa-var-bell-o: "\f0a2";
229 | $fa-var-coffee: "\f0f4";
230 | $fa-var-cutlery: "\f0f5";
231 | $fa-var-file-text-o: "\f0f6";
232 | $fa-var-building-o: "\f0f7";
233 | $fa-var-hospital-o: "\f0f8";
234 | $fa-var-ambulance: "\f0f9";
235 | $fa-var-medkit: "\f0fa";
236 | $fa-var-fighter-jet: "\f0fb";
237 | $fa-var-beer: "\f0fc";
238 | $fa-var-h-square: "\f0fd";
239 | $fa-var-plus-square: "\f0fe";
240 | $fa-var-angle-double-left: "\f100";
241 | $fa-var-angle-double-right: "\f101";
242 | $fa-var-angle-double-up: "\f102";
243 | $fa-var-angle-double-down: "\f103";
244 | $fa-var-angle-left: "\f104";
245 | $fa-var-angle-right: "\f105";
246 | $fa-var-angle-up: "\f106";
247 | $fa-var-angle-down: "\f107";
248 | $fa-var-desktop: "\f108";
249 | $fa-var-laptop: "\f109";
250 | $fa-var-tablet: "\f10a";
251 | $fa-var-mobile: "\f10b";
252 | $fa-var-circle-o: "\f10c";
253 | $fa-var-quote-left: "\f10d";
254 | $fa-var-quote-right: "\f10e";
255 | $fa-var-spinner: "\f110";
256 | $fa-var-circle: "\f111";
257 | $fa-var-reply: "\f112";
258 | $fa-var-github-alt: "\f113";
259 | $fa-var-folder-o: "\f114";
260 | $fa-var-folder-open-o: "\f115";
261 | $fa-var-smile-o: "\f118";
262 | $fa-var-frown-o: "\f119";
263 | $fa-var-meh-o: "\f11a";
264 | $fa-var-gamepad: "\f11b";
265 | $fa-var-keyboard-o: "\f11c";
266 | $fa-var-flag-o: "\f11d";
267 | $fa-var-flag-checkered: "\f11e";
268 | $fa-var-terminal: "\f120";
269 | $fa-var-code: "\f121";
270 | $fa-var-reply-all: "\f122";
271 | $fa-var-mail-reply-all: "\f122";
272 | $fa-var-star-half-o: "\f123";
273 | $fa-var-location-arrow: "\f124";
274 | $fa-var-crop: "\f125";
275 | $fa-var-code-fork: "\f126";
276 | $fa-var-chain-broken: "\f127";
277 | $fa-var-question: "\f128";
278 | $fa-var-info: "\f129";
279 | $fa-var-exclamation: "\f12a";
280 | $fa-var-superscript: "\f12b";
281 | $fa-var-subscript: "\f12c";
282 | $fa-var-eraser: "\f12d";
283 | $fa-var-puzzle-piece: "\f12e";
284 | $fa-var-microphone: "\f130";
285 | $fa-var-microphone-slash: "\f131";
286 | $fa-var-shield: "\f132";
287 | $fa-var-calendar-o: "\f133";
288 | $fa-var-fire-extinguisher: "\f134";
289 | $fa-var-rocket: "\f135";
290 | $fa-var-maxcdn: "\f136";
291 | $fa-var-chevron-circle-left: "\f137";
292 | $fa-var-chevron-circle-right: "\f138";
293 | $fa-var-chevron-circle-up: "\f139";
294 | $fa-var-chevron-circle-down: "\f13a";
295 | $fa-var-html5: "\f13b";
296 | $fa-var-css3: "\f13c";
297 | $fa-var-anchor: "\f13d";
298 | $fa-var-unlock-alt: "\f13e";
299 | $fa-var-bullseye: "\f140";
300 | $fa-var-ellipsis-h: "\f141";
301 | $fa-var-ellipsis-v: "\f142";
302 | $fa-var-rss-square: "\f143";
303 | $fa-var-play-circle: "\f144";
304 | $fa-var-ticket: "\f145";
305 | $fa-var-minus-square: "\f146";
306 | $fa-var-minus-square-o: "\f147";
307 | $fa-var-level-up: "\f148";
308 | $fa-var-level-down: "\f149";
309 | $fa-var-check-square: "\f14a";
310 | $fa-var-pencil-square: "\f14b";
311 | $fa-var-external-link-square: "\f14c";
312 | $fa-var-share-square: "\f14d";
313 | $fa-var-compass: "\f14e";
314 | $fa-var-caret-square-o-down: "\f150";
315 | $fa-var-caret-square-o-up: "\f151";
316 | $fa-var-caret-square-o-right: "\f152";
317 | $fa-var-eur: "\f153";
318 | $fa-var-gbp: "\f154";
319 | $fa-var-usd: "\f155";
320 | $fa-var-inr: "\f156";
321 | $fa-var-jpy: "\f157";
322 | $fa-var-rub: "\f158";
323 | $fa-var-krw: "\f159";
324 | $fa-var-btc: "\f15a";
325 | $fa-var-file: "\f15b";
326 | $fa-var-file-text: "\f15c";
327 | $fa-var-sort-alpha-asc: "\f15d";
328 | $fa-var-sort-alpha-desc: "\f15e";
329 | $fa-var-sort-amount-asc: "\f160";
330 | $fa-var-sort-amount-desc: "\f161";
331 | $fa-var-sort-numeric-asc: "\f162";
332 | $fa-var-sort-numeric-desc: "\f163";
333 | $fa-var-thumbs-up: "\f164";
334 | $fa-var-thumbs-down: "\f165";
335 | $fa-var-youtube-square: "\f166";
336 | $fa-var-youtube: "\f167";
337 | $fa-var-xing: "\f168";
338 | $fa-var-xing-square: "\f169";
339 | $fa-var-youtube-play: "\f16a";
340 | $fa-var-dropbox: "\f16b";
341 | $fa-var-stack-overflow: "\f16c";
342 | $fa-var-instagram: "\f16d";
343 | $fa-var-flickr: "\f16e";
344 | $fa-var-adn: "\f170";
345 | $fa-var-bitbucket: "\f171";
346 | $fa-var-bitbucket-square: "\f172";
347 | $fa-var-tumblr: "\f173";
348 | $fa-var-tumblr-square: "\f174";
349 | $fa-var-long-arrow-down: "\f175";
350 | $fa-var-long-arrow-up: "\f176";
351 | $fa-var-long-arrow-left: "\f177";
352 | $fa-var-long-arrow-right: "\f178";
353 | $fa-var-apple: "\f179";
354 | $fa-var-windows: "\f17a";
355 | $fa-var-android: "\f17b";
356 | $fa-var-linux: "\f17c";
357 | $fa-var-dribbble: "\f17d";
358 | $fa-var-skype: "\f17e";
359 | $fa-var-foursquare: "\f180";
360 | $fa-var-trello: "\f181";
361 | $fa-var-female: "\f182";
362 | $fa-var-male: "\f183";
363 | $fa-var-gittip: "\f184";
364 | $fa-var-sun-o: "\f185";
365 | $fa-var-moon-o: "\f186";
366 | $fa-var-archive: "\f187";
367 | $fa-var-bug: "\f188";
368 | $fa-var-vk: "\f189";
369 | $fa-var-weibo: "\f18a";
370 | $fa-var-renren: "\f18b";
371 | $fa-var-pagelines: "\f18c";
372 | $fa-var-stack-exchange: "\f18d";
373 | $fa-var-arrow-circle-o-right: "\f18e";
374 | $fa-var-arrow-circle-o-left: "\f190";
375 | $fa-var-caret-square-o-left: "\f191";
376 | $fa-var-dot-circle-o: "\f192";
377 | $fa-var-wheelchair: "\f193";
378 | $fa-var-vimeo-square: "\f194";
379 | $fa-var-try: "\f195";
380 | $fa-var-plus-square-o: "\f196";
381 |
382 |
--------------------------------------------------------------------------------
/web/bootstrap/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.0.3 (http://getbootstrap.com)
3 | * Copyright 2013 Twitter, Inc.
4 | * Licensed under http://www.apache.org/licenses/LICENSE-2.0
5 | */
6 |
7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe0e0e0',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);background-repeat:repeat-x;border-color:#2b669a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff2d6ca2',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);background-repeat:repeat-x;border-color:#3e8f3e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff419641',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);background-repeat:repeat-x;border-color:#e38d13;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffeb9316',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);background-repeat:repeat-x;border-color:#b92c28;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc12e2a',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);background-repeat:repeat-x;border-color:#28a4c9;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2aabd2',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff3f3f3',GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff282828',GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)}
--------------------------------------------------------------------------------