Compare commits
32 Commits
wip-produc
...
wip-front-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
053570e55d | ||
![]() |
ab98261889 | ||
![]() |
97bf76f9ba | ||
![]() |
f876961e1c | ||
1bf90a6f6e | |||
aa40e8903b | |||
![]() |
0f5c409c04 | ||
![]() |
bd2c8893dd | ||
![]() |
73730a81c8 | ||
![]() |
a9a267df2a | ||
![]() |
09ae6712bb | ||
![]() |
78702cc5e0 | ||
![]() |
515ef5e1b5 | ||
![]() |
19f9734349 | ||
![]() |
bb3adc37d3 | ||
![]() |
0e11c2b923 | ||
![]() |
929edb9f90 | ||
![]() |
131bb26e9e | ||
![]() |
9023e32c47 | ||
![]() |
c34d2c3a41 | ||
![]() |
27ea3a6c1b | ||
![]() |
b91aeadb45 | ||
![]() |
a4bbff1ad0 | ||
![]() |
ecd09a3f02 | ||
![]() |
dbdd32bf0d | ||
![]() |
94b6ee3020 | ||
![]() |
1f9b0eda42 | ||
![]() |
97c74f3267 | ||
![]() |
1342ed2601 | ||
![]() |
3dcf8ba93a | ||
![]() |
5b14d78037 | ||
![]() |
c8f6ba207b |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,11 +3,9 @@
|
||||
.coverage
|
||||
*.pyc
|
||||
__pycache__
|
||||
*.js.map
|
||||
*.css.map
|
||||
|
||||
/cloud/templates/
|
||||
/cloud/static/assets/
|
||||
/cloud/static/assets/css/
|
||||
node_modules/
|
||||
|
||||
/config_local.py
|
||||
|
@@ -41,7 +41,6 @@ class CloudExtension(PillarExtension):
|
||||
'EXTERNAL_SUBSCRIPTIONS_MANAGEMENT_SERVER': 'https://store.blender.org/api/',
|
||||
'EXTERNAL_SUBSCRIPTIONS_TIMEOUT_SECS': 10,
|
||||
'BLENDER_ID_WEBHOOK_USER_CHANGED_SECRET': 'oos9wah1Zoa0Yau6ahThohleiChephoi',
|
||||
'NODE_TAGS': ['animation', 'modelling', 'rigging'],
|
||||
}
|
||||
|
||||
def eve_settings(self):
|
||||
|
@@ -391,11 +391,6 @@ def privacy():
|
||||
return render_template('privacy.html')
|
||||
|
||||
|
||||
@blueprint.route('/production')
|
||||
def production():
|
||||
return render_template('production.html')
|
||||
|
||||
|
||||
@blueprint.route('/emails/welcome.send')
|
||||
@login_required
|
||||
def emails_welcome_send():
|
||||
|
55
cloud/static/assets/js/layout.min.js
vendored
Normal file
55
cloud/static/assets/js/layout.min.js
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Variables
|
||||
================================================================== */
|
||||
var searchToggleStatus = false
|
||||
|
||||
/* Selectors
|
||||
================================================================== */
|
||||
var searchButton = document.querySelector('#searchButton'),
|
||||
searchCloseButton = document.querySelector('#searchCloseButton'),
|
||||
searchNav = document.querySelector('#searchNav'),
|
||||
searchNavInput = document.querySelector('#searchNav input'),
|
||||
navbarNav = document.querySelector('#navbarNav'),
|
||||
profileMenu = document.querySelector('#navbarNav .navbar-nav').lastElementChild
|
||||
|
||||
/* Interactions
|
||||
================================================================== */
|
||||
searchButton.addEventListener('click', showSearch)
|
||||
searchCloseButton.addEventListener('click', closeSearch)
|
||||
|
||||
|
||||
/* Functions
|
||||
================================================================== */
|
||||
function showSearch() {
|
||||
searchToggleStatus = true
|
||||
searchNav.classList.remove('hidden')
|
||||
searchNavInput.focus()
|
||||
navbarNav.classList.add('hidden')
|
||||
profileMenu.classList.add('visible')
|
||||
// $('#search-overlay').addClass('visible')
|
||||
// if (searchToggleStatus == true) {
|
||||
// // $(document.body).click(function() {
|
||||
// // console.log('detect click outside');
|
||||
// // searchToggleStatus = false
|
||||
// // })
|
||||
// console.log(searchToggleStatus);
|
||||
// console.log('detect click outside');
|
||||
// searchToggleStatus = false
|
||||
// console.log(searchToggleStatus);
|
||||
// } else {
|
||||
// console.log(searchToggleStatus);
|
||||
// console.log('not detecting clicks');
|
||||
|
||||
// }
|
||||
// $(document.body).click(function () {
|
||||
// console.log('detected click outside');
|
||||
// searchToggleStatus == false
|
||||
// }) else {
|
||||
// }
|
||||
}
|
||||
|
||||
function closeSearch() {
|
||||
searchNav.classList.add('hidden')
|
||||
navbarNav.classList.remove('hidden')
|
||||
profileMenu.classList.remove('visible')
|
||||
// $('#search-overlay').removeClass('active')
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
"""Routes for fetching tagged assets."""
|
||||
|
||||
|
@@ -1,16 +0,0 @@
|
||||
import logging
|
||||
import datetime
|
||||
import functools
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
|
||||
blueprint = Blueprint('cloud.tagged', __name__, url_prefix='/tagged')
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/')
|
||||
def index():
|
||||
"""Return all tagged assets as JSON, grouped by tag."""
|
||||
|
||||
|
@@ -7,7 +7,8 @@ import json
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from flask import Blueprint, request
|
||||
from flask_login import request
|
||||
from flask import Blueprint
|
||||
import werkzeug.exceptions as wz_exceptions
|
||||
|
||||
from pillar import current_app
|
||||
|
@@ -2,7 +2,7 @@ import os
|
||||
|
||||
DEBUG = True
|
||||
|
||||
BLENDER_ID_ENDPOINT = 'http://id.local:8000/'
|
||||
BLENDER_ID_ENDPOINT = 'http://id.local:8000'
|
||||
|
||||
SERVER_NAME = 'cloud.local:5001'
|
||||
SCHEME = 'http'
|
||||
|
@@ -1,10 +1,6 @@
|
||||
FROM ubuntu:18.04
|
||||
LABEL maintainer="Sybren A. Stüvel <sybren@blender.studio>"
|
||||
FROM ubuntu:17.10
|
||||
MAINTAINER Francesco Siddi <francesco@blender.org>
|
||||
|
||||
RUN set -ex; \
|
||||
apt-get update; \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install \
|
||||
-qyy -o APT::Install-Recommends=false -o APT::Install-Suggests=false \
|
||||
tzdata openssl ca-certificates locales; \
|
||||
locale-gen en_US.UTF-8 en_GB.UTF-8 nl_NL.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
RUN apt-get update && apt-get install -qyy \
|
||||
-o APT::Install-Recommends=false -o APT::Install-Suggests=false \
|
||||
openssl ca-certificates
|
||||
|
1
docker/2_buildpy/Python-3.6.4.tar.xz.md5
Normal file
1
docker/2_buildpy/Python-3.6.4.tar.xz.md5
Normal file
@@ -0,0 +1 @@
|
||||
1325134dd525b4a2c3272a1a0214dd54 Python-3.6.4.tar.xz
|
@@ -1 +0,0 @@
|
||||
c3f30a0aff425dda77d19e02f420d6ba Python-3.6.6.tar.xz
|
@@ -34,9 +34,6 @@ make -j8 install
|
||||
# Make sure we can run Python
|
||||
ldconfig
|
||||
|
||||
# Upgrade pip
|
||||
/opt/python/bin/python3 -m pip install -U pip
|
||||
|
||||
# Build mod-wsgi-py3 for Python 3.6
|
||||
cd /dpkg/mod-wsgi-*
|
||||
./configure --with-python=/opt/python/bin/python3
|
||||
|
@@ -1,9 +1,9 @@
|
||||
FROM pillar_base
|
||||
LABEL maintainer="Sybren A. Stüvel <sybren@blender.studio>"
|
||||
LABEL maintainer Sybren A. Stüvel <sybren@blender.studio>
|
||||
|
||||
RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -qy \
|
||||
apt-get install -qy \
|
||||
build-essential \
|
||||
apache2-dev \
|
||||
checkinstall \
|
||||
@@ -11,13 +11,13 @@ RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list && \
|
||||
|
||||
RUN apt-get build-dep -y python3.6
|
||||
|
||||
ADD Python-3.6.6.tar.xz.md5 /Python-3.6.6.tar.xz.md5
|
||||
ADD Python-3.6.4.tar.xz.md5 /Python-3.6.4.tar.xz.md5
|
||||
|
||||
# Install Python sources
|
||||
RUN curl -O https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tar.xz && \
|
||||
md5sum -c Python-3.6.6.tar.xz.md5 && \
|
||||
tar xf Python-3.6.6.tar.xz && \
|
||||
rm -v Python-3.6.6.tar.xz
|
||||
RUN curl -O https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tar.xz && \
|
||||
md5sum -c Python-3.6.4.tar.xz.md5 && \
|
||||
tar xf Python-3.6.4.tar.xz && \
|
||||
rm -v Python-3.6.4.tar.xz
|
||||
|
||||
# Install mod-wsgi sources
|
||||
RUN mkdir -p /dpkg && cd /dpkg && apt-get source libapache2-mod-wsgi-py3
|
||||
@@ -32,4 +32,4 @@ RUN echo /opt/python/lib > /etc/ld.so.conf.d/python.conf
|
||||
RUN ldconfig
|
||||
ENV PATH=/opt/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
ENV PYTHONSOURCE=/Python-3.6.6
|
||||
ENV PYTHONSOURCE=/Python-3.6.4
|
||||
|
@@ -1,5 +1,5 @@
|
||||
FROM pillar_base
|
||||
LABEL maintainer="Sybren A. Stüvel <sybren@blender.studio>"
|
||||
LABEL maintainer Sybren A. Stüvel <sybren@blender.studio>
|
||||
|
||||
ADD python /opt/python
|
||||
|
||||
@@ -10,4 +10,5 @@ RUN echo Python is installed in /opt/python/ > README.python
|
||||
ENV PATH=/opt/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
RUN cd /opt/python/bin && \
|
||||
ln -s python3 python
|
||||
ln -s python3 python && \
|
||||
ln -s pip3 pip
|
||||
|
@@ -1,9 +1,7 @@
|
||||
FROM armadillica/pillar_py:3.6
|
||||
LABEL maintainer="Sybren A. Stüvel <sybren@blender.studio>"
|
||||
LABEL maintainer Sybren A. Stüvel <sybren@blender.studio>
|
||||
|
||||
RUN set -ex; \
|
||||
apt-get update; \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -qy \
|
||||
RUN apt-get update && apt-get install -qy \
|
||||
git \
|
||||
build-essential \
|
||||
checkinstall \
|
||||
|
@@ -1,9 +1,7 @@
|
||||
FROM armadillica/pillar_py:3.6
|
||||
LABEL maintainer="Sybren A. Stüvel <sybren@blender.studio>"
|
||||
LABEL maintainer Sybren A. Stüvel <sybren@blender.studio>
|
||||
|
||||
RUN set -ex; \
|
||||
apt-get update; \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -qy \
|
||||
RUN apt-get update && apt-get install -qyy \
|
||||
-o APT::Install-Recommends=false -o APT::Install-Suggests=false \
|
||||
git \
|
||||
apache2 \
|
||||
@@ -12,8 +10,8 @@ RUN set -ex; \
|
||||
libtiff5 \
|
||||
ffmpeg \
|
||||
rsyslog logrotate \
|
||||
nano vim-tiny curl; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
nano vim-tiny curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN ln -s /usr/bin/vim.tiny /usr/bin/vim
|
||||
|
||||
|
@@ -40,7 +40,7 @@
|
||||
# Redirects for blender-cloud projects
|
||||
RewriteRule "^/p/blender-cloud/?$" "/blog" [R=301,L]
|
||||
RewriteRule "^/agent327/?$" "/p/agent-327" [R=301,L]
|
||||
RewriteRule "^/caminandes/?$" "/p/caminandes-3" [R=301,L]
|
||||
RewriteRule "^/caminandes/?$" "/p/caminandes" [R=301,L]
|
||||
RewriteRule "^/cf2/?$" "/p/creature-factory-2" [R=301,L]
|
||||
RewriteRule "^/characters/?$" "/p/characters" [R=301,L]
|
||||
RewriteRule "^/gallery/?$" "/p/gallery" [R=301,L]
|
||||
|
@@ -28,7 +28,7 @@ CACHE_REDIS_URL = 'redis://redis:6379'
|
||||
|
||||
PILLAR_SERVER_ENDPOINT = 'https://cloud.blender.org/api/'
|
||||
|
||||
BLENDER_ID_ENDPOINT = 'https://www.blender.org/id/'
|
||||
BLENDER_ID_ENDPOINT = 'https://www.blender.org/id'
|
||||
|
||||
GCLOUD_APP_CREDENTIALS = '/data/config/google_app.json'
|
||||
GCLOUD_PROJECT = 'blender-cloud'
|
||||
@@ -83,22 +83,21 @@ LOGGING = {
|
||||
}
|
||||
}
|
||||
|
||||
# Latest version of the add-on.
|
||||
BLENDER_CLOUD_ADDON_VERSION = '1.9.0'
|
||||
|
||||
REDIRECTS = {
|
||||
# For old links, refer to the services page (hopefully it refreshes then)
|
||||
'downloads/blender_cloud-latest-bundle.zip': 'https://cloud.blender.org/services#blender-addon',
|
||||
|
||||
# Latest Blender Cloud add-on.
|
||||
# Latest Blender Cloud add-on; remember to update BLENDER_CLOUD_ADDON_VERSION.
|
||||
'downloads/blender_cloud-latest-addon.zip':
|
||||
f'https://storage.googleapis.com/institute-storage/addons/'
|
||||
f'blender_cloud-{BLENDER_CLOUD_ADDON_VERSION}.addon.zip',
|
||||
'https://storage.googleapis.com/institute-storage/addons/blender_cloud-1.8.0.addon.zip',
|
||||
|
||||
# Redirect old Grafista endpoint to /stats
|
||||
'/stats/': '/stats',
|
||||
}
|
||||
|
||||
# Latest version of the add-on; remember to update REDIRECTS.
|
||||
BLENDER_CLOUD_ADDON_VERSION = '1.8.0'
|
||||
|
||||
UTM_LINKS = {
|
||||
'cartoon_brew': {
|
||||
'image': 'https://imgur.com/13nQTi3.png',
|
||||
|
@@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f /installed ]; then
|
||||
return
|
||||
|
141
gulpfile.js
141
gulpfile.js
@@ -1,160 +1,113 @@
|
||||
var argv = require('minimist')(process.argv.slice(2));
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var cache = require('gulp-cached');
|
||||
var chmod = require('gulp-chmod');
|
||||
var concat = require('gulp-concat');
|
||||
var git = require('gulp-git');
|
||||
var gulp = require('gulp');
|
||||
var gulpif = require('gulp-if');
|
||||
var pug = require('gulp-pug');
|
||||
var livereload = require('gulp-livereload');
|
||||
var plumber = require('gulp-plumber');
|
||||
var rename = require('gulp-rename');
|
||||
var sass = require('gulp-sass');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
var uglify = require('gulp-uglify-es').default;
|
||||
let argv = require('minimist')(process.argv.slice(2));
|
||||
let autoprefixer = require('gulp-autoprefixer');
|
||||
let cache = require('gulp-cached');
|
||||
let concat = require('gulp-concat');
|
||||
let gulp = require('gulp');
|
||||
let gulpif = require('gulp-if');
|
||||
let pug = require('gulp-pug');
|
||||
let livereload = require('gulp-livereload');
|
||||
let plumber = require('gulp-plumber');
|
||||
let rename = require('gulp-rename');
|
||||
let sass = require('gulp-sass');
|
||||
let sourcemaps = require('gulp-sourcemaps');
|
||||
let uglify = require('gulp-uglify');
|
||||
|
||||
var enabled = {
|
||||
uglify: argv.production,
|
||||
maps: !argv.production,
|
||||
let enabled = {
|
||||
failCheck: !argv.production,
|
||||
maps: argv.production,
|
||||
prettyPug: !argv.production,
|
||||
cachify: !argv.production,
|
||||
cleanup: argv.production,
|
||||
chmod: argv.production,
|
||||
uglify: argv.production
|
||||
};
|
||||
|
||||
var destination = {
|
||||
let destination = {
|
||||
css: 'cloud/static/assets/css',
|
||||
pug: 'cloud/templates',
|
||||
js: 'cloud/static/assets/js',
|
||||
}
|
||||
|
||||
var source = {
|
||||
pillar: '../pillar/',
|
||||
bootstrap: 'node_modules/bootstrap/',
|
||||
popper: 'node_modules/popper.js/'
|
||||
}
|
||||
|
||||
js: 'cloud/static/assets/js'
|
||||
};
|
||||
|
||||
/* CSS */
|
||||
gulp.task('styles', function() {
|
||||
gulp.src('src/styles/**/*.sass')
|
||||
gulp.task('styles', function(done) {
|
||||
gulp
|
||||
.src('src/styles/**/*.sass')
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.init()))
|
||||
.pipe(sass({
|
||||
outputStyle: 'compressed'}
|
||||
))
|
||||
.pipe(sass({outputStyle: 'compressed'}))
|
||||
.pipe(autoprefixer("last 3 versions"))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
|
||||
.pipe(gulp.dest(destination.css))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
/* Templates - Pug */
|
||||
gulp.task('templates', function() {
|
||||
gulp.task('templates', function(done) {
|
||||
gulp.src('src/templates/**/*.pug')
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.cachify, cache('templating')))
|
||||
.pipe(cache('templating'))
|
||||
.pipe(pug({
|
||||
pretty: enabled.prettyPug
|
||||
}))
|
||||
.pipe(gulp.dest(destination.pug))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
// TODO(venomgfx): please check why 'gulp watch' doesn't pick up on .txt changes.
|
||||
gulp.src('src/templates/**/*.txt')
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.cachify, cache('templating')))
|
||||
.pipe(gulp.dest(destination.pug))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
/* Individual Uglified Scripts */
|
||||
gulp.task('scripts', function() {
|
||||
/* Individually uglified scripts */
|
||||
gulp.task('scripts', function(done) {
|
||||
gulp.src('src/scripts/*.js')
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.cachify, cache('scripting')))
|
||||
.pipe(cache('scripting'))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.init()))
|
||||
.pipe(gulpif(enabled.uglify, uglify()))
|
||||
.pipe(rename({suffix: '.min'}))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
|
||||
.pipe(gulpif(enabled.chmod, chmod(644)))
|
||||
.pipe(gulp.dest(destination.js))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
/* Collection of scripts in src/scripts/tutti/ to merge into tutti.min.js */
|
||||
/* Since it's always loaded, it's only for functions that we want site-wide */
|
||||
gulp.task('scripts_concat_tutti', function() {
|
||||
gulp.task('scripts_tutti', function(done) {
|
||||
gulp.src('src/scripts/tutti/**/*.js')
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.init()))
|
||||
.pipe(concat("tutti.min.js"))
|
||||
.pipe(gulpif(enabled.uglify, uglify()))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
|
||||
.pipe(gulpif(enabled.chmod, chmod(644)))
|
||||
.pipe(gulp.dest(destination.js))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
// Combine all needed Bootstrap JavaScript into a single file.
|
||||
gulp.task('scripts_concat_bootstrap', function() {
|
||||
|
||||
toUglify = [
|
||||
source.popper + 'dist/umd/popper.min.js',
|
||||
source.bootstrap + 'js/dist/index.js',
|
||||
source.bootstrap + 'js/dist/util.js',
|
||||
source.bootstrap + 'js/dist/tooltip.js',
|
||||
source.bootstrap + 'js/dist/dropdown.js',
|
||||
/* Simply move these vendor scripts from node_modules */
|
||||
gulp.task('scripts_vendor', function(done) {
|
||||
let toMove = [
|
||||
'node_modules/photoswipe/dist/photoswipe.min.js'
|
||||
];
|
||||
|
||||
gulp.src(toUglify)
|
||||
.pipe(gulpif(enabled.failCheck, plumber()))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.init()))
|
||||
.pipe(concat("bootstrap.min.js"))
|
||||
.pipe(gulpif(enabled.uglify, uglify()))
|
||||
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
|
||||
.pipe(gulpif(enabled.chmod, chmod(644)))
|
||||
.pipe(gulp.dest(destination.js))
|
||||
.pipe(gulpif(argv.livereload, livereload()));
|
||||
gulp.src(toMove)
|
||||
.pipe(gulp.dest(destination.js));
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
// While developing, run 'gulp watch'
|
||||
gulp.task('watch',function() {
|
||||
// Only listen for live reloads if ran with --livereload
|
||||
gulp.task('watch', function(done) {
|
||||
// Only reload the pages if we run with --livereload
|
||||
if (argv.livereload){
|
||||
livereload.listen();
|
||||
}
|
||||
|
||||
gulp.watch('src/styles/**/*.sass',['styles']);
|
||||
gulp.watch(source.pillar + 'src/styles/**/*.sass',['styles']);
|
||||
|
||||
gulp.watch('src/templates/**/*.pug',['templates']);
|
||||
gulp.watch('src/scripts/*.js',['scripts']);
|
||||
gulp.watch('src/scripts/tutti/**/*.js',['scripts_concat_tutti']);
|
||||
});
|
||||
|
||||
// Erases all generated files in output directories.
|
||||
gulp.task('cleanup', function() {
|
||||
var paths = [];
|
||||
for (attr in destination) {
|
||||
paths.push(destination[attr]);
|
||||
}
|
||||
|
||||
git.clean({ args: '-f -X ' + paths.join(' ') }, function (err) {
|
||||
if(err) throw err;
|
||||
});
|
||||
|
||||
gulp.watch('src/styles/**/*.sass', gulp.series('styles'));
|
||||
gulp.watch('src/templates/**/*.pug', gulp.series('templates'));
|
||||
gulp.watch('src/scripts/*.js', gulp.series('scripts'));
|
||||
gulp.watch('src/scripts/tutti/*.js', gulp.series('scripts_tutti'));
|
||||
});
|
||||
|
||||
|
||||
// Run 'gulp' to build everything at once
|
||||
var tasks = [];
|
||||
if (enabled.cleanup) tasks.push('cleanup');
|
||||
|
||||
gulp.task('default', tasks.concat(['styles', 'templates', 'scripts', 'scripts_concat_tutti', 'scripts_concat_bootstrap']));
|
||||
gulp.task('default', gulp.series('styles', 'templates', 'scripts', 'scripts_tutti', 'scripts_vendor'));
|
||||
|
4798
package-lock.json
generated
4798
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@@ -7,25 +7,26 @@
|
||||
"url": "git://git.blender.org/blender-cloud.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "~3.9.1",
|
||||
"gulp-autoprefixer": "~6.0.0",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-autoprefixer": "~5.0.0",
|
||||
"gulp-cached": "~1.1.1",
|
||||
"gulp-chmod": "~2.0.0",
|
||||
"gulp-concat": "~2.6.1",
|
||||
"gulp-git": "~2.7.0",
|
||||
"gulp-if": "^2.0.2",
|
||||
"gulp-git": "~2.8.0",
|
||||
"gulp-livereload": "~4.0.0",
|
||||
"gulp-livereload": "~3.8.1",
|
||||
"gulp-plumber": "~1.2.0",
|
||||
"gulp-pug": "~4.0.1",
|
||||
"gulp-rename": "~1.4.0",
|
||||
"gulp-rename": "~1.3.0",
|
||||
"gulp-sass": "~4.0.1",
|
||||
"gulp-sourcemaps": "~2.6.4",
|
||||
"gulp-uglify-es": "^1.0.4",
|
||||
"gulp-uglify": "~3.0.0",
|
||||
"minimist": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "^4.1.3",
|
||||
"bootstrap": "^4.1.2",
|
||||
"jquery": "^3.3.1",
|
||||
"popper.js": "^1.14.4"
|
||||
"popper.js": "^1.14.3",
|
||||
"photoswipe": "^4.1.2"
|
||||
}
|
||||
}
|
||||
|
@@ -9,4 +9,3 @@
|
||||
-e ../attract
|
||||
-e ../flamenco
|
||||
-e ../pillar-svnman
|
||||
-e .
|
||||
|
42
src/scripts/layout.js
Normal file
42
src/scripts/layout.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Selectors
|
||||
================================================================== */
|
||||
var searchButton = document.querySelector('#searchButton'),
|
||||
searchCloseButton = document.querySelector('#searchCloseButton'),
|
||||
searchNav = document.querySelector('#searchNav'),
|
||||
searchNavInput = document.querySelector('#searchNav input'),
|
||||
navbarNav = document.querySelector('#navbarNav'),
|
||||
profileMenu = document.querySelector('#navbarNav .navbar-nav').lastElementChild
|
||||
|
||||
|
||||
/* Interactions
|
||||
================================================================== */
|
||||
searchButton.addEventListener('click', showSearch)
|
||||
searchCloseButton.addEventListener('click', closeSearch)
|
||||
searchNavInput.onblur = function() {
|
||||
closeSearch()
|
||||
}
|
||||
|
||||
|
||||
/* Functions
|
||||
================================================================== */
|
||||
function showSearch() {
|
||||
searchToggleStatus = true
|
||||
searchNav.classList.remove('hidden')
|
||||
searchNavInput.focus()
|
||||
navbarNav.classList.add('hidden')
|
||||
profileMenu.classList.add('visible')
|
||||
document.addEventListener('keyup', onPressEscCloseSearch)
|
||||
}
|
||||
|
||||
function closeSearch() {
|
||||
searchNav.classList.add('hidden')
|
||||
navbarNav.classList.remove('hidden')
|
||||
profileMenu.classList.remove('visible')
|
||||
document.removeEventListener('keyup', onPressEscCloseSearch)
|
||||
}
|
||||
|
||||
function onPressEscCloseSearch(e) {
|
||||
if (e.keyCode == 27) {
|
||||
closeSearch()
|
||||
}
|
||||
}
|
@@ -1,109 +0,0 @@
|
||||
/**
|
||||
* Support for fetching & rendering assets by tags.
|
||||
*/
|
||||
(function($) {
|
||||
/* How many nodes to load initially, and when clicked on the 'Load Next' link. */
|
||||
const LOAD_INITIAL_COUNT = 5;
|
||||
const LOAD_NEXT_COUNT = 3;
|
||||
|
||||
/* Renders a node as a <li> element, returns a jQuery object. */
|
||||
function renderAsset(node) {
|
||||
let li = $('<li>').addClass('tagged-asset');
|
||||
let link = $('<a>')
|
||||
.attr('href', '/nodes/' + node._id + '/redir')
|
||||
.appendTo(li);
|
||||
|
||||
function warnNoPicture() {
|
||||
li.addClass('warning');
|
||||
link.text('no picture for node ' + node._id);
|
||||
}
|
||||
|
||||
if (!node.picture) {
|
||||
warnNoPicture();
|
||||
return li;
|
||||
}
|
||||
|
||||
// TODO: show 'loading' thingy
|
||||
$.get('/api/files/' + node.picture)
|
||||
.fail(function(error) {
|
||||
let msg = xhrErrorResponseMessage(error);
|
||||
li.addClass('error').text(msg);
|
||||
})
|
||||
.done(function(resp) {
|
||||
// Render the picture if it has the proper size.
|
||||
var show_variation = null;
|
||||
if (typeof resp.variations != 'undefined') {
|
||||
for (variation of resp.variations) {
|
||||
if (variation.size != 'm') continue;
|
||||
show_variation = variation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (show_variation == null) {
|
||||
warnNoPicture();
|
||||
return;
|
||||
}
|
||||
|
||||
let img = $('<img>')
|
||||
.attr('alt', node.name)
|
||||
.attr('src', variation.link)
|
||||
.attr('width', variation.width)
|
||||
.attr('height', variation.height);
|
||||
link.append(img);
|
||||
});
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
function loadNext(ul_element) {
|
||||
let $ul = $(ul_element);
|
||||
let tagged_assets = ul_element.tagged_assets; // Stored here by loadTaggedAssets().
|
||||
let already_loaded = $ul.find('li.tagged-asset').length;
|
||||
|
||||
let load_next = $ul.find('li.load-next');
|
||||
|
||||
let nodes_to_load = tagged_assets.slice(already_loaded, already_loaded + LOAD_NEXT_COUNT);
|
||||
for (node of nodes_to_load) {
|
||||
let li = renderAsset(node);
|
||||
load_next.before(li);
|
||||
}
|
||||
|
||||
if (already_loaded + LOAD_NEXT_COUNT >= tagged_assets.length)
|
||||
load_next.remove();
|
||||
}
|
||||
|
||||
$.fn.loadTaggedAssets = function(api_base_url) {
|
||||
this.each(function(index, ul_element) {
|
||||
// TODO(Sybren): show a 'loading' animation.
|
||||
$.get('/api/nodes/tagged/' + ul_element.dataset.assetTag)
|
||||
.fail(function(error) {
|
||||
let msg = xhrErrorResponseMessage(error);
|
||||
$('<li>').addClass('error').text(msg).appendTo(ul_element);
|
||||
})
|
||||
.done(function(resp) {
|
||||
// 'resp' is a list of node documents.
|
||||
// Store the response on the DOM <ul>-element so that we can later render more.
|
||||
ul_element.tagged_assets = resp;
|
||||
|
||||
// Here render the first N.
|
||||
for (node of resp.slice(0, LOAD_INITIAL_COUNT)) {
|
||||
let li = renderAsset(node);
|
||||
li.appendTo(ul_element);
|
||||
}
|
||||
|
||||
// Don't bother with a 'load next' link if there is no more.
|
||||
if (resp.length <= LOAD_INITIAL_COUNT) return;
|
||||
|
||||
// Construct the 'load next' link.
|
||||
let load_next = $('<li>').addClass('load-next');
|
||||
let link = $('<a>')
|
||||
.attr('href', 'javascript:void(0);')
|
||||
.click(function() { loadNext(ul_element); return false; })
|
||||
.text('Load next')
|
||||
.appendTo(load_next);
|
||||
load_next.appendTo(ul_element);
|
||||
});
|
||||
});
|
||||
};
|
||||
}(jQuery));
|
8
src/styles/_breakpoints.sass
Normal file
8
src/styles/_breakpoints.sass
Normal file
@@ -0,0 +1,8 @@
|
||||
// Bootstrap Breakpoints
|
||||
// sm 576.98px
|
||||
// md 576px - 757.98px
|
||||
// lg 992px to 1199.98px
|
||||
// xl 1200px and up
|
||||
@import ../../static/assets/bootstrap/sass/functions
|
||||
@import ../../static/assets/bootstrap/sass/variables
|
||||
@import ../../static/assets/bootstrap/sass/mixins/breakpoints
|
36
src/styles/_cards.sass
Normal file
36
src/styles/_cards.sass
Normal file
@@ -0,0 +1,36 @@
|
||||
.container.card-container
|
||||
max-width: 1200px
|
||||
margin-top: 56px
|
||||
.col-md-4
|
||||
padding: 0 20px
|
||||
&:focus
|
||||
outline: none;
|
||||
.card
|
||||
border: none
|
||||
margin-bottom: 64px
|
||||
.card-image
|
||||
background-color: #ccc
|
||||
border-radius: 0
|
||||
height: 160px
|
||||
max-height: 160px
|
||||
min-height: 160px
|
||||
margin: 0 auto
|
||||
overflow: hidden
|
||||
width: 100%
|
||||
+media-breakpoint-up(sm)
|
||||
height: 203px
|
||||
max-height: 203px
|
||||
min-height: 203px
|
||||
img
|
||||
height: 100%
|
||||
object-fit: cover
|
||||
.card-title
|
||||
margin: 11px 0 5px
|
||||
font-size: 27px
|
||||
a
|
||||
color: #111
|
||||
text-decoration: none
|
||||
.card-text
|
||||
font-size: 18px
|
||||
.card-body
|
||||
padding: 0
|
9
src/styles/_colors.sass
Normal file
9
src/styles/_colors.sass
Normal file
@@ -0,0 +1,9 @@
|
||||
$primary: #0A68FF
|
||||
$grey: #EBEBEB
|
||||
$gray: #EBEBEB
|
||||
$dark: rgba(17,17,17,1)
|
||||
$muted: rgba(17,17,17,0.75)
|
||||
$lightgray: #F5F5F5
|
||||
// $theme-colors:
|
||||
// primary: red
|
||||
//
|
54
src/styles/_footer.sass
Normal file
54
src/styles/_footer.sass
Normal file
@@ -0,0 +1,54 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
footer.container-fluid
|
||||
background: #F8F8FB
|
||||
border-top: 1px solid #E3E3E6
|
||||
.container
|
||||
margin-top: 11px
|
||||
max-width: 1200px
|
||||
.row
|
||||
max-width: 1200px
|
||||
.col-4
|
||||
flex: 0 0 100%
|
||||
flex-basis: 100%
|
||||
max-width: 100%
|
||||
margin-bottom: 60px
|
||||
padding: 0 20px 56px
|
||||
+media-breakpoint-up(sm)
|
||||
padding: 0 20px 32px
|
||||
+media-breakpoint-up(md)
|
||||
flex: 0 0 33%
|
||||
padding-bottom: 0
|
||||
max-width: 33%
|
||||
margin-bottom: 0px
|
||||
.col
|
||||
flex-basis: 50%
|
||||
padding: 0 20px 32px
|
||||
+media-breakpoint-up(sm)
|
||||
flex-basis: 0
|
||||
padding-bottom: 0
|
||||
h5
|
||||
color: $dark
|
||||
font-weight: 600
|
||||
margin-bottom: 12px
|
||||
text-transform: uppercase
|
||||
p
|
||||
color: #6d6d6e
|
||||
font-size: 16px
|
||||
line-height: 30px
|
||||
.list-unstyled
|
||||
li
|
||||
line-height: 30px
|
||||
a
|
||||
color: #6d6d6e
|
||||
font-size: 16px
|
||||
&:hover
|
||||
color: #3F3F40
|
||||
.social-icons
|
||||
.list-inline-item:not(:last-child)
|
||||
margin-right: 22px
|
||||
a
|
||||
opacity: 1
|
||||
&:hover
|
||||
opacity: 0.8
|
56
src/styles/_gallery.sass
Normal file
56
src/styles/_gallery.sass
Normal file
@@ -0,0 +1,56 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
.gallery
|
||||
.cta-arrow
|
||||
margin-top: 20px
|
||||
.container
|
||||
max-width: 1190px
|
||||
padding: 0
|
||||
+media-breakpoint-up(sm)
|
||||
padding-right: 15px
|
||||
padding-left: 15px
|
||||
.thumbnail
|
||||
float: left
|
||||
position: relative
|
||||
width: 32.8%
|
||||
padding-bottom: 32.9%
|
||||
margin: 0.4%
|
||||
overflow: hidden
|
||||
// Fixes Thumbnail Spacing
|
||||
&:nth-of-type(1),
|
||||
&:nth-of-type(2),
|
||||
&:nth-of-type(3)
|
||||
margin-top: 0
|
||||
&:nth-of-type(1),
|
||||
&:nth-of-type(4),
|
||||
&:nth-of-type(7)
|
||||
margin-left: 0
|
||||
&:nth-of-type(3),
|
||||
&:nth-of-type(6)
|
||||
margin-right: 0
|
||||
+media-breakpoint-up(sm)
|
||||
width: 22.4%
|
||||
padding-bottom: 22.4%
|
||||
margin: 1.73%
|
||||
&:nth-of-type(4)
|
||||
margin-top: 0
|
||||
&:nth-of-type(1),
|
||||
&:nth-of-type(5)
|
||||
margin-left: 0
|
||||
&:nth-of-type(4),
|
||||
&:nth-of-type(7)
|
||||
margin-left: 1.73%
|
||||
&:nth-of-type(3),
|
||||
&:nth-of-type(6)
|
||||
margin-right: 1.73%
|
||||
&:nth-of-type(4),
|
||||
&:nth-of-type(8)
|
||||
margin-right: 0
|
||||
.thumbnail-container
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 100%
|
||||
img
|
||||
width: 300%
|
||||
transform: translate(-20%, -10%)
|
@@ -1,19 +1,58 @@
|
||||
.dashboard-container
|
||||
+container-behavior
|
||||
+media-xs
|
||||
flex-direction: column
|
||||
align-content: center
|
||||
align-items: flex-start
|
||||
display: flex
|
||||
justify-content: space-around
|
||||
word-break: break-word
|
||||
|
||||
section.dashboard-main,
|
||||
section.dashboard-secondary
|
||||
+media-xs
|
||||
width: 100%
|
||||
margin: 20px auto
|
||||
|
||||
.title-underline
|
||||
img
|
||||
max-width: 100%
|
||||
|
||||
section.dashboard-main
|
||||
+container-box
|
||||
width: 52%
|
||||
|
||||
section.dashboard-secondary
|
||||
width: 46%
|
||||
flex-direction: column
|
||||
margin-right: auto
|
||||
|
||||
span.section-lead
|
||||
display: block
|
||||
padding: 10px 0
|
||||
color: $color-text-dark-secondary
|
||||
|
||||
section.dashboard-main,
|
||||
section.dashboard-secondary
|
||||
h4
|
||||
padding-bottom: 5px
|
||||
position: relative
|
||||
margin-bottom: 20px
|
||||
position: relative
|
||||
|
||||
&:before
|
||||
background-color: $primary
|
||||
content: ' '
|
||||
display: block
|
||||
height: 2px
|
||||
top: 125%
|
||||
position: absolute
|
||||
width: 50px
|
||||
height: 2px
|
||||
top: 125%
|
||||
content: ' '
|
||||
display: block
|
||||
background-color: $color-primary
|
||||
|
||||
a
|
||||
color: $color-text
|
||||
|
||||
&:hover
|
||||
color: $color-primary
|
||||
cursor: pointer
|
||||
|
||||
nav#nav-tabs,
|
||||
nav#sub-nav-tabs
|
||||
@@ -74,13 +113,37 @@ nav#sub-nav-tabs
|
||||
border-color: $color-background-light
|
||||
pointer-events: none
|
||||
|
||||
.dashboard-container
|
||||
word-break: break-word
|
||||
li.create
|
||||
cursor: pointer
|
||||
display: inline-block
|
||||
float: right
|
||||
font:
|
||||
size: 1.2em
|
||||
weight: 400
|
||||
padding: 5px 10px
|
||||
margin-top: 3px
|
||||
|
||||
a
|
||||
color: $color-success
|
||||
text-decoration: none
|
||||
|
||||
&.disabled
|
||||
cursor: wait
|
||||
border-color: $color-success
|
||||
opacity: .8
|
||||
a
|
||||
cursor: wait
|
||||
|
||||
section.stream
|
||||
ul.activity-stream__list
|
||||
$activity-stream-thumbnail-size: 110px
|
||||
background-color: white
|
||||
border-bottom: thin solid $color-background-dark
|
||||
|
||||
ul.activity-stream__list
|
||||
list-style: none
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
$activity-stream-thumbnail-size: 110px
|
||||
> li
|
||||
position: relative
|
||||
display: flex
|
||||
@@ -117,6 +180,17 @@ section.stream
|
||||
transition: font-size 100ms ease-in-out
|
||||
|
||||
&.comment
|
||||
.activity-stream__list-thumbnail
|
||||
background: transparent
|
||||
color: $node-type-comment
|
||||
font-size: 1.2em
|
||||
box-shadow: none
|
||||
|
||||
i
|
||||
+position-center-translate
|
||||
left: 22px
|
||||
top: 19px
|
||||
|
||||
.activity-stream__list-details
|
||||
padding: 0
|
||||
.title
|
||||
@@ -126,8 +200,6 @@ section.stream
|
||||
margin: 0
|
||||
|
||||
ul.meta
|
||||
+list-meta
|
||||
font-size: .9em
|
||||
padding: 0 10px 7px 10px
|
||||
|
||||
li
|
||||
@@ -228,6 +300,7 @@ section.stream
|
||||
overflow: hidden
|
||||
position: relative
|
||||
max-width: 100%
|
||||
margin-right: auto
|
||||
padding: 10px 0
|
||||
|
||||
+media-xs
|
||||
@@ -237,14 +310,18 @@ section.stream
|
||||
+ribbon
|
||||
right: -47px
|
||||
top: 5px
|
||||
font-size: 12px
|
||||
font:
|
||||
size: 12px
|
||||
weight: 500
|
||||
|
||||
span
|
||||
padding: 1px 50px
|
||||
|
||||
.title
|
||||
display: inline-block
|
||||
padding: 0 10px
|
||||
color: $color-text-dark
|
||||
font-size: 1.1em
|
||||
|
||||
span
|
||||
@include badge(hsl(hue($color-success), 60%, 45%), 3px)
|
||||
@@ -252,6 +329,24 @@ section.stream
|
||||
padding: 1px 5px
|
||||
margin-right: 5px
|
||||
|
||||
ul.meta
|
||||
+list-meta
|
||||
padding: 5px 10px 0 10px
|
||||
font-size: .85em
|
||||
color: $color-text-dark-secondary
|
||||
display: flex
|
||||
white-space: nowrap
|
||||
|
||||
&.extra
|
||||
margin-top: auto
|
||||
|
||||
li
|
||||
padding-left: 10px
|
||||
&:before
|
||||
left: -5px
|
||||
&.where-project
|
||||
+text-overflow-ellipsis
|
||||
|
||||
section.comments
|
||||
padding: 0 15px 5px
|
||||
|
||||
@@ -276,6 +371,118 @@ section.comments
|
||||
display: block
|
||||
padding-bottom: 5px
|
||||
|
||||
section.blog-stream
|
||||
+media-md
|
||||
padding-left: 10px
|
||||
+media-sm
|
||||
padding-left: 10px
|
||||
position: relative
|
||||
|
||||
.feed
|
||||
position: absolute
|
||||
top: 10px
|
||||
right: 10px
|
||||
font-size: 1.4em
|
||||
color: lighten($color-text-dark-hint, 10%)
|
||||
|
||||
&:hover
|
||||
color: $color-primary
|
||||
|
||||
> ul
|
||||
margin: 0
|
||||
padding: 0
|
||||
list-style: none
|
||||
border-top: thin solid $color-background
|
||||
|
||||
.blog_index-item
|
||||
+container-box
|
||||
display: flex
|
||||
flex-direction: column
|
||||
margin-bottom: 50px
|
||||
|
||||
&:before
|
||||
height: 1px
|
||||
background-color: $color-background-dark
|
||||
position: absolute
|
||||
bottom: -26px
|
||||
left: 25px
|
||||
right: 25px
|
||||
content: ' '
|
||||
|
||||
&:last-child
|
||||
margin-bottom: 0
|
||||
|
||||
&:before
|
||||
display: none
|
||||
|
||||
video
|
||||
max-width: 100%
|
||||
|
||||
a.item-title
|
||||
font-size: 1.6em
|
||||
padding: 5px 15px
|
||||
display: block
|
||||
color: $color-text
|
||||
|
||||
&:hover
|
||||
color: $color-primary
|
||||
|
||||
ul.meta
|
||||
+list-meta
|
||||
font-size: .9em
|
||||
padding: 15px 15px 5px
|
||||
|
||||
|
||||
&.blog-non-featured
|
||||
border-radius: 0
|
||||
margin: 0
|
||||
|
||||
.item-content
|
||||
+node-details-description
|
||||
padding: 10px 15px
|
||||
|
||||
.blog-stream__list-details
|
||||
.title
|
||||
color: $color-text-dark-primary
|
||||
display: block
|
||||
font-size: 1.3em
|
||||
|
||||
&:hover
|
||||
color: $color-primary
|
||||
|
||||
ul.meta
|
||||
+list-meta
|
||||
padding-top: 5px
|
||||
font-size: .9em
|
||||
color: $color-text-dark-secondary
|
||||
|
||||
li
|
||||
padding-left: 10px
|
||||
&:before
|
||||
left: -5px
|
||||
|
||||
.blog_index-header
|
||||
display: block
|
||||
position: relative
|
||||
|
||||
img
|
||||
border-top-left-radius: 3px
|
||||
border-top-right-radius: 3px
|
||||
width: 100%
|
||||
|
||||
.more
|
||||
text-align: center
|
||||
|
||||
a
|
||||
color: $color-text
|
||||
display: block
|
||||
padding: 25px 0
|
||||
text-decoration: underline
|
||||
width: 100%
|
||||
|
||||
&:hover
|
||||
color: $color-primary
|
||||
|
||||
section.random-asset
|
||||
border-bottom: thin solid $color-background-dark
|
||||
|
||||
@@ -446,6 +653,10 @@ section.announcement
|
||||
|
||||
.title
|
||||
padding-bottom: 10px
|
||||
font:
|
||||
family: $font-body
|
||||
size: 1.4em
|
||||
weight: 300
|
||||
|
||||
+media-xs
|
||||
font-size: 1.4em
|
||||
@@ -482,21 +693,60 @@ section.announcement
|
||||
justify-content: space-around
|
||||
flex-wrap: wrap
|
||||
|
||||
a
|
||||
+button($color-text-light, 3px)
|
||||
padding: 5px 0
|
||||
margin:
|
||||
bottom: 5px
|
||||
right: auto
|
||||
left: auto
|
||||
font-size: .9em
|
||||
opacity: 1
|
||||
flex: 1
|
||||
|
||||
+media-xs
|
||||
margin: 10px auto
|
||||
width: 100%
|
||||
|
||||
&:first-child
|
||||
margin-right: 15px
|
||||
|
||||
&.blue
|
||||
+button(hsl(hue($color-info), 60%, 45%), 3px)
|
||||
|
||||
&.orange
|
||||
+button(hsl(hue($color-secondary), 50%, 50%), 3px)
|
||||
padding: 5px 15px
|
||||
|
||||
&.green
|
||||
+button(hsl(hue($color-success), 60%, 40%), 3px, true)
|
||||
|
||||
|
||||
section.dashboard-in-production
|
||||
.in-production-project
|
||||
border-bottom: thin solid $color-background-dark
|
||||
color: $color-text-dark-primary
|
||||
display: block
|
||||
font-size: 1.1em
|
||||
margin-bottom: 15px
|
||||
|
||||
> img
|
||||
margin-bottom: 15px
|
||||
|
||||
body.homepage
|
||||
.blog
|
||||
// Custom tweak to Bootstrap grid for the only case when
|
||||
// the post is inside a column (it's usually centered in the page).
|
||||
.col-md-9
|
||||
flex: 1
|
||||
max-width: 100%
|
||||
.dashboard-container
|
||||
.dashboard-main
|
||||
+media-xs
|
||||
width: 100%
|
||||
background-color: transparent
|
||||
box-shadow: none
|
||||
width: 60%
|
||||
|
||||
.jumbotron
|
||||
padding-top: 6em
|
||||
padding-bottom: 6em
|
||||
.dashboard-secondary
|
||||
+container-box
|
||||
+media-xs
|
||||
width: 100%
|
||||
width: 38%
|
||||
|
||||
*
|
||||
font-size: $h1-font-size
|
||||
|
||||
.lead
|
||||
font-size: $font-size-base
|
||||
> section
|
||||
padding: 15px
|
||||
|
2
src/styles/_iframe.sass
Normal file
2
src/styles/_iframe.sass
Normal file
@@ -0,0 +1,2 @@
|
||||
.embed-responsive
|
||||
margin: 48px auto
|
32
src/styles/_jumbotron.sass
Normal file
32
src/styles/_jumbotron.sass
Normal file
@@ -0,0 +1,32 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
.jumbotron
|
||||
background-color: #fff
|
||||
background-repeat: no-repeat
|
||||
background-position: left top
|
||||
background-size: cover
|
||||
height: 360px
|
||||
width: 100%
|
||||
margin-bottom: 0px
|
||||
+media-breakpoint-up(md)
|
||||
height: 500px
|
||||
+media-breakpoint-up(xl)
|
||||
height: 600px
|
||||
.container
|
||||
max-width: 1160px
|
||||
display: flex
|
||||
height: 100%
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
h1.display-4
|
||||
color: white
|
||||
font-weight: 400
|
||||
font-size: 48px
|
||||
margin: 0
|
||||
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.30)
|
||||
.lead
|
||||
max-width: 722px
|
||||
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.80)
|
||||
p
|
||||
color: white
|
41
src/styles/_navbar-secondary.sass
Normal file
41
src/styles/_navbar-secondary.sass
Normal file
@@ -0,0 +1,41 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
.nav-scroller
|
||||
position: relative
|
||||
z-index: 2
|
||||
height: 2.75rem
|
||||
overflow-y: hidden
|
||||
.navbar-secondary
|
||||
max-width: 700px
|
||||
margin-bottom: 40px
|
||||
padding-left: 0
|
||||
border-bottom: 1px solid $gray
|
||||
+media-breakpoint-up(sm)
|
||||
margin-bottom: 56px
|
||||
.nav
|
||||
display: flex
|
||||
flex-wrap: nowrap
|
||||
overflow-x: auto
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
-webkit-overflow-scrolling: touch
|
||||
.nav-link
|
||||
font-size: 18px
|
||||
color: $dark
|
||||
padding: 13px 4px
|
||||
margin-right: 16px
|
||||
margin-left: 16px
|
||||
&:hover
|
||||
color: $muted
|
||||
.nav-title
|
||||
font-weight: 600
|
||||
@include media-breakpoint-up(md)
|
||||
padding-left: 0
|
||||
margin-left: 0
|
||||
&:hover
|
||||
color: $dark
|
||||
.active
|
||||
border-bottom: 2px solid $primary
|
||||
&:hover
|
||||
color: $dark
|
220
src/styles/_navbar.sass
Normal file
220
src/styles/_navbar.sass
Normal file
@@ -0,0 +1,220 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
nav.navbar
|
||||
background: #fff
|
||||
height: auto
|
||||
min-height: 48px
|
||||
padding: 2px 20px
|
||||
position: sticky
|
||||
+media-breakpoint-up(md)
|
||||
box-shadow: 0 2px 2px -2px rgba(0,0,0,.15)
|
||||
height: 56px
|
||||
padding: 10px 5px 10px 20px
|
||||
&.sticky-top
|
||||
+media-breakpoint-down(sm)
|
||||
position: static
|
||||
.navbar-brand
|
||||
padding: .3125rem 0
|
||||
z-index: 1002
|
||||
.navbar-toggler
|
||||
padding: 0
|
||||
border-radius: 0
|
||||
&:hover
|
||||
background: none
|
||||
.navbar-nav
|
||||
margin-bottom: 15px
|
||||
margin-top: 15px
|
||||
+media-breakpoint-up(md)
|
||||
margin: 0
|
||||
li
|
||||
line-height: 2.5
|
||||
.special
|
||||
top: 10px
|
||||
left: 35px
|
||||
a.navbar-item.active,
|
||||
a.navbar-item.active:hover,
|
||||
a.navbar-item:hover
|
||||
box-shadow: none
|
||||
li:last-of-type
|
||||
// profile menu
|
||||
z-index: 1002
|
||||
.dropdown-menu
|
||||
right: 0
|
||||
left: auto
|
||||
top: 54px
|
||||
padding: .5rem 0
|
||||
margin: .125rem 0 0
|
||||
&.visible
|
||||
visibility: visible
|
||||
li a
|
||||
padding: 0 15px 0 12px
|
||||
li:hover
|
||||
background-color: #f8f9fa
|
||||
.dropdown ul.dropdown-menu li a
|
||||
color: #111
|
||||
font-family: 'Source Sans Pro', sans-serif
|
||||
&:hover
|
||||
color: #111
|
||||
text-decoration: none
|
||||
.nav-item .nav-link
|
||||
font-size: 18px
|
||||
color: $dark
|
||||
padding: 10px
|
||||
+media-breakpoint-up(lg)
|
||||
padding: 6px 18px
|
||||
&:hover
|
||||
color: $primary
|
||||
.navbar-toggler
|
||||
border: 0
|
||||
display: block
|
||||
outline: none
|
||||
+media-breakpoint-up(md)
|
||||
display: none
|
||||
span
|
||||
width: 20px
|
||||
height: 2px
|
||||
background: $dark
|
||||
display: block
|
||||
margin-bottom: 4px
|
||||
&:last-of-type
|
||||
margin-bottom: 0
|
||||
.collapsing
|
||||
transition: none
|
||||
display: none
|
||||
#navbarNav
|
||||
animation-timing-function: cubic-bezier(0.4,0,0.2,1)
|
||||
animation-fill-mode: backwards
|
||||
opacity: 1
|
||||
transition: opacity .15s ease-in
|
||||
visibility: visible
|
||||
&.hidden
|
||||
animation-fill-mode: backwards
|
||||
animation-timing-function: cubic-bezier(0.4,0,0.2,1)
|
||||
opacity: 0
|
||||
transition: visibility 0s .15s, opacity .15s ease-in
|
||||
visibility: hidden
|
||||
.dropdown-toggle::after
|
||||
display:none !important
|
||||
&.show
|
||||
padding-bottom: 75vh
|
||||
.search-icon
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
padding: 0 8px
|
||||
+media-breakpoint-up(lg)
|
||||
padding: 0 16px
|
||||
.pi-search
|
||||
&::before
|
||||
color: rgba(17,17,17,0.75)
|
||||
font-size: 16px
|
||||
&:hover
|
||||
color: $primary
|
||||
.nav-notifications
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
padding: 0 8px
|
||||
+media-breakpoint-up(lg)
|
||||
padding: 0 16px
|
||||
.navbar-item
|
||||
height: auto
|
||||
padding: 0
|
||||
.active
|
||||
box-shadow: 0
|
||||
.flyout
|
||||
background-color: #fff
|
||||
background-clip: padding-box
|
||||
border: 1px solid rgba(0,0,0,.15)
|
||||
border-radius: .25rem
|
||||
box-shadow: 0
|
||||
font-size: 16px
|
||||
.flyout.notifications
|
||||
right: 65px
|
||||
top: 57px
|
||||
.nav-notifications:hover>#notifications-toggle
|
||||
display: block
|
||||
.nav-notifications-icon
|
||||
color: rgba(17,17,17,0.75)
|
||||
&:hover
|
||||
color: $primary
|
||||
.gravatar
|
||||
width: 32px
|
||||
border-radius: 50%
|
||||
.dropdown-menu
|
||||
margin-top: -1px
|
||||
border: 0
|
||||
border-radius: 0 0 4px 4px
|
||||
box-shadow: none
|
||||
font-size: 1rem
|
||||
color: #111
|
||||
text-align: left
|
||||
list-style: none
|
||||
background-color: #fff
|
||||
background-clip: padding-box
|
||||
box-shadow: 0px 4px 4px 0px hsla(0, 0%, 80%, 0.25)
|
||||
.dropdown:hover
|
||||
background: none
|
||||
&>.dropdown-menu
|
||||
display: block
|
||||
.dropdown-item
|
||||
color: #111
|
||||
font-size: 18px
|
||||
padding: 0px 15px
|
||||
i
|
||||
padding-right: 8px
|
||||
#userDropdown
|
||||
.nav-link
|
||||
padding-top: 4px
|
||||
padding-bottom: 0
|
||||
padding-right: 0
|
||||
outline: none
|
||||
#searchNav
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
background-color: #fff
|
||||
max-height: 56px
|
||||
position: absolute
|
||||
width: calc(100% - 40px)
|
||||
z-index: 1001
|
||||
animation-timing-function: cubic-bezier(0.4,0,0.2,1)
|
||||
animation-fill-mode: backwards
|
||||
opacity: 1
|
||||
transition: opacity .15s ease-in
|
||||
visibility: visible
|
||||
+media-breakpoint-up(md)
|
||||
width: calc(100% - 25px)
|
||||
&.hidden
|
||||
animation-fill-mode: backwards
|
||||
animation-timing-function: cubic-bezier(0.4,0,0.2,1)
|
||||
opacity: 0
|
||||
transition: visibility 0s .15s, opacity .15s ease-in
|
||||
visibility: hidden
|
||||
.search-container
|
||||
position: relative
|
||||
max-width: 560px
|
||||
width: 100%
|
||||
input
|
||||
padding: 11px 20px 11px 46px
|
||||
color: #4d4e53
|
||||
box-shadow: none
|
||||
border: 1px solid #e5e5e5
|
||||
border-radius: 4px
|
||||
border-bottom-color: none
|
||||
background-color: #fcfcfc
|
||||
font-size: 18px
|
||||
transition: border-color 150ms ease-in-out, box-shadow 150ms ease-in-out
|
||||
width: 100%
|
||||
max-width: 560px
|
||||
.search-icon
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
top: 14px
|
||||
left: 11px
|
||||
#searchCloseButton
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
right: 16px
|
||||
top: 12px
|
43
src/styles/_typography.sass
Normal file
43
src/styles/_typography.sass
Normal file
@@ -0,0 +1,43 @@
|
||||
html
|
||||
// changing font-size here, will change all bootstrap font-sizes
|
||||
font-size: 20px
|
||||
body
|
||||
font-family: 'Source Sans Pro', sans-serif
|
||||
-webkit-font-smoothing: antialiased
|
||||
-moz-osx-font-smoothing: grayscale
|
||||
color: #212529
|
||||
h1, h2, h3, h4, h5
|
||||
font-family: 'Source Sans Pro', sans-serif
|
||||
margin-top: 0
|
||||
margin-bottom: .5rem
|
||||
h1
|
||||
font-size: 48px
|
||||
line-height: 57px
|
||||
font-weight: 500
|
||||
h2
|
||||
font-size: 36px
|
||||
line-height: 47px
|
||||
font-weight: 500
|
||||
h3
|
||||
font-size: 27px
|
||||
line-height: 38px
|
||||
font-weight: 500
|
||||
h4
|
||||
font-size 21px
|
||||
font-weight: 500
|
||||
line-height: 34px
|
||||
h5
|
||||
font-size: 15px
|
||||
letter-spacing: 0.6px
|
||||
p
|
||||
font-size: 20px
|
||||
line-height: 1.5
|
||||
margin-bottom: 1rem
|
||||
.lead
|
||||
font-size: 20px
|
||||
letter-spacing: 0.4px
|
||||
a
|
||||
color: #007bff
|
||||
&:hover
|
||||
color: #007bff
|
||||
text-decoration: underline
|
@@ -10,6 +10,9 @@
|
||||
li a.navbar-item
|
||||
color: $color-text
|
||||
|
||||
.navbar-container
|
||||
+container-behavior
|
||||
|
||||
.navbar-toggle
|
||||
border: 2px solid $color-text-dark-primary
|
||||
color: $color-text
|
||||
@@ -264,6 +267,22 @@
|
||||
+media-xs
|
||||
margin-top: 20px
|
||||
|
||||
.navbar
|
||||
.nav-item-sign-in
|
||||
a.navbar-item
|
||||
background-color: $color-primary
|
||||
border: none
|
||||
border-radius: 3px
|
||||
color: white
|
||||
height: auto
|
||||
font-weight: bold
|
||||
margin-top: 5px
|
||||
margin-left: 10px
|
||||
padding: 10px 20px
|
||||
|
||||
&:hover
|
||||
background-color: lighten($color-primary, 10%)
|
||||
box-shadow: none
|
||||
|
||||
.container.wide-on-sm
|
||||
+media-sm
|
||||
@@ -315,7 +334,9 @@ section.pricing
|
||||
+button($color-primary, 3px, true)
|
||||
|
||||
h3
|
||||
font-size: 1.8em
|
||||
font:
|
||||
size: 1.8em
|
||||
family: $font-body
|
||||
padding-bottom: 0
|
||||
margin: 25px 0 0 10px
|
||||
|
||||
|
17
src/styles/base.sass
Normal file
17
src/styles/base.sass
Normal file
@@ -0,0 +1,17 @@
|
||||
/* mixins reused on every page
|
||||
================================================================== */
|
||||
@import ../styles/typography
|
||||
@import ../styles/navbar
|
||||
@import ../styles/footer
|
||||
|
||||
|
||||
/* Undo Old Base.css, main.css
|
||||
================================================================== */
|
||||
.container
|
||||
width: 100%
|
||||
padding-right: 15px
|
||||
padding-left: 15px
|
||||
margin-right: auto
|
||||
margin-left: auto
|
||||
.navbar+.page-content
|
||||
padding-top: 0
|
@@ -1,99 +1,26 @@
|
||||
// Bootstrap variables and utilities.
|
||||
@import "../../node_modules/bootstrap/scss/functions"
|
||||
@import "../../node_modules/bootstrap/scss/variables"
|
||||
@import "../../node_modules/bootstrap/scss/mixins"
|
||||
@import ../../../pillar/src/styles/_normalize
|
||||
@import ../../../pillar/src/styles/_config
|
||||
@import ../../../pillar/src/styles/_utils
|
||||
|
||||
// Pillar variables and utilities.
|
||||
@import "../../../pillar/src/styles/config"
|
||||
@import "../../../pillar/src/styles/utils"
|
||||
|
||||
|
||||
// Bootstrap components.
|
||||
@import "../../node_modules/bootstrap/scss/root"
|
||||
@import "../../node_modules/bootstrap/scss/reboot"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/type"
|
||||
@import "../../node_modules/bootstrap/scss/images"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/code"
|
||||
@import "../../node_modules/bootstrap/scss/grid"
|
||||
@import "../../node_modules/bootstrap/scss/tables"
|
||||
@import "../../node_modules/bootstrap/scss/forms"
|
||||
@import "../../node_modules/bootstrap/scss/buttons"
|
||||
@import "../../node_modules/bootstrap/scss/transitions"
|
||||
@import "../../node_modules/bootstrap/scss/dropdown"
|
||||
@import "../../node_modules/bootstrap/scss/button-group"
|
||||
@import "../../node_modules/bootstrap/scss/input-group"
|
||||
@import "../../node_modules/bootstrap/scss/custom-forms"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/nav"
|
||||
@import "../../node_modules/bootstrap/scss/navbar"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/card"
|
||||
@import "../../node_modules/bootstrap/scss/breadcrumb"
|
||||
@import "../../node_modules/bootstrap/scss/pagination"
|
||||
@import "../../node_modules/bootstrap/scss/badge"
|
||||
@import "../../node_modules/bootstrap/scss/jumbotron"
|
||||
@import "../../node_modules/bootstrap/scss/alert"
|
||||
@import "../../node_modules/bootstrap/scss/progress"
|
||||
@import "../../node_modules/bootstrap/scss/media"
|
||||
@import "../../node_modules/bootstrap/scss/list-group"
|
||||
@import "../../node_modules/bootstrap/scss/close"
|
||||
@import "../../node_modules/bootstrap/scss/modal"
|
||||
@import "../../node_modules/bootstrap/scss/tooltip"
|
||||
@import "../../node_modules/bootstrap/scss/popover"
|
||||
@import "../../node_modules/bootstrap/scss/carousel"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/utilities"
|
||||
@import "../../node_modules/bootstrap/scss/print"
|
||||
|
||||
|
||||
// Pillar components.
|
||||
@import "../../../pillar/src/styles/apps_base"
|
||||
@import "../../../pillar/src/styles/error"
|
||||
|
||||
@import "../../../pillar/src/styles/components/base"
|
||||
|
||||
@import "../../../pillar/src/styles/components/jumbotron"
|
||||
@import "../../../pillar/src/styles/components/alerts"
|
||||
@import "../../../pillar/src/styles/components/navbar"
|
||||
@import "../../../pillar/src/styles/components/dropdown"
|
||||
@import "../../../pillar/src/styles/components/footer"
|
||||
@import "../../../pillar/src/styles/components/shortcode"
|
||||
@import "../../../pillar/src/styles/components/statusbar"
|
||||
@import "../../../pillar/src/styles/components/search"
|
||||
|
||||
@import "../../../pillar/src/styles/components/flyout"
|
||||
@import "../../../pillar/src/styles/components/forms"
|
||||
@import "../../../pillar/src/styles/components/inputs"
|
||||
@import "../../../pillar/src/styles/components/buttons"
|
||||
@import "../../../pillar/src/styles/components/popover"
|
||||
@import "../../../pillar/src/styles/components/tooltip"
|
||||
@import "../../../pillar/src/styles/components/checkbox"
|
||||
@import "../../../pillar/src/styles/components/overlay"
|
||||
@import "../../../pillar/src/styles/components/card"
|
||||
|
||||
@import "../../../pillar/src/styles/comments"
|
||||
@import "../../../pillar/src/styles/notifications"
|
||||
/* Generic styles (comments, notifications, etc) come from base.css */
|
||||
|
||||
/* Blender Cloud specific styles */
|
||||
@import "../../../pillar/src/styles/_project"
|
||||
@import "../../../pillar/src/styles/_project-sharing"
|
||||
@import "../../../pillar/src/styles/_project-dashboard"
|
||||
@import "../../../pillar/src/styles/_user"
|
||||
|
||||
@import ../../../pillar/src/styles/_project
|
||||
@import ../../../pillar/src/styles/_project-sharing
|
||||
@import ../../../pillar/src/styles/_project-dashboard
|
||||
@import ../../../pillar/src/styles/_user
|
||||
@import _welcome
|
||||
@import _homepage
|
||||
@import _services
|
||||
@import _about
|
||||
@import "../../../pillar/src/styles/_search"
|
||||
@import "../../../pillar/src/styles/_organizations"
|
||||
@import ../../../pillar/src/styles/_search
|
||||
@import ../../../pillar/src/styles/_organizations
|
||||
|
||||
/* services, about, etc */
|
||||
@import "../../../pillar/src/styles/_pages"
|
||||
@import ../../../pillar/src/styles/_pages
|
||||
|
||||
/* plugins are included here, don't include in base unless needed by other pillar apps */
|
||||
@import "../../../pillar/src/styles/plugins/_jstree"
|
||||
@import "../../../pillar/src/styles/plugins/_js_select2"
|
||||
@import ../../../pillar/src/styles/plugins/_jstree
|
||||
@import ../../../pillar/src/styles/plugins/_js_select2
|
||||
|
||||
/* CSS for pillar-font comes from fontello.com using static/assets/font/config.json */
|
||||
|
@@ -1,384 +1,60 @@
|
||||
// Bootstrap variables and utilities.
|
||||
@import "../../node_modules/bootstrap/scss/functions"
|
||||
@import "../../node_modules/bootstrap/scss/variables"
|
||||
@import "../../node_modules/bootstrap/scss/mixins"
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
@import ../styles/jumbotron
|
||||
@import ../styles/navbar-secondary
|
||||
@import ../styles/iframe
|
||||
@import ../styles/gallery
|
||||
@import ../styles/cards
|
||||
|
||||
// Pillar variables and utilities.
|
||||
@import "../../../pillar/src/styles/config"
|
||||
@import "../../../pillar/src/styles/utils"
|
||||
/* Undo main.css padding
|
||||
================================================================== */
|
||||
body,
|
||||
.container-page
|
||||
background: #fff
|
||||
section.node-details-container.project
|
||||
padding-bottom: 0
|
||||
.node-details-title
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
|
||||
// Bootstrap components.
|
||||
@import "../../node_modules/bootstrap/scss/root"
|
||||
@import "../../node_modules/bootstrap/scss/reboot"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/type"
|
||||
@import "../../node_modules/bootstrap/scss/images"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/code"
|
||||
@import "../../node_modules/bootstrap/scss/grid"
|
||||
@import "../../node_modules/bootstrap/scss/tables"
|
||||
@import "../../node_modules/bootstrap/scss/forms"
|
||||
@import "../../node_modules/bootstrap/scss/buttons"
|
||||
@import "../../node_modules/bootstrap/scss/transitions"
|
||||
@import "../../node_modules/bootstrap/scss/dropdown"
|
||||
@import "../../node_modules/bootstrap/scss/button-group"
|
||||
@import "../../node_modules/bootstrap/scss/input-group"
|
||||
@import "../../node_modules/bootstrap/scss/custom-forms"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/nav"
|
||||
@import "../../node_modules/bootstrap/scss/navbar"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/card"
|
||||
@import "../../node_modules/bootstrap/scss/breadcrumb"
|
||||
@import "../../node_modules/bootstrap/scss/pagination"
|
||||
@import "../../node_modules/bootstrap/scss/badge"
|
||||
@import "../../node_modules/bootstrap/scss/jumbotron"
|
||||
@import "../../node_modules/bootstrap/scss/alert"
|
||||
@import "../../node_modules/bootstrap/scss/progress"
|
||||
@import "../../node_modules/bootstrap/scss/media"
|
||||
@import "../../node_modules/bootstrap/scss/list-group"
|
||||
@import "../../node_modules/bootstrap/scss/close"
|
||||
@import "../../node_modules/bootstrap/scss/modal"
|
||||
@import "../../node_modules/bootstrap/scss/tooltip"
|
||||
@import "../../node_modules/bootstrap/scss/popover"
|
||||
@import "../../node_modules/bootstrap/scss/carousel"
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/utilities"
|
||||
@import "../../node_modules/bootstrap/scss/print"
|
||||
|
||||
|
||||
// Pillar components.
|
||||
@import "../../../pillar/src/styles/apps_base"
|
||||
@import "../../../pillar/src/styles/error"
|
||||
|
||||
@import "../../../pillar/src/styles/components/base"
|
||||
|
||||
@import "../../../pillar/src/styles/components/jumbotron"
|
||||
@import "../../../pillar/src/styles/components/alerts"
|
||||
@import "../../../pillar/src/styles/components/navbar"
|
||||
@import "../../../pillar/src/styles/components/dropdown"
|
||||
@import "../../../pillar/src/styles/components/footer"
|
||||
@import "../../../pillar/src/styles/components/shortcode"
|
||||
@import "../../../pillar/src/styles/components/statusbar"
|
||||
@import "../../../pillar/src/styles/components/search"
|
||||
|
||||
@import "../../../pillar/src/styles/components/flyout"
|
||||
@import "../../../pillar/src/styles/components/inputs"
|
||||
@import "../../../pillar/src/styles/components/buttons"
|
||||
@import "../../../pillar/src/styles/components/popover"
|
||||
@import "../../../pillar/src/styles/components/tooltip"
|
||||
@import "../../../pillar/src/styles/components/checkbox"
|
||||
@import "../../../pillar/src/styles/components/overlay"
|
||||
@import "../../../pillar/src/styles/components/card"
|
||||
|
||||
@import "../../../pillar/src/styles/notifications"
|
||||
|
||||
@import "../../../pillar/src/styles/_search"
|
||||
|
||||
$node-latest-thumbnail-size: 160px
|
||||
$node-latest-gallery-thumbnail-size: 200px
|
||||
|
||||
nav.navbar
|
||||
.navbar-header
|
||||
+media-xs
|
||||
width: 100%
|
||||
|
||||
.navbar-toggle
|
||||
border: none
|
||||
color: $color-text
|
||||
position: absolute
|
||||
right: 10px
|
||||
|
||||
.navbar-nav
|
||||
+media-xs
|
||||
padding: 10px
|
||||
|
||||
.search-input
|
||||
display: none
|
||||
|
||||
.node-details-container
|
||||
max-width: 620px
|
||||
font-size: 1.3em
|
||||
line-height: 1.5em
|
||||
margin: 0 auto 40px auto
|
||||
padding-bottom: 40px
|
||||
|
||||
+media-xs
|
||||
padding-left: 10px
|
||||
padding-right: 10px
|
||||
/* Override jumbotron to make it shorter than the default */
|
||||
.jumbotron
|
||||
height: 400px
|
||||
|
||||
/* Landing Page Sass
|
||||
================================================================== */
|
||||
.cta-arrow
|
||||
img
|
||||
padding-left: 11px
|
||||
.node-details-title
|
||||
&.container
|
||||
max-width: 1190px
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
ul,
|
||||
p
|
||||
margin-bottom: 1.3em
|
||||
|
||||
header
|
||||
display: flex
|
||||
flex-direction: column /* stack flex items vertically */
|
||||
position: relative
|
||||
img.header
|
||||
width: 100%
|
||||
flex-direction: column /* stack flex items vertically */
|
||||
position: relative
|
||||
a.page-card-cta
|
||||
position: absolute
|
||||
left: 76%
|
||||
top: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
color: white
|
||||
font-weight: bold
|
||||
background: #ff4970
|
||||
border-radius: 3px
|
||||
border: none
|
||||
box-shadow: 1px 1px 0 rgba(black, .2)
|
||||
padding: 7px 20px
|
||||
text-decoration: none
|
||||
text-shadow: none
|
||||
|
||||
&:hover
|
||||
background: lighten(#ff4970, 5%)
|
||||
|
||||
.landing
|
||||
h2
|
||||
text-align: center
|
||||
margin-bottom: 40px
|
||||
|
||||
max-width: 700px
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
section
|
||||
max-width: 1024px
|
||||
padding-top: 20px
|
||||
border-top: thin solid $color-background
|
||||
margin: 0 auto
|
||||
|
||||
.navbar-secondary
|
||||
max-width: 620px
|
||||
margin: 0 auto
|
||||
|
||||
.navbar-collapse
|
||||
padding-left: 0
|
||||
|
||||
li
|
||||
a
|
||||
padding-left: 20px
|
||||
padding-right: 20px
|
||||
color: $color-text
|
||||
&:hover
|
||||
&.active
|
||||
background: none
|
||||
color: black
|
||||
box-shadow: 0px 2px 0 rgba(red, .8)
|
||||
|
||||
.node-extra
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
//padding: 0 20px
|
||||
width: 100%
|
||||
|
||||
|
||||
.node-updates
|
||||
flex: 1
|
||||
font-size: 1.1em
|
||||
|
||||
ul
|
||||
padding: 0
|
||||
margin: 0 0 15px 0
|
||||
display: flex
|
||||
flex-direction: row
|
||||
flex-wrap: wrap
|
||||
|
||||
li
|
||||
display: flex
|
||||
flex-direction: column
|
||||
list-style: none
|
||||
padding: 5px
|
||||
cursor: pointer
|
||||
width: 33.3333%
|
||||
|
||||
+media-xs
|
||||
width: 100%
|
||||
|
||||
&.texture, &.group_texture
|
||||
width: 25%
|
||||
|
||||
&:hover
|
||||
img
|
||||
opacity: .9
|
||||
a.title
|
||||
//color: $color-primary
|
||||
text-decoration: underline
|
||||
|
||||
&.post
|
||||
.info .title
|
||||
//color: $node-type-post
|
||||
font-size: 1.1em
|
||||
a.image
|
||||
border: none
|
||||
//border-color: $node-type-post
|
||||
background-color: hsl(hue($node-type-post), 20%, 55%)
|
||||
|
||||
&.asset.image a.image
|
||||
border-color: $node-type-asset_image
|
||||
background-color: hsl(hue($node-type-asset_image), 20%, 55%)
|
||||
&.asset.file a.image
|
||||
border-color: $node-type-asset_file
|
||||
background-color: hsl(hue($node-type-asset_file), 20%, 55%)
|
||||
&.asset.video a.image
|
||||
border-color: $node-type-asset_video
|
||||
background-color: hsl(hue($node-type-asset_video), 20%, 55%)
|
||||
|
||||
.image
|
||||
width: 100%
|
||||
height: $node-latest-thumbnail-size
|
||||
min-height: $node-latest-thumbnail-size
|
||||
max-height: $node-latest-thumbnail-size
|
||||
background-color: $color-background
|
||||
margin: 5px auto 10px auto
|
||||
position: relative
|
||||
overflow: hidden
|
||||
border-radius: 0
|
||||
|
||||
img
|
||||
max-height: $node-latest-thumbnail-size
|
||||
+position-center-translate
|
||||
|
||||
i
|
||||
color: rgba(white, .9)
|
||||
font-size: 1.8em
|
||||
position: absolute
|
||||
bottom: 3px
|
||||
left: 5px
|
||||
text-shadow: 1px 1px 0 rgba(black, .2)
|
||||
|
||||
&.pi-file-archive
|
||||
font-size: 1.5em
|
||||
bottom: 5px
|
||||
&.pi-newspaper
|
||||
font-size: 1.6em
|
||||
left: 7px
|
||||
|
||||
.ribbon
|
||||
+ribbon
|
||||
|
||||
.info
|
||||
width: 100%
|
||||
height: 100%
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: space-between
|
||||
word-break: break-word
|
||||
|
||||
.description
|
||||
font-size: 1em
|
||||
line-height: 1.8em
|
||||
padding-top: 8px
|
||||
color: $color-text-dark-primary
|
||||
|
||||
.title
|
||||
display: block
|
||||
font-size: 1.3em
|
||||
color: $color-text-dark
|
||||
font-weight: 600
|
||||
+clearfix
|
||||
+text-overflow-ellipsis
|
||||
|
||||
span.details
|
||||
width: 100%
|
||||
display: block
|
||||
font-size: 1em
|
||||
line-height: 1.2em
|
||||
padding: 5px 0
|
||||
color: $color-text-dark-secondary
|
||||
+clearfix
|
||||
|
||||
.who
|
||||
margin-left: 3px
|
||||
.what
|
||||
text-transform: capitalize
|
||||
|
||||
|
||||
$bg-color: #444
|
||||
$bg-color2: #666
|
||||
$yellow: rgb(249,229,89)
|
||||
$almost-white: rgb(255,255,255)
|
||||
$btn-transparent-color: rgba(249,229,89,1)
|
||||
$btn-transparent-bg: rgba(249,229,89,0)
|
||||
|
||||
|
||||
section.gallery
|
||||
max-width: 1024px
|
||||
margin: 60px auto 0 auto
|
||||
text-align: center
|
||||
padding-bottom: 40px
|
||||
|
||||
p
|
||||
color: $almost-white
|
||||
padding: 0 40px
|
||||
|
||||
|
||||
.thumbnail
|
||||
float: left
|
||||
position: relative
|
||||
width: 23%
|
||||
padding-bottom: 23%
|
||||
margin: 0.83%
|
||||
overflow: hidden
|
||||
&:hover
|
||||
box-shadow: 2px 2px 50px 0 rgba(0,0,0,0.3)
|
||||
|
||||
.img-container
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
img
|
||||
width: 300%
|
||||
transform: translate(-20%,-10%)
|
||||
|
||||
&:hover .img-caption
|
||||
top: 0
|
||||
left: 0
|
||||
.btn-trans
|
||||
background: rgba(255,255,255,0.4)
|
||||
|
||||
.img-caption
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: rgba(0, 0, 0, 0.3)
|
||||
text-align: center
|
||||
|
||||
.table
|
||||
display: table
|
||||
.table-cell
|
||||
display: table-cell
|
||||
vertical-align: bottom
|
||||
border: none
|
||||
|
||||
@media screen and (max-width: 992px)
|
||||
.thumbnail
|
||||
width: 22%
|
||||
padding-bottom: 22%
|
||||
margin: 1.5%
|
||||
|
||||
.img-container:hover .img-caption
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
.img-caption
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: rgba(0, 0, 0, .7)
|
||||
text-align: center
|
||||
a
|
||||
color: $yellow
|
||||
|
||||
@media screen and (max-width: 720px)
|
||||
.thumbnail
|
||||
width: 29%
|
||||
padding-bottom: 29%
|
||||
margin: 2.16%
|
||||
|
||||
@media screen and (max-width: 470px)
|
||||
.thumbnail
|
||||
width: 44%
|
||||
padding-bottom: 44%
|
||||
margin: 3%
|
||||
margin-top: 104px
|
||||
+media-breakpoint-up(sm)
|
||||
margin-top: 152px
|
||||
&:first-child
|
||||
margin-top: 0
|
||||
h2
|
||||
margin-bottom: 24px
|
||||
+media-breakpoint-up(sm)
|
||||
margin-bottom: 40px
|
||||
.container.card-container
|
||||
margin-top: 0
|
||||
.card
|
||||
.card-image
|
||||
margin-top: 0
|
||||
footer.container-fluid
|
||||
margin-top: 72px
|
||||
+media-breakpoint-up(sm)
|
||||
margin-top: 112px
|
||||
+media-breakpoint-up(lg)
|
||||
margin-top: 136px
|
15
src/styles/projects-index-collection.sass
Normal file
15
src/styles/projects-index-collection.sass
Normal file
@@ -0,0 +1,15 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
@import ../styles/jumbotron
|
||||
@import ../styles/navbar-secondary
|
||||
@import ../styles/cards
|
||||
|
||||
body,
|
||||
.container-page
|
||||
background: #fff
|
||||
footer.container-fluid
|
||||
margin-top: 72px
|
||||
+media-breakpoint-up(sm)
|
||||
margin-top: 112px
|
||||
+media-breakpoint-up(lg)
|
||||
margin-top: 136px
|
29
src/styles/welcome.sass
Normal file
29
src/styles/welcome.sass
Normal file
@@ -0,0 +1,29 @@
|
||||
@import ../styles/colors
|
||||
@import ../styles/breakpoints
|
||||
|
||||
nav.navbar
|
||||
+media-breakpoint-up(md)
|
||||
padding: 10px 10px 10px 20px
|
||||
.nav-item-sign-in
|
||||
line-height: 1.5
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
.navbar-item
|
||||
.join .navbar .nav-item-sign-in a.navbar-item
|
||||
background: $primary
|
||||
font-size: 16px
|
||||
font-weight: 600
|
||||
margin: 0
|
||||
padding: 8px 16px
|
||||
width: 100%
|
||||
&:hover
|
||||
background: $primary
|
||||
+media-breakpoint-up(md)
|
||||
width: auto
|
||||
// temporarily restore old primary color
|
||||
h2,
|
||||
h3
|
||||
color: #68B3C8
|
||||
footer.container-fluid
|
||||
margin-top: 0
|
@@ -1,26 +0,0 @@
|
||||
include ../mixins/components
|
||||
|
||||
| {% macro navigation_tabs(title) %}
|
||||
+nav-secondary()
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'homepage' %}active{% endif %}",
|
||||
href="{{ url_for('main.homepage') }}")
|
||||
| Activity
|
||||
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'home' %}active{% endif %}",
|
||||
href="{{ url_for('projects.home_project') }}")
|
||||
| Home
|
||||
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'dashboard' %}active{% endif %}",
|
||||
href="{{ url_for('projects.index') }}")
|
||||
| My Projects
|
||||
|
||||
| {% if current_user.has_organizations() %}
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'organizations' %}active{% endif %}",
|
||||
href="{{ url_for('pillar.web.organizations.index') }}")
|
||||
| My Organizations
|
||||
| {% endif %}
|
||||
| {% endmacro %}
|
@@ -193,16 +193,16 @@ style.
|
||||
small October 30th, 2015
|
||||
.page-card-summary
|
||||
| Introducing integrated blogs in Blender Cloud projects. Glass Half is the first project fully developed on the new Blender Cloud. It's also the first and only project to have share its
|
||||
a(href='/p/glass-half/5627bb22f0e7220061109c9f') animation dailies
|
||||
a(href='https://cloud.blender.org/p/glass-half/5627bb22f0e7220061109c9f') animation dailies
|
||||
| ! But the biggest outcome from Glass Half was definitely
|
||||
a(href='/p/glass-half/569d6044c379cf445461293e') Flexirig
|
||||
a(href='https://cloud.blender.org/p/glass-half/569d6044c379cf445461293e') Flexirig
|
||||
| .
|
||||
.page-card-side
|
||||
a(href='/p/glass-half/blog/glass-half-premiere')
|
||||
a(href='https://cloud.blender.org/p/glass-half/blog/glass-half-premiere')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2015_10_30_glass.jpg') }}", alt="Glass Half")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/new-art-gallery-with-gleb-alexandrov')
|
||||
a(href='https://cloud.blender.org/blog/new-art-gallery-with-gleb-alexandrov')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2015_11_19_art.jpg') }}", alt="Art Gallery")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -218,11 +218,11 @@ style.
|
||||
.page-card-summary
|
||||
| With so much going on in the Cloud at at the studio. The Blender Institute Podcast was born! Sharing our daily studio work, Blender community news, and interacting with the awesome Blender Cloud subscribers.
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-blender-institute-podcast')
|
||||
a(href='https://cloud.blender.org/blog/introducing-blender-institute-podcast')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2015_11_24_bip.jpg') }}", alt="Blender Institute Podcast")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/p/blenrig/blog/welcome-to-the-blenrig-project')
|
||||
a(href='https://cloud.blender.org/p/blenrig/blog/welcome-to-the-blenrig-project')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2015_12_01_blenrig.jpg') }}", alt="Blenrig")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -238,11 +238,11 @@ style.
|
||||
.page-card-summary
|
||||
| The biggest source for CC0/Public Domain textures on the interwebs goes live. First as beta, as a quick gift right before Xmas 2015!
|
||||
.page-card-side
|
||||
a(href='/blog/new-texture-library')
|
||||
a(href='https://cloud.blender.org/blog/new-texture-library')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2015_12_23_textures.jpg') }}", alt="Texture Library")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/nraryew-the-character-lib')
|
||||
a(href='https://cloud.blender.org/blog/nraryew-the-character-lib')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_01_05_charlib.jpg') }}", alt="Character Library")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -262,11 +262,11 @@ style.
|
||||
a(href='https://www.youtube.com/watch?v=kQH897V9bDg&list=PLI2TkLMzCSr_H6ppmzDtU0ut0RwxGvXjv') nicely edited Weekly video reports
|
||||
| .
|
||||
.page-card-side
|
||||
a(href='/p/caminandes-3/blog/caminandes-llamigos')
|
||||
a(href='https://cloud.blender.org/p/caminandes-3/blog/caminandes-llamigos')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_01_30_llamigos.jpg') }}", alt="Caminandes: Llamigos")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/welcome-sybren')
|
||||
a(href='https://cloud.blender.org/blog/welcome-sybren')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_03_01_sybren.jpg') }}", alt="Dr. Sybren!")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -282,11 +282,11 @@ style.
|
||||
.page-card-summary
|
||||
| Create your own private projects on Blender Cloud.
|
||||
.page-card-side
|
||||
a(href='/blog/welcome-sybren')
|
||||
a(href='https://cloud.blender.org/blog/welcome-sybren')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_05_03_projects.jpg') }}", alt="Projects")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-project-sharing')
|
||||
a(href='https://cloud.blender.org/blog/introducing-project-sharing')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_05_09_projectsharing.jpg') }}", alt="Sharing")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -302,11 +302,11 @@ style.
|
||||
.page-card-summary
|
||||
| Browse the textures from within Blender!
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-project-sharing')
|
||||
a(href='https://cloud.blender.org/blog/introducing-project-sharing')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_05_11_addon.jpg') }}", alt="Blender Cloud Add-on")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-private-texture-libraries')
|
||||
a(href='https://cloud.blender.org/blog/introducing-private-texture-libraries')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_05_23_privtextures.jpg') }}", alt="Texture Libraries")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -322,11 +322,11 @@ style.
|
||||
.page-card-summary
|
||||
| Sync your Blender preferences across multiple devices.
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-blender-sync')
|
||||
a(href='https://cloud.blender.org/blog/introducing-blender-sync')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_06_30_sync.jpg') }}", alt="Blender Sync")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-image-sharing')
|
||||
a(href='https://cloud.blender.org/blog/introducing-image-sharing')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_07_14_image.jpg') }}", alt="Image Sharing")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -337,21 +337,21 @@ style.
|
||||
section.page-card
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
a(href='/blog/introducing-the-hdri-library')
|
||||
a(href='https://cloud.blender.org/blog/introducing-the-hdri-library')
|
||||
| HDRI Library
|
||||
small July 27th, 2016
|
||||
.page-card-summary
|
||||
| High-dynamic range images are now available on Blender Cloud! With their own special viewer. Also available via the Blender Cloud add-on.
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-the-hdri-library')
|
||||
a(href='https://cloud.blender.org/blog/introducing-the-hdri-library')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_07_27_hdri.jpg') }}", alt="HDRI Library")
|
||||
section.page-card
|
||||
.page-card-side
|
||||
a(href='/blog/introducing-the-hdri-library')
|
||||
a(href='https://cloud.blender.org/blog/introducing-the-hdri-library')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2016_12_06_toon.jpg') }}", alt="Hdri Library")
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
a(href='/blog/new-training-toon-character-workflow')
|
||||
a(href='https://cloud.blender.org/blog/new-training-toon-character-workflow')
|
||||
| Toon Character Workflow
|
||||
small December 6th, 2016
|
||||
.page-card-summary
|
||||
@@ -366,7 +366,7 @@ style.
|
||||
| to all resources and training produced so far!
|
||||
a.page-card-cta(href='https://store.blender.org/product/membership/') Subscribe
|
||||
.page-card-side
|
||||
a(href='/p/agent-327')
|
||||
a(href='https://cloud.blender.org/p/agent-327')
|
||||
img.img-responsive(src="{{ url_for('static_cloud', filename='img/2017_03_10_agent.jpg') }}", alt="Agent 327")
|
||||
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:type", content="website")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="https://cloud.blender.org/")
|
||||
|
||||
meta(property="og:title", content="Blender Cloud")
|
||||
meta(name="twitter:title", content="Blender Cloud")
|
||||
@@ -18,51 +18,59 @@ meta(property="og:image", content="{% if main_project.picture_header %}{{ main_p
|
||||
meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_project.picture_header.thumbnail('l', api=api) }}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg')}}{% endif %}")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
| {{ navigation_tabs(title) }}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block body %}
|
||||
.container-fluid.dashboard-container.imgs-fluid
|
||||
.row
|
||||
.col-md-8
|
||||
section.blog
|
||||
ul.list-unstyled
|
||||
.dashboard-container
|
||||
section.dashboard-main
|
||||
|
||||
section.blog-stream
|
||||
ul.blog-stream__list
|
||||
| {% if latest_posts %}
|
||||
| {% for node in latest_posts %}
|
||||
| {{ render_blog_post(node) }}
|
||||
| {% endfor %}
|
||||
| {% else %}
|
||||
li
|
||||
| No blog entries... yet!
|
||||
.blog-stream__list-details
|
||||
ul.meta
|
||||
li.when No blog entries... yet!
|
||||
| {% endif %}
|
||||
|
||||
.d-block.text-center
|
||||
a.d-inline-block.p-3.text-muted(href="{{ url_for('main.main_blog') }}")
|
||||
.more
|
||||
a(href="{{ url_for('main.main_blog') }}")
|
||||
| See All Blog Posts
|
||||
|
||||
a.d-inline-block.p-3.text-muted(
|
||||
a.feed(
|
||||
href="{{ url_for('main.feeds_blogs') }}",
|
||||
title="Blogs Feed",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-rss
|
||||
| RSS Feed
|
||||
|
||||
.col-md-4
|
||||
.dashboard-sidebar
|
||||
section.pt-3
|
||||
h6.title-underline In Production
|
||||
a(href="/p/spring/")
|
||||
|
||||
section.dashboard-secondary
|
||||
| {{ navigation_tabs(title) }}
|
||||
|
||||
section.dashboard-in-production
|
||||
h4 In Production
|
||||
span.section-lead.
|
||||
Check out these projects currently in production!
|
||||
|
||||
a.in-production-project(href="https://cloud.blender.org/p/spring/")
|
||||
img(src="{{ url_for('static', filename='assets/img/projects/spring_450x150.jpg')}}")
|
||||
p.
|
||||
#[strong Spring] - A poetic short film about a mountain spirit and her wise little dog.
|
||||
|
||||
p.text-muted.pt-2.
|
||||
A poetic short film about a mountain spirit and her wise little dog. #[a(href="/p/spring/") Check it out].
|
||||
a.in-production-project(href="https://cloud.blender.org/p/hero/")
|
||||
img(src="{{ url_for('static', filename='assets/img/projects/hero_450x150.jpg')}}")
|
||||
p.
|
||||
#[strong Hero] - A '2D' trailer-style movie focused on getting grease pencil
|
||||
production ready for Blender 2.8.
|
||||
|
||||
section.stream.py-3
|
||||
h6.title-underline Latest Assets
|
||||
section.stream
|
||||
|
||||
ul.activity-stream__list.list-unstyled
|
||||
h4 Latest Assets
|
||||
|
||||
ul.activity-stream__list
|
||||
| {% for n in activity_stream %}
|
||||
li(
|
||||
class="{{ n.node_type }} {{ n.properties.content_type }} {% if n.picture %}with-picture{% endif %}",
|
||||
@@ -96,7 +104,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
.ribbon
|
||||
span free
|
||||
| {% endif %}
|
||||
ul.list-unstyled.d-flex.text-muted
|
||||
ul.meta
|
||||
| {% if not n.picture %}
|
||||
li.when
|
||||
a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
|
||||
@@ -115,7 +123,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
| {% endif %}
|
||||
|
||||
| {% if n.picture %}
|
||||
ul.list-unstyled.d-flex.text-muted.extra
|
||||
ul.meta.extra
|
||||
li.when
|
||||
a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
|
||||
li.who {{ n.user.full_name }}
|
||||
@@ -126,12 +134,12 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
| No items to list.
|
||||
|
||||
|
||||
section.random-asset.py-3
|
||||
h6.title-underline
|
||||
section.random-asset
|
||||
h4
|
||||
a(href="/search") Explore the Cloud
|
||||
.pb-3.text-muted Random selection of the best assets & tutorials
|
||||
span.section-lead Random selection of the best assets & tutorials
|
||||
|
||||
ul.random-asset__list.list-unstyled
|
||||
ul.random-asset__list
|
||||
| {% for n in random_featured %}
|
||||
| {% if n.picture and loop.first %}
|
||||
li.random-asset__list-item.project
|
||||
@@ -143,7 +151,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
.random-asset__list-details
|
||||
a.title(href="{{ n.project.url }}") {{ n.project.name }}
|
||||
| {% if n.project.summary %}
|
||||
ul.list-unstyled.d-flex.text-muted
|
||||
ul.meta
|
||||
li.what
|
||||
a(href="{{ n.project.url }}") {{ n.project.summary }}
|
||||
| {% endif %}
|
||||
@@ -167,7 +175,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
|
||||
a.title(href="{{ n.url }}")
|
||||
| {{ n.name }}
|
||||
ul.list-unstyled.d-flex.text-muted
|
||||
ul.meta
|
||||
li.what
|
||||
a(href="{{ n.url }}")
|
||||
| {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}Folder{% endif %}
|
||||
@@ -199,7 +207,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
| {% endif %}
|
||||
.random-asset__list-details
|
||||
a.title(href="{{ n.url }}") {{ n.name }}
|
||||
ul.list-unstyled.d-flex.text-muted
|
||||
ul.meta
|
||||
li.what
|
||||
a(href="{{ n.url }}")
|
||||
| {% if n.properties.content_type %}{{ n.properties.content_type }}{% else %}Folder{% endif %}
|
||||
@@ -210,10 +218,11 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
| {% endfor %}
|
||||
|
||||
|
||||
section.comments.py-3
|
||||
h6.title-underline Latest Comments
|
||||
section.comments
|
||||
|
||||
ul.list-unstyled
|
||||
h4 Latest Comments
|
||||
|
||||
ul
|
||||
| {% if latest_comments %}
|
||||
| {% for n in latest_comments %}
|
||||
li(
|
||||
@@ -223,7 +232,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
|
||||
a.comment-content(href="{{ n.url }}")
|
||||
| {{ n.properties.content | striptags | truncate(200) }}
|
||||
|
||||
ul.list-unstyled.d-flex.text-muted
|
||||
ul.meta
|
||||
li.who {{ n.user.full_name }}
|
||||
| {% if n.attached_to %}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ html(lang="en")
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
title {% if self.page_title() %}{% block page_title %}{% endblock %} — {% endif %}Blender Cloud
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1, shrink-to-fit=no")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
||||
meta(name="description", content="Blender Cloud is a web based service developed by Blender Institute that allows people to access the training videos and all the data from the open projects.")
|
||||
meta(name="author", content="Blender Institute")
|
||||
meta(name="theme-color", content="#3e92aa")
|
||||
@@ -19,7 +19,7 @@ html(lang="en")
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:title", content="Blender Cloud")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="https://cloud.blender.org")
|
||||
meta(property="og:type", content="website")
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/background_gleb_locomotive.jpg')}}")
|
||||
meta(property="og:description", content="Blender Cloud is a web based service developed by Blender Institute that allows people to access the training videos and all the data from the open projects.")
|
||||
@@ -45,22 +45,33 @@ html(lang="en")
|
||||
|
||||
link(href="{{ url_for('static', filename='assets/img/favicon.png') }}", rel="shortcut icon")
|
||||
link(href="{{ url_for('static', filename='assets/img/apple-touch-icon-precomposed.png') }}", rel="icon apple-touch-icon-precomposed", sizes="192x192")
|
||||
link(rel="stylesheet", href="{{ url_for('static', filename='assets/bootstrap/css/bootstrap.min.css') }}")
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
|
||||
link(rel="stylesheet", href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600")
|
||||
link(href="{{ url_for('static', filename='assets/google-font-roboto/roboto.css') }}", rel="stylesheet")
|
||||
|
||||
| {% block head %}{% endblock %}
|
||||
|
||||
| {% block css %}
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/base.css') }}", rel="stylesheet")
|
||||
| {% if title == 'blog' %}
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/blog.css') }}", rel="stylesheet")
|
||||
| {% else %}
|
||||
link(href="{{ url_for('static_cloud', filename='assets/css/main.css') }}", rel="stylesheet")
|
||||
link(href="{{ url_for('static_cloud', filename='assets/css/base.css') }}", rel="stylesheet")
|
||||
|
||||
| {% endif %}
|
||||
| {% endblock css %}
|
||||
|
||||
|
||||
| {% if not title %}{% set title="default" %}{% endif %}
|
||||
|
||||
body(class="{{ title }}")
|
||||
.container-page
|
||||
| {% with messages = get_flashed_messages(with_categories=True) %}
|
||||
| {% if messages %}
|
||||
|
||||
| {% for (category, message) in messages %}
|
||||
.alert(role="alert", class="alert-{{ category }}")
|
||||
i.alert-icon(class="{{ category }}")
|
||||
@@ -68,38 +79,30 @@ html(lang="en")
|
||||
button.close(type="button", data-dismiss="alert")
|
||||
i.pi-cancel
|
||||
| {% endfor %}
|
||||
|
||||
| {% endif %}
|
||||
| {% endwith %}
|
||||
|
||||
nav.navbar.navbar-expand-md.fixed-top.bg-white
|
||||
a.navbar-brand(
|
||||
href="{{ url_for('main.homepage') }}",
|
||||
title="Blender Cloud")
|
||||
span.app-logo
|
||||
i.pi-blender-cloud
|
||||
|
||||
button.navbar-toggler.text-light(
|
||||
data-target=".navbar-collapse",
|
||||
data-toggle="collapse",
|
||||
type="button")
|
||||
span.sr-only Toggle navigation
|
||||
span.navbar-toggler-icon.d-flex.align-items-center
|
||||
i.pi-menu
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block navigation_search %}
|
||||
// TODO (pablo) - bring it back asap
|
||||
.search-input
|
||||
input#cloud-search(
|
||||
type="text",
|
||||
placeholder="Search assets, tutorials...")
|
||||
//- Navigation Bar
|
||||
nav.navbar.navbar-expand-md.navbar-light.sticky-top
|
||||
//- Logo
|
||||
a.navbar-brand(href="{{ url_for('main.homepage') }}")
|
||||
img(src="{{ url_for('static', filename='assets/img/logo-blender-cloud-text.svg') }}", alt="alt")
|
||||
//- Mobile Nav Button
|
||||
button.navbar-toggler(type='button', data-toggle='collapse', data-target='#navbarNav', aria-controls="navbarNav", aria-expanded="false", aria-label="Toggle navigation")
|
||||
span
|
||||
span
|
||||
span
|
||||
//- Search Bar
|
||||
#searchNav.hidden
|
||||
span.search-container
|
||||
input#cloud-search(type="text", placeholder="Search Blender Cloud")
|
||||
i.search-icon.pi-search
|
||||
| {% endblock navigation_search %}
|
||||
|
||||
.collapse.navbar-collapse
|
||||
ul.navbar-nav.ml-auto
|
||||
a#searchCloseButton(ahref="#")
|
||||
img(src="{{ url_for('static', filename='assets/img/icons/icon-close-button.svg') }}", alt="alt")
|
||||
//- Links
|
||||
#navbarNav.collapse.navbar-collapse.justify-content-end
|
||||
ul.navbar-nav
|
||||
| {% if node and node.properties and node.properties.category %}
|
||||
| {% set category = node.properties.category %}
|
||||
| {% else %}
|
||||
@@ -107,176 +110,59 @@ html(lang="en")
|
||||
| {% endif %}
|
||||
|
||||
| {% block navigation_sections %}
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('main.main_blog') }}",
|
||||
title="Blender Cloud Blog",
|
||||
data-toggle="tooltip",
|
||||
data-placement="bottom",
|
||||
class="{% if category == 'blog' %}active{% endif %}")
|
||||
span Blog
|
||||
|
||||
li.dropdown
|
||||
a.navbar-item.dropdown-toggle(
|
||||
href="",
|
||||
data-toggle="dropdown",
|
||||
title="Libraries")
|
||||
span Libraries
|
||||
i.pi-angle-down
|
||||
|
||||
ul.dropdown-menu.p-0
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('projects.view', project_url='hdri') }}",
|
||||
title="HDRI Library",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
li.nav-item
|
||||
a.nav-link(href="{{ url_for('main.main_blog') }}", class="{% if category == 'blog' %}active{% endif %}") Blog
|
||||
li.nav-item.dropdown
|
||||
a.nav-link.dropdown-toggle(href="#", data-toggle="dropdown") Libraries
|
||||
.dropdown-menu
|
||||
a.dropdown-item(
|
||||
href="{{ url_for('projects.view', project_url='hdri') }}")
|
||||
i.pi-globe
|
||||
| HDRI
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('projects.view', project_url='textures') }}",
|
||||
title="Textures Library",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
a.dropdown-item(
|
||||
href="{{ url_for('projects.view', project_url='textures') }}")
|
||||
i.pi-folder-texture
|
||||
| Textures
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('projects.view', project_url='characters') }}",
|
||||
title="Character Library",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
a.dropdown-item(
|
||||
href="{{ url_for('projects.view', project_url='characters') }}")
|
||||
i.pi-character
|
||||
| Characters
|
||||
|
||||
|
||||
li(class="dropdown")
|
||||
a.navbar-item.dropdown-toggle(
|
||||
href="{{ url_for('cloud.workshops') }}"
|
||||
data-toggle="dropdown",
|
||||
title="Training")
|
||||
span Training
|
||||
i.pi-angle-down
|
||||
|
||||
ul.dropdown-menu
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('cloud.courses') }}",
|
||||
title="Courses",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
li.nav-item.dropdown
|
||||
a.nav-link.dropdown-toggle(href="#", data-toggle="dropdown") Training
|
||||
.dropdown-menu
|
||||
a.dropdown-item(href="{{ url_for('cloud.courses') }}")
|
||||
i.pi-graduation-cap
|
||||
| Courses
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('cloud.workshops') }}",
|
||||
title="Workshops",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
a.dropdown-item(href="{{ url_for('cloud.workshops') }}")
|
||||
i.pi-lightbulb
|
||||
| Workshops
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('projects.view', project_url='gallery') }}",
|
||||
title="Curated artwork collection",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
a.dropdown-item(href="{{ url_for('projects.view', project_url='gallery') }}")
|
||||
i.pi-image
|
||||
| Art Gallery
|
||||
li.nav-item
|
||||
a.nav-link(href="{{ url_for('cloud.open_projects') }}",
|
||||
class="{% if category in ['open-projects', 'film'] %}active{% endif %}") Open Projects
|
||||
li.nav-item
|
||||
a.nav-link(href="{{ url_for('cloud.services') }}",
|
||||
class="{% if category == 'services' %}active{% endif %}") Services
|
||||
|
||||
li(class="dropdown")
|
||||
a.navbar-item.dropdown-toggle(
|
||||
href="{{ url_for('cloud.open_projects') }}",
|
||||
title="Browse all the Open Projects",
|
||||
data-toggle="dropdown",
|
||||
class="{% if category in ['open-projects', 'film'] %}active{% endif %}")
|
||||
span Open Projects
|
||||
i.pi-angle-down
|
||||
|
||||
ul.dropdown-menu
|
||||
li
|
||||
a.navbar-item(href="/p/spring")
|
||||
span.px-2 Spring
|
||||
li
|
||||
a.navbar-item(href="/p/hero")
|
||||
span.px-2 Hero
|
||||
li
|
||||
a.navbar-item(href="/p/dailydweebs")
|
||||
span.px-2 The Daily Dweebs
|
||||
li
|
||||
a.navbar-item(href="/p/agent-327")
|
||||
span.px-2 Agent 327
|
||||
li
|
||||
a.navbar-item(href="/p/caminandes-3")
|
||||
span.px-2 Caminandes: Llamigos
|
||||
|
||||
li.dropdown-divider
|
||||
|
||||
li
|
||||
a.navbar-item(href="{{ url_for('cloud.open_projects') }}")
|
||||
span.pl-2 All Open Projects
|
||||
|
||||
li(class="dropdown")
|
||||
a.navbar-item.dropdown-toggle(
|
||||
href="{{ url_for('cloud.services') }}",
|
||||
title="Blender Cloud Services",
|
||||
data-toggle="dropdown",
|
||||
class="{% if category == 'services' %}active{% endif %}")
|
||||
span Services
|
||||
i.pi-angle-down
|
||||
|
||||
ul.dropdown-menu
|
||||
li
|
||||
a.navbar-item(
|
||||
href="/attract",
|
||||
title="Production Management",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-attract
|
||||
| Attract
|
||||
li
|
||||
a.navbar-item(
|
||||
href="/flamenco",
|
||||
title="Render Management",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-flamenco
|
||||
| Flamenco
|
||||
|
||||
li
|
||||
a.navbar-item(
|
||||
href="/services#blender-cloud-add-on",
|
||||
title="Blender Sync, Texture Browser and more",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-blender
|
||||
| Blender Cloud Add-on
|
||||
|
||||
li.dropdown-divider
|
||||
|
||||
li
|
||||
a.navbar-item(
|
||||
href="{{ url_for('cloud.services') }}",
|
||||
title="All Blender Cloud services",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-list
|
||||
| All Services
|
||||
|
||||
li.nav-item.search-icon
|
||||
a#searchButton.navbar-item(data-toggle='collpase', data-target='#searchbarNav', href="#")
|
||||
i.pi-search
|
||||
| {% endblock navigation_sections %}
|
||||
|
||||
| {% if current_user.is_anonymous %}
|
||||
li.nav-item
|
||||
a.nav-link(
|
||||
href="https://store.blender.org/product/membership/",
|
||||
title="Sign up") Sign up
|
||||
| {% endif %}
|
||||
|
||||
| {% block navigation_user %}
|
||||
| {% include 'menus/notifications.html' %}
|
||||
| {% include 'menus/user.html' %}
|
||||
| {% endblock navigation_user %}
|
||||
|
||||
| {% if current_user.is_anonymous %}
|
||||
li.pt-1
|
||||
a.btn.btn-sm.btn-primary.px-3.mx-1(
|
||||
href="https://store.blender.org/product/membership/",
|
||||
title="Sign up") Sign up
|
||||
| {% endif %}
|
||||
| {% endblock navigation_user %}
|
||||
|
||||
.page-content
|
||||
#search-overlay
|
||||
@@ -287,114 +173,79 @@ html(lang="en")
|
||||
| {% block body %}{% endblock %}
|
||||
|
||||
| {% block footer_container %}
|
||||
.footer-wrapper
|
||||
footer.container-fluid
|
||||
| {% block footer_navigation %}
|
||||
.footer-navigation
|
||||
.container
|
||||
.container.py-5
|
||||
.row
|
||||
.col-md-4.col-xs-6
|
||||
h4
|
||||
a(href="{{ url_for('main.homepage') }}")
|
||||
i.pi-blender-cloud-logo
|
||||
.col-4
|
||||
h5 Blender Cloud
|
||||
p A creative hub for your projects, powered by free and open source software.
|
||||
ul.list-inline.social-icons
|
||||
li.list-inline-item
|
||||
a(href="https://www.facebook.com/BlenderCloudOfficial/")
|
||||
img(src="../../static/assets/img/icons/icon-social-facebook.svg", alt="alt")
|
||||
li.list-inline-item
|
||||
a(href="https://twitter.com/Blender_Cloud")
|
||||
img(src="../../static/assets/img/icons/icon-social-twitter.svg", alt="alt")
|
||||
li.list-inline-item
|
||||
a(href="https://www.youtube.com/channel/UC5qvW9fotdsSJkCguB_t-kQ")
|
||||
img(src="../../static/assets/img/icons/icon-social-youtube.svg", alt="alt")
|
||||
.col
|
||||
h5 Libraries
|
||||
ul.list-unstyled.text-small
|
||||
li
|
||||
a(href="{{ url_for('projects.view', project_url='hdri') }}") HDRI
|
||||
li
|
||||
a(href="{{ url_for('projects.view', project_url='textures') }}") Textures
|
||||
li
|
||||
a(href="{{ url_for('projects.view', project_url='characters') }}") Characters
|
||||
.col
|
||||
h5 Training
|
||||
ul.list-unstyled.text-small
|
||||
li
|
||||
a(href="{{ url_for('projects.view', project_url='gallery') }}") Art Gallery
|
||||
li
|
||||
a(href="{{ url_for('cloud.courses') }}") Courses
|
||||
li
|
||||
a(href="{{ url_for('cloud.workshops') }}") Workshops
|
||||
.col
|
||||
h5 Resources
|
||||
ul.list-unstyled.text-small
|
||||
li
|
||||
a(href="https://www.blender.org") Blender
|
||||
li
|
||||
a(href="https://store.blender.org/") Blender Store
|
||||
li
|
||||
a(href="https://www.blender.org/foundation/") Contact Us
|
||||
li
|
||||
a(href="{{ url_for('cloud.terms_and_conditions') }}") Terms and Conditions
|
||||
li
|
||||
a(href="{{ url_for('cloud.privacy') }}") Privacy
|
||||
.col
|
||||
h5 Services
|
||||
ul.list-unstyled.text-small
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#attract") Attract
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#blender-cloud-add-on") Blender Cloud Add-on
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#blender-sync") Blender Sync
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#flamenco") Flamenco
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#image-sharing") Image Sharing
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#projects") Private Projects
|
||||
li
|
||||
a(href="https://cloud.blender.org/services#texture-browser") Texture Browser
|
||||
|
||||
p.pl-2.
|
||||
Blender Cloud is the creative hub for your projects,
|
||||
powered by Free and Open Source Software.
|
||||
|
||||
h5.d-flex
|
||||
a.px-2(href="https://twitter.com/Blender_Cloud",
|
||||
title="Follow us on Twitter")
|
||||
i.pi-social-youtube
|
||||
|
||||
a.px-2(href="https://twitter.com/Blender_Cloud",
|
||||
title="Follow us on Twitter")
|
||||
i.pi-social-twitter
|
||||
|
||||
a.px-2(href="https://www.facebook.com/BlenderCloudOfficial/",
|
||||
title="Follow us on Facebook")
|
||||
i.pi-social-facebook
|
||||
|
||||
.col-md-2.col-xs-6
|
||||
h7.font-weight-bold
|
||||
| TRAINING
|
||||
|
||||
ul.list-unstyled
|
||||
li
|
||||
a(href="{{ url_for('cloud.courses') }}")
|
||||
| Courses
|
||||
li
|
||||
a(href="{{ url_for('cloud.workshops') }}")
|
||||
| Workshops
|
||||
li
|
||||
a(href="{{ url_for('projects.view', project_url='gallery') }}")
|
||||
| Art Gallery
|
||||
|
||||
.col-md-2.col-xs-6
|
||||
h7.font-weight-bold
|
||||
| LIBRARIES
|
||||
|
||||
ul.list-unstyled
|
||||
li
|
||||
a(href="{{ url_for('main.main_blog') }}",
|
||||
title="Blender Cloud Blog")
|
||||
| HDRIs
|
||||
li
|
||||
a(href="{{ url_for('cloud.services') }}",
|
||||
title="Blender Cloud Services")
|
||||
| Textures
|
||||
li
|
||||
a(href="{{ url_for('cloud.about') }}",
|
||||
title="About Blender Cloud")
|
||||
| Characters
|
||||
|
||||
.col-md-2.col-xs-6
|
||||
h7.font-weight-bold
|
||||
a(href="{{ url_for('cloud.services') }}")
|
||||
| SERVICES
|
||||
|
||||
ul.list-unstyled
|
||||
li
|
||||
a(href="{{ url_for('main.main_blog') }}",
|
||||
title="Blender Cloud Blog")
|
||||
| Add-on
|
||||
li
|
||||
a(href="{{ url_for('main.main_blog') }}",
|
||||
title="Blender Cloud Blog")
|
||||
| Blender Sync
|
||||
li
|
||||
a(href="{{ url_for('cloud.services') }}",
|
||||
title="Blender Cloud Services")
|
||||
| Attract
|
||||
li
|
||||
a(href="{{ url_for('cloud.about') }}",
|
||||
title="About Blender Cloud")
|
||||
| Flamenco
|
||||
li
|
||||
a(href="{{ url_for('cloud.about') }}",
|
||||
title="About Blender Cloud")
|
||||
| Image Sharing
|
||||
|
||||
.col-md-2.col-xs-6
|
||||
h7.font-weight-bold
|
||||
| BLENDER
|
||||
ul.list-unstyled
|
||||
li
|
||||
a(href="{{ url_for('main.main_blog') }}",
|
||||
title="Blender Cloud Blog")
|
||||
| blender.org
|
||||
li
|
||||
a(href="{{ url_for('cloud.terms_and_conditions') }}",
|
||||
title="Terms and Conditions")
|
||||
| Terms and Conditions
|
||||
li
|
||||
a(href="{{ url_for('cloud.privacy') }}",
|
||||
title="Privacy")
|
||||
| Privacy
|
||||
| {% endblock footer_navigation %}
|
||||
|
||||
#hop(title="Be awesome in space")
|
||||
i.pi-angle-up
|
||||
|
||||
//- Scroll Up Arrow. Not sure if it's necessary
|
||||
//- | {% block footer %}
|
||||
//- footer.container
|
||||
//- #hop(title="Be awesome in space")
|
||||
//- i.pi-angle-up
|
||||
//- | {% endblock footer %}
|
||||
| {% endblock footer_container %}
|
||||
|
||||
#notification-pop(data-url="", data-read-toggle="")
|
||||
@@ -407,7 +258,19 @@ html(lang="en")
|
||||
span.nc-date
|
||||
a(href="")
|
||||
|
||||
script(src="{{ url_for('static_cloud', filename='assets/js/bootstrap.min.js') }}")
|
||||
noscript
|
||||
link(href='//fonts.googleapis.com/css?family=Roboto:300,400', rel='stylesheet', type='text/css')
|
||||
|
||||
//- script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.bootstrap-3.3.7.min.js') }}")
|
||||
|
||||
//- local bootstrap js returns error message, investigate later
|
||||
//- script(src="{{ url_for('static', filename='assets/jquery/jquery.slim.min.js') }}")
|
||||
//- script(src="{{ url_for('static', filename='assets/popper.js/popper.min.js') }}")
|
||||
//- script(src="{{ url_for('static', filename='assets/bootstrap/js/bootstrap.min.js') }}")
|
||||
script(src="https://code.jquery.com/jquery-3.3.1.min.js", integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=", crossorigin="anonymous")
|
||||
script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js", integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49", crossorigin="anonymous")
|
||||
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js", integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em", crossorigin="anonymous")
|
||||
script(src="{{ url_for('static_cloud', filename='assets/js/layout.min.js') }}")
|
||||
|
||||
| {% if current_user.is_authenticated %}
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typewatch-3.0.0.min.js') }}")
|
||||
@@ -436,6 +299,9 @@ html(lang="en")
|
||||
if (typeof $().tooltip != 'undefined'){
|
||||
$('[data-toggle="tooltip"]').tooltip({'delay' : {'show': 0, 'hide': 0}});
|
||||
}
|
||||
if(typeof($.fn.popover) != 'undefined'){
|
||||
$('[data-toggle="popover"]').popover();
|
||||
}
|
||||
|
||||
| {% block footer_scripts_pre %}{% endblock %}
|
||||
| {% block footer_scripts %}{% endblock %}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
| {% endif %}
|
||||
|
||||
| {% block menu_avatar %}
|
||||
a.navbar-item.dropdown-toggle(href="#", data-toggle="dropdown", title="{{ current_user.email }}")
|
||||
a.nav-link.dropdown-toggle(href="#", data-toggle="dropdown", title="{{ current_user.email }}", aria-haspopup="true", aria-expanded="false")
|
||||
img.gravatar(
|
||||
src="{{ current_user.gravatar }}",
|
||||
class="{{ subscription }}",
|
||||
@@ -26,26 +26,26 @@ a.navbar-item.dropdown-toggle(href="#", data-toggle="dropdown", title="{{ curren
|
||||
|
||||
|
||||
| {% block menu_list %}
|
||||
li.subscription-status(class="{{ subscription }}")
|
||||
.dropdown-menu.subscription-status(class="{{ subscription }}", aria-labelledby="dropdownMenuLink")
|
||||
| {% if subscription == 'subscriber' %}
|
||||
a.navbar-item(
|
||||
a.dropdown-item(
|
||||
href="{{url_for('settings.billing')}}"
|
||||
title="View subscription info")
|
||||
i.pi-grin
|
||||
span Your subscription is active!
|
||||
| {% elif subscription == 'demo' %}
|
||||
a.navbar-item(
|
||||
a.dropdown-item(
|
||||
href="{{url_for('settings.billing')}}"
|
||||
title="View subscription info")
|
||||
i.pi-heart-filled
|
||||
span You have a free account.
|
||||
| {% elif current_user.has_cap('can-renew-subscription') %}
|
||||
a.navbar-item(target='_blank', href="/renew", title="Renew subscription")
|
||||
a.dropdown-item(target='_blank', href="/renew", title="Renew subscription")
|
||||
i.pi-heart
|
||||
span.info Your subscription is not active.
|
||||
span.renew Click here to renew.
|
||||
| {% else %}
|
||||
a.navbar-item(
|
||||
a.dropdown-item(
|
||||
href="https://store.blender.org/product/membership/"
|
||||
title="Renew subscription")
|
||||
i.pi-unhappy
|
||||
@@ -56,7 +56,7 @@ li.subscription-status(class="{{ subscription }}")
|
||||
| {{ super() }}
|
||||
|
||||
li
|
||||
a.navbar-item(
|
||||
a.dropdown-item(
|
||||
href="{{ url_for('settings.billing') }}"
|
||||
title="Billing")
|
||||
i.pi-credit-card
|
||||
|
@@ -1,69 +0,0 @@
|
||||
// {#
|
||||
// Header of landing pages. title or text can be skipped:
|
||||
// +jumbotron("{{ page_title }}", null, "{{ page_header_image }}")
|
||||
// Any extra attributes added (in a separate group) will be passed as is:
|
||||
// +jumbotron("{{ page_title }}", null, "{{ page_header_image }}")(data-node-id='{{ node._id }}')
|
||||
// #}
|
||||
mixin jumbotron(title, text, image, url)
|
||||
if url
|
||||
a.jumbotron.jumbotron-overlay.text-white(
|
||||
style='background-image: url(' + image + ');',
|
||||
href=url)&attributes(attributes)
|
||||
.container
|
||||
.row
|
||||
.col-md-9
|
||||
if title
|
||||
.display-4.text-uppercase.font-weight-bold
|
||||
=title
|
||||
if text
|
||||
.lead
|
||||
=text
|
||||
else
|
||||
.jumbotron.jumbotron-overlay.text-white(style='background-image: url(' + image + ');')&attributes(attributes)
|
||||
.container
|
||||
.row
|
||||
.col-md-9
|
||||
if title
|
||||
.display-4.text-uppercase.font-weight-bold
|
||||
=title
|
||||
if text
|
||||
.lead
|
||||
=text
|
||||
|
||||
// {# Secondary navigation.
|
||||
// e.g. Workshops, Courses. #}
|
||||
mixin nav-secondary(title)
|
||||
ul.nav.nav-secondary&attributes(attributes)
|
||||
if title
|
||||
li.font-weight-bold.px-2
|
||||
=title
|
||||
|
||||
if block
|
||||
block
|
||||
else
|
||||
p No items defined.
|
||||
|
||||
mixin nav-secondary-link()
|
||||
li.nav-item
|
||||
a.nav-link&attributes(attributes)
|
||||
block
|
||||
|
||||
// {# Takes as argument the number of columns to use in this deck. 1-6 #}
|
||||
mixin card-deck(columns)
|
||||
.card-deck.card-padless(class='card-' + columns + '-columns')
|
||||
if block
|
||||
block
|
||||
else
|
||||
p No cards defined.
|
||||
|
||||
// {#
|
||||
// Passes all attributes to the card.
|
||||
// You can do fun stuff in a loop even like:
|
||||
// +card(data-url="{{ url_for('projects.view', project_url=project.url) }}", tabindex='{{ loop.index }}')
|
||||
// #}
|
||||
mixin card()
|
||||
.card.card-fade.cursor-pointer.mb-4.js-project-go&attributes(attributes)
|
||||
if block
|
||||
block
|
||||
else
|
||||
p No card content defined.
|
@@ -1,164 +0,0 @@
|
||||
include ../../../mixins/components
|
||||
|
||||
| {% import 'projects/_macros.html' as projectmacros %}
|
||||
| {% macro render_blog_post(node, project=None, pages=None) %}
|
||||
|
||||
.expand-image-links.imgs-fluid
|
||||
| {% if node.picture %}
|
||||
+jumbotron(
|
||||
"{{ node.name }}",
|
||||
"{{ node._created | pretty_date }}",
|
||||
"{{ node.picture.thumbnail('h', api=api) }}",
|
||||
"{{ node.url }}")(class="row")
|
||||
| {% else %}
|
||||
.pt-3.text-center.text-muted
|
||||
h2
|
||||
a.text-muted(href="{{ node.url }}")
|
||||
| {{ node.name }}
|
||||
ul.d-flex.list-unstyled.justify-content-center
|
||||
| {% if node.project.name %}
|
||||
li.pr-2 {{ node.project.name }}
|
||||
| {% endif %}
|
||||
| {% if node.user.full_name %}
|
||||
li.pr-2
|
||||
| {{ node.user.full_name }}
|
||||
| {% endif %}
|
||||
li
|
||||
a.px-2.text-muted(href="{{ node.url }}",
|
||||
title="Updated {{ node._updated | pretty_date }}")
|
||||
| {{ node._created | pretty_date }}
|
||||
li
|
||||
a.px-2(href="{{ node.url }}#comments")
|
||||
| Leave a comment
|
||||
|
||||
| {% if node.has_method('PUT') %}
|
||||
li
|
||||
a.px-2(href="{{url_for('nodes.edit', node_id=node._id)}}")
|
||||
i.pi-edit
|
||||
| Edit Post
|
||||
| {% endif %}
|
||||
| {% endif %}
|
||||
|
||||
| {% if project and project._id != config.MAIN_PROJECT_ID %}
|
||||
| {{ projectmacros.render_secondary_navigation(project, pages=pages) }}
|
||||
| {% endif %}
|
||||
|
||||
.row
|
||||
.col-md-9.mx-auto
|
||||
|
||||
.item-content.pt-4
|
||||
| {{ node.properties | markdowned('content') }}
|
||||
|
||||
hr.my-4
|
||||
| {% endmacro %}
|
||||
|
||||
//- ******************************************************* -//
|
||||
| {% macro render_blog_list_item(node) %}
|
||||
.row.position-relative.py-2
|
||||
.col-md-1
|
||||
| {% if node.picture %}
|
||||
a.imgs-fluid(href="{{ node.url }}")
|
||||
img(src="{{ node.picture.thumbnail('s', api=api) }}")
|
||||
| {% else %}
|
||||
.bg-primary.rounded.h-100
|
||||
a.d-flex.align-items-center.justify-content-center.h-100.text-white(href="{{ node.url }}")
|
||||
i.pi-document-text
|
||||
| {% endif %}
|
||||
|
||||
.col-md-11
|
||||
h5
|
||||
a.text-muted(href="{{ node.url }}") {{node.name}}
|
||||
|
||||
.text-muted.
|
||||
#[span(title="{{node._created}}") {{node._created | pretty_date }}]
|
||||
{% if node._created != node._updated %}
|
||||
#[span(title="{{node._updated}}") (updated {{node._updated | pretty_date }})]
|
||||
{% endif %}
|
||||
{% if node.properties.category %} · {{node.properties.category}}{% endif %}
|
||||
· {{node.user.full_name}}
|
||||
{% if node.properties.status != 'published' %} · {{ node.properties.status}} {% endif %}
|
||||
|
||||
| {% endmacro %}
|
||||
|
||||
|
||||
//- ******************************************************* -//
|
||||
| {% macro render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta, pages=None) %}
|
||||
| {% if can_create_blog_posts %}
|
||||
+nav-secondary
|
||||
+nav-secondary-link(href="{{url_for('nodes.posts_create', project_id=project._id)}}")
|
||||
span.text-success
|
||||
i.pi-plus
|
||||
| Create New Blog Post
|
||||
| {% endif %}
|
||||
|
||||
| {% if posts %}
|
||||
| {{ render_blog_post(posts[0], project=project, pages=pages) }}
|
||||
|
||||
.container
|
||||
.row
|
||||
.col-md-9.mx-auto
|
||||
| {% for node in posts[1:] %}
|
||||
| {% if loop.first %}
|
||||
h5.text-muted.text-center Blasts from the past
|
||||
| {% endif %}
|
||||
| {{ render_blog_list_item(node) }}
|
||||
| {% endfor %}
|
||||
|
||||
| {% if more_posts_available %}
|
||||
.blog-archive-navigation
|
||||
a(href="{{ project.blog_archive_url }}")
|
||||
| {{posts_meta.total - posts|length}} more blog posts over here
|
||||
i.pi-angle-right
|
||||
| {% endif %}
|
||||
|
||||
| {% else %}
|
||||
|
||||
.text-center
|
||||
p No posts... yet!
|
||||
|
||||
| {% endif %} {# posts #}
|
||||
| {% endmacro %}
|
||||
|
||||
|
||||
//- Macro for rendering the navigation buttons for prev/next pages -//
|
||||
| {% macro render_archive_pagination(project) %}
|
||||
.blog-archive-navigation
|
||||
| {% if project.blog_archive_prev %}
|
||||
a.archive-nav-button(
|
||||
href="{{ project.blog_archive_prev }}", rel="prev")
|
||||
i.pi-angle-left
|
||||
| Previous page
|
||||
| {% else %}
|
||||
span.archive-nav-button
|
||||
i.pi-angle-left
|
||||
| Previous page
|
||||
| {% endif %}
|
||||
|
||||
a.archive-nav-button(
|
||||
href="{{ url_for('main.project_blog', project_url=project.url) }}")
|
||||
| Blog Index
|
||||
|
||||
| {% if project.blog_archive_next %}
|
||||
a.archive-nav-button(
|
||||
href="{{ project.blog_archive_next }}", rel="next")
|
||||
| Next page
|
||||
i.pi-angle-right
|
||||
| {% else %}
|
||||
span.archive-nav-button
|
||||
| Next page
|
||||
i.pi-angle-right
|
||||
| {% endif %}
|
||||
|
||||
| {% endmacro %}
|
||||
|
||||
| {% macro render_archive(project, posts, posts_meta) %}
|
||||
|
||||
| {{ render_archive_pagination(project) }}
|
||||
|
||||
| {% for node in posts %}
|
||||
| {{ render_blog_list_item(node) }}
|
||||
| {% endfor %}
|
||||
|
||||
| {{ render_archive_pagination(project) }}
|
||||
|
||||
| {% endmacro %}
|
@@ -1,213 +0,0 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% from '_macros/_navigation.html' import navigation_tabs %}
|
||||
include ../mixins/components
|
||||
|
||||
| {% set title = 'organizations' %}
|
||||
| {% block page_title %}Organizations{% endblock %}
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:title", content="Dashboard")
|
||||
meta(name="twitter:title", content="Blender Cloud")
|
||||
|
||||
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
|
||||
meta(property="og:type", content="website")
|
||||
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
| {% endblock %}
|
||||
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
| {{ navigation_tabs(title) }}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block body %}
|
||||
+nav-secondary
|
||||
| {% if can_create_organization %}
|
||||
+nav-secondary-link(
|
||||
class="create",
|
||||
onclick='createNewOrganization(this)')
|
||||
span.text-success
|
||||
i.pi-plus
|
||||
| Create Organization
|
||||
| {% endif %}
|
||||
|
||||
li#create_organization_result_panel.result
|
||||
|
||||
.container-fluid.dashboard-container
|
||||
.row
|
||||
.col-md-6
|
||||
ul.projects__list
|
||||
| {% if organizations %}
|
||||
| {% for organization in organizations['_items'] %}
|
||||
| {% set link_url = url_for('pillar.web.organizations.view_embed', organization_id=organization._id) %}
|
||||
li.projects__list-item(
|
||||
data-url="{{ link_url }}",
|
||||
id="organization-{{ organization._id }}")
|
||||
a.projects__list-thumbnail(
|
||||
href="{{ link_url }}")
|
||||
i.pi-users
|
||||
.projects__list-details
|
||||
a.title(href="{{ link_url }}")
|
||||
| {{ organization.name }}
|
||||
|
||||
ul.meta
|
||||
li(title="Members")
|
||||
| {{ organization.members|hide_none|count }} Member{{ organization.members|hide_none|count|pluralize }}
|
||||
| {% if (organization.unknown_members|count) != 0 %}
|
||||
| ({{ organization.unknown_members|hide_none|count }} pending)
|
||||
| {% endif %}
|
||||
li(title="Seats")
|
||||
| {{ organization.seat_count }} Seat{{ organization.seat_count|pluralize }}
|
||||
|
||||
| {% endfor %}
|
||||
| {% else %}
|
||||
li.projects__list-item
|
||||
a.projects__list-thumbnail
|
||||
i.pi-blender-cloud
|
||||
.projects__list-details
|
||||
span Create an Organization to get started!
|
||||
| {% endif %}
|
||||
|
||||
.col-md-6.py-1.pb-3
|
||||
#item-details
|
||||
|
||||
| {% endblock %}
|
||||
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typeahead-0.11.1.min.js')}}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.autocomplete-0.22.0.min.js') }}", async=true)
|
||||
|
||||
script.
|
||||
|
||||
/* Returns a more-or-less reasonable message given an error response object. */
|
||||
function xhrErrorResponseMessage(err) {
|
||||
if (typeof err.responseJSON == 'undefined')
|
||||
return err.statusText;
|
||||
|
||||
if (typeof err.responseJSON._error != 'undefined' && typeof err.responseJSON._error.message != 'undefined')
|
||||
return err.responseJSON._error.message;
|
||||
|
||||
if (typeof err.responseJSON._message != 'undefined')
|
||||
return err.responseJSON._message
|
||||
|
||||
return err.statusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an organization in the #item-details div.
|
||||
*/
|
||||
function item_open(item_id, pushState)
|
||||
{
|
||||
if (item_id === undefined ) {
|
||||
throw new ReferenceError("item_open(" + item_id + ") called.");
|
||||
}
|
||||
|
||||
// Style elements starting with item_type and dash, e.g. "#job-uuid"
|
||||
var clean_classes = 'active processing';
|
||||
var current_item = $('#organization-' + item_id);
|
||||
|
||||
$('[id^="organization-"]').removeClass(clean_classes);
|
||||
current_item
|
||||
.removeClass(clean_classes)
|
||||
.addClass('processing');
|
||||
|
||||
var item_url = '/o/' + item_id;
|
||||
|
||||
$.get(item_url, function(item_data) {
|
||||
$('#item-details').html(item_data);
|
||||
|
||||
current_item
|
||||
.removeClass(clean_classes)
|
||||
.addClass('active');
|
||||
|
||||
}).fail(function(xhr) {
|
||||
if (console) {
|
||||
console.log('Error fetching organization', item_id, 'from', item_url);
|
||||
console.log('XHR:', xhr);
|
||||
}
|
||||
|
||||
current_item.removeClass(clean_classes);
|
||||
toastr.error('Failed to open organization');
|
||||
|
||||
if (xhr.status) {
|
||||
$('#item-details').html(xhr.responseText);
|
||||
} else {
|
||||
$('#item-details').html('<p class="text-danger">Opening ' + item_type + ' failed. There possibly was ' +
|
||||
'an error connecting to the server. Please check your network connection and ' +
|
||||
'try again.</p>');
|
||||
}
|
||||
});
|
||||
|
||||
// Determine whether we should push the new state or not.
|
||||
pushState = (typeof pushState !== 'undefined') ? pushState : true;
|
||||
if (!pushState) return;
|
||||
|
||||
// Push the correct URL onto the history.
|
||||
var push_state = {itemId: item_id};
|
||||
|
||||
window.history.pushState(
|
||||
push_state,
|
||||
'Organization: ' + item_id,
|
||||
item_url
|
||||
);
|
||||
}
|
||||
|
||||
$('li.projects__list-item').click(function(e){
|
||||
url = $(this).data('url');
|
||||
if (typeof url === 'undefined') return;
|
||||
|
||||
window.location.href = url;
|
||||
if (console) console.log(url);
|
||||
|
||||
$(this).addClass('active');
|
||||
$(this).find('.projects__list-thumbnail i')
|
||||
.removeAttr('class')
|
||||
.addClass('pi-spin spin');
|
||||
});
|
||||
|
||||
|
||||
{% if open_organization_id %}
|
||||
$(function() { item_open('{{ open_organization_id }}', false); });
|
||||
{% endif %}
|
||||
|
||||
{% if can_create_organization %}
|
||||
function createNewOrganization(button) {
|
||||
$(button)
|
||||
.attr('disabled', 'disabled')
|
||||
.fadeTo(200, 0.1);
|
||||
$('#create_organization_result_panel').html('');
|
||||
|
||||
// TODO: create a form to get the initial info from the user.
|
||||
$.post(
|
||||
'{{ url_for('pillar.web.organizations.create_new') }}',
|
||||
{
|
||||
name: 'New Organization',
|
||||
seat_count: 1,
|
||||
}
|
||||
)
|
||||
.done(function(result) {
|
||||
var $p = $('<p>').text('organization created, reloading list.')
|
||||
$('#create_organization_result_panel').html($p);
|
||||
|
||||
window.location.href = result.location;
|
||||
})
|
||||
.fail(function(err) {
|
||||
var msg = xhrErrorResponseMessage(err);
|
||||
$('#create_organization_result_panel').html('Error creating organization: ' + msg);
|
||||
|
||||
$(button)
|
||||
.fadeTo(1000, 1.0)
|
||||
.queue(function() {
|
||||
$(this)
|
||||
.removeAttr('disabled')
|
||||
.dequeue()
|
||||
;
|
||||
})
|
||||
})
|
||||
;
|
||||
return false;
|
||||
}
|
||||
{% endif %}
|
||||
| {% endblock %}
|
@@ -1,35 +0,0 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% block page_title %}Production of Stuff{% endblock %}
|
||||
| {% block head %}
|
||||
script(src="{{ url_for('static_cloud', filename='assets/js/tagged_assets.min.js') }}")
|
||||
|
||||
script.
|
||||
$(function() {
|
||||
$('ul.asset-list').loadTaggedAssets();
|
||||
})
|
||||
| {% endblock %}
|
||||
| {% block body %}
|
||||
#page-container
|
||||
#page-content
|
||||
h2 Production of Stuff
|
||||
p.
|
||||
Here are our hand-selected assets 'bout stuff.
|
||||
|
||||
h3 Animation
|
||||
ul.asset-list(data-asset-tag="animation")
|
||||
|
||||
h3 Modelling
|
||||
ul.asset-list(data-asset-tag="modelling")
|
||||
|
||||
h3 Rigging
|
||||
ul.asset-list(data-asset-tag="rigging")
|
||||
|
||||
h3 pipeline
|
||||
ul.asset-list(data-asset-tag="pipeline")
|
||||
|
||||
h3 lookdev
|
||||
ul.asset-list(data-asset-tag="lookdev")
|
||||
|
||||
h3 crazyspace
|
||||
ul.asset-list(data-asset-tag="crazyspace")
|
||||
| {% endblock body%}
|
@@ -1,59 +0,0 @@
|
||||
| {% extends 'projects/home_layout.html' %}
|
||||
| {% set subtab = 'blender_sync' %}
|
||||
| {% set learn_more_btn_url = '/blog/introducing-blender-sync' %}
|
||||
| {% block currenttab %}
|
||||
.container-fluid
|
||||
section.nav-tabs__tab.active#tab-blender_sync
|
||||
.tab_header-container
|
||||
.tab_header-intro(
|
||||
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
|
||||
.tab_header-intro_text
|
||||
h2 Connect Blender with the Cloud
|
||||
p
|
||||
| Save your Blender preferences and keymaps once, load them anywhere.
|
||||
<br/>
|
||||
| Use the
|
||||
=' '
|
||||
a(href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip') Blender Cloud add-on
|
||||
=' '
|
||||
| to synchronise your settings from within Blender.
|
||||
|
||||
| {% if show_addon_download_buttons %}
|
||||
.row
|
||||
.col-md-6
|
||||
a.btn.btn-block.btn-outline-success(
|
||||
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip")
|
||||
i.pi-download
|
||||
| Download <small>v</small>{{ config.BLENDER_CLOUD_ADDON_VERSION }}
|
||||
.col-md-6
|
||||
a.btn.btn-link(
|
||||
href="{{ learn_more_btn_url }}")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
| {% endif %}
|
||||
|
||||
.tab_header-intro_icons
|
||||
i.pi-blender
|
||||
i.pi-heart-filled
|
||||
i.pi-blender-cloud
|
||||
|
||||
| {% for version in synced_versions %}
|
||||
.blender_sync-main
|
||||
.blender_sync-main-header
|
||||
h5.blender_sync-main-title
|
||||
i.pi-blender
|
||||
| Blender {{ version.version }}
|
||||
.blender_sync-main-last
|
||||
| Last synced on: {{ version.date|pretty_date }}
|
||||
| {% else %}
|
||||
.blender_sync-main.empty
|
||||
.blender_sync-main-header
|
||||
span.blender_sync-main-title
|
||||
| No settings synced yet
|
||||
<hr/>
|
||||
a.download(
|
||||
href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip')
|
||||
| Download add-on
|
||||
| {% endfor %}
|
||||
| {% endblock %}
|
||||
|
@@ -1,51 +0,0 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% from '_macros/_navigation.html' import navigation_tabs %}
|
||||
include ../mixins/components
|
||||
|
||||
| {% set title = 'home' %}
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:type", content="website")
|
||||
meta(property="og:url", content="https://cloud.blender.org{{ request.path }}")
|
||||
|
||||
meta(property="og:title", content="Blender Cloud - Home")
|
||||
meta(name="twitter:title", content="Blender Cloud")
|
||||
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block page_title %}
|
||||
| {{current_user.full_name}}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
| {{ navigation_tabs(title) }}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block body %}
|
||||
.dashboard-container
|
||||
|
||||
section#projects.bg-white
|
||||
+nav-secondary()(id='sub-nav-tabs__list')
|
||||
+nav-secondary-link(id="subtab-blender_sync", data-tab-url="{{ url_for('projects.home_project')}}")
|
||||
| Blender Sync
|
||||
|
||||
+nav-secondary-link(id="subtab-images", data-tab-url="{{ url_for('projects.home_project_shared_images')}}")
|
||||
| Images
|
||||
|
||||
| {% block currenttab %}{% endblock %}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script.
|
||||
$(document).ready(function () {
|
||||
$('#subtab-{{ subtab }}').addClass('active');
|
||||
|
||||
var $nav_tabs = $('#sub-nav-tabs__list').find('a.nav-link');
|
||||
$nav_tabs.on('click', function (e) {
|
||||
console.log($(this));
|
||||
window.location = $(this).attr('data-tab-url');
|
||||
});
|
||||
});
|
||||
| {% endblock %}
|
@@ -1,300 +0,0 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% from '_macros/_navigation.html' import navigation_tabs %}
|
||||
include ../mixins/components
|
||||
|
||||
| {% set title = 'dashboard' %}
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:title", content="Dashboard")
|
||||
meta(name="twitter:title", content="Blender Cloud")
|
||||
|
||||
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
|
||||
meta(property="og:type", content="website")
|
||||
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block page_title %}
|
||||
| {{current_user.full_name}}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block css %}
|
||||
| {{ super() }}
|
||||
style.
|
||||
.deleted-projects-toggle {
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
font-size: 20px;
|
||||
padding: 3px;
|
||||
text-shadow: 0 0 2px white;
|
||||
}
|
||||
.deleted-projects-toggle .show-deleted {
|
||||
color: #aaa;
|
||||
}
|
||||
.deleted-projects-toggle .hide-deleted {
|
||||
color: #bbb;
|
||||
}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
| {{ navigation_tabs(title) }}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
|
||||
| {% block body %}
|
||||
.dashboard-container
|
||||
section.dashboard-main
|
||||
section#projects.bg-white
|
||||
+nav-secondary()(id='sub-nav-tabs__list')
|
||||
+nav-secondary-link(data-tab-toggle='own_projects', class="active")
|
||||
| Own Projects
|
||||
| {% if projects_user|length != 0 %}
|
||||
span ({{ projects_user|length }})
|
||||
| {% endif %}
|
||||
|
||||
+nav-secondary-link(data-tab-toggle='shared')
|
||||
| Shared with me
|
||||
| {% if projects_shared|length != 0 %}
|
||||
span ({{ projects_shared|length }})
|
||||
| {% endif %}
|
||||
|
||||
| {% if current_user.has_cap('subscriber') %}
|
||||
+nav-secondary-link(
|
||||
id="project-create",
|
||||
data-url="{{ url_for('projects.create') }}",
|
||||
href="{{ url_for('projects.create') }}")
|
||||
span.text-success
|
||||
| #[i.pi-plus] Create New Project
|
||||
| {% elif current_user.has_cap('can-renew-subscription') %}
|
||||
+nav-secondary-link(
|
||||
id="project-create",
|
||||
data-url="{{ url_for('projects.create') }}",
|
||||
href="/renew",
|
||||
target="_blank")
|
||||
| #[i.pi-heart-filled.text-danger] Resubscribe to Create a Project
|
||||
| {% endif %}
|
||||
|
||||
nav.nav-tabs__tab.active#own_projects
|
||||
.deleted-projects-toggle
|
||||
| {% if show_deleted_projects %}
|
||||
a.hide-deleted(href="{{ request.base_url }}", title='Hide deleted projects')
|
||||
i.pi-trash
|
||||
| {% else %}
|
||||
a.show-deleted(href="{{ request.base_url }}?deleted=1", title='Show deleted projects')
|
||||
i.pi-trash
|
||||
| {% endif %}
|
||||
|
||||
ul.projects__list
|
||||
| {% for project in projects_deleted %}
|
||||
li.projects__list-item.deleted
|
||||
span.projects__list-thumbnail
|
||||
| {% if project.picture_square %}
|
||||
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
|
||||
| {% else %}
|
||||
i.pi-blender-cloud
|
||||
| {% endif %}
|
||||
.projects__list-details
|
||||
span.title {{ project.name }}
|
||||
ul.meta
|
||||
li.status.deleted Deleted
|
||||
li.edit
|
||||
a(href="javascript:undelete_project('{{ project._id }}')") Restore project
|
||||
| {% else %}
|
||||
| {% if show_deleted_projects %}
|
||||
li.projects__list-item.deleted You have no recenly deleted projects. Deleted projects can be restored within a month after deletion.
|
||||
| {% endif %}
|
||||
| {% endfor %}
|
||||
|
||||
| {% for project in projects_user %}
|
||||
li.projects__list-item(
|
||||
data-url="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
a.projects__list-thumbnail(
|
||||
href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
| {% if project.picture_square %}
|
||||
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
|
||||
| {% else %}
|
||||
i.pi-blender-cloud
|
||||
| {% endif %}
|
||||
.projects__list-details
|
||||
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
| {{ project.name }}
|
||||
|
||||
ul.meta
|
||||
li.status(
|
||||
class="{{ project.is_private | yesno('private,public,') }}",
|
||||
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
|
||||
| {{ project.is_private | yesno('Private,Public,') }}
|
||||
li.when(title="{{ project._created }}") {{ project._created | pretty_date }}
|
||||
li.edit
|
||||
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
|
||||
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
|
||||
li.pending Not Published
|
||||
| {% endif %}
|
||||
| {% else %}
|
||||
| {% if current_user.has_cap('subscriber') %}
|
||||
li.projects__list-item(data-url="{{ url_for('projects.create') }}")
|
||||
a.projects__list-thumbnail
|
||||
i.pi-plus
|
||||
.projects__list-details
|
||||
a.title(href="{{ url_for('projects.create') }}")
|
||||
| Create a project to get started!
|
||||
| {% elif current_user.has_cap('can-renew-subscription') %}
|
||||
li.projects__list-item(data-url="https://store.blender.org/renew-my-subscription.php")
|
||||
a.projects__list-thumbnail
|
||||
i.pi-plus
|
||||
.projects__list-details
|
||||
a.title(href="https://store.blender.org/renew-my-subscription.php")
|
||||
| Renew your Blender Cloud subscription to create your own projects!
|
||||
| {% else %}
|
||||
li.projects__list-item(data-url="/join")
|
||||
a.projects__list-thumbnail
|
||||
i.pi-plus
|
||||
.projects__list-details
|
||||
a.title(href="/join")
|
||||
| Join Blender Cloud to create your own projects!
|
||||
| {% endif %}
|
||||
| {% endfor %}
|
||||
|
||||
section.nav-tabs__tab#shared(style='display: none')
|
||||
ul.projects__list
|
||||
| {% if projects_shared %}
|
||||
| {% for project in projects_shared %}
|
||||
li.projects__list-item(
|
||||
data-url="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
a.projects__list-thumbnail(
|
||||
href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
| {% if project.picture_square %}
|
||||
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
|
||||
| {% else %}
|
||||
i.pi-blender-cloud
|
||||
| {% endif %}
|
||||
.projects__list-details
|
||||
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
| {{ project.name }}
|
||||
|
||||
ul.meta
|
||||
li.status(
|
||||
class="{{ project.is_private | yesno('private,public,') }}",
|
||||
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
|
||||
| {{ project.is_private | yesno('Private,Public,') }}
|
||||
li.when {{ project._created | pretty_date }}
|
||||
li.who by {{ project.user.full_name }}
|
||||
li.edit
|
||||
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
|
||||
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
|
||||
li.pending Not Published
|
||||
| {% endif %}
|
||||
|
||||
li.leave
|
||||
span.user-remove-prompt
|
||||
| Leave Project
|
||||
|
||||
span.user-remove
|
||||
| Are you sure?
|
||||
span.user-remove-confirm(
|
||||
user-id="{{ current_user.objectid }}",
|
||||
project-url="{{url_for('projects.sharing', project_url=project.url)}}")
|
||||
i.pi-check
|
||||
| Yes, leave
|
||||
span.user-remove-cancel
|
||||
i.pi-cancel
|
||||
| No, cancel
|
||||
|
||||
| {% endfor %}
|
||||
| {% else %}
|
||||
li.projects__list-item
|
||||
a.projects__list-thumbnail
|
||||
i.pi-heart-broken
|
||||
.projects__list-details
|
||||
.title
|
||||
| No projects shared with you... yet!
|
||||
| {% endif %}
|
||||
| {% endblock %}
|
||||
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script.
|
||||
$(document).ready(function() {
|
||||
|
||||
$('li.projects__list-item').click(function(e){
|
||||
url = $(this).data('url');
|
||||
if (typeof url === 'undefined') return;
|
||||
|
||||
window.location.href = url;
|
||||
if (console) console.log(url);
|
||||
|
||||
$(this).addClass('active');
|
||||
$(this).find('.projects__list-thumbnail i')
|
||||
.removeAttr('class')
|
||||
.addClass('pi-spin spin');
|
||||
});
|
||||
|
||||
// Tabs behavior
|
||||
var $nav_tabs_list = $('#sub-nav-tabs__list');
|
||||
var $nav_tabs = $nav_tabs_list.find('a.nav-link');
|
||||
$nav_tabs.on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
$nav_tabs.removeClass('active');
|
||||
$(this).addClass('active');
|
||||
|
||||
$('.nav-tabs__tab').hide();
|
||||
$('#' + $(this).attr('data-tab-toggle')).show();
|
||||
});
|
||||
|
||||
// Leave project
|
||||
var $projects_list = $('ul.projects__list');
|
||||
$projects_list.find('span.user-remove-prompt').on('click', function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
$(this).next().show();
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
$projects_list.find('span.user-remove-cancel').on('click', function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
$(this).parent().prev().show();
|
||||
$(this).parent().hide();
|
||||
});
|
||||
|
||||
$projects_list.find('span.user-remove-confirm').on('click', function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var parent = $(this).closest('.projects__list-item');
|
||||
|
||||
function removeUser(userId, projectUrl){
|
||||
$.post(projectUrl, {user_id: userId, action: 'remove'})
|
||||
.done(function (data) {
|
||||
parent.remove();
|
||||
});
|
||||
}
|
||||
|
||||
removeUser($(this).attr('user-id'), $(this).attr('project-url'));
|
||||
});
|
||||
|
||||
hopToTop(); // Display jump to top button
|
||||
});
|
||||
|
||||
|
||||
var patch_url = '{{ url_for('projects.patch.patch_project', project_id='PROJECTID') }}';
|
||||
function undelete_project(project_id) {
|
||||
console.log('undeleting project', project_id);
|
||||
$.ajax({
|
||||
url: patch_url.replace('PROJECTID', project_id),
|
||||
method: 'PATCH',
|
||||
data: JSON.stringify({'op': 'undelete'}),
|
||||
contentType: 'application/json'
|
||||
})
|
||||
.done(function(data, textStatus, jqXHR) {
|
||||
location.href = jqXHR.getResponseHeader('Location');
|
||||
})
|
||||
.fail(function(err) {
|
||||
toastr.error(xhrErrorResponseMessage(err), 'Undeletion failed');
|
||||
})
|
||||
}
|
||||
| {% endblock %}
|
@@ -51,7 +51,7 @@ meta(name="twitter:description", content="Blender Cloud, your source for open co
|
||||
|
||||
| {% endif %}
|
||||
|
||||
meta(property="og:url", content="{{url_for('projects.view_node', project_url=project.url, node_id=node._id, _external=True)}}")
|
||||
meta(property="og:url", content="{{url_for('projects.view_node', project_url=project.url, node_id=node._id)}}")
|
||||
| {% else %}
|
||||
meta(property="og:title", content="{{ project.name }} Blog on Blender Cloud")
|
||||
meta(name="twitter:title", content="{{ project.name }} Blog on Blender Cloud")
|
||||
@@ -75,47 +75,45 @@ meta(property="og:url", content="{{url_for('projects.view', project_url=project.
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-6.2.8.min.js') }}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-ga-0.4.2.min.js') }}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-hotkeys-0.2.20.min.js') }}")
|
||||
script(src="{{ url_for('static_cloud', filename='assets/js/photoswipe.min.js') }}")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block css %}
|
||||
| {{ super() }}
|
||||
link(href="{{ url_for('static_cloud', filename='assets/css/project-landing.css') }}", rel="stylesheet")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block body %}
|
||||
header
|
||||
//a(href="{{ url_for( 'projects.view', project_url=project.url) }}")
|
||||
img.header(src="{{ project.picture_header.thumbnail('h', api=api) }}")
|
||||
.jumbotron.jumbotron-fluid(
|
||||
style="background-image: url('{{ project.picture_header.thumbnail('h', api=api) }}'); background-position: 50% 50%;")
|
||||
|
||||
| {# Secondary Navigation #}
|
||||
| {% block navbar_secondary %}
|
||||
| {{ projectmacros.render_secondary_navigation(project, pages=pages) }}
|
||||
|
||||
| {% endblock navbar_secondary %}
|
||||
#container.landing
|
||||
|
||||
.container.landing
|
||||
section.node-details-container.project
|
||||
.node-details-title
|
||||
.node-details-title.container
|
||||
h1 {{ project.name }}
|
||||
|
||||
| {% if project.description %}
|
||||
.node-details-description
|
||||
| {{ project | markdowned('description') }}
|
||||
| {% endif %}
|
||||
|
||||
|
||||
section.gallery
|
||||
h2 Gallery
|
||||
h2.text-center Gallery
|
||||
.container
|
||||
| {% for n in activity_stream %}
|
||||
| {% if n.node_type not in ['comment', 'post'] and n.picture %}
|
||||
.thumbnail.expand-image-links
|
||||
.img-container
|
||||
.thumbnail-container
|
||||
a(href="{{ n.picture.thumbnail('l', api=api) }}", data-node_id="{{ n._id }}")
|
||||
img(src="{{ n.picture.thumbnail('l', api=api) }}", alt="{{ n.name }}")
|
||||
.img-caption.table
|
||||
| {# Not using for the moment
|
||||
span.table-cell {{ n.name }}
|
||||
| #}
|
||||
| {% endif %}
|
||||
| {% endfor %}
|
||||
div(class="clearfix")
|
||||
.clearfix
|
||||
| {% if project.nodes_featured %}
|
||||
| {# In some cases featured_nodes might might be embedded #}
|
||||
| {% if '_id' in project.nodes_featured[0] %}
|
||||
@@ -123,42 +121,39 @@ header
|
||||
| {% else %}
|
||||
| {% set featured_node_id=project.nodes_featured[0] %}
|
||||
| {% endif %}
|
||||
a.btn(href="{{ url_for('projects.view_node', project_url=project.url, node_id=featured_node_id) }}") See more
|
||||
p.cta-arrow.text-center
|
||||
a(href="{{ url_for('projects.view_node', project_url=project.url, node_id=featured_node_id) }}")
|
||||
| See more
|
||||
i.pi-angle-right
|
||||
| {% endif %}
|
||||
|
||||
|
||||
|
||||
section.node-extra
|
||||
h2 Latest Updates
|
||||
|
||||
h2.text-center Latest Updates
|
||||
| {% if activity_stream %}
|
||||
.node-updates
|
||||
ul.node-updates-list
|
||||
.container.card-container
|
||||
.row
|
||||
| {% for n in activity_stream %}
|
||||
| {% if n.node_type == 'post' %}
|
||||
li.node-updates-list-item(
|
||||
data-node_id="{{ n._id }}",
|
||||
class="{{ n.node_type }} {{ n.properties.content_type | hide_none }}")
|
||||
a.image(href="{{ url_for_node(node=n) }}")
|
||||
.col-md-4
|
||||
.card
|
||||
a.card-image(href="{{ url_for_node(node=n) }}")
|
||||
| {% if n.picture %}
|
||||
img(src="{{ n.picture.thumbnail('l', api=api) }}")
|
||||
img.card-img-top(src="{{ n.picture.thumbnail('l', api=api) }}")
|
||||
| {% endif %}
|
||||
|
||||
.info
|
||||
a.title(href="{{ url_for_node(node=n) }}") {{ n.name }}
|
||||
p.description(href="{{ url_for_node(node=n) }}")
|
||||
| {% if n.node_type == 'post' %}
|
||||
| {{ n.properties | markdowned('content') | striptags | truncate(140, end="... <small>read more</small>") | safe | hide_none }}
|
||||
| {% else %}
|
||||
| {{ n | markdowned('description') | striptags | truncate(140, end="... <small>read more</small>") | safe | hide_none }}
|
||||
| {% endif %}
|
||||
//span.details
|
||||
// span.what {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}{{ n.node_type | undertitle }}{% endif %} ·
|
||||
// span.when {{ n._updated | pretty_date }} by
|
||||
// span.who {{ n.user.full_name }}
|
||||
.card-body
|
||||
h4.card-title
|
||||
a(href="{{ url_for_node(node=n) }}") {{ n.name }}
|
||||
p.card-text {{ n.properties | markdowned('content') | striptags | truncate(140, end="... <small>read more</small>") | safe | hide_none }}
|
||||
| {% endif %}
|
||||
| {% endfor %}
|
||||
| {% endif %}
|
||||
a.btn(href="{{ url_for('main.project_blog', project_url=project.url) }}") See all updates
|
||||
.clearfix
|
||||
p.cta-arrow.text-center
|
||||
a(href="{{ url_for('main.project_blog', project_url=project.url) }}")
|
||||
| See all updates
|
||||
i.pi-angle-right
|
||||
|
||||
| {% endblock body %}
|
||||
|
||||
|
@@ -1,688 +0,0 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% from '_macros/_add_new_menu.html' import add_new_menu %}
|
||||
include ../mixins/components
|
||||
|
||||
| {% block page_title %}{{ project.name }}{% endblock%}
|
||||
| {% set title = 'project' %}
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:type", content="website")
|
||||
|
||||
| {% if og_picture %}
|
||||
meta(property="og:image", content="{{ og_picture.thumbnail('l', api=api) }}")
|
||||
meta(name="twitter:image", content="{{ og_picture.thumbnail('l', api=api) }}")
|
||||
| {% elif node and node.picture %}
|
||||
meta(property="og:image", content="{{ node.picture.thumbnail('l', api=api) }}")
|
||||
meta(name="twitter:image", content="{{ node.picture.thumbnail('l', api=api) }}")
|
||||
| {% elif project.picture_header %}
|
||||
meta(property="og:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
|
||||
meta(name="twitter:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
|
||||
| {% endif %}
|
||||
|
||||
| {% if show_project %}
|
||||
meta(property="og:title", content="{{ project.name }} - Blender Cloud")
|
||||
meta(name="twitter:title", content="{{ project.name }} - Blender Cloud")
|
||||
meta(property="og:description", content="{{ project.summary }}")
|
||||
meta(name="twitter:description", content="{{ project.summary }}")
|
||||
|
||||
meta(property="og:url", content="{{ url_for('projects.view', project_url=project.url, _external=True) }}")
|
||||
| {% else %}
|
||||
|
||||
| {% if node %}
|
||||
meta(property="og:title", content="{{ node.name }} - Blender Cloud")
|
||||
meta(name="twitter:title", content="{{ node.name }} on Blender Cloud")
|
||||
|
||||
| {% if node.node_type == 'post' %}
|
||||
|
||||
| {% if node.properties.content %}
|
||||
meta(property="og:description", content="{{ node.properties.content | truncate(180) }}")
|
||||
meta(name="twitter:description", content="{{ node.properties.content | truncate(180) }}")
|
||||
| {% else %}
|
||||
meta(property="og:description", content="Blender Cloud, your source for open content and training")
|
||||
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
|
||||
| {% endif %}
|
||||
|
||||
| {% else %}
|
||||
|
||||
| {% if node.description %}
|
||||
meta(property="og:description", content="{{ node.description | truncate(180) }}")
|
||||
meta(name="twitter:description", content="{{ node.description | truncate(180) }}")
|
||||
| {% else %}
|
||||
meta(property="og:description", content="Blender Cloud, your source for open content and training")
|
||||
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
|
||||
| {% endif %}
|
||||
|
||||
| {% endif %}
|
||||
|
||||
meta(property="og:url", content="{{url_for('projects.view_node', project_url=project.url, node_id=node._id)}}")
|
||||
| {% else %}
|
||||
meta(property="og:title", content="{{ project.name }} Blog on Blender Cloud")
|
||||
meta(name="twitter:title", content="{{ project.name }} Blog on Blender Cloud")
|
||||
meta(property="og:description", content="{{ project.summary }}")
|
||||
meta(name="twitter:description", content="{{ project.summary }}")
|
||||
|
||||
meta(property="og:url", content="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| {% endif %}
|
||||
|
||||
| {% endif %}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block head %}
|
||||
link(href="{{ url_for('static_pillar', filename='assets/jstree/themes/default/style.min.css') }}", rel="stylesheet")
|
||||
| {% if node %}
|
||||
link(rel="amphtml", href="{{ url_for('nodes.view', node_id=node._id, _external=True, format='amp') }}")
|
||||
| {% endif %}
|
||||
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-6.2.8.min.js') }}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-ga-0.4.2.min.js') }}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-hotkeys-0.2.20.min.js') }}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/video_plugins.min.js') }}")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block css %}
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
|
||||
link(href="{{ url_for('static_pillar', filename='assets/css/project-main.css') }}", rel="stylesheet")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
+nav-secondary()(class="bg-white")
|
||||
| {% if project.category == 'course' %}
|
||||
li.text-capitalize
|
||||
a.nav-link.text-muted.px-0(href="{{ url_for('cloud.courses') }}")
|
||||
| Courses
|
||||
| {% elif project.category == 'workshop' %}
|
||||
li.text-capitalize
|
||||
a.nav-link.text-muted.px-0(href="{{ url_for('cloud.workshops') }}")
|
||||
| Workshops
|
||||
li.px-1
|
||||
i.pi-angle-right
|
||||
| {% endif %}
|
||||
|
||||
+nav-secondary-link(
|
||||
class="px-0",
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| {{ project.name }}
|
||||
|
||||
| {% if project.category == "open_project" %}
|
||||
+nav-secondary-link(
|
||||
class="active",
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| Explore
|
||||
+nav-secondary-link(
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| Blog
|
||||
+nav-secondary-link(
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| About
|
||||
+nav-secondary-link(
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| Team
|
||||
+nav-secondary-link(
|
||||
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
| Awards
|
||||
| {% endif %}
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block body %}
|
||||
#project-container
|
||||
#project-side-container
|
||||
#project_sidebar.bg-white
|
||||
ul.project-tabs.p-0
|
||||
//- li.tabs-thumbnail(class="{% if project.picture_square %}image{% endif %}")
|
||||
//- a(href="{{url_for('projects.view', project_url=project.url)}}")
|
||||
//- #project-loading
|
||||
//- i.pi-spin
|
||||
//- | {% if project.picture_square %}
|
||||
//- img(src="{{ project.picture_square.thumbnail('b', api=api) }}")
|
||||
//- | {% else %}
|
||||
//- i.pi-home
|
||||
//- | {% endif %}
|
||||
|
||||
li.tabs-browse(
|
||||
title="Browse",
|
||||
data-toggle="tooltip",
|
||||
data-placement="right",
|
||||
class="active")
|
||||
a(href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
i.pi-folder
|
||||
|
||||
| {% if not project.is_private %}
|
||||
| {% if current_user_is_subscriber %}
|
||||
li.tabs-search(
|
||||
title="Search",
|
||||
data-toggle="tooltip",
|
||||
data-placement="right")
|
||||
a(href="{{ url_for('projects.search', project_url=project.url, _external=True)}} ")
|
||||
i.pi-search
|
||||
| {% else %}
|
||||
li.tabs-search(
|
||||
title="Search (subscribers only)",
|
||||
data-toggle="tooltip",
|
||||
data-placement="right")
|
||||
a(href="{{ url_for('cloud.join') }}")
|
||||
i.pi-search
|
||||
| {% endif %}
|
||||
| {% endif %}
|
||||
| {{ extension_sidebar_links }}
|
||||
|
||||
| {% if project.has_method('PUT') %}
|
||||
li(
|
||||
title="Edit Project",
|
||||
data-toggle="tooltip",
|
||||
data-placement="right")
|
||||
a(href="{{ url_for('projects.edit', project_url=project.url) }}")
|
||||
i.pi-cog
|
||||
| {% endif %}
|
||||
|
||||
|
||||
#project_nav(class="{{ title }}")
|
||||
#project_nav-container
|
||||
| {% if title != 'about' %}
|
||||
//- +nav-secondary(class="bg-white")
|
||||
//- +nav-secondary-link(
|
||||
//- class="active",
|
||||
//- href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
//- | {{ project.name }}
|
||||
//- #project_nav-header.bg-white
|
||||
|
||||
//- a.project-title.p-2.font-weight-bold.text-dark(
|
||||
//- href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
|
||||
//- | {{ project.name }}
|
||||
|
||||
| {% block project_tree %}
|
||||
#project_tree.bg-white
|
||||
| {% endblock project_tree %}
|
||||
| {% endif %}
|
||||
|
||||
|
||||
#project_context-container.border-left
|
||||
| {% if project.has_method('PUT') %}
|
||||
#project_context-header.bg-white
|
||||
span#status-bar
|
||||
|
||||
ul.project-edit-tools.disabled
|
||||
li.dropdown
|
||||
button#item_add.project-mode-view.btn.btn-sm.btn-outline-secondary.dropdown-toggle(
|
||||
type="button",
|
||||
data-toggle="dropdown",
|
||||
aria-haspopup="true",
|
||||
aria-expanded="false")
|
||||
i.button-add-icon.pi-collection-plus
|
||||
| New...
|
||||
|
||||
ul.dropdown-menu.add_new-menu
|
||||
| {{ add_new_menu(project.node_types) }}
|
||||
|
||||
li.button-edit
|
||||
a#item_edit.project-mode-view.btn.btn-sm.btn-outline-secondary.ml-2(
|
||||
href="javascript:void(0);",
|
||||
title="Edit",
|
||||
data-project_id="{{project._id}}")
|
||||
i.button-edit-icon.pi-edit
|
||||
| Edit Project
|
||||
|
||||
li.dropdown
|
||||
button.dropdown-toggle.project-mode-view.btn.btn-sm.btn-outline-secondary.mx-2(
|
||||
type="button",
|
||||
data-toggle="dropdown",
|
||||
aria-haspopup="true",
|
||||
aria-expanded="false")
|
||||
i.pi-more-vertical.p-0
|
||||
|
||||
ul.dropdown-menu
|
||||
| {% if current_user.has_cap('admin') %}
|
||||
li.dropdown-item
|
||||
a#item_featured(
|
||||
href="javascript:void(0);",
|
||||
title="Feature on project's homepage",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-star
|
||||
| Toggle Featured
|
||||
|
||||
li.dropdown-item
|
||||
a#item_toggle_public(
|
||||
href="javascript:void(0);",
|
||||
title="Make it accessible to anyone",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-lock-open
|
||||
| Toggle Public
|
||||
| {% endif %}
|
||||
|
||||
li.dropdown-item
|
||||
a#item_toggle_projheader(
|
||||
href="javascript:void(0);",
|
||||
title="Feature as project's header",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-star
|
||||
| Toggle Project Header video
|
||||
|
||||
li.dropdown-item.button-move
|
||||
a#item_move(
|
||||
href="javascript:void(0);",
|
||||
title="Move into a folder...",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.button-move-icon.pi-move
|
||||
| Move
|
||||
|
||||
li.dropdown-item.button-delete
|
||||
a#item_delete(
|
||||
href="javascript:void(0);",
|
||||
title="Can be undone within a month",
|
||||
data-toggle="tooltip",
|
||||
data-placement="left")
|
||||
i.pi-trash
|
||||
| Delete Project
|
||||
|
||||
// Edit Mode
|
||||
li.button-cancel
|
||||
a#item_cancel.project-mode-edit.btn.btn-outline-secondary(
|
||||
href="javascript:void(0);",
|
||||
title="Cancel changes")
|
||||
i.button-cancel-icon.pi-cancel
|
||||
| Cancel
|
||||
|
||||
li.button-save
|
||||
a#item_save.project-mode-edit.btn.btn-outline-success.mx-2(
|
||||
href="javascript:void(0);",
|
||||
title="Save changes")
|
||||
i.button-save-icon.pi-check
|
||||
| Save Changes
|
||||
|
||||
| {% endif %}
|
||||
|
||||
| {% set utm_source = request.args.get('utm_source') %}
|
||||
| {% if config.UTM_LINKS and utm_source in config.UTM_LINKS %}
|
||||
#utm_container
|
||||
a(href="{{config.UTM_LINKS[utm_source]['link']}}")
|
||||
img(src="{{config.UTM_LINKS[utm_source]['image']}}", alt="gift", class="img-responsive")
|
||||
| {% endif %}
|
||||
#project_context
|
||||
| {% block project_context %}
|
||||
| {% if show_project %}
|
||||
| {% include "projects/view_embed.html" %}
|
||||
| {% endif %}
|
||||
| {% endblock project_context %}
|
||||
|
||||
#overlay-mode-move-container
|
||||
.overlay-container
|
||||
.title
|
||||
i.pi-angle-left
|
||||
| Select the <strong>folder</strong> where you want to move it
|
||||
.buttons
|
||||
button#item_move_accept.move.disabled
|
||||
| Select a Folder
|
||||
button#item_move_cancel.cancel
|
||||
i.pi-cancel
|
||||
| Cancel
|
||||
|
||||
| {% endblock %}
|
||||
|
||||
| {% block footer_container %}{% endblock %}
|
||||
|
||||
| {% block footer_scripts_pre %}
|
||||
|
||||
| {% if project.has_method('PUT') %}
|
||||
| {# JS containing the Edit, Add, Featured, and Move functions #}
|
||||
script(type="text/javascript", src="{{ url_for('static_pillar', filename='assets/js/project-edit.min.js') }}")
|
||||
| {% endif %}
|
||||
|
||||
script.
|
||||
function updateToggleProjHeaderMenuItem() {
|
||||
var $toggle_projheader = $('#item_toggle_projheader');
|
||||
|
||||
if (ProjectUtils.isProject()) {
|
||||
$toggle_projheader.hide();
|
||||
return;
|
||||
}
|
||||
if (ProjectUtils.nodeType() == 'asset') {
|
||||
$toggle_projheader.show();
|
||||
} else {
|
||||
$toggle_projheader.hide();
|
||||
}
|
||||
}
|
||||
$(updateToggleProjHeaderMenuItem);
|
||||
|
||||
// Function to update the interface on loadNodeContent, and edit/saving assets
|
||||
function updateUi(nodeId, mode) {
|
||||
|
||||
if (mode === 'view') {
|
||||
$('.project-mode-view').displayAs('inline-block');
|
||||
$('.project-mode-edit').hide();
|
||||
|
||||
$("#node-edit-form").unbind("submit");
|
||||
$("#item_save").unbind("click");
|
||||
$("#item_cancel").unbind("click");
|
||||
} else if (mode === 'edit') {
|
||||
$('.project-mode-view').hide();
|
||||
$('.project-mode-edit').displayAs('inline-block');
|
||||
} else {
|
||||
if (console) console.log('Invalid mode:', mode);
|
||||
}
|
||||
|
||||
// Prevent flicker by scrolling to top.
|
||||
$("#project_context-container").scrollTop(0);
|
||||
|
||||
// Enable specific items under the Add New dropdown
|
||||
if (ProjectUtils.nodeType() === 'group') {
|
||||
addMenuEnable(['asset', 'group']);
|
||||
|
||||
} else if (ProjectUtils.nodeType() === 'group_texture') {
|
||||
addMenuEnable(['group_texture', 'texture']);
|
||||
|
||||
} else if (ProjectUtils.nodeType() === 'group_hdri') {
|
||||
addMenuEnable(['group_hdri', 'hdri']);
|
||||
|
||||
} else if (!ProjectUtils.isProject()) {
|
||||
addMenuEnable(false);
|
||||
}
|
||||
|
||||
updateToggleProjHeaderMenuItem();
|
||||
|
||||
// Set the page title on the document
|
||||
var page_title = $('#node-title').text() + " - {{ project.name }} — Blender Cloud";
|
||||
DocumentTitleAPI.set_page_title(page_title);
|
||||
|
||||
// TODO: Maybe remove this, now it's also in loadNodeContent(), but double-check
|
||||
// it's done like that in all users of updateUi().
|
||||
$('#project-loading').removeAttr('class');
|
||||
}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script(src="{{ url_for('static_pillar', filename='assets/jstree/jstree.min.js') }}")
|
||||
|
||||
script.
|
||||
{% if show_project %}
|
||||
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: true, nodeId: ''});
|
||||
{% else %}
|
||||
{% if node %}
|
||||
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: false, nodeId: '{{node._id}}'});
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
var projectTree = document.getElementById('project_tree');
|
||||
|
||||
var urlNodeMove = "{{url_for('projects.move_node')}}";
|
||||
var urlNodeFeature = "{{url_for('projects.add_featured_node')}}";
|
||||
var urlNodeDelete = "{{url_for('projects.delete_node')}}";
|
||||
var urlNodeTogglePublic = "{{url_for('projects.toggle_node_public')}}";
|
||||
var urlNodeToggleProjHeader = "{{url_for('projects.toggle_node_project_header')}}";
|
||||
var urlProjectDelete = "{{url_for('projects.delete')}}";
|
||||
var urlProjectEdit = "{{url_for('projects.edit', project_url=project.url)}}";
|
||||
|
||||
|
||||
function loadNodeContent(url, nodeId) {
|
||||
$('#project-loading').addClass('active');
|
||||
$.get(url, function(dataHtml) {
|
||||
// Update the DOM injecting the generate HTML into the page
|
||||
$('#project_context').html(dataHtml);
|
||||
})
|
||||
.done(function(){
|
||||
updateUi(nodeId, 'view');
|
||||
})
|
||||
.fail(function(dataResponse) {
|
||||
$('#project_context').html($('<iframe id="server_error"/>'));
|
||||
$('#server_error').attr('src', url);
|
||||
})
|
||||
.always(function(){
|
||||
$('#project-loading').removeAttr('class');
|
||||
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function loadProjectContent(url) {
|
||||
$('#project-loading').addClass('active');
|
||||
|
||||
$.get(url, function(dataHtml) {
|
||||
// Update the DOM injecting the generated HTML into the page
|
||||
$('#project_context').html(dataHtml);
|
||||
})
|
||||
.done(function() {
|
||||
updateUi('', 'view');
|
||||
addMenuEnable();
|
||||
addMenuDisable(['texture']);
|
||||
})
|
||||
.fail(function(dataResponse) {
|
||||
$('#project_context').html($('<iframe id="server_error"/>'));
|
||||
$('#server_error').attr('src', url);
|
||||
})
|
||||
.always(function(){
|
||||
$('#project-loading').removeAttr('class');
|
||||
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function displayStorage(storageNodeId, path) {
|
||||
var url = '/nodes/' + storageNodeId + '/view?path=' + path;
|
||||
loadNodeContent(url);
|
||||
}
|
||||
|
||||
|
||||
function displayNode(nodeId, pushState) {
|
||||
// Remove the 'n_' suffix from the id
|
||||
if (nodeId.substring(0, 2) == 'n_') {
|
||||
nodeId = nodeId.substr(2);
|
||||
}
|
||||
|
||||
var url = '/nodes/' + nodeId + '/view';
|
||||
loadNodeContent(url, nodeId);
|
||||
|
||||
// Determine whether we should push the new state or not.
|
||||
pushState = (typeof pushState !== 'undefined') ? pushState : true;
|
||||
if (!pushState) return;
|
||||
|
||||
// Push the correct URL onto the history.
|
||||
var push_state = {nodeId: nodeId, url: url};
|
||||
var push_url = '{{url_for("projects.view", project_url=project.url)}}' + nodeId;
|
||||
// console.log('Pushing state ', push_state, ' with URL ', push_url);
|
||||
window.history.pushState(
|
||||
push_state,
|
||||
'Node ' + nodeId, // TODO: use sensible title
|
||||
push_url
|
||||
);
|
||||
}
|
||||
|
||||
function redirectToNode(nodeId) {
|
||||
var generic_url = '{{ url_for("projects.view_node", project_url=project.url, node_id="theNodeId") }}';
|
||||
var node_url = generic_url.replace('theNodeId', nodeId);
|
||||
|
||||
// This makes the user skip the current page when using the 'back' button,
|
||||
// i.e. it works as a proper redirect.
|
||||
location.replace(node_url);
|
||||
}
|
||||
|
||||
window.onpopstate = function(event) {
|
||||
var state = event.state;
|
||||
// console.log('State popped. location:', document.location, 'state:', state);
|
||||
|
||||
// Deselect any selected node. We'll select the visited node (if any) later on.
|
||||
var jstreeAPI = $(projectTree).jstree(true);
|
||||
jstreeAPI.deselect_all(true);
|
||||
|
||||
if (state == null) {
|
||||
// Went back to the project.
|
||||
displayProject();
|
||||
return;
|
||||
}
|
||||
|
||||
// Went back to a node.
|
||||
loadNodeContent(state.url, state.nodeId);
|
||||
|
||||
// Annoying hack because jstreeAPI.select_node() can only suppress the
|
||||
// changed.jstree event, and NOT the selected_node.jstree event.
|
||||
projectTree.dataset.ignoreSelectNode = true;
|
||||
jstreeAPI.select_node('n_' + state.nodeId, true);
|
||||
delete projectTree.dataset.ignoreSelectNode;
|
||||
};
|
||||
|
||||
function displayProject() {
|
||||
var url = "{{url_for('projects.view', project_url=project.url, embed=1)}}";
|
||||
loadProjectContent(url);
|
||||
}
|
||||
|
||||
|
||||
function getHashId() {
|
||||
if (console)
|
||||
console.log('getHashId() should not be used any more!');
|
||||
}
|
||||
|
||||
/* Loaded once, on page load */
|
||||
function loadContent() {
|
||||
|
||||
var nodeId = ProjectUtils.nodeId();
|
||||
var isProject = ProjectUtils.isProject();
|
||||
if (isProject) {
|
||||
// No need to asynchronously load the project, as it's embedded by Jinja.
|
||||
// displayProject() is still needed, though, when people use 'back' to go there.
|
||||
if (location.hash) {
|
||||
// Handle old-style /p/{url}/#node-ID links, and redirect them to the correct spot.
|
||||
redirectToNode(location.hash.substr(1));
|
||||
}
|
||||
$('.project-mode-view').displayAs('inline-block');
|
||||
$('.project-mode-edit').hide();
|
||||
} else {
|
||||
displayNode(nodeId, false);
|
||||
}
|
||||
|
||||
$(projectTree).jstree({
|
||||
'core': {
|
||||
'data': function (obj, callback) {
|
||||
if(obj.id === '#') { //tree root
|
||||
if (isProject) {
|
||||
$.getJSON("{{url_for('projects.jstree', project_url=project.url)}}", function (jsonObject) {
|
||||
callback.call(this, jsonObject['items']);
|
||||
});
|
||||
} else {
|
||||
$.getJSON('/nodes/' + nodeId + '/jstree', function(jsonObject) {
|
||||
callback.call(this, jsonObject['items']);
|
||||
});
|
||||
}
|
||||
} else { //normal node
|
||||
var childNodeId;
|
||||
if (obj.original.type == 'group_storage') {
|
||||
childNodeId = obj.original.storage_node;
|
||||
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1&path=' + obj.original.path, function(jsonObject) {
|
||||
callback.call(this, jsonObject.children);
|
||||
});
|
||||
} else {
|
||||
// Remove the 'n_' suffix from the id
|
||||
childNodeId = obj.id.substring(2);
|
||||
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1', function(jsonObject) {
|
||||
callback.call(this, jsonObject.children);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"#": {"valid_children": ["collection"]},
|
||||
"chapter" : {"icon": "pi-folder"},
|
||||
"group" : {"icon": "pi-folder"},
|
||||
"group_texture" : {"icon": "pi-folder-texture"},
|
||||
"group_hdri" : {"icon": "pi-folder-texture", "max_children": 0},
|
||||
"group_storage" : {"icon": "pi-folder"},
|
||||
"filesystem_node" : {"icon": "pi-folder"},
|
||||
"file" : {"icon": "pi-document", "max_children": 0},
|
||||
"filesystem_file" : {"icon": "pi-document", "max_children": 0},
|
||||
"image" : {"icon": "pi-image", "max_children": 0},
|
||||
"hdri" : {"icon": "pi-globe", "max_children": 0},
|
||||
"texture" : {"icon": "pi-texture", "max_children": 0},
|
||||
"video" : {"icon": "pi-play", "max_children": 0},
|
||||
"blog" : {"icon": "pi-newspaper", "max_children": 0},
|
||||
"page" : {"icon": "pi-document-text", "max_children": 0},
|
||||
"default" : {"icon": "pi-document"}
|
||||
},
|
||||
"plugins": ["types",] //, "state", "sort"
|
||||
});
|
||||
|
||||
|
||||
var jstreeAPI = $(projectTree).jstree(true);
|
||||
|
||||
$(projectTree).on("select_node.jstree", function (e, data) {
|
||||
var selectedNodeId = data.node.id.substr(2);
|
||||
|
||||
// Ignore events that can't be suppressed otherwise.
|
||||
// This can be removed if jstreeAPI.select_node() allows suppressing
|
||||
// the select_node.jstree event.
|
||||
if (e.target.dataset.ignoreSelectNode === 'true') return;
|
||||
|
||||
if (typeof(data.node.original.path) === 'undefined') {
|
||||
var movingMode = Cookies.getJSON('bcloud_moving_node');
|
||||
|
||||
// Check if we are in the process of moving a node
|
||||
if (movingMode) {
|
||||
// Allow moving nodes only inside of node_type group
|
||||
if (data.node.original.type != 'group' || movingMode.node_id === selectedNodeId || movingMode.node_id === ProjectUtils.parentNodeId()) {
|
||||
|
||||
if (movingMode.node_type === 'texture') {
|
||||
|
||||
if (data.node.original.type === 'group_texture') {
|
||||
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
|
||||
} else {
|
||||
$('#item_move_accept').html('Select a Texture Folder').addClass('disabled');
|
||||
}
|
||||
|
||||
} else if (movingMode.node_type === 'hdri') {
|
||||
|
||||
if (data.node.original.type === 'group_hdri') {
|
||||
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
|
||||
} else {
|
||||
$('#item_move_accept').html('Select an HDRi Folder').addClass('disabled');
|
||||
}
|
||||
|
||||
} else {
|
||||
$('#item_move_accept').html('Select a Folder').addClass('disabled');
|
||||
}
|
||||
|
||||
} else {
|
||||
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
// Check the type of node and act accordingly
|
||||
if (data.node.original.custom_view) {
|
||||
window.location = data.node.a_attr.href;
|
||||
} else {
|
||||
var currentNodeId = ProjectUtils.nodeId();
|
||||
if (currentNodeId != selectedNodeId) {
|
||||
displayNode(selectedNodeId);
|
||||
}
|
||||
|
||||
jstreeAPI.open_node(data.node);
|
||||
}
|
||||
} else {
|
||||
displayStorage(data.node.original.storage_node, data.node.original.path);
|
||||
jstreeAPI.toggle_node(data.node);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
{% if is_embedded_edit is not defined or is_embedded_edit %}
|
||||
// Initialize the page if we are not directly editing a node (most of the time)
|
||||
loadContent();
|
||||
{% endif %}
|
||||
|
||||
var project_container = document.getElementById('project-container');
|
||||
|
||||
/* UI Stuff */
|
||||
$(window).on("load resize",function(){
|
||||
containerResizeY($(window).height());
|
||||
|
||||
if ($(window).width() > 480) {
|
||||
project_container.style.height = (window.innerHeight - project_container.offsetTop) + "px";
|
||||
}
|
||||
});
|
||||
|
||||
{% if current_user_is_subscriber %}
|
||||
$(projectTree).addClass('is_subscriber');
|
||||
{% endif %}
|
||||
|
||||
| {% endblock %}
|
||||
|
||||
| {% block comment_scripts %} {% endblock%}
|
@@ -1,30 +1,28 @@
|
||||
| {% extends 'layout.html' %}
|
||||
|
||||
include mixins/components
|
||||
|
||||
| {# Default case is Open Projects #}
|
||||
| {% set page_title = 'Open Projects' %}
|
||||
| {% set page_description = 'Full production data and tutorials from all open movies, for you to use freely' %}
|
||||
| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_agent327_01.jpg') %}
|
||||
| {% set page_header_text = 'The iconic Blender Institute Open Movies. Featuring all the production files, assets, artwork, and never-seen-before content.' %}
|
||||
| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/banner-open-projects.jpg') %}
|
||||
| {% set page_header_text = 'See how each film came to be. Explore our production files, assets, artwork and more. Get full access to behind the scenes at the Blender Animation Studio. Follow along as we share our process and techniques for each movie.' %}
|
||||
|
||||
| {% if title == 'courses' %}
|
||||
| {% set page_title = 'Courses' %}
|
||||
| {% if title == 'courses' or title == 'workshops' %}
|
||||
| {% set page_title = 'Training' %}
|
||||
| {% set page_description = 'Production quality training by 3D professionals' %}
|
||||
| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg') %}
|
||||
| {% set page_header_text = 'Character modeling, 3D printing, VFX, rigging and more.' %}
|
||||
| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/banner-training.jpg') %}
|
||||
| {% set page_header_text = 'Browse through our structured courses. Choose a workshop where top Blender Artists walk you through professional techniques to build a specific project. Visit the Art Gallery where you can download and study source files from your favorite artists.' %}
|
||||
|
||||
| {% elif title == 'workshops' %}
|
||||
| {% set page_title = 'Workshops' %}
|
||||
| {% set page_description = 'Production quality training by 3D professionals' %}
|
||||
| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg') %}
|
||||
| {% set page_header_text = 'Enter the artist workshop and learn by example.' %}
|
||||
//- | {% elif title == 'workshops' %}
|
||||
//- | {% set page_title = 'Workshops' %}
|
||||
//- | {% set page_description = 'Production quality training by 3D professionals' %}
|
||||
//- | {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg') %}
|
||||
//- | {% set page_header_text = 'Enter the artist workshop and learn by example.' %}
|
||||
|
||||
| {% endif %}
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:type", content="website")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="https://cloud.blender.org")
|
||||
|
||||
meta(property="og:title", content="{{ page_title }} on Blender Cloud")
|
||||
meta(name="twitter:title", content="{{ page_title }} on Blender Cloud")
|
||||
@@ -35,57 +33,53 @@ meta(name="twitter:description", content="{{ page_description }}")
|
||||
meta(property="og:image", content="{{ page_header_image }}")
|
||||
meta(name="twitter:image", content="{{ page_header_image }}")
|
||||
| {% endblock %}
|
||||
| {% block css %}
|
||||
| {{ super() }}
|
||||
link(href="{{ url_for('static_cloud', filename='assets/css/projects-index-collection.css') }}", rel="stylesheet")
|
||||
| {% endblock css %}
|
||||
|
||||
| {% block page_title %}
|
||||
| {{ page_title }}
|
||||
| {% endblock %}
|
||||
|
||||
| {% block navigation_tabs %}
|
||||
|
||||
| {% if title in ['courses', 'workshops'] %}
|
||||
+nav-secondary
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'workshops' %}active{% endif %}",
|
||||
href="{{ url_for('cloud.workshops') }}")
|
||||
| Workshops
|
||||
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'courses' %}active{% endif %}",
|
||||
href="{{ url_for('cloud.courses') }}")
|
||||
| Courses
|
||||
|
||||
+nav-secondary-link(
|
||||
class="{% if title == 'gallery' %}active{% endif %}",
|
||||
href="{{ url_for('projects.view', project_url='gallery') }}")
|
||||
| Art Gallery
|
||||
| {% endif %}
|
||||
|
||||
| {% endblock navigation_tabs %}
|
||||
|
||||
| {% block body %}
|
||||
|
||||
.container.pb-5
|
||||
.pt-4
|
||||
h2.text-uppercase.font-weight-bold
|
||||
| {{ page_title }}
|
||||
.lead
|
||||
| {{ page_header_text }}
|
||||
|
||||
hr.pb-2
|
||||
|
||||
+card-deck(3)
|
||||
//- Jumbotron
|
||||
.jumbotron.jumbotron-fluid(style="background-image: url('{{ page_header_image }}')")
|
||||
.container
|
||||
h1.display-4.node_index-collection-name {{ page_title }}
|
||||
p.lead.node_index-collection-description {{ page_header_text }}
|
||||
//- Secondary Navigation
|
||||
| {% if title == 'courses' or title == 'workshops' %}
|
||||
.container.navbar-secondary
|
||||
ul.nav.justify-content-left
|
||||
li.nav-item
|
||||
a.nav-link.nav-title(href="#") Training
|
||||
li.nav-item
|
||||
a.nav-link(href="#", class="{% if title == 'courses' %}active{% endif %}") Courses
|
||||
li.nav-item
|
||||
a.nav-link(href="#", class="{% if title == 'workshops' %}active{% endif %}") Workshops
|
||||
li.nav-item
|
||||
a.nav-link(href="#") Art Gallery
|
||||
| {% endif %}
|
||||
//- Project Cards
|
||||
.container.card-container
|
||||
.row
|
||||
| {% for project in projects %}
|
||||
|
||||
| {% if (project.status == 'published') or (project.status == 'pending' and current_user.is_authenticated) and project._id != config.MAIN_PROJECT_ID %}
|
||||
+card(data-url="{{ url_for('projects.view', project_url=project.url) }}", tabindex='{{ loop.index }}')
|
||||
|
||||
.col-md-4(
|
||||
data-url="{{ url_for('projects.view', project_url=project.url) }}",
|
||||
tabindex="{{ loop.index }}")
|
||||
.card
|
||||
| {% if project.picture_header %}
|
||||
a(href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
img.card-img-top(
|
||||
src="{{ project.picture_header.thumbnail('l', api=api) }}", alt="{{ project.name }}")
|
||||
a.card-image(href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
img.card-img-top(src="{{ project.picture_header.thumbnail('l', api=api) }}")
|
||||
| {% endif %}
|
||||
|
||||
.card-body
|
||||
h5.card-title
|
||||
h4.card-title
|
||||
a(href="{{ url_for('projects.view', project_url=project.url) }}")
|
||||
| {{project.name}}
|
||||
| {% if project.status == 'pending' and current_user.is_authenticated and current_user.has_role('admin') %}
|
||||
small (pending)
|
||||
@@ -95,16 +89,18 @@ meta(name="twitter:image", content="{{ page_header_image }}")
|
||||
p.card-text
|
||||
| {{project.summary|safe}}
|
||||
| {% endif %}
|
||||
|
||||
| {% endif %}
|
||||
| {% endfor %}
|
||||
|
||||
|
||||
| {% endblock %}
|
||||
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script.
|
||||
$('.js-project-go').on('click', function(e){
|
||||
e.preventDefault();
|
||||
window.location.href = $(this).data('url');
|
||||
});
|
||||
//- script.
|
||||
//- $('.node_index-collection-card.project').on('click', function(e){
|
||||
//- e.preventDefault();
|
||||
//- window.location.href = $(this).data('url');
|
||||
//- });
|
||||
| {% endblock %}
|
||||
|
@@ -1,11 +1,10 @@
|
||||
| {% extends 'layout.html' %}
|
||||
| {% block page_title %}Services{% endblock %}
|
||||
| {% set title = 'services' %}
|
||||
include mixins/components
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:type", content="website")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="{{ url_for('cloud.services') }}")
|
||||
|
||||
meta(property="og:title", content="Services - Blender Cloud")
|
||||
meta(name="twitter:title", content="Services - Blender Cloud")
|
||||
@@ -21,10 +20,26 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
|
||||
| {% endblock %}
|
||||
|
||||
| {% block body %}
|
||||
- var header_text = "On Blender Cloud you can create and share personal projects, access our texture and HDRI library (or create your own), keep track of your production, manage your renders and much more!";
|
||||
+jumbotron("Services", header_text, "{{ url_for('static', filename='assets/img/backgrounds/services_projects.jpg')}}")
|
||||
#page-container
|
||||
#page-header(style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/services_projects.jpg')}})")
|
||||
.container
|
||||
.page-title
|
||||
| Blender Cloud Services
|
||||
.page-title-summary
|
||||
span.text-background
|
||||
p.
|
||||
Blender Cloud is the creative hub for your projects, powered by Free and Open Source software.
|
||||
|
||||
p.
|
||||
On Blender Cloud you can create and share personal projects, access our texture and HDRI
|
||||
library (or create your own), keep track of your production, manage your renders and much more!
|
||||
|
||||
.navbar-backdrop-overlay
|
||||
|
||||
- var addon_text = 'Available through the <a href="{{ url_for(\'cloud.services\') }}#blender-cloud-add-on">Blender Cloud add-on</a>'
|
||||
|
||||
#page-content
|
||||
|
||||
- var addon_text = 'Available through the <a href="{{ url_for(\'cloud.services\') }}#blender-cloud-add-on">Blender Cloud add-on</a>';
|
||||
section#blender-cloud-add-on.page-card
|
||||
.page-card-side
|
||||
h2.page-card-title
|
||||
@@ -39,8 +54,8 @@ section#blender-cloud-add-on.page-card
|
||||
|
||||
small Blender Cloud add-on requires Blender 2.78 or newer
|
||||
|
||||
a.btn.btn-primary(
|
||||
href="/r/downloads/blender_cloud-latest-addon.zip")
|
||||
a.page-card-cta.download(
|
||||
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-addon.zip")
|
||||
i.pi-download
|
||||
| Download add-on <small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }}
|
||||
|
||||
@@ -61,15 +76,10 @@ section#blender-sync.page-card.right
|
||||
|
||||
.tip !{addon_text}
|
||||
|
||||
a.btn.btn-outline-primary(
|
||||
href="/r/downloads/blender_cloud-latest-addon.zip")
|
||||
i.pi-download
|
||||
| Download add-on <small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }}
|
||||
|
||||
a.btn.btn-link(
|
||||
href="/blog/introducing-blender-sync")
|
||||
a.page-card-cta(
|
||||
href="https://cloud.blender.org/blog/introducing-blender-sync")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
|
||||
.page-card-side
|
||||
img(
|
||||
@@ -81,13 +91,13 @@ section#texture-browser.page-card.right
|
||||
h2.page-card-title Texture & HDRI Browser
|
||||
.page-card-summary
|
||||
p.
|
||||
Access the <a href="/p/textures/">Blender Cloud Textures</a>
|
||||
Access the <a href="https://cloud.blender.org/p/textures/">Blender Cloud Textures</a>
|
||||
library from within Blender using our exclusive add-on.
|
||||
Create, manage and share <em>your own</em> texture libraries!
|
||||
|
||||
.tip !{addon_text}
|
||||
|
||||
a.btn.btn-outline-primary.js-watch-video(
|
||||
a.page-card-cta.js-watch-video.download(
|
||||
href="https://www.youtube.com/watch?v=-srXYv2Osjw",
|
||||
data-youtube-id="-srXYv2Osjw")
|
||||
i.pi-play
|
||||
@@ -107,16 +117,15 @@ section#image-sharing.page-card.right
|
||||
|
||||
.tip !{addon_text}
|
||||
|
||||
a.btn.btn-outline-primary.js-watch-video(
|
||||
a.page-card-cta.download.js-watch-video(
|
||||
href="https://www.youtube.com/watch?v=yvtqeMBOAyk",
|
||||
data-youtube-id="yvtqeMBOAyk")
|
||||
i.pi-play
|
||||
| Watch Video
|
||||
|
||||
a.btn.btn-link(
|
||||
href="/blog/introducing-image-sharing")
|
||||
a.page-card-cta.outline(
|
||||
href="https://cloud.blender.org/blog/introducing-image-sharing")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
|
||||
.page-card-side
|
||||
img(
|
||||
@@ -130,10 +139,9 @@ section#projects.page-card.right
|
||||
Create and manage your own personal projects.
|
||||
Upload assets and collaborate with other Blender Cloud members.
|
||||
|
||||
a.btn.btn-link(
|
||||
href="/blog/introducing-private-projects")
|
||||
a.page-card-cta(
|
||||
href="https://cloud.blender.org/blog/introducing-private-projects")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
|
||||
.page-card-side
|
||||
img(
|
||||
@@ -147,17 +155,16 @@ section#attract.page-card.right
|
||||
.page-card-summary.
|
||||
Production-management software for your film, game, or commercial projects.
|
||||
|
||||
a.btn.btn-outline-primary.js-watch-video(
|
||||
a.page-card-cta.download.js-watch-video(
|
||||
href="https://www.youtube.com/watch?v=b9x1rlyyt_o",
|
||||
data-youtube-id="b9x1rlyyt_o")
|
||||
i.pi-play
|
||||
| Watch Video
|
||||
|
||||
a.btn.btn-link(
|
||||
href="/blog/attract-and-flamenco-public-beta",
|
||||
a.page-card-cta(
|
||||
href="https://cloud.blender.org/blog/attract-and-flamenco-public-beta",
|
||||
title="Learn more about Attract")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
|
||||
.page-card-side
|
||||
img(
|
||||
@@ -171,17 +178,16 @@ section#flamenco.page-card.right
|
||||
.page-card-summary.
|
||||
Take control of your computing infrastructure and get things done.
|
||||
|
||||
a.btn.btn-outline-primary.js-watch-video(
|
||||
a.page-card-cta.download.js-watch-video(
|
||||
href="https://www.youtube.com/watch?v=7cnFKhsM67Q",
|
||||
data-youtube-id="7cnFKhsM67Q")
|
||||
i.pi-play
|
||||
| Watch Video
|
||||
|
||||
a.btn.btn-link(
|
||||
a.page-card-cta(
|
||||
href="https://flamenco.io",
|
||||
title="Learn more about Flamenco")
|
||||
| Learn More
|
||||
i.pi-angle-right
|
||||
|
||||
.page-card-side
|
||||
img(
|
||||
@@ -189,18 +195,15 @@ section#flamenco.page-card.right
|
||||
|
||||
|
||||
| {% if not current_user.has_role('subscriber') %}
|
||||
section.page-card(
|
||||
section.page-card.subscribe(
|
||||
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
|
||||
.page-card-side
|
||||
|
||||
h2.page-card-title
|
||||
| All of this, plus hours of training and production assets.
|
||||
|
||||
.page-card-summary.text-white
|
||||
.page-card-summary
|
||||
| Join us for only $9.90/month!
|
||||
|
||||
a.btn.btn-outline-light.px-3(href="https://store.blender.org/product/membership/")
|
||||
i.pi-heart.mr-2
|
||||
a.page-card-cta(
|
||||
href="https://store.blender.org/product/membership/")
|
||||
| Subscribe Now
|
||||
| {% endif %}
|
||||
|
||||
@@ -209,13 +212,12 @@ section.page-card(
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script.
|
||||
// Hide the video overlay.
|
||||
// Click anywhere in the page to hide the overlay
|
||||
function hideOverlay() {
|
||||
$('#page-overlay.video').removeClass('active');
|
||||
$('#page-overlay.video .video-embed').html('');
|
||||
}
|
||||
|
||||
// Click anywhere in the page or hit Esc to hide the overlay.
|
||||
$(document).click(function() {
|
||||
hideOverlay();
|
||||
});
|
||||
@@ -227,12 +229,12 @@ script.
|
||||
});
|
||||
|
||||
$('a.js-watch-video').click(function(e){
|
||||
var videoId = $(this).attr('data-youtube-id');
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$('#page-overlay.video').addClass('active');
|
||||
|
||||
var videoId = $(this).attr('data-youtube-id');
|
||||
$('#page-overlay .video-embed').html('<iframe src="https://www.youtube.com/embed/' + videoId +'?rel=0&showinfo=0;autoplay=1" frameborder="0" allowfullscreen></iframe>')
|
||||
});
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:title", content="Blender Cloud Statistics")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="https://cloud.blender.org/stats")
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/background_andy_hdribot_01.jpg')}}")
|
||||
| {% endblock %}
|
||||
|
||||
|
@@ -65,7 +65,7 @@ p Your organisation provides you with your subscription.
|
||||
|
||||
hr
|
||||
p
|
||||
button#recheck_subscription.btn.btn-outline-secondary(onclick="javascript:recheck_subscription(this)") Re-check my subscription
|
||||
button#recheck_subscription.btn.btn-default(onclick="javascript:recheck_subscription(this)") Re-check my subscription
|
||||
|
||||
hr
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
| {% endfor %}
|
||||
|
||||
.buttons
|
||||
button.btn.btn-outline-success.button-submit(type='submit')
|
||||
button.btn.btn-default.button-submit(type='submit')
|
||||
i.pi-check
|
||||
| Save Changes
|
||||
| {% endblock %}
|
||||
|
@@ -8,9 +8,13 @@
|
||||
|
||||
| {% block og %}
|
||||
meta(property="og:title", content="Blender Cloud - Open Content Production Platform")
|
||||
meta(property="og:url", content="{{ request.url }}")
|
||||
meta(property="og:url", content="https://cloud.blender.org/")
|
||||
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/background_dweebs_01.jpg')}}")
|
||||
| {% endblock og %}
|
||||
| {% block css %}
|
||||
| {{ super() }}
|
||||
link(href="{{ url_for('static_cloud', filename='assets/css/welcome.css') }}", rel="stylesheet")
|
||||
| {% endblock css %}
|
||||
|
||||
| {% block page_overlay %}
|
||||
#page-overlay.video
|
||||
@@ -19,21 +23,19 @@ meta(property="og:image", content="{{ url_for('static', filename='assets/img/bac
|
||||
|
||||
| {% block navigation_search %}{% endblock %}
|
||||
| {% block navigation_sections %}
|
||||
li
|
||||
a.navbar-item(href="{{ url_for('main.main_blog') }}")
|
||||
span Blog
|
||||
li
|
||||
a.navbar-item(href="#pricing")
|
||||
span Pricing
|
||||
li.nav-item
|
||||
a.nav-link(href="{{ url_for('main.main_blog') }}") Blog
|
||||
li.nav-item
|
||||
a.nav-link(href="#pricing") Pricing
|
||||
| {% endblock navigation_sections %}
|
||||
|
||||
| {% block navigation_user %}
|
||||
li.pt-1.pr-1
|
||||
li.nav-item-sign-in
|
||||
| {% if current_user.is_anonymous %}
|
||||
a.btn.btn-outline-success(href="{{ url_for('users.login', next='/') }}")
|
||||
a.navbar-item(href="{{ url_for('users.login', next='/') }}")
|
||||
| Log in and Explore
|
||||
| {% else %}
|
||||
a.btn.btn-outline-success(href="{{ url_for('main.homepage') }}")
|
||||
a.navbar-item(href="{{ url_for('main.homepage') }}")
|
||||
| Explore
|
||||
| {% endif %}
|
||||
| {% endblock navigation_user %}
|
||||
@@ -70,7 +72,7 @@ li.pt-1.pr-1
|
||||
improve it for everyone's benefit.
|
||||
|
||||
.page-card-side
|
||||
a.page-card-image(href="/p/caminandes-3/56bdacccc379cf00797160b0", target="_blank")
|
||||
a.page-card-image(href="https://cloud.blender.org/p/caminandes-3/56bdacccc379cf00797160b0", target="_blank")
|
||||
video(autoplay, loop)
|
||||
source(src="{{ url_for('static', filename='assets/img/features/animation_review_01.mp4')}}")
|
||||
|
||||
@@ -92,7 +94,7 @@ li.pt-1.pr-1
|
||||
Access high quality content, organized in
|
||||
#[a(href="{{ url_for('cloud.courses') }}") classes],
|
||||
#[a(href="{{ url_for('cloud.workshops') }}") workshop] and the
|
||||
#[a(href="/p/gallery") art gallery],
|
||||
#[a(href="https://cloud.blender.org/p/gallery") art gallery],
|
||||
a curated artwork selection, where you can open a
|
||||
.blend file and see how it was made.
|
||||
|
||||
@@ -108,7 +110,7 @@ li.pt-1.pr-1
|
||||
| See #[a.learn(href="{{ url_for('cloud.courses') }}") Courses] & #[a.learn(href="{{ url_for('cloud.courses') }}") Workshops]
|
||||
|
||||
.page-card-side
|
||||
a.page-card-image(href="/p/scripting-for-artists/")
|
||||
a.page-card-image(href="https://cloud.blender.org/p/scripting-for-artists/")
|
||||
img(
|
||||
alt="Sybren teaches Python Scripting with Blender",
|
||||
src="{{ url_for('static', filename='assets/img/backgrounds/background_sybren_01.jpg')}}")
|
||||
@@ -121,7 +123,7 @@ li.pt-1.pr-1
|
||||
.page-triplet-container.homepage
|
||||
.row
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/minecraft-animation-workshop/")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/minecraft-animation-workshop/")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="Textures",
|
||||
@@ -130,11 +132,11 @@ li.pt-1.pr-1
|
||||
h3 Minecraft Animation
|
||||
p.
|
||||
Learn how to make animations with this workshop by Dillon Gu.
|
||||
a.triplet-cta(href="/p/minecraft-animation-workshop/")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/minecraft-animation-workshop/")
|
||||
| LEARN MORE
|
||||
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/motion-graphics/")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/motion-graphics/")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="HDRI",
|
||||
@@ -143,11 +145,11 @@ li.pt-1.pr-1
|
||||
h3 Motion Graphics
|
||||
p.
|
||||
A comprehensive guide to motion graphics techniques using Blender.
|
||||
a.triplet-cta(href="/p/motion-graphics/")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/motion-graphics/")
|
||||
| LEARN MORE
|
||||
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/gallery")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/gallery")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="Characters",
|
||||
@@ -156,25 +158,25 @@ li.pt-1.pr-1
|
||||
h3 Art Walk-throughs
|
||||
p.
|
||||
Follow the creative process and techniques behind stunning artwork.
|
||||
a.triplet-cta(href="/p/gallery")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/gallery")
|
||||
| LEARN MORE
|
||||
|
||||
.row.training-other
|
||||
.col-md-10.col-md-offset-1
|
||||
p.
|
||||
Other training:
|
||||
#[a(href="/p/toon-character-workflow/") Toon Character Workflow],
|
||||
#[a(href="/p/3d-printing/") Blender for 3D Printing],
|
||||
#[a(href="/p/game-asset-creation/") Game Asset Creation],
|
||||
#[a(href="/p/blenderella/") Character Modeling],
|
||||
#[a(href="/p/character-animation/") Character Animation],
|
||||
#[a(href="/p/humane-rigging/") Introduction] and
|
||||
#[a(href="/p/blenrig/") Advanced Rigging],
|
||||
#[a(href="/p/track-match-2/") VFX Workflow],
|
||||
#[a(href="/p/creature-factory-2/") Creature] and
|
||||
#[a(href="/p/venoms-lab-2/") Cartoon Character creation],
|
||||
#[a(href="/p/chaos-evolution/") Advanced]
|
||||
#[a(href="/p/blend-and-paint/") Digital Painting] and
|
||||
#[a(href="https://cloud.blender.org/p/toon-character-workflow/") Toon Character Workflow],
|
||||
#[a(href="https://cloud.blender.org/p/3d-printing/") Blender for 3D Printing],
|
||||
#[a(href="https://cloud.blender.org/p/game-asset-creation/") Game Asset Creation],
|
||||
#[a(href="https://cloud.blender.org/p/blenderella/") Character Modeling],
|
||||
#[a(href="https://cloud.blender.org/p/character-animation/") Character Animation],
|
||||
#[a(href="https://cloud.blender.org/p/humane-rigging/") Introduction] and
|
||||
#[a(href="https://cloud.blender.org/p/blenrig/") Advanced Rigging],
|
||||
#[a(href="https://cloud.blender.org/p/track-match-2/") VFX Workflow],
|
||||
#[a(href="https://cloud.blender.org/p/creature-factory-2/") Creature] and
|
||||
#[a(href="https://cloud.blender.org/p/venoms-lab-2/") Cartoon Character creation],
|
||||
#[a(href="https://cloud.blender.org/p/chaos-evolution/") Advanced]
|
||||
#[a(href="https://cloud.blender.org/p/blend-and-paint/") Digital Painting] and
|
||||
#[a(href="{{ url_for('cloud.courses') }}") much more]!
|
||||
|
||||
|
||||
@@ -215,7 +217,7 @@ li.pt-1.pr-1
|
||||
.page-triplet-container.homepage
|
||||
.row
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/hero/")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/hero/")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="Hero",
|
||||
@@ -224,11 +226,11 @@ li.pt-1.pr-1
|
||||
h3 Hero
|
||||
p.
|
||||
The first ever Grease Pencil open movie made with Blender 2.8
|
||||
a.triplet-cta(href="/p/hero/")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/hero/")
|
||||
| LEARN MORE
|
||||
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/spring/")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/spring/")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="Spring",
|
||||
@@ -237,11 +239,11 @@ li.pt-1.pr-1
|
||||
h3 Spring
|
||||
p.
|
||||
A poetic fantasy film. #[br] A stunning visual journey.
|
||||
a.triplet-cta(href="/p/spring/")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/spring/")
|
||||
| LEARN MORE
|
||||
|
||||
.col-md-4
|
||||
.triplet-card(data-url="/p/caminandes-3/")
|
||||
.triplet-card(data-url="https://cloud.blender.org/p/caminandes-3/")
|
||||
.triplet-card-thumbnail
|
||||
img(
|
||||
alt="Caminandes",
|
||||
@@ -250,21 +252,21 @@ li.pt-1.pr-1
|
||||
h3 Caminandes
|
||||
p.
|
||||
Follow the adventures of Koro through the Patagonian pampas.
|
||||
a.triplet-cta(href="/p/caminandes-3/")
|
||||
a.triplet-cta(href="https://cloud.blender.org/p/caminandes-3/")
|
||||
| LEARN MORE
|
||||
|
||||
.row.training-other
|
||||
.col-md-10.col-md-offset-1
|
||||
p.
|
||||
Other open movies:
|
||||
#[a(href="/p/elephants-dream/") Elephants Dream],
|
||||
#[a(href="/p/big-buck-bunny/") Big Buck Bunny],
|
||||
#[a(href="/p/sintel/") Sintel],
|
||||
#[a(href="/p/tears-of-steel/") Tears of Steel],
|
||||
#[a(href="/p/cosmos-laundromat/") Cosmos Laundromat],
|
||||
#[a(href="/p/glass-half/") Glass Half],
|
||||
#[a(href="/p/dailydweebs/") The Daily Dweebs],
|
||||
#[a(href="/p/agent-327/") Agent 327]
|
||||
#[a(href="https://cloud.blender.org/p/elephants-dream/") Elephants Dream],
|
||||
#[a(href="https://cloud.blender.org/p/big-buck-bunny/") Big Buck Bunny],
|
||||
#[a(href="https://cloud.blender.org/p/sintel/") Sintel],
|
||||
#[a(href="https://cloud.blender.org/p/tears-of-steel/") Tears of Steel],
|
||||
#[a(href="https://cloud.blender.org/p/cosmos-laundromat/") Cosmos Laundromat],
|
||||
#[a(href="https://cloud.blender.org/p/glass-half/") Glass Half],
|
||||
#[a(href="https://cloud.blender.org/p/dailydweebs/") The Daily Dweebs],
|
||||
#[a(href="https://cloud.blender.org/p/agent-327/") Agent 327]
|
||||
and #[a(href="{{ url_for('cloud.open_projects') }}") more]
|
||||
|
||||
|
||||
|
7
static/assets/bootstrap/css/bootstrap.min.css
vendored
Normal file
7
static/assets/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
static/assets/bootstrap/css/bootstrap.min.css.map
Normal file
1
static/assets/bootstrap/css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
7
static/assets/bootstrap/js/bootstrap.min.js
vendored
Normal file
7
static/assets/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
static/assets/bootstrap/js/bootstrap.min.js.map
Normal file
1
static/assets/bootstrap/js/bootstrap.min.js.map
Normal file
File diff suppressed because one or more lines are too long
43
static/assets/bootstrap/sass/_alert.sass
Normal file
43
static/assets/bootstrap/sass/_alert.sass
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.alert
|
||||
position: relative
|
||||
padding: $alert-padding-y $alert-padding-x
|
||||
margin-bottom: $alert-margin-bottom
|
||||
border: $alert-border-width solid transparent
|
||||
|
||||
+border-radius($alert-border-radius)
|
||||
|
||||
// Headings for larger alerts
|
||||
.alert-heading
|
||||
// Specified to prevent conflicts of changing $headings-color
|
||||
color: inherit
|
||||
|
||||
// Provide class for links that match alerts
|
||||
.alert-link
|
||||
font-weight: $alert-link-font-weight
|
||||
|
||||
// Dismissible alerts
|
||||
//
|
||||
// Expand the right padding and account for the close button's positioning.
|
||||
|
||||
.alert-dismissible
|
||||
padding-right: $close-font-size + $alert-padding-x * 2
|
||||
|
||||
// Adjust close link position
|
||||
.close
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
padding: $alert-padding-y $alert-padding-x
|
||||
color: inherit
|
||||
|
||||
// Alternate styles
|
||||
//
|
||||
// Generate contextual modifier classes for colorizing the alert.
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
.alert-#{$color}
|
||||
+alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level))
|
43
static/assets/bootstrap/sass/_badge.sass
Normal file
43
static/assets/bootstrap/sass/_badge.sass
Normal file
@@ -0,0 +1,43 @@
|
||||
// Base class
|
||||
//
|
||||
// Requires one of the contextual, color modifier classes for `color` and
|
||||
// `background-color`.
|
||||
|
||||
.badge
|
||||
display: inline-block
|
||||
padding: $badge-padding-y $badge-padding-x
|
||||
font-size: $badge-font-size
|
||||
font-weight: $badge-font-weight
|
||||
line-height: 1
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
vertical-align: baseline
|
||||
|
||||
+border-radius($badge-border-radius)
|
||||
|
||||
// Empty badges collapse automatically
|
||||
&:empty
|
||||
display: none
|
||||
|
||||
// Quick fix for badges in buttons
|
||||
.btn .badge
|
||||
position: relative
|
||||
top: -1px
|
||||
|
||||
// Pill badges
|
||||
//
|
||||
// Make them extra rounded with a modifier to replace v3's badges.
|
||||
|
||||
.badge-pill
|
||||
padding-right: $badge-pill-padding-x
|
||||
padding-left: $badge-pill-padding-x
|
||||
|
||||
+border-radius($badge-pill-border-radius)
|
||||
|
||||
// Colors
|
||||
//
|
||||
// Contextual variations (linked badges get darker on :hover).
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
.badge-#{$color}
|
||||
+badge-variant($value)
|
38
static/assets/bootstrap/sass/_breadcrumb.sass
Normal file
38
static/assets/bootstrap/sass/_breadcrumb.sass
Normal file
@@ -0,0 +1,38 @@
|
||||
.breadcrumb
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
padding: $breadcrumb-padding-y $breadcrumb-padding-x
|
||||
margin-bottom: $breadcrumb-margin-bottom
|
||||
list-style: none
|
||||
background-color: $breadcrumb-bg
|
||||
|
||||
+border-radius($breadcrumb-border-radius)
|
||||
|
||||
.breadcrumb-item
|
||||
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||
+ .breadcrumb-item
|
||||
padding-left: $breadcrumb-item-padding
|
||||
|
||||
&::before
|
||||
display: inline-block
|
||||
|
||||
// Suppress underlining of the separator in modern browsers
|
||||
padding-right: $breadcrumb-item-padding
|
||||
color: $breadcrumb-divider-color
|
||||
content: $breadcrumb-divider
|
||||
|
||||
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
|
||||
// without `<ul>`s. The `::before` pseudo-element generates an element
|
||||
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
|
||||
//
|
||||
// To trick IE into suppressing the underline, we give the pseudo-element an
|
||||
// underline and then immediately remove it.
|
||||
+ .breadcrumb-item:hover::before
|
||||
text-decoration: underline
|
||||
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
+ .breadcrumb-item:hover::before
|
||||
text-decoration: none
|
||||
|
||||
&.active
|
||||
color: $breadcrumb-active-color
|
151
static/assets/bootstrap/sass/_button-group.sass
Normal file
151
static/assets/bootstrap/sass/_button-group.sass
Normal file
@@ -0,0 +1,151 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
// Make the div behave like a button
|
||||
.btn-group,
|
||||
.btn-group-vertical
|
||||
position: relative
|
||||
display: inline-flex
|
||||
vertical-align: middle
|
||||
|
||||
// match .btn alignment given font-size hack above
|
||||
|
||||
> .btn
|
||||
position: relative
|
||||
flex: 0 1 auto
|
||||
|
||||
// Bring the hover, focused, and "active" buttons to the front to overlay
|
||||
// the borders properly
|
||||
+hover
|
||||
z-index: 1
|
||||
|
||||
|
||||
&:focus,
|
||||
&:active,
|
||||
&.active
|
||||
z-index: 1
|
||||
|
||||
// Prevent double borders when buttons are next to each other
|
||||
.btn + .btn,
|
||||
.btn + .btn-group,
|
||||
.btn-group + .btn,
|
||||
.btn-group + .btn-group
|
||||
margin-left: -$btn-border-width
|
||||
|
||||
// Optional: Group multiple button groups together for a toolbar
|
||||
.btn-toolbar
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
justify-content: flex-start
|
||||
|
||||
.input-group
|
||||
width: auto
|
||||
|
||||
.btn-group
|
||||
> .btn:first-child
|
||||
margin-left: 0
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn
|
||||
+border-right-radius(0)
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn
|
||||
+border-left-radius(0)
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default button sizing classes into new ones for easier manipulation.
|
||||
|
||||
.btn-group-sm > .btn
|
||||
@extend .btn-sm
|
||||
|
||||
.btn-group-lg > .btn
|
||||
@extend .btn-lg
|
||||
|
||||
//
|
||||
// Split button dropdowns
|
||||
//
|
||||
|
||||
.dropdown-toggle-split
|
||||
padding-right: $btn-padding-x * 0.75
|
||||
padding-left: $btn-padding-x * 0.75
|
||||
|
||||
&::after,
|
||||
.dropup &::after,
|
||||
.dropright &::after
|
||||
margin-left: 0
|
||||
|
||||
.dropleft &::before
|
||||
margin-right: 0
|
||||
|
||||
.btn-sm + .dropdown-toggle-split
|
||||
padding-right: $btn-padding-x-sm * 0.75
|
||||
padding-left: $btn-padding-x-sm * 0.75
|
||||
|
||||
.btn-lg + .dropdown-toggle-split
|
||||
padding-right: $btn-padding-x-lg * 0.75
|
||||
padding-left: $btn-padding-x-lg * 0.75
|
||||
|
||||
// The clickable button for toggling the menu
|
||||
// Set the same inset shadow as the :active state
|
||||
.btn-group.show .dropdown-toggle
|
||||
+box-shadow($btn-active-box-shadow)
|
||||
|
||||
// Show no shadow for `.btn-link` since it has no other button styles.
|
||||
&.btn-link
|
||||
+box-shadow(none)
|
||||
|
||||
//
|
||||
// Vertical button groups
|
||||
//
|
||||
|
||||
.btn-group-vertical
|
||||
flex-direction: column
|
||||
align-items: flex-start
|
||||
justify-content: center
|
||||
|
||||
.btn,
|
||||
.btn-group
|
||||
width: 100%
|
||||
|
||||
> .btn + .btn,
|
||||
> .btn + .btn-group,
|
||||
> .btn-group + .btn,
|
||||
> .btn-group + .btn-group
|
||||
margin-top: -$btn-border-width
|
||||
margin-left: 0
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn
|
||||
+border-bottom-radius(0)
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn
|
||||
+border-top-radius(0)
|
||||
|
||||
// Checkbox and radio options
|
||||
//
|
||||
// In order to support the browser's form validation feedback, powered by the
|
||||
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
|
||||
// `display: none;` or `visibility: hidden;` as that also hides the popover.
|
||||
// Simply visually hiding the inputs via `opacity` would leave them clickable in
|
||||
// certain cases which is prevented by using `clip` and `pointer-events`.
|
||||
// This way, we ensure a DOM element is visible to position the popover from.
|
||||
//
|
||||
// See https://github.com/twbs/bootstrap/pull/12794 and
|
||||
// https://github.com/twbs/bootstrap/pull/14559 for more information.
|
||||
|
||||
.btn-group-toggle
|
||||
> .btn,
|
||||
> .btn-group > .btn
|
||||
margin-bottom: 0
|
||||
|
||||
// Override default `<label>` value
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"]
|
||||
position: absolute
|
||||
clip: rect(0, 0, 0, 0)
|
||||
pointer-events: none
|
123
static/assets/bootstrap/sass/_buttons.sass
Normal file
123
static/assets/bootstrap/sass/_buttons.sass
Normal file
@@ -0,0 +1,123 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.btn
|
||||
display: inline-block
|
||||
font-weight: $btn-font-weight
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
vertical-align: middle
|
||||
user-select: none
|
||||
border: $btn-border-width solid transparent
|
||||
|
||||
+button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius)
|
||||
+transition($btn-transition)
|
||||
|
||||
// Share hover and focus styles
|
||||
+hover-focus
|
||||
text-decoration: none
|
||||
|
||||
|
||||
&:focus,
|
||||
&.focus
|
||||
outline: 0
|
||||
box-shadow: $btn-focus-box-shadow
|
||||
|
||||
// Disabled comes first so active can properly restyle
|
||||
&.disabled,
|
||||
&:disabled
|
||||
opacity: $btn-disabled-opacity
|
||||
|
||||
+box-shadow(none)
|
||||
|
||||
// Opinionated: add "hand" cursor to non-disabled .btn elements
|
||||
&:not(:disabled):not(.disabled)
|
||||
cursor: pointer
|
||||
|
||||
&:not(:disabled):not(.disabled):active,
|
||||
&:not(:disabled):not(.disabled).active
|
||||
background-image: none
|
||||
|
||||
+box-shadow($btn-active-box-shadow)
|
||||
|
||||
&:focus
|
||||
+box-shadow($btn-focus-box-shadow, $btn-active-box-shadow)
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
a.btn.disabled,
|
||||
fieldset:disabled a.btn
|
||||
pointer-events: none
|
||||
|
||||
//
|
||||
// Alternate buttons
|
||||
//
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
.btn-#{$color}
|
||||
+button-variant($value, $value)
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
.btn-outline-#{$color}
|
||||
+button-outline-variant($value)
|
||||
|
||||
//
|
||||
// Link buttons
|
||||
//
|
||||
|
||||
// Make a button look and behave like a link
|
||||
.btn-link
|
||||
font-weight: $font-weight-normal
|
||||
color: $link-color
|
||||
background-color: transparent
|
||||
|
||||
+hover
|
||||
color: $link-hover-color
|
||||
text-decoration: $link-hover-decoration
|
||||
background-color: transparent
|
||||
border-color: transparent
|
||||
|
||||
|
||||
&:focus,
|
||||
&.focus
|
||||
text-decoration: $link-hover-decoration
|
||||
border-color: transparent
|
||||
box-shadow: none
|
||||
|
||||
&:disabled,
|
||||
&.disabled
|
||||
color: $btn-link-disabled-color
|
||||
pointer-events: none
|
||||
|
||||
// No need for an active state here
|
||||
|
||||
//
|
||||
// Button Sizes
|
||||
//
|
||||
|
||||
.btn-lg
|
||||
+button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $btn-line-height-lg, $btn-border-radius-lg)
|
||||
|
||||
.btn-sm
|
||||
+button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-line-height-sm, $btn-border-radius-sm)
|
||||
|
||||
//
|
||||
// Block button
|
||||
//
|
||||
|
||||
.btn-block
|
||||
display: block
|
||||
width: 100%
|
||||
|
||||
// Vertically space out multiple block buttons
|
||||
+ .btn-block
|
||||
margin-top: $btn-block-spacing-y
|
||||
|
||||
// Specificity overrides
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"]
|
||||
&.btn-block
|
||||
width: 100%
|
261
static/assets/bootstrap/sass/_card.sass
Normal file
261
static/assets/bootstrap/sass/_card.sass
Normal file
@@ -0,0 +1,261 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.card
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: column
|
||||
min-width: 0
|
||||
word-wrap: break-word
|
||||
background-color: $card-bg
|
||||
background-clip: border-box
|
||||
border: $card-border-width solid $card-border-color
|
||||
|
||||
+border-radius($card-border-radius)
|
||||
|
||||
> hr
|
||||
margin-right: 0
|
||||
margin-left: 0
|
||||
|
||||
> .list-group:first-child
|
||||
.list-group-item:first-child
|
||||
+border-top-radius($card-border-radius)
|
||||
|
||||
> .list-group:last-child
|
||||
.list-group-item:last-child
|
||||
+border-bottom-radius($card-border-radius)
|
||||
|
||||
.card-body
|
||||
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||
flex: 1 1 auto
|
||||
padding: $card-spacer-x
|
||||
|
||||
.card-title
|
||||
margin-bottom: $card-spacer-y
|
||||
|
||||
.card-subtitle
|
||||
margin-top: -($card-spacer-y / 2)
|
||||
margin-bottom: 0
|
||||
|
||||
.card-text:last-child
|
||||
margin-bottom: 0
|
||||
|
||||
.card-link
|
||||
+hover
|
||||
text-decoration: none
|
||||
|
||||
|
||||
+ .card-link
|
||||
margin-left: $card-spacer-x
|
||||
|
||||
//
|
||||
// Optional textual caps
|
||||
//
|
||||
|
||||
.card-header
|
||||
padding: $card-spacer-y $card-spacer-x
|
||||
margin-bottom: 0
|
||||
|
||||
// Removes the default margin-bottom of <hN>
|
||||
background-color: $card-cap-bg
|
||||
border-bottom: $card-border-width solid $card-border-color
|
||||
|
||||
&:first-child
|
||||
+border-radius($card-inner-border-radius $card-inner-border-radius 0 0)
|
||||
|
||||
+ .list-group
|
||||
.list-group-item:first-child
|
||||
border-top: 0
|
||||
|
||||
.card-footer
|
||||
padding: $card-spacer-y $card-spacer-x
|
||||
background-color: $card-cap-bg
|
||||
border-top: $card-border-width solid $card-border-color
|
||||
|
||||
&:last-child
|
||||
+border-radius(0 0 $card-inner-border-radius $card-inner-border-radius)
|
||||
|
||||
//
|
||||
// Header navs
|
||||
//
|
||||
|
||||
.card-header-tabs
|
||||
margin-right: -($card-spacer-x / 2)
|
||||
margin-bottom: -$card-spacer-y
|
||||
margin-left: -($card-spacer-x / 2)
|
||||
border-bottom: 0
|
||||
|
||||
.card-header-pills
|
||||
margin-right: -($card-spacer-x / 2)
|
||||
margin-left: -($card-spacer-x / 2)
|
||||
|
||||
// Card image
|
||||
.card-img-overlay
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
padding: $card-img-overlay-padding
|
||||
|
||||
.card-img
|
||||
width: 100%
|
||||
|
||||
// Required because we use flexbox and this inherently applies align-self: stretch
|
||||
+border-radius($card-inner-border-radius)
|
||||
|
||||
// Card image caps
|
||||
.card-img-top
|
||||
width: 100%
|
||||
|
||||
// Required because we use flexbox and this inherently applies align-self: stretch
|
||||
+border-top-radius($card-inner-border-radius)
|
||||
|
||||
.card-img-bottom
|
||||
width: 100%
|
||||
|
||||
// Required because we use flexbox and this inherently applies align-self: stretch
|
||||
+border-bottom-radius($card-inner-border-radius)
|
||||
|
||||
// Card deck
|
||||
|
||||
.card-deck
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
.card
|
||||
margin-bottom: $card-deck-margin
|
||||
|
||||
+media-breakpoint-up(sm)
|
||||
flex-flow: row wrap
|
||||
margin-right: -$card-deck-margin
|
||||
margin-left: -$card-deck-margin
|
||||
|
||||
.card
|
||||
display: flex
|
||||
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%
|
||||
flex-direction: column
|
||||
margin-right: $card-deck-margin
|
||||
margin-bottom: 0
|
||||
|
||||
// Override the default
|
||||
margin-left: $card-deck-margin
|
||||
|
||||
//
|
||||
// Card groups
|
||||
//
|
||||
|
||||
.card-group
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card
|
||||
margin-bottom: $card-group-margin
|
||||
|
||||
+media-breakpoint-up(sm)
|
||||
flex-flow: row wrap
|
||||
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%
|
||||
margin-bottom: 0
|
||||
|
||||
+ .card
|
||||
margin-left: 0
|
||||
border-left: 0
|
||||
|
||||
// Handle rounded corners
|
||||
@if $enable-rounded
|
||||
&:first-child
|
||||
+border-right-radius(0)
|
||||
|
||||
.card-img-top,
|
||||
.card-header
|
||||
border-top-right-radius: 0
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer
|
||||
border-bottom-right-radius: 0
|
||||
|
||||
&:last-child
|
||||
+border-left-radius(0)
|
||||
|
||||
.card-img-top,
|
||||
.card-header
|
||||
border-top-left-radius: 0
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer
|
||||
border-bottom-left-radius: 0
|
||||
|
||||
&:only-child
|
||||
+border-radius($card-border-radius)
|
||||
|
||||
.card-img-top,
|
||||
.card-header
|
||||
+border-top-radius($card-border-radius)
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer
|
||||
+border-bottom-radius($card-border-radius)
|
||||
|
||||
&:not(:first-child):not(:last-child):not(:only-child)
|
||||
+border-radius(0)
|
||||
|
||||
.card-img-top,
|
||||
.card-img-bottom,
|
||||
.card-header,
|
||||
.card-footer
|
||||
+border-radius(0)
|
||||
|
||||
//
|
||||
// Columns
|
||||
//
|
||||
|
||||
.card-columns
|
||||
.card
|
||||
margin-bottom: $card-columns-margin
|
||||
|
||||
+media-breakpoint-up(sm)
|
||||
column-count: $card-columns-count
|
||||
column-gap: $card-columns-gap
|
||||
orphans: 1
|
||||
widows: 1
|
||||
|
||||
.card
|
||||
display: inline-block
|
||||
|
||||
// Don't let them vertically span multiple columns
|
||||
width: 100%
|
||||
|
||||
// Don't let their width change
|
||||
|
||||
//
|
||||
// Accordion
|
||||
//
|
||||
|
||||
.accordion
|
||||
.card:not(:first-of-type):not(:last-of-type)
|
||||
border-bottom: 0
|
||||
border-radius: 0
|
||||
|
||||
.card:not(:first-of-type)
|
||||
.card-header:first-child
|
||||
border-radius: 0
|
||||
|
||||
.card:first-of-type
|
||||
border-bottom: 0
|
||||
border-bottom-right-radius: 0
|
||||
border-bottom-left-radius: 0
|
||||
|
||||
.card:last-of-type
|
||||
border-top-left-radius: 0
|
||||
border-top-right-radius: 0
|
218
static/assets/bootstrap/sass/_carousel.sass
Normal file
218
static/assets/bootstrap/sass/_carousel.sass
Normal file
@@ -0,0 +1,218 @@
|
||||
// Notes on the classes:
|
||||
//
|
||||
// 1. The .carousel-item-left and .carousel-item-right is used to indicate where
|
||||
// the active slide is heading.
|
||||
// 2. .active.carousel-item is the current slide.
|
||||
// 3. .active.carousel-item-left and .active.carousel-item-right is the current
|
||||
// slide in its in-transition state. Only one of these occurs at a time.
|
||||
// 4. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
|
||||
// is the upcoming slide in transition.
|
||||
|
||||
.carousel
|
||||
position: relative
|
||||
|
||||
.carousel-inner
|
||||
position: relative
|
||||
width: 100%
|
||||
overflow: hidden
|
||||
|
||||
.carousel-item
|
||||
position: relative
|
||||
display: none
|
||||
align-items: center
|
||||
width: 100%
|
||||
backface-visibility: hidden
|
||||
perspective: 1000px
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next,
|
||||
.carousel-item-prev
|
||||
display: block
|
||||
|
||||
+transition($carousel-transition)
|
||||
|
||||
.carousel-item-next,
|
||||
.carousel-item-prev
|
||||
position: absolute
|
||||
top: 0
|
||||
|
||||
.carousel-item-next.carousel-item-left,
|
||||
.carousel-item-prev.carousel-item-right
|
||||
transform: translateX(0)
|
||||
|
||||
@supports (transform-style: preserve-3d)
|
||||
transform: translate3d(0, 0, 0)
|
||||
|
||||
.carousel-item-next,
|
||||
.active.carousel-item-right
|
||||
transform: translateX(100%)
|
||||
|
||||
@supports (transform-style: preserve-3d)
|
||||
transform: translate3d(100%, 0, 0)
|
||||
|
||||
.carousel-item-prev,
|
||||
.active.carousel-item-left
|
||||
transform: translateX(-100%)
|
||||
|
||||
@supports (transform-style: preserve-3d)
|
||||
transform: translate3d(-100%, 0, 0)
|
||||
|
||||
//
|
||||
// Alternate transitions
|
||||
//
|
||||
|
||||
.carousel-fade
|
||||
.carousel-item
|
||||
opacity: 0
|
||||
transition-duration: .6s
|
||||
transition-property: opacity
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next.carousel-item-left,
|
||||
.carousel-item-prev.carousel-item-right
|
||||
opacity: 1
|
||||
|
||||
.active.carousel-item-left,
|
||||
.active.carousel-item-right
|
||||
opacity: 0
|
||||
|
||||
.carousel-item-next,
|
||||
.carousel-item-prev,
|
||||
.carousel-item.active,
|
||||
.active.carousel-item-left,
|
||||
.active.carousel-item-prev
|
||||
transform: translateX(0)
|
||||
|
||||
@supports (transform-style: preserve-3d)
|
||||
transform: translate3d(0, 0, 0)
|
||||
|
||||
//
|
||||
// Left/right controls for nav
|
||||
//
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next
|
||||
position: absolute
|
||||
top: 0
|
||||
bottom: 0
|
||||
|
||||
// Use flex for alignment (1-3)
|
||||
display: flex
|
||||
|
||||
// 1. allow flex styles
|
||||
align-items: center
|
||||
|
||||
// 2. vertically center contents
|
||||
justify-content: center
|
||||
|
||||
// 3. horizontally center contents
|
||||
width: $carousel-control-width
|
||||
color: $carousel-control-color
|
||||
text-align: center
|
||||
opacity: $carousel-control-opacity
|
||||
|
||||
// We can't have a transition here because WebKit cancels the carousel
|
||||
// animation if you trip this while in the middle of another animation.
|
||||
|
||||
// Hover/focus state
|
||||
+hover-focus
|
||||
color: $carousel-control-color
|
||||
text-decoration: none
|
||||
outline: 0
|
||||
opacity: .9
|
||||
|
||||
.carousel-control-prev
|
||||
left: 0
|
||||
|
||||
@if $enable-gradients
|
||||
background: linear-gradient(90deg, rgba($black, 0.25), rgba($black, 0.001))
|
||||
|
||||
.carousel-control-next
|
||||
right: 0
|
||||
|
||||
@if $enable-gradients
|
||||
background: linear-gradient(270deg, rgba($black, 0.25), rgba($black, 0.001))
|
||||
|
||||
// Icons for within
|
||||
.carousel-control-prev-icon,
|
||||
.carousel-control-next-icon
|
||||
display: inline-block
|
||||
width: $carousel-control-icon-width
|
||||
height: $carousel-control-icon-width
|
||||
background: transparent no-repeat center center
|
||||
background-size: 100% 100%
|
||||
|
||||
.carousel-control-prev-icon
|
||||
background-image: $carousel-control-prev-icon-bg
|
||||
|
||||
.carousel-control-next-icon
|
||||
background-image: $carousel-control-next-icon-bg
|
||||
|
||||
// Optional indicator pips
|
||||
//
|
||||
// Add an ordered list with the following class and add a list item for each
|
||||
// slide your carousel holds.
|
||||
|
||||
.carousel-indicators
|
||||
position: absolute
|
||||
right: 0
|
||||
bottom: 10px
|
||||
left: 0
|
||||
z-index: 15
|
||||
display: flex
|
||||
justify-content: center
|
||||
padding-left: 0
|
||||
|
||||
// override <ol> default
|
||||
// Use the .carousel-control's width as margin so we don't overlay those
|
||||
margin-right: $carousel-control-width
|
||||
margin-left: $carousel-control-width
|
||||
list-style: none
|
||||
|
||||
li
|
||||
position: relative
|
||||
flex: 0 1 auto
|
||||
width: $carousel-indicator-width
|
||||
height: $carousel-indicator-height
|
||||
margin-right: $carousel-indicator-spacer
|
||||
margin-left: $carousel-indicator-spacer
|
||||
text-indent: -999px
|
||||
cursor: pointer
|
||||
background-color: rgba($carousel-indicator-active-bg, 0.5)
|
||||
|
||||
// Use pseudo classes to increase the hit area by 10px on top and bottom.
|
||||
&::before
|
||||
position: absolute
|
||||
top: -10px
|
||||
left: 0
|
||||
display: inline-block
|
||||
width: 100%
|
||||
height: 10px
|
||||
content: ""
|
||||
|
||||
&::after
|
||||
position: absolute
|
||||
bottom: -10px
|
||||
left: 0
|
||||
display: inline-block
|
||||
width: 100%
|
||||
height: 10px
|
||||
content: ""
|
||||
|
||||
.active
|
||||
background-color: $carousel-indicator-active-bg
|
||||
|
||||
// Optional captions
|
||||
//
|
||||
//
|
||||
|
||||
.carousel-caption
|
||||
position: absolute
|
||||
right: (100% - $carousel-caption-width) / 2
|
||||
bottom: 20px
|
||||
left: (100% - $carousel-caption-width) / 2
|
||||
z-index: 10
|
||||
padding-top: 20px
|
||||
padding-bottom: 20px
|
||||
color: $carousel-caption-color
|
||||
text-align: center
|
32
static/assets/bootstrap/sass/_close.sass
Normal file
32
static/assets/bootstrap/sass/_close.sass
Normal file
@@ -0,0 +1,32 @@
|
||||
.close
|
||||
float: right
|
||||
font-size: $close-font-size
|
||||
font-weight: $close-font-weight
|
||||
line-height: 1
|
||||
color: $close-color
|
||||
text-shadow: $close-text-shadow
|
||||
opacity: .5
|
||||
|
||||
&:not(:disabled):not(.disabled)
|
||||
+hover-focus
|
||||
color: $close-color
|
||||
text-decoration: none
|
||||
opacity: .75
|
||||
|
||||
|
||||
// Opinionated: add "hand" cursor to non-disabled .close elements
|
||||
cursor: pointer
|
||||
|
||||
// Additional properties for button version
|
||||
// iOS requires the button element instead of an anchor tag.
|
||||
// If you want the anchor version, it requires `href="#"`.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||
|
||||
// stylelint-disable property-no-vendor-prefix, selector-no-qualifying-type
|
||||
button.close
|
||||
padding: 0
|
||||
background-color: transparent
|
||||
border: 0
|
||||
-webkit-appearance: none
|
||||
|
||||
// stylelint-enable
|
43
static/assets/bootstrap/sass/_code.sass
Normal file
43
static/assets/bootstrap/sass/_code.sass
Normal file
@@ -0,0 +1,43 @@
|
||||
// Inline code
|
||||
code
|
||||
font-size: $code-font-size
|
||||
color: $code-color
|
||||
word-break: break-word
|
||||
|
||||
// Streamline the style when inside anchors to avoid broken underline and more
|
||||
a > &
|
||||
color: inherit
|
||||
|
||||
// User input typically entered via keyboard
|
||||
kbd
|
||||
padding: $kbd-padding-y $kbd-padding-x
|
||||
font-size: $kbd-font-size
|
||||
color: $kbd-color
|
||||
background-color: $kbd-bg
|
||||
|
||||
+border-radius($border-radius-sm)
|
||||
+box-shadow($kbd-box-shadow)
|
||||
|
||||
kbd
|
||||
padding: 0
|
||||
font-size: 100%
|
||||
font-weight: $nested-kbd-font-weight
|
||||
|
||||
+box-shadow(none)
|
||||
|
||||
// Blocks of code
|
||||
pre
|
||||
display: block
|
||||
font-size: $code-font-size
|
||||
color: $pre-color
|
||||
|
||||
// Account for some code outputs that place code tags in pre tags
|
||||
code
|
||||
font-size: inherit
|
||||
color: inherit
|
||||
word-break: normal
|
||||
|
||||
// Enable scrollable blocks of code
|
||||
.pre-scrollable
|
||||
max-height: $pre-scrollable-max-height
|
||||
overflow-y: scroll
|
416
static/assets/bootstrap/sass/_custom-forms.sass
Normal file
416
static/assets/bootstrap/sass/_custom-forms.sass
Normal file
@@ -0,0 +1,416 @@
|
||||
// Embedded icons from Open Iconic.
|
||||
// Released under MIT and copyright 2014 Waybury.
|
||||
// https://useiconic.com/open
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Base class takes care of all the key behavioral aspects.
|
||||
|
||||
.custom-control
|
||||
position: relative
|
||||
display: block
|
||||
min-height: 1rem * $line-height-base
|
||||
padding-left: $custom-control-gutter
|
||||
|
||||
.custom-control-inline
|
||||
display: inline-flex
|
||||
margin-right: $custom-control-spacer-x
|
||||
|
||||
.custom-control-input
|
||||
position: absolute
|
||||
z-index: -1
|
||||
|
||||
// Put the input behind the label so it doesn't overlay text
|
||||
opacity: 0
|
||||
|
||||
&:checked ~ .custom-control-label::before
|
||||
color: $custom-control-indicator-checked-color
|
||||
|
||||
+gradient-bg($custom-control-indicator-checked-bg)
|
||||
+box-shadow($custom-control-indicator-checked-box-shadow)
|
||||
|
||||
&:focus ~ .custom-control-label::before
|
||||
// the mixin is not used here to make sure there is feedback
|
||||
box-shadow: $custom-control-indicator-focus-box-shadow
|
||||
|
||||
&:active ~ .custom-control-label::before
|
||||
color: $custom-control-indicator-active-color
|
||||
background-color: $custom-control-indicator-active-bg
|
||||
|
||||
+box-shadow($custom-control-indicator-active-box-shadow)
|
||||
|
||||
&:disabled
|
||||
~ .custom-control-label
|
||||
color: $custom-control-label-disabled-color
|
||||
|
||||
&::before
|
||||
background-color: $custom-control-indicator-disabled-bg
|
||||
|
||||
// Custom control indicators
|
||||
//
|
||||
// Build the custom controls out of pseudo-elements.
|
||||
|
||||
.custom-control-label
|
||||
position: relative
|
||||
margin-bottom: 0
|
||||
|
||||
// Background-color and (when enabled) gradient
|
||||
&::before
|
||||
position: absolute
|
||||
top: ($line-height-base - $custom-control-indicator-size) / 2
|
||||
left: -$custom-control-gutter
|
||||
display: block
|
||||
width: $custom-control-indicator-size
|
||||
height: $custom-control-indicator-size
|
||||
pointer-events: none
|
||||
content: ""
|
||||
user-select: none
|
||||
background-color: $custom-control-indicator-bg
|
||||
|
||||
+box-shadow($custom-control-indicator-box-shadow)
|
||||
|
||||
// Foreground (icon)
|
||||
&::after
|
||||
position: absolute
|
||||
top: ($line-height-base - $custom-control-indicator-size) / 2
|
||||
left: -$custom-control-gutter
|
||||
display: block
|
||||
width: $custom-control-indicator-size
|
||||
height: $custom-control-indicator-size
|
||||
content: ""
|
||||
background-repeat: no-repeat
|
||||
background-position: center center
|
||||
background-size: $custom-control-indicator-bg-size
|
||||
|
||||
// Checkboxes
|
||||
//
|
||||
// Tweak just a few things for checkboxes.
|
||||
|
||||
.custom-checkbox
|
||||
.custom-control-label::before
|
||||
+border-radius($custom-checkbox-indicator-border-radius)
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label
|
||||
&::before
|
||||
+gradient-bg($custom-control-indicator-checked-bg)
|
||||
|
||||
&::after
|
||||
background-image: $custom-checkbox-indicator-icon-checked
|
||||
|
||||
.custom-control-input:indeterminate ~ .custom-control-label
|
||||
&::before
|
||||
+gradient-bg($custom-checkbox-indicator-indeterminate-bg)
|
||||
+box-shadow($custom-checkbox-indicator-indeterminate-box-shadow)
|
||||
|
||||
&::after
|
||||
background-image: $custom-checkbox-indicator-icon-indeterminate
|
||||
|
||||
.custom-control-input:disabled
|
||||
&:checked ~ .custom-control-label::before
|
||||
background-color: $custom-control-indicator-checked-disabled-bg
|
||||
|
||||
&:indeterminate ~ .custom-control-label::before
|
||||
background-color: $custom-control-indicator-checked-disabled-bg
|
||||
|
||||
// Radios
|
||||
//
|
||||
// Tweak just a few things for radios.
|
||||
|
||||
.custom-radio
|
||||
.custom-control-label::before
|
||||
border-radius: $custom-radio-indicator-border-radius
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label
|
||||
&::before
|
||||
+gradient-bg($custom-control-indicator-checked-bg)
|
||||
|
||||
&::after
|
||||
background-image: $custom-radio-indicator-icon-checked
|
||||
|
||||
.custom-control-input:disabled
|
||||
&:checked ~ .custom-control-label::before
|
||||
background-color: $custom-control-indicator-checked-disabled-bg
|
||||
|
||||
// Select
|
||||
//
|
||||
// Replaces the browser default select with a custom one, mostly pulled from
|
||||
// https://primer.github.io/.
|
||||
//
|
||||
|
||||
.custom-select
|
||||
display: inline-block
|
||||
width: 100%
|
||||
height: $custom-select-height
|
||||
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x
|
||||
line-height: $custom-select-line-height
|
||||
color: $custom-select-color
|
||||
vertical-align: middle
|
||||
background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center
|
||||
background-size: $custom-select-bg-size
|
||||
border: $custom-select-border-width solid $custom-select-border-color
|
||||
|
||||
@if $enable-rounded
|
||||
border-radius: $custom-select-border-radius
|
||||
@else
|
||||
border-radius: 0
|
||||
|
||||
+box-shadow($custom-select-box-shadow)
|
||||
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
border-color: $custom-select-focus-border-color
|
||||
outline: 0
|
||||
|
||||
@if $enable-shadows
|
||||
box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow
|
||||
@else
|
||||
box-shadow: $custom-select-focus-box-shadow
|
||||
|
||||
&::-ms-value
|
||||
// For visual consistency with other platforms/browsers,
|
||||
// suppress the default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color
|
||||
background-color: $input-bg
|
||||
|
||||
&[multiple],
|
||||
&[size]:not([size="1"])
|
||||
height: auto
|
||||
padding-right: $custom-select-padding-x
|
||||
background-image: none
|
||||
|
||||
&:disabled
|
||||
color: $custom-select-disabled-color
|
||||
background-color: $custom-select-disabled-bg
|
||||
|
||||
// Hides the default caret in IE11
|
||||
&::-ms-expand
|
||||
opacity: 0
|
||||
|
||||
.custom-select-sm
|
||||
height: $custom-select-height-sm
|
||||
padding-top: $custom-select-padding-y
|
||||
padding-bottom: $custom-select-padding-y
|
||||
font-size: $custom-select-font-size-sm
|
||||
|
||||
.custom-select-lg
|
||||
height: $custom-select-height-lg
|
||||
padding-top: $custom-select-padding-y
|
||||
padding-bottom: $custom-select-padding-y
|
||||
font-size: $custom-select-font-size-lg
|
||||
|
||||
// File
|
||||
//
|
||||
// Custom file input.
|
||||
|
||||
.custom-file
|
||||
position: relative
|
||||
display: inline-block
|
||||
width: 100%
|
||||
height: $custom-file-height
|
||||
margin-bottom: 0
|
||||
|
||||
.custom-file-input
|
||||
position: relative
|
||||
z-index: 2
|
||||
width: 100%
|
||||
height: $custom-file-height
|
||||
margin: 0
|
||||
opacity: 0
|
||||
|
||||
&:focus ~ .custom-file-label
|
||||
border-color: $custom-file-focus-border-color
|
||||
box-shadow: $custom-file-focus-box-shadow
|
||||
|
||||
&::after
|
||||
border-color: $custom-file-focus-border-color
|
||||
|
||||
&:disabled ~ .custom-file-label
|
||||
background-color: $custom-file-disabled-bg
|
||||
|
||||
@each $lang, $value in $custom-file-text
|
||||
&:lang(#{$lang}) ~ .custom-file-label::after
|
||||
content: $value
|
||||
|
||||
.custom-file-label
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
left: 0
|
||||
z-index: 1
|
||||
height: $custom-file-height
|
||||
padding: $custom-file-padding-y $custom-file-padding-x
|
||||
line-height: $custom-file-line-height
|
||||
color: $custom-file-color
|
||||
background-color: $custom-file-bg
|
||||
border: $custom-file-border-width solid $custom-file-border-color
|
||||
|
||||
+border-radius($custom-file-border-radius)
|
||||
+box-shadow($custom-file-box-shadow)
|
||||
|
||||
&::after
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
z-index: 3
|
||||
display: block
|
||||
height: $custom-file-height-inner
|
||||
padding: $custom-file-padding-y $custom-file-padding-x
|
||||
line-height: $custom-file-line-height
|
||||
color: $custom-file-button-color
|
||||
content: "Browse"
|
||||
|
||||
+gradient-bg($custom-file-button-bg)
|
||||
|
||||
border-left: $custom-file-border-width solid $custom-file-border-color
|
||||
|
||||
+border-radius(0 $custom-file-border-radius $custom-file-border-radius 0)
|
||||
|
||||
// Range
|
||||
//
|
||||
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
|
||||
// elements cannot be mixed. As such, there are no shared styles for focus or
|
||||
// active states on prefixed selectors.
|
||||
|
||||
.custom-range
|
||||
width: 100%
|
||||
padding-left: 0
|
||||
|
||||
// Firefox specific
|
||||
background-color: transparent
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
|
||||
&::-moz-focus-outer
|
||||
border: 0
|
||||
|
||||
&::-webkit-slider-thumb
|
||||
width: $custom-range-thumb-width
|
||||
height: $custom-range-thumb-height
|
||||
margin-top: -($custom-range-thumb-width * 0.25)
|
||||
|
||||
// Webkit specific?
|
||||
+gradient-bg($custom-range-thumb-bg)
|
||||
|
||||
border: $custom-range-thumb-border
|
||||
|
||||
+border-radius($custom-range-thumb-border-radius)
|
||||
+box-shadow($custom-range-thumb-box-shadow)
|
||||
+transition($custom-forms-transition)
|
||||
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
box-shadow: $custom-range-thumb-focus-box-shadow
|
||||
|
||||
// No mixin for focus accessibility
|
||||
|
||||
&:active
|
||||
+gradient-bg($custom-range-thumb-active-bg)
|
||||
|
||||
&::-webkit-slider-runnable-track
|
||||
width: $custom-range-track-width
|
||||
height: $custom-range-track-height
|
||||
color: transparent
|
||||
|
||||
// Why?
|
||||
cursor: $custom-range-track-cursor
|
||||
background-color: $custom-range-track-bg
|
||||
border-color: transparent
|
||||
|
||||
+border-radius($custom-range-track-border-radius)
|
||||
+box-shadow($custom-range-track-box-shadow)
|
||||
|
||||
&::-moz-range-thumb
|
||||
width: $custom-range-thumb-width
|
||||
height: $custom-range-thumb-height
|
||||
|
||||
+gradient-bg($custom-range-thumb-bg)
|
||||
|
||||
border: $custom-range-thumb-border
|
||||
|
||||
+border-radius($custom-range-thumb-border-radius)
|
||||
+box-shadow($custom-range-thumb-box-shadow)
|
||||
+transition($custom-forms-transition)
|
||||
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
box-shadow: $custom-range-thumb-focus-box-shadow
|
||||
|
||||
// No mixin for focus accessibility
|
||||
|
||||
&:active
|
||||
+gradient-bg($custom-range-thumb-active-bg)
|
||||
|
||||
&::-moz-range-track
|
||||
width: $custom-range-track-width
|
||||
height: $custom-range-track-height
|
||||
color: transparent
|
||||
cursor: $custom-range-track-cursor
|
||||
background-color: $custom-range-track-bg
|
||||
border-color: transparent
|
||||
|
||||
// Firefox specific?
|
||||
+border-radius($custom-range-track-border-radius)
|
||||
+box-shadow($custom-range-track-box-shadow)
|
||||
|
||||
&::-ms-thumb
|
||||
width: $custom-range-thumb-width
|
||||
height: $custom-range-thumb-height
|
||||
|
||||
+gradient-bg($custom-range-thumb-bg)
|
||||
|
||||
border: $custom-range-thumb-border
|
||||
|
||||
+border-radius($custom-range-thumb-border-radius)
|
||||
+box-shadow($custom-range-thumb-box-shadow)
|
||||
+transition($custom-forms-transition)
|
||||
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
box-shadow: $custom-range-thumb-focus-box-shadow
|
||||
|
||||
// No mixin for focus accessibility
|
||||
|
||||
&:active
|
||||
+gradient-bg($custom-range-thumb-active-bg)
|
||||
|
||||
&::-ms-track
|
||||
width: $custom-range-track-width
|
||||
height: $custom-range-track-height
|
||||
color: transparent
|
||||
cursor: $custom-range-track-cursor
|
||||
background-color: transparent
|
||||
border-color: transparent
|
||||
border-width: $custom-range-thumb-height * 0.5
|
||||
|
||||
+box-shadow($custom-range-track-box-shadow)
|
||||
|
||||
&::-ms-fill-lower
|
||||
background-color: $custom-range-track-bg
|
||||
|
||||
+border-radius($custom-range-track-border-radius)
|
||||
|
||||
&::-ms-fill-upper
|
||||
margin-right: 15px
|
||||
|
||||
// arbitrary?
|
||||
background-color: $custom-range-track-bg
|
||||
|
||||
+border-radius($custom-range-track-border-radius)
|
||||
|
||||
.custom-control-label::before,
|
||||
.custom-file-label,
|
||||
.custom-select
|
||||
+transition($custom-forms-transition)
|
170
static/assets/bootstrap/sass/_dropdown.sass
Normal file
170
static/assets/bootstrap/sass/_dropdown.sass
Normal file
@@ -0,0 +1,170 @@
|
||||
// The dropdown wrapper (`<div>`)
|
||||
.dropup,
|
||||
.dropright,
|
||||
.dropdown,
|
||||
.dropleft
|
||||
position: relative
|
||||
|
||||
.dropdown-toggle
|
||||
// Generate the caret automatically
|
||||
+caret
|
||||
|
||||
// The dropdown menu
|
||||
.dropdown-menu
|
||||
position: absolute
|
||||
top: 100%
|
||||
left: 0
|
||||
z-index: $zindex-dropdown
|
||||
display: none
|
||||
|
||||
// none by default, but block on "open" of the menu
|
||||
float: left
|
||||
min-width: $dropdown-min-width
|
||||
padding: $dropdown-padding-y 0
|
||||
margin: $dropdown-spacer 0 0
|
||||
|
||||
// override default ul
|
||||
font-size: $font-size-base
|
||||
|
||||
// Redeclare because nesting can cause inheritance issues
|
||||
color: $body-color
|
||||
text-align: left
|
||||
|
||||
// Ensures proper alignment if parent has it changed (e.g., modal footer)
|
||||
list-style: none
|
||||
background-color: $dropdown-bg
|
||||
background-clip: padding-box
|
||||
border: $dropdown-border-width solid $dropdown-border-color
|
||||
|
||||
+border-radius($dropdown-border-radius)
|
||||
+box-shadow($dropdown-box-shadow)
|
||||
|
||||
.dropdown-menu-right
|
||||
right: 0
|
||||
left: auto
|
||||
|
||||
// Allow for dropdowns to go bottom up (aka, dropup-menu)
|
||||
// Just add .dropup after the standard .dropdown class and you're set.
|
||||
.dropup
|
||||
.dropdown-menu
|
||||
top: auto
|
||||
bottom: 100%
|
||||
margin-top: 0
|
||||
margin-bottom: $dropdown-spacer
|
||||
|
||||
.dropdown-toggle
|
||||
+caret(up)
|
||||
|
||||
.dropright
|
||||
.dropdown-menu
|
||||
top: 0
|
||||
right: auto
|
||||
left: 100%
|
||||
margin-top: 0
|
||||
margin-left: $dropdown-spacer
|
||||
|
||||
.dropdown-toggle
|
||||
+caret(right)
|
||||
|
||||
&::after
|
||||
vertical-align: 0
|
||||
|
||||
.dropleft
|
||||
.dropdown-menu
|
||||
top: 0
|
||||
right: 100%
|
||||
left: auto
|
||||
margin-top: 0
|
||||
margin-right: $dropdown-spacer
|
||||
|
||||
.dropdown-toggle
|
||||
+caret(left)
|
||||
|
||||
&::before
|
||||
vertical-align: 0
|
||||
|
||||
// When enabled Popper.js, reset basic dropdown position
|
||||
// stylelint-disable no-duplicate-selectors
|
||||
.dropdown-menu
|
||||
&[x-placement^="top"],
|
||||
&[x-placement^="right"],
|
||||
&[x-placement^="bottom"],
|
||||
&[x-placement^="left"]
|
||||
right: auto
|
||||
bottom: auto
|
||||
|
||||
// stylelint-enable no-duplicate-selectors
|
||||
|
||||
// Dividers (basically an `<hr>`) within the dropdown
|
||||
.dropdown-divider
|
||||
+nav-divider($dropdown-divider-bg)
|
||||
|
||||
// Links, buttons, and more within the dropdown menu
|
||||
//
|
||||
// `<button>`-specific styles are denoted with `// For <button>s`
|
||||
.dropdown-item
|
||||
display: block
|
||||
width: 100%
|
||||
|
||||
// For `<button>`s
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x
|
||||
clear: both
|
||||
font-weight: $font-weight-normal
|
||||
color: $dropdown-link-color
|
||||
text-align: inherit
|
||||
|
||||
// For `<button>`s
|
||||
white-space: nowrap
|
||||
|
||||
// prevent links from randomly breaking onto new lines
|
||||
background-color: transparent
|
||||
|
||||
// For `<button>`s
|
||||
border: 0
|
||||
|
||||
// For `<button>`s
|
||||
|
||||
+hover-focus
|
||||
color: $dropdown-link-hover-color
|
||||
text-decoration: none
|
||||
|
||||
+gradient-bg($dropdown-link-hover-bg)
|
||||
|
||||
|
||||
&.active,
|
||||
&:active
|
||||
color: $dropdown-link-active-color
|
||||
text-decoration: none
|
||||
|
||||
+gradient-bg($dropdown-link-active-bg)
|
||||
|
||||
&.disabled,
|
||||
&:disabled
|
||||
color: $dropdown-link-disabled-color
|
||||
background-color: transparent
|
||||
|
||||
// Remove CSS gradients if they're enabled
|
||||
@if $enable-gradients
|
||||
background-image: none
|
||||
|
||||
.dropdown-menu.show
|
||||
display: block
|
||||
|
||||
// Dropdown section headers
|
||||
.dropdown-header
|
||||
display: block
|
||||
padding: $dropdown-padding-y $dropdown-item-padding-x
|
||||
margin-bottom: 0
|
||||
|
||||
// for use with heading elements
|
||||
font-size: $font-size-sm
|
||||
color: $dropdown-header-color
|
||||
white-space: nowrap
|
||||
|
||||
// as with > li > a
|
||||
|
||||
// Dropdown text
|
||||
.dropdown-item-text
|
||||
display: block
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x
|
||||
color: $dropdown-link-color
|
306
static/assets/bootstrap/sass/_forms.sass
Normal file
306
static/assets/bootstrap/sass/_forms.sass
Normal file
@@ -0,0 +1,306 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Textual form controls
|
||||
//
|
||||
|
||||
.form-control
|
||||
display: block
|
||||
width: 100%
|
||||
padding: $input-padding-y $input-padding-x
|
||||
font-size: $font-size-base
|
||||
line-height: $input-line-height
|
||||
color: $input-color
|
||||
background-color: $input-bg
|
||||
background-clip: padding-box
|
||||
border: $input-border-width solid $input-border-color
|
||||
|
||||
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||
@if $enable-rounded
|
||||
// Manually use the if/else instead of the mixin to account for iOS override
|
||||
border-radius: $input-border-radius
|
||||
@else
|
||||
// Otherwise undo the iOS default
|
||||
border-radius: 0
|
||||
|
||||
+box-shadow($input-box-shadow)
|
||||
+transition($input-transition)
|
||||
|
||||
// Unstyle the caret on `<select>`s in IE10+.
|
||||
&::-ms-expand
|
||||
background-color: transparent
|
||||
border: 0
|
||||
|
||||
// Customize the `:focus` state to imitate native WebKit styles.
|
||||
+form-control-focus
|
||||
|
||||
// Placeholder
|
||||
&::placeholder
|
||||
color: $input-placeholder-color
|
||||
|
||||
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
|
||||
opacity: 1
|
||||
|
||||
// Disabled and read-only inputs
|
||||
//
|
||||
// HTML5 says that controls under a fieldset > legend:first-child won't be
|
||||
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||
// don't honor that edge case; we style them as disabled anyway.
|
||||
&:disabled,
|
||||
&[readonly]
|
||||
background-color: $input-disabled-bg
|
||||
|
||||
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||
opacity: 1
|
||||
|
||||
select.form-control
|
||||
&:not([size]):not([multiple])
|
||||
height: $input-height
|
||||
|
||||
&:focus::-ms-value
|
||||
// Suppress the nested default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
|
||||
// match the appearance of the native widget.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color
|
||||
background-color: $input-bg
|
||||
|
||||
// Make file inputs better match text inputs by forcing them to new lines.
|
||||
.form-control-file,
|
||||
.form-control-range
|
||||
display: block
|
||||
width: 100%
|
||||
|
||||
//
|
||||
// Labels
|
||||
//
|
||||
|
||||
// For use with horizontal and inline forms, when you need the label (or legend)
|
||||
// text to align with the form controls.
|
||||
.col-form-label
|
||||
padding-top: calc(#{$input-padding-y} + #{$input-border-width})
|
||||
padding-bottom: calc(#{$input-padding-y} + #{$input-border-width})
|
||||
margin-bottom: 0
|
||||
|
||||
// Override the `<label>/<legend>` default
|
||||
font-size: inherit
|
||||
|
||||
// Override the `<legend>` default
|
||||
line-height: $input-line-height
|
||||
|
||||
.col-form-label-lg
|
||||
padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width})
|
||||
padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width})
|
||||
font-size: $font-size-lg
|
||||
line-height: $input-line-height-lg
|
||||
|
||||
.col-form-label-sm
|
||||
padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width})
|
||||
padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width})
|
||||
font-size: $font-size-sm
|
||||
line-height: $input-line-height-sm
|
||||
|
||||
// Readonly controls as plain text
|
||||
//
|
||||
// Apply class to a readonly input to make it appear like regular plain
|
||||
// text (without any border, background color, focus indicator)
|
||||
|
||||
.form-control-plaintext
|
||||
display: block
|
||||
width: 100%
|
||||
padding-top: $input-padding-y
|
||||
padding-bottom: $input-padding-y
|
||||
margin-bottom: 0
|
||||
|
||||
// match inputs if this class comes on inputs with default margins
|
||||
line-height: $input-line-height
|
||||
color: $input-plaintext-color
|
||||
background-color: transparent
|
||||
border: solid transparent
|
||||
border-width: $input-border-width 0
|
||||
|
||||
&.form-control-sm,
|
||||
&.form-control-lg
|
||||
padding-right: 0
|
||||
padding-left: 0
|
||||
|
||||
// Form control sizing
|
||||
//
|
||||
// Build on `.form-control` with modifier classes to decrease or increase the
|
||||
// height and font-size of form controls.
|
||||
//
|
||||
// The `.form-group-* form-control` variations are sadly duplicated to avoid the
|
||||
// issue documented in https://github.com/twbs/bootstrap/issues/15074.
|
||||
|
||||
.form-control-sm
|
||||
padding: $input-padding-y-sm $input-padding-x-sm
|
||||
font-size: $font-size-sm
|
||||
line-height: $input-line-height-sm
|
||||
|
||||
+border-radius($input-border-radius-sm)
|
||||
|
||||
select.form-control-sm
|
||||
&:not([size]):not([multiple])
|
||||
height: $input-height-sm
|
||||
|
||||
.form-control-lg
|
||||
padding: $input-padding-y-lg $input-padding-x-lg
|
||||
font-size: $font-size-lg
|
||||
line-height: $input-line-height-lg
|
||||
|
||||
+border-radius($input-border-radius-lg)
|
||||
|
||||
select.form-control-lg
|
||||
&:not([size]):not([multiple])
|
||||
height: $input-height-lg
|
||||
|
||||
// Form groups
|
||||
//
|
||||
// Designed to help with the organization and spacing of vertical forms. For
|
||||
// horizontal forms, use the predefined grid classes.
|
||||
|
||||
.form-group
|
||||
margin-bottom: $form-group-margin-bottom
|
||||
|
||||
.form-text
|
||||
display: block
|
||||
margin-top: $form-text-margin-top
|
||||
|
||||
// Form grid
|
||||
//
|
||||
// Special replacement for our grid system's `.row` for tighter form layouts.
|
||||
|
||||
.form-row
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
margin-right: -5px
|
||||
margin-left: -5px
|
||||
|
||||
> .col,
|
||||
> [class*="col-"]
|
||||
padding-right: 5px
|
||||
padding-left: 5px
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Indent the labels to position radios/checkboxes as hanging controls.
|
||||
|
||||
.form-check
|
||||
position: relative
|
||||
display: block
|
||||
padding-left: $form-check-input-gutter
|
||||
|
||||
.form-check-input
|
||||
position: absolute
|
||||
margin-top: $form-check-input-margin-y
|
||||
margin-left: -$form-check-input-gutter
|
||||
|
||||
&:disabled ~ .form-check-label
|
||||
color: $text-muted
|
||||
|
||||
.form-check-label
|
||||
margin-bottom: 0
|
||||
|
||||
// Override default `<label>` bottom margin
|
||||
|
||||
.form-check-inline
|
||||
display: inline-flex
|
||||
align-items: center
|
||||
padding-left: 0
|
||||
|
||||
// Override base .form-check
|
||||
margin-right: $form-check-inline-margin-x
|
||||
|
||||
// Undo .form-check-input defaults and add some `margin-right`.
|
||||
.form-check-input
|
||||
position: static
|
||||
margin-top: 0
|
||||
margin-right: $form-check-inline-input-margin-x
|
||||
margin-left: 0
|
||||
|
||||
// Form validation
|
||||
//
|
||||
// Provide feedback to users when form field values are valid or invalid. Works
|
||||
// primarily for client-side validation via scoped `:invalid` and `:valid`
|
||||
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
|
||||
// server side validation.
|
||||
|
||||
+form-validation-state("valid", $form-feedback-valid-color)
|
||||
+form-validation-state("invalid", $form-feedback-invalid-color)
|
||||
|
||||
// Inline forms
|
||||
//
|
||||
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
|
||||
// forms begin stacked on extra small (mobile) devices and then go inline when
|
||||
// viewports reach <768px.
|
||||
//
|
||||
// Requires wrapping inputs and labels with `.form-group` for proper display of
|
||||
// default HTML form controls and our custom form controls (e.g., input groups).
|
||||
|
||||
.form-inline
|
||||
display: flex
|
||||
flex-flow: row wrap
|
||||
align-items: center
|
||||
|
||||
// Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
|
||||
|
||||
// Because we use flex, the initial sizing of checkboxes is collapsed and
|
||||
// doesn't occupy the full-width (which is what we want for xs grid tier),
|
||||
// so we force that here.
|
||||
.form-check
|
||||
width: 100%
|
||||
|
||||
// Kick in the inline
|
||||
+media-breakpoint-up(sm)
|
||||
label
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
margin-bottom: 0
|
||||
|
||||
// Inline-block all the things for "inline"
|
||||
.form-group
|
||||
display: flex
|
||||
flex: 0 0 auto
|
||||
flex-flow: row wrap
|
||||
align-items: center
|
||||
margin-bottom: 0
|
||||
|
||||
// Allow folks to *not* use `.form-group`
|
||||
.form-control
|
||||
display: inline-block
|
||||
width: auto
|
||||
|
||||
// Prevent labels from stacking above inputs in `.form-group`
|
||||
vertical-align: middle
|
||||
|
||||
// Make static controls behave like regular ones
|
||||
.form-control-plaintext
|
||||
display: inline-block
|
||||
|
||||
.input-group,
|
||||
.custom-select
|
||||
width: auto
|
||||
|
||||
// Remove default margin on radios/checkboxes that were used for stacking, and
|
||||
// then undo the floating of radios and checkboxes to match.
|
||||
.form-check
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: auto
|
||||
padding-left: 0
|
||||
|
||||
.form-check-input
|
||||
position: relative
|
||||
margin-top: 0
|
||||
margin-right: $form-check-input-margin-x
|
||||
margin-left: 0
|
||||
|
||||
.custom-control
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.custom-control-label
|
||||
margin-bottom: 0
|
76
static/assets/bootstrap/sass/_functions.sass
Normal file
76
static/assets/bootstrap/sass/_functions.sass
Normal file
@@ -0,0 +1,76 @@
|
||||
// Bootstrap functions
|
||||
//
|
||||
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
|
||||
|
||||
// Ascending
|
||||
// Used to evaluate Sass maps like our grid breakpoints.
|
||||
=_assert-ascending($map, $map-name)
|
||||
$prev-key: null
|
||||
$prev-num: null
|
||||
|
||||
@each $key, $num in $map
|
||||
@if $prev-num == null
|
||||
// Do nothing
|
||||
@else if not comparable($prev-num, $num)
|
||||
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !"
|
||||
@else if $prev-num >= $num
|
||||
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !"
|
||||
|
||||
$prev-key: $key
|
||||
$prev-num: $num
|
||||
|
||||
// Starts at zero
|
||||
// Another grid mixin that ensures the min-width of the lowest breakpoint starts at 0.
|
||||
=_assert-starts-at-zero($map)
|
||||
$values: map-values($map)
|
||||
$first-value: nth($values, 1)
|
||||
|
||||
@if $first-value != 0
|
||||
@warn "First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}."
|
||||
|
||||
// Replace `$search` with `$replace` in `$string`
|
||||
// Used on our SVG icon backgrounds for custom forms.
|
||||
//
|
||||
// @author Hugo Giraudel
|
||||
// @param {String} $string - Initial string
|
||||
// @param {String} $search - Substring to replace
|
||||
// @param {String} $replace ('') - New value
|
||||
// @return {String} - Updated string
|
||||
@function str-replace($string, $search, $replace: "")
|
||||
$index: str-index($string, $search)
|
||||
|
||||
@if $index
|
||||
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace)
|
||||
|
||||
@return $string
|
||||
|
||||
// Color contrast
|
||||
@function color-yiq($color)
|
||||
$r: red($color)
|
||||
$g: green($color)
|
||||
$b: blue($color)
|
||||
|
||||
$yiq: ($r * 299 + $g * 587 + $b * 114) / 1000
|
||||
|
||||
@if $yiq >= $yiq-contrasted-threshold
|
||||
@return $yiq-text-dark
|
||||
@else
|
||||
@return $yiq-text-light
|
||||
|
||||
// Retrieve color Sass maps
|
||||
@function color($key: "blue")
|
||||
@return map-get($colors, $key)
|
||||
|
||||
@function theme-color($key: "primary")
|
||||
@return map-get($theme-colors, $key)
|
||||
|
||||
@function gray($key: "100")
|
||||
@return map-get($grays, $key)
|
||||
|
||||
// Request a theme color level
|
||||
@function theme-color-level($color-name: "primary", $level: 0)
|
||||
$color: theme-color($color-name)
|
||||
$color-base: if($level > 0, $black, $white)
|
||||
$level: abs($level)
|
||||
|
||||
@return mix($color-base, $color, $level * $theme-color-interval)
|
43
static/assets/bootstrap/sass/_grid.sass
Normal file
43
static/assets/bootstrap/sass/_grid.sass
Normal file
@@ -0,0 +1,43 @@
|
||||
// Container widths
|
||||
//
|
||||
// Set the container width, and override it for fixed navbars in media queries.
|
||||
|
||||
@if $enable-grid-classes
|
||||
.container
|
||||
+make-container
|
||||
+make-container-max-widths
|
||||
|
||||
// Fluid container
|
||||
//
|
||||
// Utilizes the mixin meant for fixed width containers, but with 100% width for
|
||||
// fluid, full width layouts.
|
||||
|
||||
@if $enable-grid-classes
|
||||
.container-fluid
|
||||
+make-container
|
||||
|
||||
// Row
|
||||
//
|
||||
// Rows contain and clear the floats of your columns.
|
||||
|
||||
@if $enable-grid-classes
|
||||
.row
|
||||
+make-row
|
||||
|
||||
// Remove the negative margin from default .row, then the horizontal padding
|
||||
// from all immediate children columns (to prevent runaway style inheritance).
|
||||
.no-gutters
|
||||
margin-right: 0
|
||||
margin-left: 0
|
||||
|
||||
> .col,
|
||||
> [class*="col-"]
|
||||
padding-right: 0
|
||||
padding-left: 0
|
||||
|
||||
// Columns
|
||||
//
|
||||
// Common styles for small and large grid columns
|
||||
|
||||
@if $enable-grid-classes
|
||||
+make-grid-columns
|
37
static/assets/bootstrap/sass/_images.sass
Normal file
37
static/assets/bootstrap/sass/_images.sass
Normal file
@@ -0,0 +1,37 @@
|
||||
// Responsive images (ensure images don't scale beyond their parents)
|
||||
//
|
||||
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
|
||||
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
|
||||
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
|
||||
// which weren't expecting the images within themselves to be involuntarily resized.
|
||||
// See also https://github.com/twbs/bootstrap/issues/18178
|
||||
.img-fluid
|
||||
+img-fluid
|
||||
|
||||
// Image thumbnails
|
||||
.img-thumbnail
|
||||
padding: $thumbnail-padding
|
||||
background-color: $thumbnail-bg
|
||||
border: $thumbnail-border-width solid $thumbnail-border-color
|
||||
|
||||
+border-radius($thumbnail-border-radius)
|
||||
+box-shadow($thumbnail-box-shadow)
|
||||
|
||||
// Keep them at most 100% wide
|
||||
+img-fluid
|
||||
|
||||
//
|
||||
// Figures
|
||||
//
|
||||
|
||||
.figure
|
||||
// Ensures the caption's text aligns with the image.
|
||||
display: inline-block
|
||||
|
||||
.figure-img
|
||||
margin-bottom: $spacer / 2
|
||||
line-height: 1
|
||||
|
||||
.figure-caption
|
||||
font-size: $figure-caption-font-size
|
||||
color: $figure-caption-color
|
159
static/assets/bootstrap/sass/_input-group.sass
Normal file
159
static/assets/bootstrap/sass/_input-group.sass
Normal file
@@ -0,0 +1,159 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.input-group
|
||||
position: relative
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
// For form validation feedback
|
||||
align-items: stretch
|
||||
width: 100%
|
||||
|
||||
> .form-control,
|
||||
> .custom-select,
|
||||
> .custom-file
|
||||
position: relative
|
||||
|
||||
// For focus state's z-index
|
||||
flex: 1 1 auto
|
||||
|
||||
// Add width 1% and flex-basis auto to ensure that button will not wrap out
|
||||
// the column. Applies to IE Edge+ and Firefox. Chrome does not require this.
|
||||
width: 1%
|
||||
margin-bottom: 0
|
||||
|
||||
+ .form-control,
|
||||
+ .custom-select,
|
||||
+ .custom-file
|
||||
margin-left: -$input-border-width
|
||||
|
||||
// Bring the "active" form control to the top of surrounding elements
|
||||
> .form-control:focus,
|
||||
> .custom-select:focus,
|
||||
> .custom-file .custom-file-input:focus ~ .custom-file-label
|
||||
z-index: 3
|
||||
|
||||
> .form-control,
|
||||
> .custom-select
|
||||
&:not(:last-child)
|
||||
+border-right-radius(0)
|
||||
|
||||
&:not(:first-child)
|
||||
+border-left-radius(0)
|
||||
|
||||
// Custom file inputs have more complex markup, thus requiring different
|
||||
// border-radius overrides.
|
||||
> .custom-file
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
&:not(:last-child) .custom-file-label,
|
||||
&:not(:last-child) .custom-file-label::after
|
||||
+border-right-radius(0)
|
||||
|
||||
&:not(:first-child) .custom-file-label
|
||||
+border-left-radius(0)
|
||||
|
||||
// Prepend and append
|
||||
//
|
||||
// While it requires one extra layer of HTML for each, dedicated prepend and
|
||||
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
|
||||
// 3) support HTML5 form validation.
|
||||
|
||||
.input-group-prepend,
|
||||
.input-group-append
|
||||
display: flex
|
||||
|
||||
// Ensure buttons are always above inputs for more visually pleasing borders.
|
||||
// This isn't needed for `.input-group-text` since it shares the same border-color
|
||||
// as our inputs.
|
||||
.btn
|
||||
position: relative
|
||||
z-index: 2
|
||||
|
||||
.btn + .btn,
|
||||
.btn + .input-group-text,
|
||||
.input-group-text + .input-group-text,
|
||||
.input-group-text + .btn
|
||||
margin-left: -$input-border-width
|
||||
|
||||
.input-group-prepend
|
||||
margin-right: -$input-border-width
|
||||
|
||||
.input-group-append
|
||||
margin-left: -$input-border-width
|
||||
|
||||
// Textual addons
|
||||
//
|
||||
// Serves as a catch-all element for any text or radio/checkbox input you wish
|
||||
// to prepend or append to an input.
|
||||
|
||||
.input-group-text
|
||||
display: flex
|
||||
align-items: center
|
||||
padding: $input-padding-y $input-padding-x
|
||||
margin-bottom: 0
|
||||
|
||||
// Allow use of <label> elements by overriding our default margin-bottom
|
||||
font-size: $font-size-base
|
||||
|
||||
// Match inputs
|
||||
font-weight: $font-weight-normal
|
||||
line-height: $input-line-height
|
||||
color: $input-group-addon-color
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
background-color: $input-group-addon-bg
|
||||
border: $input-border-width solid $input-group-addon-border-color
|
||||
|
||||
+border-radius($input-border-radius)
|
||||
|
||||
// Nuke default margins from checkboxes and radios to vertically center within.
|
||||
input[type="radio"],
|
||||
input[type="checkbox"]
|
||||
margin-top: 0
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default form control sizing classes into new ones for easier
|
||||
// manipulation.
|
||||
|
||||
.input-group-lg > .form-control,
|
||||
.input-group-lg > .input-group-prepend > .input-group-text,
|
||||
.input-group-lg > .input-group-append > .input-group-text,
|
||||
.input-group-lg > .input-group-prepend > .btn,
|
||||
.input-group-lg > .input-group-append > .btn
|
||||
@extend .form-control-lg
|
||||
|
||||
.input-group-sm > .form-control,
|
||||
.input-group-sm > .input-group-prepend > .input-group-text,
|
||||
.input-group-sm > .input-group-append > .input-group-text,
|
||||
.input-group-sm > .input-group-prepend > .btn,
|
||||
.input-group-sm > .input-group-append > .btn
|
||||
@extend .form-control-sm
|
||||
|
||||
// Prepend and append rounded corners
|
||||
//
|
||||
// These rulesets must come after the sizing ones to properly override sm and lg
|
||||
// border-radius values when extending. They're more specific than we'd like
|
||||
// with the `.input-group >` part, but without it, we cannot override the sizing.
|
||||
|
||||
.input-group > .input-group-prepend > .btn,
|
||||
.input-group > .input-group-prepend > .input-group-text,
|
||||
.input-group > .input-group-append:not(:last-child) > .btn,
|
||||
.input-group > .input-group-append:not(:last-child) > .input-group-text,
|
||||
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child)
|
||||
+border-right-radius(0)
|
||||
|
||||
.input-group > .input-group-append > .btn,
|
||||
.input-group > .input-group-append > .input-group-text,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .btn,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
|
||||
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
|
||||
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child)
|
||||
+border-left-radius(0)
|
15
static/assets/bootstrap/sass/_jumbotron.sass
Normal file
15
static/assets/bootstrap/sass/_jumbotron.sass
Normal file
@@ -0,0 +1,15 @@
|
||||
.jumbotron
|
||||
padding: $jumbotron-padding ($jumbotron-padding / 2)
|
||||
margin-bottom: $jumbotron-padding
|
||||
background-color: $jumbotron-bg
|
||||
|
||||
+border-radius($border-radius-lg)
|
||||
|
||||
+media-breakpoint-up(sm)
|
||||
padding: ($jumbotron-padding * 2) $jumbotron-padding
|
||||
|
||||
.jumbotron-fluid
|
||||
padding-right: 0
|
||||
padding-left: 0
|
||||
|
||||
+border-radius(0)
|
109
static/assets/bootstrap/sass/_list-group.sass
Normal file
109
static/assets/bootstrap/sass/_list-group.sass
Normal file
@@ -0,0 +1,109 @@
|
||||
// Base class
|
||||
//
|
||||
// Easily usable on <ul>, <ol>, or <div>.
|
||||
|
||||
.list-group
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
// No need to set list-style: none; since .list-group-item is block level
|
||||
padding-left: 0
|
||||
|
||||
// reset padding because ul and ol
|
||||
margin-bottom: 0
|
||||
|
||||
// Interactive list items
|
||||
//
|
||||
// Use anchor or button elements instead of `li`s or `div`s to create interactive
|
||||
// list items. Includes an extra `.active` modifier class for selected items.
|
||||
|
||||
.list-group-item-action
|
||||
width: 100%
|
||||
|
||||
// For `<button>`s (anchors become 100% by default though)
|
||||
color: $list-group-action-color
|
||||
text-align: inherit
|
||||
|
||||
// For `<button>`s (anchors inherit)
|
||||
|
||||
// Hover state
|
||||
+hover-focus
|
||||
color: $list-group-action-hover-color
|
||||
text-decoration: none
|
||||
background-color: $list-group-hover-bg
|
||||
|
||||
|
||||
&:active
|
||||
color: $list-group-action-active-color
|
||||
background-color: $list-group-action-active-bg
|
||||
|
||||
// Individual list items
|
||||
//
|
||||
// Use on `li`s or `div`s within the `.list-group` parent.
|
||||
|
||||
.list-group-item
|
||||
position: relative
|
||||
display: block
|
||||
padding: $list-group-item-padding-y $list-group-item-padding-x
|
||||
|
||||
// Place the border on the list items and negative margin up for better styling
|
||||
margin-bottom: -$list-group-border-width
|
||||
background-color: $list-group-bg
|
||||
border: $list-group-border-width solid $list-group-border-color
|
||||
|
||||
&:first-child
|
||||
+border-top-radius($list-group-border-radius)
|
||||
|
||||
&:last-child
|
||||
margin-bottom: 0
|
||||
|
||||
+border-bottom-radius($list-group-border-radius)
|
||||
|
||||
+hover-focus
|
||||
z-index: 1
|
||||
|
||||
// Place hover/active items above their siblings for proper border styling
|
||||
text-decoration: none
|
||||
|
||||
|
||||
&.disabled,
|
||||
&:disabled
|
||||
color: $list-group-disabled-color
|
||||
background-color: $list-group-disabled-bg
|
||||
|
||||
// Include both here for `<a>`s and `<button>`s
|
||||
&.active
|
||||
z-index: 2
|
||||
|
||||
// Place active items above their siblings for proper border styling
|
||||
color: $list-group-active-color
|
||||
background-color: $list-group-active-bg
|
||||
border-color: $list-group-active-border-color
|
||||
|
||||
// Flush list items
|
||||
//
|
||||
// Remove borders and border-radius to keep list group items edge-to-edge. Most
|
||||
// useful within other components (e.g., cards).
|
||||
|
||||
.list-group-flush
|
||||
.list-group-item
|
||||
border-right: 0
|
||||
border-left: 0
|
||||
|
||||
+border-radius(0)
|
||||
|
||||
&:first-child
|
||||
.list-group-item:first-child
|
||||
border-top: 0
|
||||
|
||||
&:last-child
|
||||
.list-group-item:last-child
|
||||
border-bottom: 0
|
||||
|
||||
// Contextual variants
|
||||
//
|
||||
// Add modifier classes to change text and background color on individual items.
|
||||
// Organizationally, this must come after the `:hover` states.
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
+list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6))
|
6
static/assets/bootstrap/sass/_media.sass
Normal file
6
static/assets/bootstrap/sass/_media.sass
Normal file
@@ -0,0 +1,6 @@
|
||||
.media
|
||||
display: flex
|
||||
align-items: flex-start
|
||||
|
||||
.media-body
|
||||
flex: 1
|
41
static/assets/bootstrap/sass/_mixins.sass
Normal file
41
static/assets/bootstrap/sass/_mixins.sass
Normal file
@@ -0,0 +1,41 @@
|
||||
// Toggles
|
||||
//
|
||||
// Used in conjunction with global variables to enable certain theme features.
|
||||
|
||||
// Utilities
|
||||
@import mixins/breakpoints
|
||||
@import mixins/hover
|
||||
@import mixins/image
|
||||
@import mixins/badge
|
||||
@import mixins/resize
|
||||
@import mixins/screen-reader
|
||||
@import mixins/size
|
||||
@import mixins/reset-text
|
||||
@import mixins/text-emphasis
|
||||
@import mixins/text-hide
|
||||
@import mixins/text-truncate
|
||||
@import mixins/visibility
|
||||
|
||||
// // Components
|
||||
@import mixins/alert
|
||||
@import mixins/buttons
|
||||
@import mixins/caret
|
||||
@import mixins/pagination
|
||||
@import mixins/lists
|
||||
@import mixins/list-group
|
||||
@import mixins/nav-divider
|
||||
@import mixins/forms
|
||||
@import mixins/table-row
|
||||
|
||||
// // Skins
|
||||
@import mixins/background-variant
|
||||
@import mixins/border-radius
|
||||
@import mixins/box-shadow
|
||||
@import mixins/gradients
|
||||
@import mixins/transition
|
||||
|
||||
// // Layout
|
||||
@import mixins/clearfix
|
||||
@import mixins/grid-framework
|
||||
@import mixins/grid
|
||||
@import mixins/float
|
175
static/assets/bootstrap/sass/_modal.sass
Normal file
175
static/assets/bootstrap/sass/_modal.sass
Normal file
@@ -0,0 +1,175 @@
|
||||
// .modal-open - body class for killing the scroll
|
||||
// .modal - container to scroll within
|
||||
// .modal-dialog - positioning shell for the actual modal
|
||||
// .modal-content - actual modal w/ bg and corners and stuff
|
||||
|
||||
// Kill the scroll on the body
|
||||
.modal-open
|
||||
overflow: hidden
|
||||
|
||||
// Container that the modal scrolls within
|
||||
.modal
|
||||
position: fixed
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
z-index: $zindex-modal
|
||||
display: none
|
||||
overflow: hidden
|
||||
|
||||
// Prevent Chrome on Windows from adding a focus outline. For details, see
|
||||
// https://github.com/twbs/bootstrap/pull/10951.
|
||||
outline: 0
|
||||
|
||||
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
|
||||
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
|
||||
// See also https://github.com/twbs/bootstrap/issues/17695
|
||||
|
||||
.modal-open &
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
|
||||
// Shell div to position the modal with bottom padding
|
||||
.modal-dialog
|
||||
position: relative
|
||||
width: auto
|
||||
margin: $modal-dialog-margin
|
||||
|
||||
// allow clicks to pass through for custom click handling to close modal
|
||||
pointer-events: none
|
||||
|
||||
// When fading in the modal, animate it to slide down
|
||||
.modal.fade &
|
||||
+transition($modal-transition)
|
||||
|
||||
transform: translate(0, -25%)
|
||||
|
||||
.modal.show &
|
||||
transform: translate(0, 0)
|
||||
|
||||
.modal-dialog-centered
|
||||
display: flex
|
||||
align-items: center
|
||||
min-height: calc(100% - (#{$modal-dialog-margin} * 2))
|
||||
|
||||
// Actual modal
|
||||
.modal-content
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: column
|
||||
width: 100%
|
||||
|
||||
// Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
|
||||
// counteract the pointer-events: none; in the .modal-dialog
|
||||
pointer-events: auto
|
||||
background-color: $modal-content-bg
|
||||
background-clip: padding-box
|
||||
border: $modal-content-border-width solid $modal-content-border-color
|
||||
|
||||
+border-radius($modal-content-border-radius)
|
||||
+box-shadow($modal-content-box-shadow-xs)
|
||||
|
||||
// Remove focus outline from opened modal
|
||||
outline: 0
|
||||
|
||||
// Modal background
|
||||
.modal-backdrop
|
||||
position: fixed
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
z-index: $zindex-modal-backdrop
|
||||
background-color: $modal-backdrop-bg
|
||||
|
||||
// Fade for backdrop
|
||||
&.fade
|
||||
opacity: 0
|
||||
|
||||
&.show
|
||||
opacity: $modal-backdrop-opacity
|
||||
|
||||
// Modal header
|
||||
// Top section of the modal w/ title and dismiss
|
||||
.modal-header
|
||||
display: flex
|
||||
align-items: flex-start
|
||||
|
||||
// so the close btn always stays on the upper right corner
|
||||
justify-content: space-between
|
||||
|
||||
// Put modal header elements (title and dismiss) on opposite ends
|
||||
padding: $modal-header-padding
|
||||
border-bottom: $modal-header-border-width solid $modal-header-border-color
|
||||
|
||||
+border-top-radius($modal-content-border-radius)
|
||||
|
||||
.close
|
||||
padding: $modal-header-padding
|
||||
|
||||
// auto on the left force icon to the right even when there is no .modal-title
|
||||
margin: (-$modal-header-padding) (-$modal-header-padding) (-$modal-header-padding) auto
|
||||
|
||||
// Title text within header
|
||||
.modal-title
|
||||
margin-bottom: 0
|
||||
line-height: $modal-title-line-height
|
||||
|
||||
// Modal body
|
||||
// Where all modal content resides (sibling of .modal-header and .modal-footer)
|
||||
.modal-body
|
||||
position: relative
|
||||
|
||||
// Enable `flex-grow: 1` so that the body take up as much space as possible
|
||||
// when should there be a fixed height on `.modal-dialog`.
|
||||
flex: 1 1 auto
|
||||
padding: $modal-inner-padding
|
||||
|
||||
// Footer (for actions)
|
||||
.modal-footer
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
// vertically center
|
||||
justify-content: flex-end
|
||||
|
||||
// Right align buttons with flex property because text-align doesn't work on flex items
|
||||
padding: $modal-inner-padding
|
||||
border-top: $modal-footer-border-width solid $modal-footer-border-color
|
||||
|
||||
// Easily place margin between footer elements
|
||||
> :not(:first-child)
|
||||
margin-left: .25rem
|
||||
|
||||
> :not(:last-child)
|
||||
margin-right: .25rem
|
||||
|
||||
// Measure scrollbar width for padding body during modal show/hide
|
||||
.modal-scrollbar-measure
|
||||
position: absolute
|
||||
top: -9999px
|
||||
width: 50px
|
||||
height: 50px
|
||||
overflow: scroll
|
||||
|
||||
// Scale up the modal
|
||||
+media-breakpoint-up(sm)
|
||||
// Automatically set modal's width for larger viewports
|
||||
.modal-dialog
|
||||
max-width: $modal-md
|
||||
margin: $modal-dialog-margin-y-sm-up auto
|
||||
|
||||
.modal-dialog-centered
|
||||
min-height: calc(100% - (#{$modal-dialog-margin-y-sm-up} * 2))
|
||||
|
||||
.modal-content
|
||||
+box-shadow($modal-content-box-shadow-sm-up)
|
||||
|
||||
.modal-sm
|
||||
max-width: $modal-sm
|
||||
|
||||
|
||||
+media-breakpoint-up(lg)
|
||||
.modal-lg
|
||||
max-width: $modal-lg
|
99
static/assets/bootstrap/sass/_nav.sass
Normal file
99
static/assets/bootstrap/sass/_nav.sass
Normal file
@@ -0,0 +1,99 @@
|
||||
// Base class
|
||||
//
|
||||
// Kickstart any navigation component with a set of style resets. Works with
|
||||
// `<nav>`s or `<ul>`s.
|
||||
|
||||
.nav
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
padding-left: 0
|
||||
margin-bottom: 0
|
||||
list-style: none
|
||||
|
||||
.nav-link
|
||||
display: block
|
||||
padding: $nav-link-padding-y $nav-link-padding-x
|
||||
|
||||
+hover-focus
|
||||
text-decoration: none
|
||||
|
||||
|
||||
// Disabled state lightens text
|
||||
&.disabled
|
||||
color: $nav-link-disabled-color
|
||||
|
||||
//
|
||||
// Tabs
|
||||
//
|
||||
|
||||
.nav-tabs
|
||||
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color
|
||||
|
||||
.nav-item
|
||||
margin-bottom: -$nav-tabs-border-width
|
||||
|
||||
.nav-link
|
||||
border: $nav-tabs-border-width solid transparent
|
||||
|
||||
+border-top-radius($nav-tabs-border-radius)
|
||||
|
||||
+hover-focus
|
||||
border-color: $nav-tabs-link-hover-border-color
|
||||
|
||||
|
||||
&.disabled
|
||||
color: $nav-link-disabled-color
|
||||
background-color: transparent
|
||||
border-color: transparent
|
||||
|
||||
.nav-link.active,
|
||||
.nav-item.show .nav-link
|
||||
color: $nav-tabs-link-active-color
|
||||
background-color: $nav-tabs-link-active-bg
|
||||
border-color: $nav-tabs-link-active-border-color
|
||||
|
||||
.dropdown-menu
|
||||
// Make dropdown border overlap tab border
|
||||
margin-top: -$nav-tabs-border-width
|
||||
|
||||
// Remove the top rounded corners here since there is a hard edge above the menu
|
||||
+border-top-radius(0)
|
||||
|
||||
//
|
||||
// Pills
|
||||
//
|
||||
|
||||
.nav-pills
|
||||
.nav-link
|
||||
+border-radius($nav-pills-border-radius)
|
||||
|
||||
.nav-link.active,
|
||||
.show > .nav-link
|
||||
color: $nav-pills-link-active-color
|
||||
background-color: $nav-pills-link-active-bg
|
||||
|
||||
//
|
||||
// Justified variants
|
||||
//
|
||||
|
||||
.nav-fill
|
||||
.nav-item
|
||||
flex: 1 1 auto
|
||||
text-align: center
|
||||
|
||||
.nav-justified
|
||||
.nav-item
|
||||
flex-basis: 0
|
||||
flex-grow: 1
|
||||
text-align: center
|
||||
|
||||
// Tabbable tabs
|
||||
//
|
||||
// Hide tabbable panes to start, show them when `.active`
|
||||
|
||||
.tab-content
|
||||
> .tab-pane
|
||||
display: none
|
||||
|
||||
> .active
|
||||
display: block
|
261
static/assets/bootstrap/sass/_navbar.sass
Normal file
261
static/assets/bootstrap/sass/_navbar.sass
Normal file
@@ -0,0 +1,261 @@
|
||||
// Contents
|
||||
//
|
||||
// Navbar
|
||||
// Navbar brand
|
||||
// Navbar nav
|
||||
// Navbar text
|
||||
// Navbar divider
|
||||
// Responsive navbar
|
||||
// Navbar position
|
||||
// Navbar themes
|
||||
|
||||
// Navbar
|
||||
//
|
||||
// Provide a static navbar from which we expand to create full-width, fixed, and
|
||||
// other navbar variations.
|
||||
|
||||
.navbar
|
||||
position: relative
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
// allow us to do the line break for collapsing content
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
|
||||
// space out brand from logo
|
||||
padding: $navbar-padding-y $navbar-padding-x
|
||||
|
||||
// Because flex properties aren't inherited, we need to redeclare these first
|
||||
// few properties so that content nested within behave properly.
|
||||
> .container,
|
||||
> .container-fluid
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
|
||||
// Navbar brand
|
||||
//
|
||||
// Used for brand, project, or site names.
|
||||
|
||||
.navbar-brand
|
||||
display: inline-block
|
||||
padding-top: $navbar-brand-padding-y
|
||||
padding-bottom: $navbar-brand-padding-y
|
||||
margin-right: $navbar-padding-x
|
||||
font-size: $navbar-brand-font-size
|
||||
line-height: inherit
|
||||
white-space: nowrap
|
||||
|
||||
+hover-focus
|
||||
text-decoration: none
|
||||
|
||||
// Navbar nav
|
||||
//
|
||||
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
|
||||
|
||||
.navbar-nav
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
// cannot use `inherit` to get the `.navbar`s value
|
||||
padding-left: 0
|
||||
margin-bottom: 0
|
||||
list-style: none
|
||||
|
||||
.nav-link
|
||||
padding-right: 0
|
||||
padding-left: 0
|
||||
|
||||
.dropdown-menu
|
||||
position: static
|
||||
float: none
|
||||
|
||||
// Navbar text
|
||||
//
|
||||
//
|
||||
|
||||
.navbar-text
|
||||
display: inline-block
|
||||
padding-top: $nav-link-padding-y
|
||||
padding-bottom: $nav-link-padding-y
|
||||
|
||||
// Responsive navbar
|
||||
//
|
||||
// Custom styles for responsive collapsing and toggling of navbar contents.
|
||||
// Powered by the collapse Bootstrap JavaScript plugin.
|
||||
|
||||
// When collapsed, prevent the toggleable navbar contents from appearing in
|
||||
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
|
||||
// on the `.navbar` parent.
|
||||
.navbar-collapse
|
||||
flex-basis: 100%
|
||||
flex-grow: 1
|
||||
|
||||
// For always expanded or extra full navbars, ensure content aligns itself
|
||||
// properly vertically. Can be easily overridden with flex utilities.
|
||||
align-items: center
|
||||
|
||||
// Button for toggling the navbar when in its collapsed state
|
||||
.navbar-toggler
|
||||
padding: $navbar-toggler-padding-y $navbar-toggler-padding-x
|
||||
font-size: $navbar-toggler-font-size
|
||||
line-height: 1
|
||||
background-color: transparent
|
||||
|
||||
// remove default button style
|
||||
border: $border-width solid transparent
|
||||
|
||||
// remove default button style
|
||||
+border-radius($navbar-toggler-border-radius)
|
||||
|
||||
+hover-focus
|
||||
text-decoration: none
|
||||
|
||||
|
||||
// Opinionated: add "hand" cursor to non-disabled .navbar-toggler elements
|
||||
&:not(:disabled):not(.disabled)
|
||||
cursor: pointer
|
||||
|
||||
// Keep as a separate element so folks can easily override it with another icon
|
||||
// or image file as needed.
|
||||
.navbar-toggler-icon
|
||||
display: inline-block
|
||||
width: 1.5em
|
||||
height: 1.5em
|
||||
vertical-align: middle
|
||||
content: ""
|
||||
background: no-repeat center center
|
||||
background-size: 100% 100%
|
||||
|
||||
// Generate series of `.navbar-expand-*` responsive classes for configuring
|
||||
// where your navbar collapses.
|
||||
.navbar-expand
|
||||
@each $breakpoint in map-keys($grid-breakpoints)
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints)
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints)
|
||||
|
||||
&#{$infix}
|
||||
+media-breakpoint-down($breakpoint)
|
||||
> .container,
|
||||
> .container-fluid
|
||||
padding-right: 0
|
||||
padding-left: 0
|
||||
|
||||
|
||||
+media-breakpoint-up($next)
|
||||
flex-flow: row nowrap
|
||||
justify-content: flex-start
|
||||
|
||||
.navbar-nav
|
||||
flex-direction: row
|
||||
|
||||
.dropdown-menu
|
||||
position: absolute
|
||||
|
||||
.nav-link
|
||||
padding-right: $navbar-nav-link-padding-x
|
||||
padding-left: $navbar-nav-link-padding-x
|
||||
|
||||
// For nesting containers, have to redeclare for alignment purposes
|
||||
> .container,
|
||||
> .container-fluid
|
||||
flex-wrap: nowrap
|
||||
|
||||
.navbar-collapse
|
||||
display: flex !important
|
||||
|
||||
// stylelint-disable-line declaration-no-important
|
||||
|
||||
// Changes flex-bases to auto because of an IE10 bug
|
||||
flex-basis: auto
|
||||
|
||||
.navbar-toggler
|
||||
display: none
|
||||
|
||||
// Navbar themes
|
||||
//
|
||||
// Styles for switching between navbars with light or dark background.
|
||||
|
||||
// Dark links against a light background
|
||||
.navbar-light
|
||||
.navbar-brand
|
||||
color: $navbar-light-active-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-light-active-color
|
||||
|
||||
.navbar-nav
|
||||
.nav-link
|
||||
color: $navbar-light-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-light-hover-color
|
||||
|
||||
|
||||
&.disabled
|
||||
color: $navbar-light-disabled-color
|
||||
|
||||
.show > .nav-link,
|
||||
.active > .nav-link,
|
||||
.nav-link.show,
|
||||
.nav-link.active
|
||||
color: $navbar-light-active-color
|
||||
|
||||
.navbar-toggler
|
||||
color: $navbar-light-color
|
||||
border-color: $navbar-light-toggler-border-color
|
||||
|
||||
.navbar-toggler-icon
|
||||
background-image: $navbar-light-toggler-icon-bg
|
||||
|
||||
.navbar-text
|
||||
color: $navbar-light-color
|
||||
|
||||
a
|
||||
color: $navbar-light-active-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-light-active-color
|
||||
|
||||
// White links against a dark background
|
||||
.navbar-dark
|
||||
.navbar-brand
|
||||
color: $navbar-dark-active-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-dark-active-color
|
||||
|
||||
.navbar-nav
|
||||
.nav-link
|
||||
color: $navbar-dark-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-dark-hover-color
|
||||
|
||||
|
||||
&.disabled
|
||||
color: $navbar-dark-disabled-color
|
||||
|
||||
.show > .nav-link,
|
||||
.active > .nav-link,
|
||||
.nav-link.show,
|
||||
.nav-link.active
|
||||
color: $navbar-dark-active-color
|
||||
|
||||
.navbar-toggler
|
||||
color: $navbar-dark-color
|
||||
border-color: $navbar-dark-toggler-border-color
|
||||
|
||||
.navbar-toggler-icon
|
||||
background-image: $navbar-dark-toggler-icon-bg
|
||||
|
||||
.navbar-text
|
||||
color: $navbar-dark-color
|
||||
|
||||
a
|
||||
color: $navbar-dark-active-color
|
||||
|
||||
+hover-focus
|
||||
color: $navbar-dark-active-color
|
67
static/assets/bootstrap/sass/_pagination.sass
Normal file
67
static/assets/bootstrap/sass/_pagination.sass
Normal file
@@ -0,0 +1,67 @@
|
||||
.pagination
|
||||
display: flex
|
||||
|
||||
+list-unstyled
|
||||
+border-radius
|
||||
|
||||
.page-link
|
||||
position: relative
|
||||
display: block
|
||||
padding: $pagination-padding-y $pagination-padding-x
|
||||
margin-left: -$pagination-border-width
|
||||
line-height: $pagination-line-height
|
||||
color: $pagination-color
|
||||
background-color: $pagination-bg
|
||||
border: $pagination-border-width solid $pagination-border-color
|
||||
|
||||
&:hover
|
||||
z-index: 2
|
||||
color: $pagination-hover-color
|
||||
text-decoration: none
|
||||
background-color: $pagination-hover-bg
|
||||
border-color: $pagination-hover-border-color
|
||||
|
||||
&:focus
|
||||
z-index: 2
|
||||
outline: $pagination-focus-outline
|
||||
box-shadow: $pagination-focus-box-shadow
|
||||
|
||||
// Opinionated: add "hand" cursor to non-disabled .page-link elements
|
||||
&:not(:disabled):not(.disabled)
|
||||
cursor: pointer
|
||||
|
||||
.page-item
|
||||
&:first-child
|
||||
.page-link
|
||||
margin-left: 0
|
||||
|
||||
+border-left-radius($border-radius)
|
||||
|
||||
&:last-child
|
||||
.page-link
|
||||
+border-right-radius($border-radius)
|
||||
|
||||
&.active .page-link
|
||||
z-index: 1
|
||||
color: $pagination-active-color
|
||||
background-color: $pagination-active-bg
|
||||
border-color: $pagination-active-border-color
|
||||
|
||||
&.disabled .page-link
|
||||
color: $pagination-disabled-color
|
||||
pointer-events: none
|
||||
|
||||
// Opinionated: remove the "hand" cursor set previously for .page-link
|
||||
cursor: auto
|
||||
background-color: $pagination-disabled-bg
|
||||
border-color: $pagination-disabled-border-color
|
||||
|
||||
//
|
||||
// Sizing
|
||||
//
|
||||
|
||||
.pagination-lg
|
||||
+pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg)
|
||||
|
||||
.pagination-sm
|
||||
+pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm)
|
165
static/assets/bootstrap/sass/_popover.sass
Normal file
165
static/assets/bootstrap/sass/_popover.sass
Normal file
@@ -0,0 +1,165 @@
|
||||
.popover
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
z-index: $zindex-popover
|
||||
display: block
|
||||
max-width: $popover-max-width
|
||||
|
||||
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
|
||||
// So reset our font and text properties to avoid inheriting weird values.
|
||||
+reset-text
|
||||
|
||||
font-size: $popover-font-size
|
||||
|
||||
// Allow breaking very long words so they don't overflow the popover's bounds
|
||||
word-wrap: break-word
|
||||
background-color: $popover-bg
|
||||
background-clip: padding-box
|
||||
border: $popover-border-width solid $popover-border-color
|
||||
|
||||
+border-radius($popover-border-radius)
|
||||
+box-shadow($popover-box-shadow)
|
||||
|
||||
.arrow
|
||||
position: absolute
|
||||
display: block
|
||||
width: $popover-arrow-width
|
||||
height: $popover-arrow-height
|
||||
margin: 0 $border-radius-lg
|
||||
|
||||
&::before,
|
||||
&::after
|
||||
position: absolute
|
||||
display: block
|
||||
content: ""
|
||||
border-color: transparent
|
||||
border-style: solid
|
||||
|
||||
.bs-popover-top
|
||||
margin-bottom: $popover-arrow-height
|
||||
|
||||
.arrow
|
||||
bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1)
|
||||
|
||||
.arrow::before,
|
||||
.arrow::after
|
||||
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0
|
||||
|
||||
.arrow::before
|
||||
bottom: 0
|
||||
border-top-color: $popover-arrow-outer-color
|
||||
|
||||
.arrow::after
|
||||
bottom: $popover-border-width
|
||||
border-top-color: $popover-arrow-color
|
||||
|
||||
.bs-popover-right
|
||||
margin-left: $popover-arrow-height
|
||||
|
||||
.arrow
|
||||
left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1)
|
||||
width: $popover-arrow-height
|
||||
height: $popover-arrow-width
|
||||
margin: $border-radius-lg 0
|
||||
|
||||
// make sure the arrow does not touch the popover's rounded corners
|
||||
|
||||
.arrow::before,
|
||||
.arrow::after
|
||||
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0
|
||||
|
||||
.arrow::before
|
||||
left: 0
|
||||
border-right-color: $popover-arrow-outer-color
|
||||
|
||||
.arrow::after
|
||||
left: $popover-border-width
|
||||
border-right-color: $popover-arrow-color
|
||||
|
||||
.bs-popover-bottom
|
||||
margin-top: $popover-arrow-height
|
||||
|
||||
.arrow
|
||||
top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1)
|
||||
|
||||
.arrow::before,
|
||||
.arrow::after
|
||||
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2)
|
||||
|
||||
.arrow::before
|
||||
top: 0
|
||||
border-bottom-color: $popover-arrow-outer-color
|
||||
|
||||
.arrow::after
|
||||
top: $popover-border-width
|
||||
border-bottom-color: $popover-arrow-color
|
||||
|
||||
// This will remove the popover-header's border just below the arrow
|
||||
.popover-header::before
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 50%
|
||||
display: block
|
||||
width: $popover-arrow-width
|
||||
margin-left: $popover-arrow-width / -2
|
||||
content: ""
|
||||
border-bottom: $popover-border-width solid $popover-header-bg
|
||||
|
||||
.bs-popover-left
|
||||
margin-right: $popover-arrow-height
|
||||
|
||||
.arrow
|
||||
right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1)
|
||||
width: $popover-arrow-height
|
||||
height: $popover-arrow-width
|
||||
margin: $border-radius-lg 0
|
||||
|
||||
// make sure the arrow does not touch the popover's rounded corners
|
||||
|
||||
.arrow::before,
|
||||
.arrow::after
|
||||
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height
|
||||
|
||||
.arrow::before
|
||||
right: 0
|
||||
border-left-color: $popover-arrow-outer-color
|
||||
|
||||
.arrow::after
|
||||
right: $popover-border-width
|
||||
border-left-color: $popover-arrow-color
|
||||
|
||||
.bs-popover-auto
|
||||
&[x-placement^="top"]
|
||||
@extend .bs-popover-top
|
||||
|
||||
&[x-placement^="right"]
|
||||
@extend .bs-popover-right
|
||||
|
||||
&[x-placement^="bottom"]
|
||||
@extend .bs-popover-bottom
|
||||
|
||||
&[x-placement^="left"]
|
||||
@extend .bs-popover-left
|
||||
|
||||
// Offset the popover to account for the popover arrow
|
||||
.popover-header
|
||||
padding: $popover-header-padding-y $popover-header-padding-x
|
||||
margin-bottom: 0
|
||||
|
||||
// Reset the default from Reboot
|
||||
font-size: $font-size-base
|
||||
color: $popover-header-color
|
||||
background-color: $popover-header-bg
|
||||
border-bottom: $popover-border-width solid darken($popover-header-bg, 5%)
|
||||
|
||||
$offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width})
|
||||
|
||||
+border-top-radius($offset-border-width)
|
||||
|
||||
&:empty
|
||||
display: none
|
||||
|
||||
.popover-body
|
||||
padding: $popover-body-padding-y $popover-body-padding-x
|
||||
color: $popover-body-color
|
124
static/assets/bootstrap/sass/_print.sass
Normal file
124
static/assets/bootstrap/sass/_print.sass
Normal file
@@ -0,0 +1,124 @@
|
||||
// stylelint-disable declaration-no-important, selector-no-qualifying-type
|
||||
|
||||
// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css
|
||||
|
||||
// ==========================================================================
|
||||
// Print styles.
|
||||
// Inlined to avoid the additional HTTP request:
|
||||
// https://www.phpied.com/delay-loading-your-print-css/
|
||||
// ==========================================================================
|
||||
|
||||
@if $enable-print-styles
|
||||
@media print
|
||||
*,
|
||||
*::before,
|
||||
*::after
|
||||
// Bootstrap specific; comment out `color` and `background`
|
||||
//color: $black !important; // Black prints faster
|
||||
text-shadow: none !important
|
||||
|
||||
//background: transparent !important;
|
||||
box-shadow: none !important
|
||||
|
||||
a
|
||||
&:not(.btn)
|
||||
text-decoration: underline
|
||||
|
||||
// Bootstrap specific; comment the following selector out
|
||||
//a[href]::after {
|
||||
// content: " (" attr(href) ")";
|
||||
//}
|
||||
|
||||
abbr[title]::after
|
||||
content: " (" attr(title) ")"
|
||||
|
||||
// Bootstrap specific; comment the following selector out
|
||||
//
|
||||
// Don't show links that are fragment identifiers,
|
||||
// or use the `javascript:` pseudo protocol
|
||||
//
|
||||
|
||||
//a[href^="#"]::after,
|
||||
//a[href^="javascript:"]::after {
|
||||
// content: "";
|
||||
//}
|
||||
|
||||
pre
|
||||
white-space: pre-wrap !important
|
||||
|
||||
pre,
|
||||
blockquote
|
||||
border: $border-width solid $gray-500
|
||||
|
||||
// Bootstrap custom code; using `$border-width` instead of 1px
|
||||
page-break-inside: avoid
|
||||
|
||||
//
|
||||
// Printing Tables:
|
||||
// http://css-discuss.incutio.com/wiki/Printing_Tables
|
||||
//
|
||||
|
||||
thead
|
||||
display: table-header-group
|
||||
|
||||
tr,
|
||||
img
|
||||
page-break-inside: avoid
|
||||
|
||||
p,
|
||||
h2,
|
||||
h3
|
||||
orphans: 3
|
||||
widows: 3
|
||||
|
||||
h2,
|
||||
h3
|
||||
page-break-after: avoid
|
||||
|
||||
// Bootstrap specific changes start
|
||||
|
||||
// Specify a size and min-width to make printing closer across browsers.
|
||||
// We don't set margin here because it breaks `size` in Chrome. We also
|
||||
// don't use `!important` on `size` as it breaks in Chrome.
|
||||
@page
|
||||
size: $print-page-size
|
||||
|
||||
body
|
||||
min-width: $print-body-min-width !important
|
||||
|
||||
.container
|
||||
min-width: $print-body-min-width !important
|
||||
|
||||
// Bootstrap components
|
||||
.navbar
|
||||
display: none
|
||||
|
||||
.badge
|
||||
border: $border-width solid $black
|
||||
|
||||
.table
|
||||
border-collapse: collapse !important
|
||||
|
||||
td,
|
||||
th
|
||||
background-color: $white !important
|
||||
|
||||
.table-bordered
|
||||
th,
|
||||
td
|
||||
border: 1px solid $gray-300 !important
|
||||
|
||||
.table-dark
|
||||
color: inherit
|
||||
|
||||
th,
|
||||
td,
|
||||
thead th,
|
||||
tbody + tbody
|
||||
border-color: $table-border-color
|
||||
|
||||
.table .thead-dark th
|
||||
color: inherit
|
||||
border-color: $table-border-color
|
||||
|
||||
// Bootstrap specific changes end
|
37
static/assets/bootstrap/sass/_progress.sass
Normal file
37
static/assets/bootstrap/sass/_progress.sass
Normal file
@@ -0,0 +1,37 @@
|
||||
@keyframes progress-bar-stripes
|
||||
from
|
||||
background-position: $progress-height 0
|
||||
|
||||
to
|
||||
background-position: 0 0
|
||||
|
||||
.progress
|
||||
display: flex
|
||||
height: $progress-height
|
||||
overflow: hidden
|
||||
|
||||
// force rounded corners by cropping it
|
||||
font-size: $progress-font-size
|
||||
background-color: $progress-bg
|
||||
|
||||
+border-radius($progress-border-radius)
|
||||
+box-shadow($progress-box-shadow)
|
||||
|
||||
.progress-bar
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
color: $progress-bar-color
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
background-color: $progress-bar-bg
|
||||
|
||||
+transition($progress-bar-transition)
|
||||
|
||||
.progress-bar-striped
|
||||
+gradient-striped
|
||||
|
||||
background-size: $progress-height $progress-height
|
||||
|
||||
.progress-bar-animated
|
||||
animation: progress-bar-stripes $progress-bar-animation-timing
|
513
static/assets/bootstrap/sass/_reboot.sass
Normal file
513
static/assets/bootstrap/sass/_reboot.sass
Normal file
@@ -0,0 +1,513 @@
|
||||
// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
|
||||
|
||||
// Reboot
|
||||
//
|
||||
// Normalization of HTML elements, manually forked from Normalize.css to remove
|
||||
// styles targeting irrelevant browsers while applying new styles.
|
||||
//
|
||||
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
|
||||
|
||||
// Document
|
||||
//
|
||||
// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
|
||||
// 2. Change the default font family in all browsers.
|
||||
// 3. Correct the line height in all browsers.
|
||||
// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
|
||||
// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so
|
||||
// we force a non-overlapping, non-auto-hiding scrollbar to counteract.
|
||||
// 6. Change the default tap highlight to be completely transparent in iOS.
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after
|
||||
box-sizing: border-box
|
||||
|
||||
// 1
|
||||
|
||||
html
|
||||
font-family: sans-serif
|
||||
|
||||
// 2
|
||||
line-height: 1.15
|
||||
|
||||
// 3
|
||||
-webkit-text-size-adjust: 100%
|
||||
|
||||
// 4
|
||||
-ms-text-size-adjust: 100%
|
||||
|
||||
// 4
|
||||
-ms-overflow-style: scrollbar
|
||||
|
||||
// 5
|
||||
-webkit-tap-highlight-color: rgba($black, 0)
|
||||
|
||||
// 6
|
||||
|
||||
// IE10+ doesn't honor `<meta name="viewport">` in some cases.
|
||||
@at-root
|
||||
@-ms-viewport
|
||||
width: device-width
|
||||
|
||||
// stylelint-disable selector-list-comma-newline-after
|
||||
// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
|
||||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section
|
||||
display: block
|
||||
|
||||
// stylelint-enable selector-list-comma-newline-after
|
||||
|
||||
// Body
|
||||
//
|
||||
// 1. Remove the margin in all browsers.
|
||||
// 2. As a best practice, apply a default `background-color`.
|
||||
// 3. Set an explicit initial text-align value so that we can later use the
|
||||
// the `inherit` value on things like `<th>` elements.
|
||||
|
||||
body
|
||||
margin: 0
|
||||
|
||||
// 1
|
||||
font-family: $font-family-base
|
||||
font-size: $font-size-base
|
||||
font-weight: $font-weight-base
|
||||
line-height: $line-height-base
|
||||
color: $body-color
|
||||
text-align: left
|
||||
|
||||
// 3
|
||||
background-color: $body-bg
|
||||
|
||||
// 2
|
||||
|
||||
// Suppress the focus outline on elements that cannot be accessed via keyboard.
|
||||
// This prevents an unwanted focus outline from appearing around elements that
|
||||
// might still respond to pointer events.
|
||||
//
|
||||
// Credit: https://github.com/suitcss/base
|
||||
[tabindex="-1"]:focus
|
||||
outline: 0 !important
|
||||
|
||||
// Content grouping
|
||||
//
|
||||
// 1. Add the correct box sizing in Firefox.
|
||||
// 2. Show the overflow in Edge and IE.
|
||||
|
||||
hr
|
||||
box-sizing: content-box
|
||||
|
||||
// 1
|
||||
height: 0
|
||||
|
||||
// 1
|
||||
overflow: visible
|
||||
|
||||
// 2
|
||||
|
||||
//
|
||||
// Typography
|
||||
//
|
||||
|
||||
// Remove top margins from headings
|
||||
//
|
||||
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
|
||||
// margin for easier control within type scales as it avoids margin collapsing.
|
||||
// stylelint-disable selector-list-comma-newline-after
|
||||
h1, h2, h3, h4, h5, h6
|
||||
margin-top: 0
|
||||
margin-bottom: $headings-margin-bottom
|
||||
|
||||
// stylelint-enable selector-list-comma-newline-after
|
||||
|
||||
// Reset margins on paragraphs
|
||||
//
|
||||
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
|
||||
// bottom margin to use `rem` units instead of `em`.
|
||||
p
|
||||
margin-top: 0
|
||||
margin-bottom: $paragraph-margin-bottom
|
||||
|
||||
// Abbreviations
|
||||
//
|
||||
// 1. Remove the bottom border in Firefox 39-.
|
||||
// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
// 3. Add explicit cursor to indicate changed behavior.
|
||||
// 4. Duplicate behavior to the data-* attribute for our tooltip plugin
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title]
|
||||
// 4
|
||||
text-decoration: underline
|
||||
|
||||
// 2
|
||||
text-decoration: underline dotted
|
||||
|
||||
// 2
|
||||
cursor: help
|
||||
|
||||
// 3
|
||||
border-bottom: 0
|
||||
|
||||
// 1
|
||||
|
||||
address
|
||||
margin-bottom: 1rem
|
||||
font-style: normal
|
||||
line-height: inherit
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl
|
||||
margin-top: 0
|
||||
margin-bottom: 1rem
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol
|
||||
margin-bottom: 0
|
||||
|
||||
dt
|
||||
font-weight: $dt-font-weight
|
||||
|
||||
dd
|
||||
margin-bottom: .5rem
|
||||
margin-left: 0
|
||||
|
||||
// Undo browser default
|
||||
|
||||
blockquote
|
||||
margin: 0 0 1rem
|
||||
|
||||
dfn
|
||||
font-style: italic
|
||||
|
||||
// Add the correct font style in Android 4.3-
|
||||
|
||||
// stylelint-disable font-weight-notation
|
||||
b,
|
||||
strong
|
||||
font-weight: bolder
|
||||
|
||||
// Add the correct font weight in Chrome, Edge, and Safari
|
||||
|
||||
// stylelint-enable font-weight-notation
|
||||
|
||||
small
|
||||
font-size: 80%
|
||||
|
||||
// Add the correct font size in all browsers
|
||||
|
||||
//
|
||||
// Prevent `sub` and `sup` elements from affecting the line height in
|
||||
// all browsers.
|
||||
//
|
||||
|
||||
sub,
|
||||
sup
|
||||
position: relative
|
||||
font-size: 75%
|
||||
line-height: 0
|
||||
vertical-align: baseline
|
||||
|
||||
sub
|
||||
bottom: -.25em
|
||||
|
||||
sup
|
||||
top: -.5em
|
||||
|
||||
//
|
||||
// Links
|
||||
//
|
||||
|
||||
a
|
||||
color: $link-color
|
||||
text-decoration: $link-decoration
|
||||
background-color: transparent
|
||||
|
||||
// Remove the gray background on active links in IE 10.
|
||||
-webkit-text-decoration-skip: objects
|
||||
|
||||
// Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||
|
||||
+hover
|
||||
color: $link-hover-color
|
||||
text-decoration: $link-hover-decoration
|
||||
|
||||
// And undo these styles for placeholder links/named anchors (without href)
|
||||
// which have not been made explicitly keyboard-focusable (without tabindex).
|
||||
// It would be more straightforward to just use a[href] in previous block, but that
|
||||
// causes specificity issues in many other styles that are too complex to fix.
|
||||
// See https://github.com/twbs/bootstrap/issues/19402
|
||||
|
||||
a:not([href]):not([tabindex])
|
||||
color: inherit
|
||||
text-decoration: none
|
||||
|
||||
+hover-focus
|
||||
color: inherit
|
||||
text-decoration: none
|
||||
|
||||
|
||||
&:focus
|
||||
outline: 0
|
||||
|
||||
//
|
||||
// Code
|
||||
//
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp
|
||||
font-family: $font-family-monospace
|
||||
font-size: 1em
|
||||
|
||||
// Correct the odd `em` font sizing in all browsers.
|
||||
|
||||
pre
|
||||
// Remove browser default top margin
|
||||
margin-top: 0
|
||||
|
||||
// Reset browser default of `1em` to use `rem`s
|
||||
margin-bottom: 1rem
|
||||
|
||||
// Don't allow content to break outside
|
||||
overflow: auto
|
||||
|
||||
// We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so
|
||||
// we force a non-overlapping, non-auto-hiding scrollbar to counteract.
|
||||
-ms-overflow-style: scrollbar
|
||||
|
||||
//
|
||||
// Figures
|
||||
//
|
||||
|
||||
figure
|
||||
// Apply a consistent margin strategy (matches our type styles).
|
||||
margin: 0 0 1rem
|
||||
|
||||
//
|
||||
// Images and content
|
||||
//
|
||||
|
||||
img
|
||||
vertical-align: middle
|
||||
border-style: none
|
||||
|
||||
// Remove the border on images inside links in IE 10-.
|
||||
|
||||
svg:not(:root)
|
||||
overflow: hidden
|
||||
|
||||
// Hide the overflow in IE
|
||||
vertical-align: middle
|
||||
|
||||
//
|
||||
// Tables
|
||||
//
|
||||
|
||||
table
|
||||
border-collapse: collapse
|
||||
|
||||
// Prevent double borders
|
||||
|
||||
caption
|
||||
padding-top: $table-cell-padding
|
||||
padding-bottom: $table-cell-padding
|
||||
color: $table-caption-color
|
||||
text-align: left
|
||||
caption-side: bottom
|
||||
|
||||
th
|
||||
// Matches default `<td>` alignment by inheriting from the `<body>`, or the
|
||||
// closest parent with a set `text-align`.
|
||||
text-align: inherit
|
||||
|
||||
//
|
||||
// Forms
|
||||
//
|
||||
|
||||
label
|
||||
// Allow labels to use `margin` for spacing.
|
||||
display: inline-block
|
||||
margin-bottom: $label-margin-bottom
|
||||
|
||||
// Remove the default `border-radius` that macOS Chrome adds.
|
||||
//
|
||||
// Details at https://github.com/twbs/bootstrap/issues/24093
|
||||
button
|
||||
border-radius: 0
|
||||
|
||||
// Work around a Firefox/IE bug where the transparent `button` background
|
||||
// results in a loss of the default `button` focus styles.
|
||||
//
|
||||
// Credit: https://github.com/suitcss/base/
|
||||
button:focus
|
||||
outline: 1px dotted
|
||||
outline: 5px auto -webkit-focus-ring-color
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea
|
||||
margin: 0
|
||||
|
||||
// Remove the margin in Firefox and Safari
|
||||
font-family: inherit
|
||||
font-size: inherit
|
||||
line-height: inherit
|
||||
|
||||
button,
|
||||
input
|
||||
overflow: visible
|
||||
|
||||
// Show the overflow in Edge
|
||||
|
||||
button,
|
||||
select
|
||||
text-transform: none
|
||||
|
||||
// Remove the inheritance of text transform in Firefox
|
||||
|
||||
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||
// controls in Android 4.
|
||||
// 2. Correct the inability to style clickable types in iOS and Safari.
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"]
|
||||
-webkit-appearance: button
|
||||
|
||||
// 2
|
||||
|
||||
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner
|
||||
padding: 0
|
||||
border-style: none
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"]
|
||||
box-sizing: border-box
|
||||
|
||||
// 1. Add the correct box sizing in IE 10-
|
||||
padding: 0
|
||||
|
||||
// 2. Remove the padding in IE 10-
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"]
|
||||
// Remove the default appearance of temporal inputs to avoid a Mobile Safari
|
||||
// bug where setting a custom line-height prevents text from being vertically
|
||||
// centered within the input.
|
||||
// See https://bugs.webkit.org/show_bug.cgi?id=139848
|
||||
// and https://github.com/twbs/bootstrap/issues/11266
|
||||
-webkit-appearance: listbox
|
||||
|
||||
textarea
|
||||
overflow: auto
|
||||
|
||||
// Remove the default vertical scrollbar in IE.
|
||||
// Textareas should really only resize vertically so they don't break their (horizontal) containers.
|
||||
resize: vertical
|
||||
|
||||
fieldset
|
||||
// Browsers set a default `min-width: min-content;` on fieldsets,
|
||||
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
|
||||
// So we reset that to ensure fieldsets behave more like a standard block element.
|
||||
// See https://github.com/twbs/bootstrap/issues/12359
|
||||
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
|
||||
min-width: 0
|
||||
|
||||
// Reset the default outline behavior of fieldsets so they don't affect page layout.
|
||||
padding: 0
|
||||
margin: 0
|
||||
border: 0
|
||||
|
||||
// 1. Correct the text wrapping in Edge and IE.
|
||||
// 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
legend
|
||||
display: block
|
||||
width: 100%
|
||||
max-width: 100%
|
||||
|
||||
// 1
|
||||
padding: 0
|
||||
margin-bottom: .5rem
|
||||
font-size: 1.5rem
|
||||
line-height: inherit
|
||||
color: inherit
|
||||
|
||||
// 2
|
||||
white-space: normal
|
||||
|
||||
// 1
|
||||
|
||||
progress
|
||||
vertical-align: baseline
|
||||
|
||||
// Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
|
||||
// Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button
|
||||
height: auto
|
||||
|
||||
[type="search"]
|
||||
// This overrides the extra rounded corners on search inputs in iOS so that our
|
||||
// `.form-control` class can properly style them. Note that this cannot simply
|
||||
// be added to `.form-control` as it's not specific enough. For details, see
|
||||
// https://github.com/twbs/bootstrap/issues/11586.
|
||||
outline-offset: -2px
|
||||
|
||||
// 2. Correct the outline style in Safari.
|
||||
-webkit-appearance: none
|
||||
|
||||
//
|
||||
// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||
//
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration
|
||||
-webkit-appearance: none
|
||||
|
||||
//
|
||||
// 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
// 2. Change font properties to `inherit` in Safari.
|
||||
//
|
||||
|
||||
\::-webkit-file-upload-button
|
||||
font: inherit
|
||||
|
||||
// 2
|
||||
-webkit-appearance: button
|
||||
|
||||
// 1
|
||||
|
||||
//
|
||||
// Correct element displays
|
||||
//
|
||||
|
||||
output
|
||||
display: inline-block
|
||||
|
||||
summary
|
||||
display: list-item
|
||||
|
||||
// Add the correct display in all browsers
|
||||
cursor: pointer
|
||||
|
||||
template
|
||||
display: none
|
||||
|
||||
// Add the correct display in IE
|
||||
|
||||
// Always hide an element with the `hidden` HTML attribute (from PureCSS).
|
||||
// Needed for proper display in IE 10-.
|
||||
[hidden]
|
||||
display: none !important
|
15
static/assets/bootstrap/sass/_root.sass
Normal file
15
static/assets/bootstrap/sass/_root.sass
Normal file
@@ -0,0 +1,15 @@
|
||||
\:root
|
||||
// Custom variable values only support SassScript inside `#{}`.
|
||||
@each $color, $value in $colors
|
||||
--#{$color}: #{$value}
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
--#{$color}: #{$value}
|
||||
|
||||
@each $bp, $value in $grid-breakpoints
|
||||
--breakpoint-#{$bp}: #{$value}
|
||||
|
||||
// Use `inspect` for lists so that quoted items keep the quotes.
|
||||
// See https://github.com/sass/sass/issues/2383#issuecomment-336349172
|
||||
--font-family-sans-serif: #{inspect($font-family-sans-serif)}
|
||||
--font-family-monospace: #{inspect($font-family-monospace)}
|
149
static/assets/bootstrap/sass/_tables.sass
Normal file
149
static/assets/bootstrap/sass/_tables.sass
Normal file
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// Basic Bootstrap table
|
||||
//
|
||||
|
||||
.table
|
||||
width: 100%
|
||||
max-width: 100%
|
||||
margin-bottom: $spacer
|
||||
background-color: $table-bg
|
||||
|
||||
// Reset for nesting within parents with `background-color`.
|
||||
|
||||
th,
|
||||
td
|
||||
padding: $table-cell-padding
|
||||
vertical-align: top
|
||||
border-top: $table-border-width solid $table-border-color
|
||||
|
||||
thead th
|
||||
vertical-align: bottom
|
||||
border-bottom: (2 * $table-border-width) solid $table-border-color
|
||||
|
||||
tbody + tbody
|
||||
border-top: (2 * $table-border-width) solid $table-border-color
|
||||
|
||||
.table
|
||||
background-color: $body-bg
|
||||
|
||||
//
|
||||
// Condensed table w/ half padding
|
||||
//
|
||||
|
||||
.table-sm
|
||||
th,
|
||||
td
|
||||
padding: $table-cell-padding-sm
|
||||
|
||||
// Border versions
|
||||
//
|
||||
// Add or remove borders all around the table and between all the columns.
|
||||
|
||||
.table-bordered
|
||||
border: $table-border-width solid $table-border-color
|
||||
|
||||
th,
|
||||
td
|
||||
border: $table-border-width solid $table-border-color
|
||||
|
||||
thead
|
||||
th,
|
||||
td
|
||||
border-bottom-width: 2 * $table-border-width
|
||||
|
||||
.table-borderless
|
||||
th,
|
||||
td,
|
||||
thead th,
|
||||
tbody + tbody
|
||||
border: 0
|
||||
|
||||
// Zebra-striping
|
||||
//
|
||||
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
|
||||
|
||||
.table-striped
|
||||
tbody tr:nth-of-type(#{$table-striped-order})
|
||||
background-color: $table-accent-bg
|
||||
|
||||
// Hover effect
|
||||
//
|
||||
// Placed here since it has to come after the potential zebra striping
|
||||
|
||||
.table-hover
|
||||
tbody tr
|
||||
+hover
|
||||
background-color: $table-hover-bg
|
||||
|
||||
// Table backgrounds
|
||||
//
|
||||
// Exact selectors below required to override `.table-striped` and prevent
|
||||
// inheritance to nested tables.
|
||||
|
||||
@each $color, $value in $theme-colors
|
||||
+table-row-variant($color, theme-color-level($color, -9))
|
||||
|
||||
+table-row-variant(active, $table-active-bg)
|
||||
|
||||
// Dark styles
|
||||
//
|
||||
// Same table markup, but inverted color scheme: dark background and light text.
|
||||
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
.table
|
||||
.thead-dark
|
||||
th
|
||||
color: $table-dark-color
|
||||
background-color: $table-dark-bg
|
||||
border-color: $table-dark-border-color
|
||||
|
||||
.thead-light
|
||||
th
|
||||
color: $table-head-color
|
||||
background-color: $table-head-bg
|
||||
border-color: $table-border-color
|
||||
|
||||
.table-dark
|
||||
color: $table-dark-color
|
||||
background-color: $table-dark-bg
|
||||
|
||||
th,
|
||||
td,
|
||||
thead th
|
||||
border-color: $table-dark-border-color
|
||||
|
||||
&.table-bordered
|
||||
border: 0
|
||||
|
||||
&.table-striped
|
||||
tbody tr:nth-of-type(odd)
|
||||
background-color: $table-dark-accent-bg
|
||||
|
||||
&.table-hover
|
||||
tbody tr
|
||||
+hover
|
||||
background-color: $table-dark-hover-bg
|
||||
|
||||
// Responsive tables
|
||||
//
|
||||
// Generate series of `.table-responsive-*` classes for configuring the screen
|
||||
// size of where your table will overflow.
|
||||
|
||||
.table-responsive
|
||||
@each $breakpoint in map-keys($grid-breakpoints)
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints)
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints)
|
||||
|
||||
&#{$infix}
|
||||
+media-breakpoint-down($breakpoint)
|
||||
display: block
|
||||
width: 100%
|
||||
overflow-x: auto
|
||||
-webkit-overflow-scrolling: touch
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar
|
||||
|
||||
// See https://github.com/twbs/bootstrap/pull/10057
|
||||
|
||||
// Prevent double border on horizontal scroll due to use of `display: block;`
|
||||
> .table-bordered
|
||||
border: 0
|
102
static/assets/bootstrap/sass/_tooltip.sass
Normal file
102
static/assets/bootstrap/sass/_tooltip.sass
Normal file
@@ -0,0 +1,102 @@
|
||||
// Base class
|
||||
.tooltip
|
||||
position: absolute
|
||||
z-index: $zindex-tooltip
|
||||
display: block
|
||||
margin: $tooltip-margin
|
||||
|
||||
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
|
||||
// So reset our font and text properties to avoid inheriting weird values.
|
||||
+reset-text
|
||||
|
||||
font-size: $tooltip-font-size
|
||||
|
||||
// Allow breaking very long words so they don't overflow the tooltip's bounds
|
||||
word-wrap: break-word
|
||||
opacity: 0
|
||||
|
||||
&.show
|
||||
opacity: $tooltip-opacity
|
||||
|
||||
.arrow
|
||||
position: absolute
|
||||
display: block
|
||||
width: $tooltip-arrow-width
|
||||
height: $tooltip-arrow-height
|
||||
|
||||
&::before
|
||||
position: absolute
|
||||
content: ""
|
||||
border-color: transparent
|
||||
border-style: solid
|
||||
|
||||
.bs-tooltip-top
|
||||
padding: $tooltip-arrow-height 0
|
||||
|
||||
.arrow
|
||||
bottom: 0
|
||||
|
||||
&::before
|
||||
top: 0
|
||||
border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0
|
||||
border-top-color: $tooltip-arrow-color
|
||||
|
||||
.bs-tooltip-right
|
||||
padding: 0 $tooltip-arrow-height
|
||||
|
||||
.arrow
|
||||
left: 0
|
||||
width: $tooltip-arrow-height
|
||||
height: $tooltip-arrow-width
|
||||
|
||||
&::before
|
||||
right: 0
|
||||
border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0
|
||||
border-right-color: $tooltip-arrow-color
|
||||
|
||||
.bs-tooltip-bottom
|
||||
padding: $tooltip-arrow-height 0
|
||||
|
||||
.arrow
|
||||
top: 0
|
||||
|
||||
&::before
|
||||
bottom: 0
|
||||
border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height
|
||||
border-bottom-color: $tooltip-arrow-color
|
||||
|
||||
.bs-tooltip-left
|
||||
padding: 0 $tooltip-arrow-height
|
||||
|
||||
.arrow
|
||||
right: 0
|
||||
width: $tooltip-arrow-height
|
||||
height: $tooltip-arrow-width
|
||||
|
||||
&::before
|
||||
left: 0
|
||||
border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height
|
||||
border-left-color: $tooltip-arrow-color
|
||||
|
||||
.bs-tooltip-auto
|
||||
&[x-placement^="top"]
|
||||
@extend .bs-tooltip-top
|
||||
|
||||
&[x-placement^="right"]
|
||||
@extend .bs-tooltip-right
|
||||
|
||||
&[x-placement^="bottom"]
|
||||
@extend .bs-tooltip-bottom
|
||||
|
||||
&[x-placement^="left"]
|
||||
@extend .bs-tooltip-left
|
||||
|
||||
// Wrapper for the tooltip content
|
||||
.tooltip-inner
|
||||
max-width: $tooltip-max-width
|
||||
padding: $tooltip-padding-y $tooltip-padding-x
|
||||
color: $tooltip-color
|
||||
text-align: center
|
||||
background-color: $tooltip-bg
|
||||
|
||||
+border-radius($tooltip-border-radius)
|
18
static/assets/bootstrap/sass/_transitions.sass
Normal file
18
static/assets/bootstrap/sass/_transitions.sass
Normal file
@@ -0,0 +1,18 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
.fade
|
||||
+transition($transition-fade)
|
||||
|
||||
&:not(.show)
|
||||
opacity: 0
|
||||
|
||||
.collapse
|
||||
&:not(.show)
|
||||
display: none
|
||||
|
||||
.collapsing
|
||||
position: relative
|
||||
height: 0
|
||||
overflow: hidden
|
||||
|
||||
+transition($transition-collapse)
|
123
static/assets/bootstrap/sass/_type.sass
Normal file
123
static/assets/bootstrap/sass/_type.sass
Normal file
@@ -0,0 +1,123 @@
|
||||
// stylelint-disable declaration-no-important, selector-list-comma-newline-after
|
||||
|
||||
//
|
||||
// Headings
|
||||
//
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
.h1, .h2, .h3, .h4, .h5, .h6
|
||||
margin-bottom: $headings-margin-bottom
|
||||
font-family: $headings-font-family
|
||||
font-weight: $headings-font-weight
|
||||
line-height: $headings-line-height
|
||||
color: $headings-color
|
||||
|
||||
h1, .h1
|
||||
font-size: $h1-font-size
|
||||
|
||||
h2, .h2
|
||||
font-size: $h2-font-size
|
||||
|
||||
h3, .h3
|
||||
font-size: $h3-font-size
|
||||
|
||||
h4, .h4
|
||||
font-size: $h4-font-size
|
||||
|
||||
h5, .h5
|
||||
font-size: $h5-font-size
|
||||
|
||||
h6, .h6
|
||||
font-size: $h6-font-size
|
||||
|
||||
.lead
|
||||
font-size: $lead-font-size
|
||||
font-weight: $lead-font-weight
|
||||
|
||||
// Type display classes
|
||||
.display-1
|
||||
font-size: $display1-size
|
||||
font-weight: $display1-weight
|
||||
line-height: $display-line-height
|
||||
|
||||
.display-2
|
||||
font-size: $display2-size
|
||||
font-weight: $display2-weight
|
||||
line-height: $display-line-height
|
||||
|
||||
.display-3
|
||||
font-size: $display3-size
|
||||
font-weight: $display3-weight
|
||||
line-height: $display-line-height
|
||||
|
||||
.display-4
|
||||
font-size: $display4-size
|
||||
font-weight: $display4-weight
|
||||
line-height: $display-line-height
|
||||
|
||||
//
|
||||
// Horizontal rules
|
||||
//
|
||||
|
||||
hr
|
||||
margin-top: $hr-margin-y
|
||||
margin-bottom: $hr-margin-y
|
||||
border: 0
|
||||
border-top: $hr-border-width solid $hr-border-color
|
||||
|
||||
//
|
||||
// Emphasis
|
||||
//
|
||||
|
||||
small,
|
||||
.small
|
||||
font-size: $small-font-size
|
||||
font-weight: $font-weight-normal
|
||||
|
||||
mark,
|
||||
.mark
|
||||
padding: $mark-padding
|
||||
background-color: $mark-bg
|
||||
|
||||
//
|
||||
// Lists
|
||||
//
|
||||
|
||||
.list-unstyled
|
||||
+list-unstyled
|
||||
|
||||
// Inline turns list items into inline-block
|
||||
.list-inline
|
||||
+list-unstyled
|
||||
|
||||
.list-inline-item
|
||||
display: inline-block
|
||||
|
||||
&:not(:last-child)
|
||||
margin-right: $list-inline-padding
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
// Builds on `abbr`
|
||||
.initialism
|
||||
font-size: 90%
|
||||
text-transform: uppercase
|
||||
|
||||
// Blockquotes
|
||||
.blockquote
|
||||
margin-bottom: $spacer
|
||||
font-size: $blockquote-font-size
|
||||
|
||||
.blockquote-footer
|
||||
display: block
|
||||
font-size: 80%
|
||||
|
||||
// back to default font-size
|
||||
color: $blockquote-small-color
|
||||
|
||||
&::before
|
||||
content: "\2014 \00A0"
|
||||
|
||||
// em dash, nbsp
|
15
static/assets/bootstrap/sass/_utilities.sass
Normal file
15
static/assets/bootstrap/sass/_utilities.sass
Normal file
@@ -0,0 +1,15 @@
|
||||
@import utilities/align
|
||||
@import utilities/background
|
||||
@import utilities/borders
|
||||
@import utilities/clearfix
|
||||
@import utilities/display
|
||||
@import utilities/embed
|
||||
@import utilities/flex
|
||||
@import utilities/float
|
||||
@import utilities/position
|
||||
@import utilities/screenreaders
|
||||
@import utilities/shadows
|
||||
@import utilities/sizing
|
||||
@import utilities/spacing
|
||||
@import utilities/text
|
||||
@import utilities/visibility
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user