├── .gitignore ├── .jshintrc ├── History.md ├── Makefile ├── Readme.md ├── component.json ├── docs └── screenshot.png ├── index.js ├── index.less ├── less ├── app.less ├── components │ ├── comment.less │ ├── comments.less │ ├── issue.less │ ├── labels.less │ ├── pager.less │ └── repo-input.less ├── mixins.less └── pages │ ├── all-issues.less │ └── issue.less ├── lib ├── app.js ├── components │ ├── comment.js │ ├── comments.js │ ├── issue.js │ ├── issue.jsx │ ├── label.js │ ├── labels.js │ ├── pager.js │ ├── recent-time.js │ └── repo-input.js ├── pages │ ├── all-issues.js │ ├── issue.js │ └── issue.jsx ├── router.js ├── utils.js └── view.js ├── package.json ├── test └── test_utils.js ├── twitter-audition.css └── web ├── bootstrap ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.min.css │ ├── bootstrap.css │ └── bootstrap.min.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── js │ ├── bootstrap.js │ └── bootstrap.min.js └── less │ ├── alerts.less │ ├── badges.less │ ├── bootstrap.less │ ├── breadcrumbs.less │ ├── button-groups.less │ ├── buttons.less │ ├── carousel.less │ ├── close.less │ ├── code.less │ ├── component-animations.less │ ├── dropdowns.less │ ├── forms.less │ ├── glyphicons.less │ ├── grid.less │ ├── input-groups.less │ ├── jumbotron.less │ ├── labels.less │ ├── list-group.less │ ├── media.less │ ├── mixins.less │ ├── modals.less │ ├── navbar.less │ ├── navs.less │ ├── normalize.less │ ├── pager.less │ ├── pagination.less │ ├── panels.less │ ├── popovers.less │ ├── print.less │ ├── progress-bars.less │ ├── responsive-utilities.less │ ├── scaffolding.less │ ├── tables.less │ ├── theme.less │ ├── thumbnails.less │ ├── tooltip.less │ ├── type.less │ ├── utilities.less │ ├── variables.less │ └── wells.less ├── font-awesome ├── css │ ├── font-awesome.css │ └── font-awesome.min.css ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── less │ ├── bordered-pulled.less │ ├── core.less │ ├── fixed-width.less │ ├── font-awesome.less │ ├── icons.less │ ├── larger.less │ ├── list.less │ ├── mixins.less │ ├── path.less │ ├── rotated-flipped.less │ ├── spinning.less │ ├── stacked.less │ └── variables.less └── scss │ ├── _bordered-pulled.scss │ ├── _core.scss │ ├── _fixed-width.scss │ ├── _icons.scss │ ├── _larger.scss │ ├── _list.scss │ ├── _mixins.scss │ ├── _path.scss │ ├── _rotated-flipped.scss │ ├── _spinning.scss │ ├── _stacked.scss │ ├── _variables.scss │ └── font-awesome.scss ├── index.html ├── react.js └── setup.js /.gitignore: -------------------------------------------------------------------------------- 1 | /components 2 | build 3 | *.swp 4 | node_modules 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "strict": false, 3 | "laxcomma": true, 4 | "undef": true, 5 | "node": true, 6 | "globals": { 7 | "React": false 8 | }, 9 | "-W033": false, 10 | "-W024": false, 11 | "-W030": false, 12 | "-W069": false, 13 | "-W089": false, 14 | "-W098": false, 15 | "-W116": false, 16 | "-W065": false 17 | } 18 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/History.md -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PAGES = $(patsubst %.jsx, %.js, $(wildcard lib/pages/*.jsx)) 3 | COMPONENTS = $(patsubst %.jsx, %.js, $(wildcard lib/components/*.jsx)) 4 | COMPILED = $(PAGES) $(COMPONENTS) 5 | 6 | build: components index.js twitter-audition.css lib $(COMPILED) 7 | @component build --dev -s twitterAudition -o web -n build 8 | 9 | twitter-audition.css: index.less less 10 | @lessc index.less > $@ 11 | 12 | lib/pages/%.js: lib/pages/%.jsx 13 | @jsx $< > $@ 14 | 15 | lib/components/%.js: lib/components/%.jsx 16 | @jsx $< > $@ 17 | 18 | components: component.json 19 | @component install --dev 20 | 21 | clean: 22 | rm -fr build components template.js 23 | 24 | view: 25 | @xdg-open web/index.html 26 | 27 | test: lint test-only 28 | 29 | lint: 30 | jshint *.js lib test 31 | 32 | test-only: 33 | mocha -R spec 34 | 35 | gh-pages: build 36 | cp -r web w 37 | git co gh-pages 38 | rm -rf bootstrap font-awesome 39 | mv w/* ./ 40 | rmdir w 41 | 42 | .PHONY: clean test test-only lint gh-pages 43 | -------------------------------------------------------------------------------- /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 | [![Screenshot](docs/screenshot.png)](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 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter-audition", 3 | "repo": "jaredly/twitter-audition", 4 | "description": "", 5 | "version": "0.0.1", 6 | "keywords": [], 7 | "dependencies": { 8 | "components/backbone": "*", 9 | "component/jquery": "*", 10 | "lodash/lodash": "*", 11 | "component/moment": "*", 12 | "chjj/marked": "*" 13 | }, 14 | "development": {}, 15 | "license": "MIT", 16 | "main": "index.js", 17 | "scripts": [ 18 | "index.js", 19 | "lib/app.js", 20 | "lib/view.js", 21 | "lib/router.js", 22 | "lib/utils.js", 23 | "lib/pages/issue.js", 24 | "lib/pages/all-issues.js", 25 | "lib/components/issue.js", 26 | "lib/components/pager.js", 27 | "lib/components/comment.js", 28 | "lib/components/comments.js", 29 | "lib/components/labels.js", 30 | "lib/components/label.js", 31 | "lib/components/repo-input.js", 32 | "lib/components/recent-time.js" 33 | ], 34 | "styles": [ 35 | "twitter-audition.css" 36 | ], 37 | "remotes": [] 38 | } 39 | -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/docs/screenshot.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | window.$ = require('jquery') 3 | var App = require('./lib/app') 4 | 5 | module.exports = function (el) { 6 | React.renderComponent(App(), el) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /index.less: -------------------------------------------------------------------------------- 1 | 2 | @import "less/app"; 3 | 4 | -------------------------------------------------------------------------------- /less/app.less: -------------------------------------------------------------------------------- 1 | 2 | @import "../web/bootstrap/less/variables"; 3 | @import "../web/bootstrap/less/utilities"; 4 | @import "../web/bootstrap/less/scaffolding"; 5 | @import "../web/bootstrap/less/mixins"; 6 | @import "../web/bootstrap/less/buttons"; 7 | @import "../web/bootstrap/less/labels"; 8 | 9 | @import "../web/font-awesome/less/font-awesome"; 10 | 11 | @import "mixins"; 12 | 13 | @import "components/repo-input"; 14 | @import "components/comments"; 15 | @import "components/comment"; 16 | @import "components/labels"; 17 | @import "components/pager"; 18 | @import "components/issue"; 19 | @import "pages/all-issues"; 20 | @import "pages/issue"; 21 | 22 | a:hover { 23 | text-decoration: none; 24 | } 25 | 26 | /* User things */ 27 | 28 | .user__avatar { 29 | .avatar-image; 30 | } 31 | 32 | .user__login { 33 | margin-left: 5px; 34 | } 35 | 36 | /* 37 | .user__login--avatar-right::after { 38 | content: @fa-var-play; 39 | position: relative; 40 | left: -6px; 41 | font-family: FontAwesome; 42 | color: #ccc; 43 | } 44 | */ 45 | 46 | .user__login--avatar-left::before { 47 | content: @fa-var-play; 48 | position: relative; 49 | left: -6px; 50 | font-family: FontAwesome; 51 | color: #ccc; 52 | } 53 | 54 | .user__avatar { 55 | border: 1px solid #ccc; 56 | border-radius: 4px; 57 | } 58 | 59 | 60 | /* main app */ 61 | 62 | .main-view { 63 | margin-top: 20px; 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /less/components/comment.less: -------------------------------------------------------------------------------- 1 | 2 | .comment { 3 | border-top: 1px solid #eee; 4 | padding-top: 15px; 5 | } 6 | 7 | .comment__header { 8 | color: #777; 9 | } 10 | 11 | .comment__commenter { 12 | .grey-name; 13 | } 14 | 15 | .comment__id { 16 | color: #ccc; 17 | margin: 0 5px; 18 | } 19 | 20 | .comment__id::before { 21 | content: @fa-var-comment; 22 | font-family: FontAwesome; 23 | } 24 | 25 | .comment__time::before { 26 | content: 'commented'; 27 | margin: 0 5px; 28 | } 29 | 30 | .comment__body { 31 | margin-left: 65px; 32 | margin-bottom: -10px; 33 | 34 | position: relative; 35 | top: -10px; 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /less/components/comments.less: -------------------------------------------------------------------------------- 1 | /** comments **/ 2 | 3 | .comments { 4 | margin: 0; 5 | padding: 0; 6 | list-style: none; 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /less/components/issue.less: -------------------------------------------------------------------------------- 1 | /** issue **/ 2 | 3 | .issue { 4 | display: flex; 5 | flex-wrap: nowrap; 6 | color: #555; 7 | cursor: pointer; 8 | padding: 5px; 9 | margin-bottom: 20px; 10 | 11 | &:hover { 12 | background-color: #f7f7f7; 13 | border-radius: 5px; 14 | } 15 | } 16 | 17 | .issue__left { 18 | flex: 1; 19 | padding-right: 10px; 20 | } 21 | 22 | .issue__right { 23 | text-align: right; 24 | } 25 | 26 | .issue__header { 27 | font-size: 18px; 28 | font-weight: bold; 29 | color: #555; 30 | } 31 | 32 | .issue__id::before { 33 | content: '#'; 34 | } 35 | 36 | .issue__id { 37 | margin-right: 10px; 38 | } 39 | 40 | .issue__body { 41 | color: #999; 42 | } 43 | 44 | .issue__labels { 45 | text-align: right; 46 | } 47 | 48 | .issue__user .user__login { 49 | display: block; 50 | color: #777; 51 | font-size: 10px; 52 | margin-top: 5px; 53 | 54 | &:hover { 55 | color: #333; 56 | } 57 | } 58 | 59 | .issue__user .user__login::before { 60 | content: '@'; 61 | } 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /less/components/labels.less: -------------------------------------------------------------------------------- 1 | 2 | .labels { 3 | margin: 0; 4 | padding: 0; 5 | list-style: none; 6 | } 7 | 8 | .labels__label { 9 | float: left; 10 | margin-left: 5px; 11 | } 12 | 13 | .labels--vertical .labels__label { 14 | float: none; 15 | display: block; 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /less/components/pager.less: -------------------------------------------------------------------------------- 1 | 2 | /** pager **/ 3 | 4 | .mypager { 5 | text-align: center; 6 | margin-bottom: 10px; 7 | } 8 | 9 | .mypager__load-more, 10 | .mypager__button { 11 | .btn; 12 | .btn-default; 13 | .btn-sm; 14 | font-family: FontAwesome; 15 | 16 | &.disabled { 17 | background-color: #ebebeb; 18 | } 19 | } 20 | .mypager__button--start::before { 21 | content: @fa-var-angle-double-left; 22 | } 23 | .mypager__button--end::before { 24 | content: @fa-var-angle-double-right; 25 | } 26 | .mypager__button--prev::before { 27 | content: @fa-var-angle-left; 28 | } 29 | .mypager__button--next::before { 30 | content: @fa-var-angle-right; 31 | } 32 | .mypager__button--start { 33 | margin-right: 5px; 34 | } 35 | .mypager__button--end { 36 | margin-left: 5px; 37 | } 38 | 39 | .mypager__load-more { 40 | margin-left: 10px; 41 | } 42 | 43 | .mypager__page { 44 | padding: 5px 10px; 45 | display: inline-block; 46 | width: 36px; 47 | cursor: pointer; 48 | color: #999; 49 | vertical-align: middle; 50 | 51 | &:hover { 52 | color: black; 53 | } 54 | } 55 | 56 | .mypager__page.disabled { 57 | color: black; 58 | font-weight: bold; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /less/components/repo-input.less: -------------------------------------------------------------------------------- 1 | 2 | .repo-input { 3 | input { 4 | border: 1px solid white; 5 | border-radius: 3px; 6 | vertical-align: middle; 7 | font-size: 18px; 8 | padding: 2px 5px; 9 | font-weight: bold; 10 | margin-right: 10px; 11 | margin-left: 10px; 12 | cursor: pointer; 13 | 14 | &:focus { 15 | outline: none; 16 | box-shadow: 0 0 3px #777; 17 | cursor: text; 18 | } 19 | 20 | } 21 | 22 | button { 23 | .btn; 24 | .btn-default; 25 | 26 | &[disabled], 27 | &.disabled { 28 | background-color: #ebebeb; 29 | } 30 | } 31 | } 32 | 33 | .repo-input__title { 34 | color: #777; 35 | font-size: 18px; 36 | font-weight: bold; 37 | vertical-align: middle; 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /less/mixins.less: -------------------------------------------------------------------------------- 1 | 2 | .grey-name { 3 | color: #555; 4 | font-weight: bold; 5 | } 6 | 7 | .l-body { 8 | width: 700px; 9 | margin: 50px auto; 10 | } 11 | 12 | .shadowed { 13 | box-shadow: 0 0 5px #777; 14 | } 15 | 16 | .very-round { 17 | border-radius: 5px; 18 | } 19 | 20 | .issue-viewer { 21 | .shadowed; 22 | .very-round; 23 | .l-body; 24 | 25 | padding: 20px; 26 | } 27 | 28 | .l-space-below { 29 | margin-bottom: 15px; 30 | } 31 | 32 | .l-space-left { 33 | margin-left: 15px; 34 | } 35 | 36 | .avatar-image { 37 | width: 50px; 38 | height: 50px; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /less/pages/all-issues.less: -------------------------------------------------------------------------------- 1 | /* all issues page */ 2 | 3 | .issue-list { 4 | list-style: none; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /less/pages/issue.less: -------------------------------------------------------------------------------- 1 | /* issue page */ 2 | 3 | /** top header **/ 4 | .issue-page__back { 5 | .btn; 6 | .btn-default; 7 | .btn-sm; 8 | 9 | margin-bottom: 5px; 10 | } 11 | 12 | .issue-header__main { 13 | margin-top: 0; 14 | } 15 | 16 | .issue-page__header, 17 | .issue-header__sub, 18 | .issue-header__main { 19 | .l-space-below; 20 | } 21 | 22 | .issue-page__header__title { 23 | margin-left: 10px; 24 | color: #555; 25 | font-weight: bold; 26 | } 27 | 28 | .issue-page__state { 29 | .pull-right; 30 | .label; 31 | 32 | margin-top: 5px; 33 | margin-left: 10px; 34 | } 35 | 36 | .issue-state--open { 37 | .label-success; 38 | } 39 | 40 | .issue-state--closed { 41 | .label-warning; 42 | } 43 | 44 | .issue-page__body { 45 | margin-bottom: 15px; 46 | } 47 | 48 | /** sub header **/ 49 | 50 | .issue-header__sub { 51 | color: #999; 52 | } 53 | .issue-page__user { 54 | .grey-name; 55 | } 56 | 57 | .issue__time::before { 58 | content: 'opened this issue'; 59 | margin: 0 5px; 60 | } 61 | 62 | .issue-header__labels { 63 | float: right; 64 | margin-top: 13px; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /lib/app.js: -------------------------------------------------------------------------------- 1 | var Backbone = require('backbone') 2 | , d = React.DOM 3 | 4 | , RepoInput = require('./components/repo-input') 5 | , View = require('./view') 6 | 7 | /* 8 | * This is the main application component 9 | * 10 | * It mostly just gets data from github. 11 | * 12 | * Child components: 13 | * - repo-input (allow you to type in the name of the repo) 14 | * - view (handle everything else) 15 | */ 16 | module.exports = React.createClass({ 17 | getDefaultProps: function () { 18 | return { 19 | initialRepo: 'rails/rails' 20 | } 21 | }, 22 | getInitialState: function () { 23 | return { 24 | repo: this.props.initialRepo, 25 | loading: false, 26 | error: false, 27 | issues: [], 28 | canLoadMore: true, 29 | lastLoadedPage: 0, 30 | xhr: null 31 | } 32 | }, 33 | componentWillMount: function () { 34 | this.load() 35 | }, 36 | componentDidUpdate: function (oprops, ostate) { 37 | if (ostate.repo !== this.state.repo) { 38 | this.load() 39 | } 40 | }, 41 | 42 | setRepo: function (repo) { 43 | this.setState({ 44 | repo: repo, 45 | lastLoadedPage: 0, 46 | canLoadMore: true, 47 | issues: [] 48 | }) 49 | }, 50 | 51 | // data loading 52 | load: function () { 53 | if (this.state.xhr) { 54 | this.state.xhr.abort() 55 | } 56 | if (!this.state.canLoadMore) { 57 | return console.error('Got a request to load more, but there was no more') 58 | } 59 | var url = 'https://api.github.com/repos/' + this.state.repo + '/issues?page=' + (this.state.lastLoadedPage + 1) 60 | var xhr = $.get(url, this.gotData, 'json').fail(this.failed) 61 | this.setState({error:false, loading: true, xhr: xhr}) 62 | }, 63 | gotData: function (data) { 64 | var canLoadMore = data.length === 30 65 | this.setState({ 66 | loading: false, 67 | lastLoadedPage: this.state.lastLoadedPage + 1, 68 | // XXX: this is brittle...what if they change how many they send? 69 | canLoadMore: canLoadMore, 70 | issues: this.state.issues.concat(data), 71 | error: false, 72 | xhr: null 73 | }) 74 | 75 | if (canLoadMore) { 76 | this.load() 77 | } 78 | }, 79 | failed: function (xhr, status, reason) { 80 | this.setState({error: reason || true}) 81 | }, 82 | 83 | render: function () { 84 | return d.div( 85 | {className: 'issue-viewer'}, 86 | RepoInput({ 87 | title: 'View Issues From', 88 | initialValue: this.state.repo, 89 | onChange: this.setRepo 90 | }), 91 | this.state.error ? d.h3({}, 'Error loading repo: ' + this.state.error) : false, 92 | View({ 93 | repo: this.state.repo, 94 | issues: this.state.issues, 95 | loading: this.state.loading, 96 | setRepo: this.setRepo 97 | }) 98 | ) 99 | }, 100 | }) 101 | 102 | -------------------------------------------------------------------------------- /lib/components/comment.js: -------------------------------------------------------------------------------- 1 | /** @jsx React.DOM */ 2 | var RecentTime = require('./recent-time') 3 | , utils = require('../utils') 4 | 5 | var Comment = module.exports = React.createClass({ 6 | displayName: 'Comment', 7 | getDefaultProps: function () { 8 | model: {} 9 | }, 10 | render: function () { 11 | var comment = this.props.model 12 | , commenter = comment.user 13 | return ( 14 | React.DOM.div( {className:"comment"}, 15 | React.DOM.header( {className:"comment__header"}, 16 | React.DOM.a( {className:"comment__commenter", href:commenter.html_url}, 17 | React.DOM.img( {className:"user__avatar", 18 | src:commenter.avatar_url}), 19 | React.DOM.span( {className:"user__login user__login--avatar-left"}, commenter.login) 20 | ), 21 | RecentTime( {className:"comment__time", time:comment.created_at}), 22 | React.DOM.a( {'data-id':comment.id, className:"comment__id", href:comment.html_url}) 23 | ), 24 | React.DOM.div( {className:"comment__body"}, 25 | utils.processBody(comment.body) 26 | ) 27 | ) 28 | ) 29 | } 30 | }) 31 | 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/components/issue.js: -------------------------------------------------------------------------------- 1 | /** @jsx React.DOM */ 2 | 3 | var Labels = require('./labels') 4 | , utils = require('../utils') 5 | 6 | module.exports = React.createClass({ 7 | displayName: 'Issue', 8 | onClick: function () { 9 | window.location = this.props.href; 10 | }, 11 | render: function () { 12 | var issue = this.props.model 13 | return ( 14 | React.DOM.div( {className:"issue", onClick:this.onClick}, 15 | React.DOM.div( {className:"issue__left"}, 16 | React.DOM.a( {className:"issue__header", href:this.props.href}, 17 | React.DOM.span( {className:"issue__id"}, issue.number), 18 | React.DOM.span( {className:"issue__title"}, issue.title) 19 | ), 20 | React.DOM.div( {className:"issue__body"}, 21 | utils.teaserProcessed(issue.body) 22 | ) 23 | ), 24 | React.DOM.div( {className:"issue__right"}, 25 | React.DOM.a( {className:"issue__user", href:issue.user.html_url}, 26 | React.DOM.img( {className:"user__avatar", src:issue.user.avatar_url}), 27 | React.DOM.span( {className:"user__login user__login--avatar-right"}, issue.user.login) 28 | ), 29 | Labels( {className:"issue__labels labels--vertical", labels:issue.labels}) 30 | ) 31 | ) 32 | ) 33 | /**/ 34 | } 35 | }) 36 | -------------------------------------------------------------------------------- /lib/components/issue.jsx: -------------------------------------------------------------------------------- 1 | /** @jsx React.DOM */ 2 | 3 | var Labels = require('./labels') 4 | , utils = require('../utils') 5 | 6 | /** 7 | * An Issue in the list of Issues 8 | * 9 | * Child components: 10 | * - Labels 11 | */ 12 | module.exports = React.createClass({ 13 | displayName: 'Issue', 14 | onClick: function () { 15 | window.location = this.props.href; 16 | }, 17 | render: function () { 18 | var issue = this.props.model 19 | return ( 20 |
21 |
22 | 23 | {issue.number} 24 | {issue.title} 25 | 26 |
27 | {utils.teaserProcessed(issue.body)} 28 |
29 |
30 |
31 | 32 | 33 | {issue.user.login} 34 | 35 | 36 |
37 |
38 | ) 39 | /**/ 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /lib/components/label.js: -------------------------------------------------------------------------------- 1 | 2 | var d = React.DOM 3 | 4 | /* A single label */ 5 | var Label = module.exports = React.createClass({ 6 | render: function () { 7 | var label = this.props.model 8 | return d.a({ 9 | className: 'label', 10 | href: label.url, 11 | style: { 12 | backgroundColor: '#' + label.color, 13 | } 14 | }, label.name) 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /lib/components/labels.js: -------------------------------------------------------------------------------- 1 | 2 | var d = React.DOM 3 | , Label = require('./label') 4 | 5 | /* List of labels */ 6 | var Labels = module.exports = React.createClass({ 7 | render: function () { 8 | return d.ul({ 9 | className: 'labels ' + this.props.className 10 | }, this.props.labels.map(function (label) { 11 | return d.li({className: 'labels__label'}, Label({model: label})) 12 | })) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /lib/components/pager.js: -------------------------------------------------------------------------------- 1 | 2 | var d = React.DOM 3 | 4 | /* 5 | * Manages paging! Should be relatively intelligable 6 | */ 7 | module.exports = React.createClass({ 8 | getDefaultProps: function () { 9 | return { 10 | at: 0, 11 | max: 0, 12 | step: 25, 13 | maxPages: 9, 14 | onLoadMore: null, 15 | onPage: function () { 16 | console.error('onPage must be supppied by the parent component') 17 | } 18 | } 19 | }, 20 | // TODO: these could be refactored 21 | somePages: function () { 22 | var pages = [] 23 | , npages = Math.ceil(this.props.max / this.props.step) 24 | , currPage = parseInt(this.props.at / this.props.step) 25 | , disabled 26 | , half = parseInt((this.props.maxPages-1) / 2) 27 | , left = currPage - half 28 | 29 | if (left < 0) { 30 | left = 0 31 | } else if (left > 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 | -------------------------------------------------------------------------------- /lib/components/recent-time.js: -------------------------------------------------------------------------------- 1 | 2 | var moment = require('moment') 3 | 4 | function formatRecentTime(time) { 5 | return moment(time).fromNow() 6 | } 7 | 8 | /* 9 | * Show the time as "2 hours ago" etc using moment.js 10 | */ 11 | var RecentTime = module.exports = React.createClass({ 12 | render: function () { 13 | return React.DOM.time({ 14 | title: new Date(this.props.time) + '', 15 | dateTime: this.props.time, 16 | className: this.props.className + ' recent-time' 17 | }, formatRecentTime(this.props.time)) 18 | } 19 | }) 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 |
35 |

36 | 37 | {issue.state/* TODO capitalize? */} 38 | 39 | Back 40 | {'#' + issue.number + ' ' + issue.title} 41 |

42 |
43 | 44 | 45 | 47 | {user.login} 48 | 49 | 50 |
51 |
52 |
53 | {utils.processBody(issue.body)} 54 |
55 | 56 |
57 | ) 58 | } 59 | }) 60 | -------------------------------------------------------------------------------- /lib/router.js: -------------------------------------------------------------------------------- 1 | var Backbone = require('backbone'); 2 | 3 | module.exports = Backbone.Router.extend({ 4 | routes: { 5 | ":owner/:repo": "allIssues", 6 | ":owner/:repo/:start": "allIssues", 7 | ":owner/:repo/issue/:number": "issue", 8 | "*splat": "default" 9 | } 10 | }); 11 | 12 | -------------------------------------------------------------------------------- /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@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/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)} -------------------------------------------------------------------------------- /web/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /web/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /web/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /web/bootstrap/less/badges.less: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base classes 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: @font-size-small; 12 | font-weight: @badge-font-weight; 13 | color: @badge-color; 14 | line-height: @badge-line-height; 15 | vertical-align: baseline; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: @badge-bg; 19 | border-radius: @badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | 26 | // Quick fix for badges in buttons 27 | .btn & { 28 | position: relative; 29 | top: -1px; 30 | } 31 | } 32 | 33 | // Hover state, but only for links 34 | a.badge { 35 | &:hover, 36 | &:focus { 37 | color: @badge-link-hover-color; 38 | text-decoration: none; 39 | cursor: pointer; 40 | } 41 | } 42 | 43 | // Account for counters in navs 44 | a.list-group-item.active > .badge, 45 | .nav-pills > .active > a > .badge { 46 | color: @badge-active-color; 47 | background-color: @badge-active-bg; 48 | } 49 | .nav-pills > li > a > .badge { 50 | margin-left: 3px; 51 | } 52 | -------------------------------------------------------------------------------- /web/bootstrap/less/bootstrap.less: -------------------------------------------------------------------------------- 1 | // Core variables and mixins 2 | @import "variables.less"; 3 | @import "mixins.less"; 4 | 5 | // Reset 6 | @import "normalize.less"; 7 | @import "print.less"; 8 | 9 | // Core CSS 10 | @import "scaffolding.less"; 11 | @import "type.less"; 12 | @import "code.less"; 13 | @import "grid.less"; 14 | @import "tables.less"; 15 | @import "forms.less"; 16 | @import "buttons.less"; 17 | 18 | // Components 19 | @import "component-animations.less"; 20 | @import "glyphicons.less"; 21 | @import "dropdowns.less"; 22 | @import "button-groups.less"; 23 | @import "input-groups.less"; 24 | @import "navs.less"; 25 | @import "navbar.less"; 26 | @import "breadcrumbs.less"; 27 | @import "pagination.less"; 28 | @import "pager.less"; 29 | @import "labels.less"; 30 | @import "badges.less"; 31 | @import "jumbotron.less"; 32 | @import "thumbnails.less"; 33 | @import "alerts.less"; 34 | @import "progress-bars.less"; 35 | @import "media.less"; 36 | @import "list-group.less"; 37 | @import "panels.less"; 38 | @import "wells.less"; 39 | @import "close.less"; 40 | 41 | // Components w/ JavaScript 42 | @import "modals.less"; 43 | @import "tooltip.less"; 44 | @import "popovers.less"; 45 | @import "carousel.less"; 46 | 47 | // Utility classes 48 | @import "utilities.less"; 49 | @import "responsive-utilities.less"; 50 | -------------------------------------------------------------------------------- /web/bootstrap/less/breadcrumbs.less: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: 8px 15px; 8 | margin-bottom: @line-height-computed; 9 | list-style: none; 10 | background-color: @breadcrumb-bg; 11 | border-radius: @border-radius-base; 12 | > li { 13 | display: inline-block; 14 | + li:before { 15 | content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space 16 | padding: 0 5px; 17 | color: @breadcrumb-color; 18 | } 19 | } 20 | > .active { 21 | color: @breadcrumb-active-color; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/close.less: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: (@font-size-base * 1.5); 9 | font-weight: @close-font-weight; 10 | line-height: 1; 11 | color: @close-color; 12 | text-shadow: @close-text-shadow; 13 | .opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: @close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | .opacity(.5); 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | button& { 27 | padding: 0; 28 | cursor: pointer; 29 | background: transparent; 30 | border: 0; 31 | -webkit-appearance: none; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/bootstrap/less/code.less: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and block) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: @font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 4px; 17 | font-size: 90%; 18 | color: @code-color; 19 | background-color: @code-bg; 20 | white-space: nowrap; 21 | border-radius: @border-radius-base; 22 | } 23 | 24 | // Blocks of code 25 | pre { 26 | display: block; 27 | padding: ((@line-height-computed - 1) / 2); 28 | margin: 0 0 (@line-height-computed / 2); 29 | font-size: (@font-size-base - 1); // 14px to 13px 30 | line-height: @line-height-base; 31 | word-break: break-all; 32 | word-wrap: break-word; 33 | color: @pre-color; 34 | background-color: @pre-bg; 35 | border: 1px solid @pre-border-color; 36 | border-radius: @border-radius-base; 37 | 38 | // Account for some code outputs that place code tags in pre tags 39 | code { 40 | padding: 0; 41 | font-size: inherit; 42 | color: inherit; 43 | white-space: pre-wrap; 44 | background-color: transparent; 45 | border-radius: 0; 46 | } 47 | } 48 | 49 | // Enable scrollable blocks of code 50 | .pre-scrollable { 51 | max-height: @pre-scrollable-max-height; 52 | overflow-y: scroll; 53 | } 54 | -------------------------------------------------------------------------------- /web/bootstrap/less/component-animations.less: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity: 0; 12 | .transition(opacity .15s linear); 13 | &.in { 14 | opacity: 1; 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | &.in { 21 | display: block; 22 | } 23 | } 24 | .collapsing { 25 | position: relative; 26 | height: 0; 27 | overflow: hidden; 28 | .transition(height .35s ease); 29 | } 30 | -------------------------------------------------------------------------------- /web/bootstrap/less/dropdowns.less: -------------------------------------------------------------------------------- 1 | // 2 | // Dropdown menus 3 | // -------------------------------------------------- 4 | 5 | 6 | // Dropdown arrow/caret 7 | .caret { 8 | display: inline-block; 9 | width: 0; 10 | height: 0; 11 | margin-left: 2px; 12 | vertical-align: middle; 13 | border-top: @caret-width-base solid; 14 | border-right: @caret-width-base solid transparent; 15 | border-left: @caret-width-base solid transparent; 16 | } 17 | 18 | // The dropdown wrapper (div) 19 | .dropdown { 20 | position: relative; 21 | } 22 | 23 | // Prevent the focus on the dropdown toggle when closing dropdowns 24 | .dropdown-toggle:focus { 25 | outline: 0; 26 | } 27 | 28 | // The dropdown menu (ul) 29 | .dropdown-menu { 30 | position: absolute; 31 | top: 100%; 32 | left: 0; 33 | z-index: @zindex-dropdown; 34 | display: none; // none by default, but block on "open" of the menu 35 | float: left; 36 | min-width: 160px; 37 | padding: 5px 0; 38 | margin: 2px 0 0; // override default ul 39 | list-style: none; 40 | font-size: @font-size-base; 41 | background-color: @dropdown-bg; 42 | border: 1px solid @dropdown-fallback-border; // IE8 fallback 43 | border: 1px solid @dropdown-border; 44 | border-radius: @border-radius-base; 45 | .box-shadow(0 6px 12px rgba(0,0,0,.175)); 46 | background-clip: padding-box; 47 | 48 | // Aligns the dropdown menu to right 49 | &.pull-right { 50 | right: 0; 51 | left: auto; 52 | } 53 | 54 | // Dividers (basically an hr) within the dropdown 55 | .divider { 56 | .nav-divider(@dropdown-divider-bg); 57 | } 58 | 59 | // Links within the dropdown menu 60 | > 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/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/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 | -------------------------------------------------------------------------------- /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/jumbotron.less: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding: @jumbotron-padding; 8 | margin-bottom: @jumbotron-padding; 9 | font-size: @jumbotron-font-size; 10 | font-weight: 200; 11 | line-height: (@line-height-base * 1.5); 12 | color: @jumbotron-color; 13 | background-color: @jumbotron-bg; 14 | 15 | h1, 16 | .h1 { 17 | line-height: 1; 18 | color: @jumbotron-heading-color; 19 | } 20 | p { 21 | line-height: 1.4; 22 | } 23 | 24 | .container & { 25 | border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container 26 | } 27 | 28 | .container { 29 | max-width: 100%; 30 | } 31 | 32 | @media screen and (min-width: @screen-sm-min) { 33 | padding-top: (@jumbotron-padding * 1.6); 34 | padding-bottom: (@jumbotron-padding * 1.6); 35 | 36 | .container & { 37 | padding-left: (@jumbotron-padding * 2); 38 | padding-right: (@jumbotron-padding * 2); 39 | } 40 | 41 | h1, 42 | .h1 { 43 | font-size: (@font-size-base * 4.5); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /web/bootstrap/less/labels.less: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: @label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // Add hover effects, but only for links 18 | &[href] { 19 | &:hover, 20 | &:focus { 21 | color: @label-link-hover-color; 22 | text-decoration: none; 23 | cursor: pointer; 24 | } 25 | } 26 | 27 | // Empty labels collapse automatically (not available in IE8) 28 | &:empty { 29 | display: none; 30 | } 31 | 32 | // Quick fix for labels in buttons 33 | .btn & { 34 | position: relative; 35 | top: -1px; 36 | } 37 | } 38 | 39 | // Colors 40 | // Contextual variations (linked labels get darker on :hover) 41 | 42 | .label-default { 43 | .label-variant(@label-default-bg); 44 | } 45 | 46 | .label-primary { 47 | .label-variant(@label-primary-bg); 48 | } 49 | 50 | .label-success { 51 | .label-variant(@label-success-bg); 52 | } 53 | 54 | .label-info { 55 | .label-variant(@label-info-bg); 56 | } 57 | 58 | .label-warning { 59 | .label-variant(@label-warning-bg); 60 | } 61 | 62 | .label-danger { 63 | .label-variant(@label-danger-bg); 64 | } 65 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /web/bootstrap/less/media.less: -------------------------------------------------------------------------------- 1 | // Media objects 2 | // Source: http://stubbornella.org/content/?p=497 3 | // -------------------------------------------------- 4 | 5 | 6 | // Common styles 7 | // ------------------------- 8 | 9 | // Clear the floats 10 | .media, 11 | .media-body { 12 | overflow: hidden; 13 | zoom: 1; 14 | } 15 | 16 | // Proper spacing between instances of .media 17 | .media, 18 | .media .media { 19 | margin-top: 15px; 20 | } 21 | .media:first-child { 22 | margin-top: 0; 23 | } 24 | 25 | // For images and videos, set to block 26 | .media-object { 27 | display: block; 28 | } 29 | 30 | // Reset margins on headings for tighter default spacing 31 | .media-heading { 32 | margin: 0 0 5px; 33 | } 34 | 35 | 36 | // Media image alignment 37 | // ------------------------- 38 | 39 | .media { 40 | > .pull-left { 41 | margin-right: 10px; 42 | } 43 | > .pull-right { 44 | margin-left: 10px; 45 | } 46 | } 47 | 48 | 49 | // Media list variation 50 | // ------------------------- 51 | 52 | // Undo default ul/ol styles 53 | .media-list { 54 | padding-left: 0; 55 | list-style: none; 56 | } 57 | -------------------------------------------------------------------------------- /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/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/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/pager.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | padding-left: 0; 8 | margin: @line-height-computed 0; 9 | list-style: none; 10 | text-align: center; 11 | .clearfix(); 12 | li { 13 | display: inline; 14 | > a, 15 | > span { 16 | display: inline-block; 17 | padding: 5px 14px; 18 | background-color: @pagination-bg; 19 | border: 1px solid @pagination-border; 20 | border-radius: @pager-border-radius; 21 | } 22 | 23 | > a:hover, 24 | > a:focus { 25 | text-decoration: none; 26 | background-color: @pagination-hover-bg; 27 | } 28 | } 29 | 30 | .next { 31 | > a, 32 | > span { 33 | float: right; 34 | } 35 | } 36 | 37 | .previous { 38 | > a, 39 | > span { 40 | float: left; 41 | } 42 | } 43 | 44 | .disabled { 45 | > a, 46 | > a:hover, 47 | > a:focus, 48 | > span { 49 | color: @pager-disabled-color; 50 | background-color: @pagination-bg; 51 | cursor: not-allowed; 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/thumbnails.less: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | display: block; 9 | padding: @thumbnail-padding; 10 | margin-bottom: @line-height-computed; 11 | line-height: @line-height-base; 12 | background-color: @thumbnail-bg; 13 | border: 1px solid @thumbnail-border; 14 | border-radius: @thumbnail-border-radius; 15 | .transition(all .2s ease-in-out); 16 | 17 | > img, 18 | a > img { 19 | .img-responsive(); 20 | margin-left: auto; 21 | margin-right: auto; 22 | } 23 | 24 | // Add a hover state for linked versions only 25 | a&:hover, 26 | a&:focus, 27 | a&.active { 28 | border-color: @link-color; 29 | } 30 | 31 | // Image captions 32 | .caption { 33 | padding: @thumbnail-caption-padding; 34 | color: @thumbnail-caption-color; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /web/bootstrap/less/tooltip.less: -------------------------------------------------------------------------------- 1 | // 2 | // Tooltips 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .tooltip { 8 | position: absolute; 9 | z-index: @zindex-tooltip; 10 | display: block; 11 | visibility: visible; 12 | font-size: @font-size-small; 13 | line-height: 1.4; 14 | .opacity(0); 15 | 16 | &.in { .opacity(.9); } 17 | &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; } 18 | &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; } 19 | &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; } 20 | &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; } 21 | } 22 | 23 | // Wrapper for the tooltip content 24 | .tooltip-inner { 25 | max-width: @tooltip-max-width; 26 | padding: 3px 8px; 27 | color: @tooltip-color; 28 | text-align: center; 29 | text-decoration: none; 30 | background-color: @tooltip-bg; 31 | border-radius: @border-radius-base; 32 | } 33 | 34 | // Arrows 35 | .tooltip-arrow { 36 | position: absolute; 37 | width: 0; 38 | height: 0; 39 | border-color: transparent; 40 | border-style: solid; 41 | } 42 | .tooltip { 43 | &.top .tooltip-arrow { 44 | bottom: 0; 45 | left: 50%; 46 | margin-left: -@tooltip-arrow-width; 47 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0; 48 | border-top-color: @tooltip-arrow-color; 49 | } 50 | &.top-left .tooltip-arrow { 51 | bottom: 0; 52 | left: @tooltip-arrow-width; 53 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0; 54 | border-top-color: @tooltip-arrow-color; 55 | } 56 | &.top-right .tooltip-arrow { 57 | bottom: 0; 58 | right: @tooltip-arrow-width; 59 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0; 60 | border-top-color: @tooltip-arrow-color; 61 | } 62 | &.right .tooltip-arrow { 63 | top: 50%; 64 | left: 0; 65 | margin-top: -@tooltip-arrow-width; 66 | border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0; 67 | border-right-color: @tooltip-arrow-color; 68 | } 69 | &.left .tooltip-arrow { 70 | top: 50%; 71 | right: 0; 72 | margin-top: -@tooltip-arrow-width; 73 | border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width; 74 | border-left-color: @tooltip-arrow-color; 75 | } 76 | &.bottom .tooltip-arrow { 77 | top: 0; 78 | left: 50%; 79 | margin-left: -@tooltip-arrow-width; 80 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; 81 | border-bottom-color: @tooltip-arrow-color; 82 | } 83 | &.bottom-left .tooltip-arrow { 84 | top: 0; 85 | left: @tooltip-arrow-width; 86 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; 87 | border-bottom-color: @tooltip-arrow-color; 88 | } 89 | &.bottom-right .tooltip-arrow { 90 | top: 0; 91 | right: @tooltip-arrow-width; 92 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; 93 | border-bottom-color: @tooltip-arrow-color; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /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/utilities.less: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Floats 7 | // ------------------------- 8 | 9 | .clearfix { 10 | .clearfix(); 11 | } 12 | .center-block { 13 | .center-block(); 14 | } 15 | .pull-right { 16 | float: right !important; 17 | } 18 | .pull-left { 19 | float: left !important; 20 | } 21 | 22 | 23 | // Toggling content 24 | // ------------------------- 25 | 26 | // Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 27 | .hide { 28 | display: none !important; 29 | } 30 | .show { 31 | display: block !important; 32 | } 33 | .invisible { 34 | visibility: hidden; 35 | } 36 | .text-hide { 37 | .text-hide(); 38 | } 39 | 40 | 41 | // Hide from screenreaders and browsers 42 | // 43 | // Credit: HTML5 Boilerplate 44 | 45 | .hidden { 46 | display: none !important; 47 | visibility: hidden !important; 48 | } 49 | 50 | 51 | // For Affix plugin 52 | // ------------------------- 53 | 54 | .affix { 55 | position: fixed; 56 | } 57 | -------------------------------------------------------------------------------- /web/bootstrap/less/wells.less: -------------------------------------------------------------------------------- 1 | // 2 | // Wells 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .well { 8 | min-height: 20px; 9 | padding: 19px; 10 | margin-bottom: 20px; 11 | background-color: @well-bg; 12 | border: 1px solid darken(@well-bg, 7%); 13 | border-radius: @border-radius-base; 14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); 15 | blockquote { 16 | border-color: #ddd; 17 | border-color: rgba(0,0,0,.15); 18 | } 19 | } 20 | 21 | // Sizes 22 | .well-lg { 23 | padding: 24px; 24 | border-radius: @border-radius-large; 25 | } 26 | .well-sm { 27 | padding: 9px; 28 | border-radius: @border-radius-small; 29 | } 30 | -------------------------------------------------------------------------------- /web/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /web/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /web/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /web/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredly/github-issues-viewer/4769bfe5f812e4e1b3f1f9bf81b2b3e782d54be3/web/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /web/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /web/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /web/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /web/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /web/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /web/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /web/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /web/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 9 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 10 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /web/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /web/font-awesome/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /web/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /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/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /web/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /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/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Github Issues 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Fork me on GitHub 14 |
      15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /web/setup.js: -------------------------------------------------------------------------------- 1 | 2 | twitterAudition(document.getElementById('main')) 3 | 4 | --------------------------------------------------------------------------------