restart project

This commit is contained in:
Gustavo Silva 2020-06-11 12:46:16 +01:00
commit d27f43000e
No known key found for this signature in database
GPG Key ID: 08551320BC3EDC50
436 changed files with 36028 additions and 0 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "academic"]
path = academic
url = https://gitlab.com/gsilvapt/ansol-hugo-academic.git

6
archetypes/default.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

4
config.toml Normal file
View File

@ -0,0 +1,4 @@
baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"
theme = "academic"

View File

@ -0,0 +1 @@
{"Target":"css/academic.css","MediaType":"text/css","Data":{}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,20 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.toml]
max_line_length = 100
[*.md]
trim_trailing_whitespace = false
[{layouts/shortcodes/*.html, layouts/_default/_markup/*.html}]
insert_final_newline = false

12
themes/academic/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: gcushen # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: cushen
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://paypal.me/cushen

View File

@ -0,0 +1,41 @@
---
name: "\U0001F41B Bug report"
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
Welcome to Academic's GitHub repo 👋
We use GitHub only for bug reports and feature requests - it's our project management tool.
For **help** and **questions**, please join our **[community chat](https://spectrum.chat/academic)** or use the **[forum](https://discourse.gohugo.io/c/themes)** 🚑.
Also, you can search and browse the extensive [Academic](https://sourcethemes.com/academic/docs/) and [Hugo](https://gohugo.io/documentation/) **documentation**.
For questions on _Blogdown_, please reach out to the [Blogdown community](https://github.com/rstudio/blogdown).
### Describe the bug
A clear and concise description of what the bug is.
### To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. See error '...'
### Expected behavior
A clear and concise description of what you expected to happen.
### Technical details:
* Academic Version:
* Hugo Version:
* Browser/OS:
If applicable, add screenshots to help explain the issue.

View File

@ -0,0 +1,22 @@
---
name: "\U0001F680 Feature request"
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
## Feature Request
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,11 @@
### Purpose
Describe the purpose of this change. If there is an existing issue that is resolved by this pull request, please reference it in the form `Fixes #1234` where 1234 is the relevant issue number.
### Screenshots
If this is a GUI change, try to include screenshots of the change. If not, please delete this section.
### Documentation
If this is an enhancement, add a link here to the corresponding pull request on https://github.com/sourcethemes/academic-www or describe the documentation changes necessary.

43
themes/academic/.github/contributing.md vendored Normal file
View File

@ -0,0 +1,43 @@
# Contributing to Academic
For **help**, **support**, and **questions** please use our **[community chat](https://spectrum.chat/academic)** 🚑.
---
## Where to Start
Learn [how to contribute code on Github](https://codeburst.io/a-step-by-step-guide-to-making-your-first-github-contribution-5302260a2940).
If you're a developer looking to contribute, but you're not sure where to begin, check out the [good first issue](https://github.com/gcushen/hugo-academic/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) label on Github, which contains small tasks that have been specifically flagged as being friendly to new contributors.
After that, if you're looking for something a little more challenging to sink your teeth into, there's a broader [help wanted](https://github.com/gcushen/hugo-academic/labels/help%20wanted) label encompassing issues which need some love.
If you have a straightforward bug fix or improvement, feel free to contribute it in a [Pull Request](https://github.com/gcushen/hugo-academic/pulls).
If you have an idea for a new feature, please start by [searching the issues](https://github.com/gcushen/hugo-academic/issues) to check that the feature has not already been suggested and then suggest it by [opening a new issue](https://github.com/gcushen/hugo-academic/issues/new/choose), as adding new features to Academic first requires some analysis around the design and spec.
To contribute a **new language pack**, refer to the [language pack guide](https://sourcethemes.com/academic/docs/language/#create-or-modify-a-language-pack). Once created, place you language pack in `academic/i18n/`, add the name of the language to `academic/data/i18n/language.yaml`, and open a Pull Request on Github with these two files.
To contribute to **Academic Admin**, the automatic publication importer, refer to [its dedicated Github repository](https://github.com/sourcethemes/academic-admin).
## Stickers
🖼️ [Decorate your laptop or journal with an Academic **sticker**](https://www.redbubble.com/people/neutreno/works/34387919-academic)
## Donations
As a pure community-driven open source project, we welcome your support:
- ☕️ [**Donate a coffee**](https://paypal.me/cushen)
- 💵 [Become a backer on **Patreon**](https://www.patreon.com/cushen)
## Other ways to help
If you're not a developer there are still plenty of ways that you can help. We always need help with:
- Helping our Academic community on the [chat](https://spectrum.chat/academic)
- Improving the [documentation](https://sourcethemes.com/academic/docs/) and writing tutorials
- Just click the _Edit_ button at the bottom of pages or contribute to the [documentation repository](https://github.com/sourcethemes/academic-www)
- Testing and quality assurance
- Hosting local Academic themed events or meetups
- Promoting Academic to others by blogging, vlogging, code streaming, talking etc.

26
themes/academic/.github/stale.yml vendored Normal file
View File

@ -0,0 +1,26 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 30
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- keep
- enhancement
- bug
- documentation
- security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had any
recent activity. The resources of the Academic team are limited, and so we are asking for your help.
If this is a **bug** and you can still reproduce this error on the <code>master</code> branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a **feature request**, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically close soon if no further activity occurs. Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

17
themes/academic/.github/support.md vendored Normal file
View File

@ -0,0 +1,17 @@
# How to get support for Academic 👨‍💬👩‍💬
For **help** and **questions** please join our **[community chat](https://spectrum.chat/academic)** or use the **[forum](https://discourse.gohugo.io/c/themes)** 🚑.
Please **_do not_** raise an issue on GitHub.
Also, you can search and browse the extensive [Academic](https://sourcethemes.com/academic/docs/) and [Hugo](https://gohugo.io/documentation/) **documentation**.
For questions on _Blogdown_, please reach out to the [Blogdown community](https://github.com/rstudio/blogdown).
Issues which are not bug reports or feature requests will be closed.
## Why not GitHub?
GitHub is our project management tool, it's the place where our volunteers contribute. We use the issue list to keep track of bugs and new features that we are working on. We do this openly for transparency.
With the chat and forum, you can leverage the knowledge of our wider community to get help with any problems you are having with Academic. Please keep in mind that Academic is Free Open Source Software (FOSS), and free support is provided by the goodwill of our wonderful community members.

12
themes/academic/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
# IDE specific
.idea/
.vscode/
# Hugo
exampleSite/public/
# Jupyter
.ipynb_checkpoints/
# Node
node_modules/

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2016-present George Cushen
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

159
themes/academic/README.md Normal file
View File

@ -0,0 +1,159 @@
<p align="center"><a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"><img src="https://sourcethemes.com/academic/img/logo_200px.png" alt="Academic logo"></a></p>
# [Academic](https://sourcethemes.com/academic/): the website builder for [Hugo](https://gohugo.io)
### The Page Builder to Easily Create Professional Websites :pencil2: :newspaper: :rocket:
**Create a free website with Academic using Markdown, Jupyter, or RStudio. Choose a beautiful color theme and build anything with the Page Builder - over 50 _widgets_, _themes_, and _language packs_ included!**
[Check out the latest **demo**](https://academic-demo.netlify.app) of what you'll get in less than 10 minutes, or [view the **showcase**](https://sourcethemes.com/academic/#expo) of personal, project, and business sites.
- 👉 [**Get Started**](https://sourcethemes.com/academic/docs/install/)
- 📚 [View the **documentation**](https://sourcethemes.com/academic/docs/)
- 💬 [Chat with the **Academic community**](https://spectrum.chat/academic) or [**Hugo community**](https://discourse.gohugo.io)
- 🐦 Twitter: [@source_themes](https://twitter.com/source_themes) [@GeorgeCushen](https://twitter.com/GeorgeCushen) [#MadeWithAcademic](https://twitter.com/search?q=%23MadeWithAcademic&src=typd)
- 💡 [Request a **feature** or report a **bug**](https://github.com/gcushen/hugo-academic/issues)
- ⬆️ **Updating?** View the [Update Guide](https://sourcethemes.com/academic/docs/update/) and [Release Notes](https://sourcethemes.com/academic/updates/)
- :heart: **Support development** of Academic:
- ☕️ [**Donate a coffee**](https://paypal.me/cushen)
- 💵 [Become a backer on **Patreon** and **unlock rewards**](https://www.patreon.com/cushen)
- 🖼️ [Decorate your laptop or journal with an Academic **sticker**](https://www.redbubble.com/people/neutreno/works/34387919-academic)
- 👕 [Wear the **T-shirt**](https://academic.threadless.com/)
- :woman_technologist: [**Contribute**](https://sourcethemes.com/academic/docs/contribute/)
[![Screenshot](https://raw.githubusercontent.com/gcushen/hugo-academic/master/academic.png)](https://github.com/gcushen/hugo-academic/)
**Key features:**
- **Page builder** - Create *anything* with [**widgets**](https://sourcethemes.com/academic/docs/page-builder/) and [**elements**](https://sourcethemes.com/academic/docs/writing-markdown-latex/)
- **Edit any type of content** - Blog posts, publications, talks, slides, projects, and more!
- **Create content** in [**Markdown**](https://sourcethemes.com/academic/docs/writing-markdown-latex/), [**Jupyter**](https://sourcethemes.com/academic/docs/jupyter/), or [**RStudio**](https://sourcethemes.com/academic/docs/install/#install-with-rstudio)
- **Plugin System** - Fully customizable [**color** and **font themes**](https://sourcethemes.com/academic/themes/)
- **Display Code and Math** - Code highlighting and [LaTeX math](https://en.wikibooks.org/wiki/LaTeX/Mathematics) supported
- **Integrations** - [Google Analytics](https://analytics.google.com), [Disqus commenting](https://disqus.com), Maps, Contact Forms, and more!
- **Beautiful Site** - Simple and refreshing one page design
- **Industry-Leading SEO** - Help get your website found on search engines and social media
- **Media Galleries** - Display your images and videos with captions in a customizable gallery
- **Mobile Friendly** - Look amazing on every screen with a mobile friendly version of your site
- **Multi-language** - 15+ language packs including English, 中文, and Português
- **Multi-user** - Each author gets their own profile page
- **Privacy Pack** - Assists with GDPR
- **Stand Out** - Bring your site to life with animation, parallax backgrounds, and scroll effects
- **One-Click Deployment** - No servers. No databases. Only files.
## Themes
Academic comes with **automatic day (light) and night (dark) mode** built-in. Alternatively, click the sun/moon icon in the top right of the [Demo](https://academic-demo.netlify.app) to set your preferred mode!
Choose a stunning theme for your site and [customize it](https://sourcethemes.com/academic/docs/customization/#custom-theme) to your liking:
[![Themes](https://raw.githubusercontent.com/gcushen/hugo-academic/master/images/themes.png)](https://sourcethemes.com/academic/themes/)
[Browse more themes...](https://sourcethemes.com/academic/themes/)
## The Future of Technical Content Writing
[![Writing technical content](https://sourcethemes.com/academic/img/docs/writing-technical-content.gif)](https://academic-demo.netlify.apppost/writing-technical-content/)
## Ecosystem
* **[Academic Admin](https://github.com/sourcethemes/academic-admin):** An admin tool to import publications from BibTeX or import assets for an offline site
* **[Academic Scripts](https://github.com/sourcethemes/academic-scripts):** Scripts to help migrate content to new versions of Academic
## Install
You can choose from one of the following four methods to install:
* **one-click install using your web browser (recommended)**
* install on your computer using Git with the Command Prompt/Terminal app
* install on your computer by downloading the ZIP files
* install on your computer with RStudio
### Install with web browser
[**Create your site now with Netlify** :rocket:](https://app.netlify.com/start/deploy?repository=https://github.com/sourcethemes/academic-kickstart)
* One-click install of Academic creates an `academic-kickstart` repository in your GitHub or GitLab account
* Netlify will provide you with a customizable URL to access your new site, [or get your own domain](https://sourcethemes.com/academic/docs/domain/)
* Around 1-5 minutes after editing content in your repository, your site will automatically update
- If your site fails to update, [login to Netlify](https://www.netlify.com/), click your site, go to **Deploys**, and review the latest deploy log for any errors
* To **easily edit your site in a rich online editor in your browser**,
- [Login to Netlify](https://www.netlify.com/) and click the site you deployed with Netlify
- Go to **Settings > Identity**, and select **Enable Identity** service
- Under **Registration** preferences, select **Invite Only**
- Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**
- Head over to **`YOUR_SITE.com/admin/`** to view your content management panel and begin publishing content
- For support with _Netlify CMS_ admin panel, refer to the [Netlify CMS docs](https://www.netlifycms.org/docs/add-to-your-site/#authentication) and the very active [Netlify CMS community](https://www.netlifycms.org/community/)
* To edit your site in a [Markdown editor](https://www.typora.io) on your computer,
- Perform the steps in the [*Install with Git*](#install-with-git) section below
Once you have followed the link above to automatically install Academic, head on over to your new `academic-kickstart` repository in your GitHub (or GitLab) account and [personalize your site by editing the files in](https://sourcethemes.com/academic/docs/get-started/) `config/_default/`. Shortly after saving (i.e. *committing* a file), your site will automatically update.
View the [Homepage Builder](https://sourcethemes.com/academic/docs/page-builder/) and [Content](https://sourcethemes.com/academic/docs/managing-content/) guides to learn how to add widgets and content. For inspiration, refer to the [Markdown content](https://github.com/gcushen/hugo-academic/tree/master/exampleSite) which powers the [Demo](https://academic-demo.netlify.app).
### Install with Git
Prerequisites:
* [Download and install Git](https://git-scm.com/downloads)
* [Download and install Hugo Extended v0.65-v0.72](https://gohugo.io/getting-started/installing/#quick-install)
Install:
1. [Fork](https://github.com/sourcethemes/academic-kickstart#fork-destination-box) the *Academic Kickstart* repository to create a new website
* If you already created your site with **Netlify**, then skip this step
2. Clone your fork to your computer with Git, replacing `sourcethemes` in the command below with your GitHub username:
```bash
git clone https://github.com/sourcethemes/academic-kickstart.git My_Website
```
3. Initialize the theme:
```bash
cd My_Website
git submodule update --init --recursive
```
### Install with ZIP
Prerequisites:
* [Download and install Hugo Extended v0.65-v0.72](https://gohugo.io/getting-started/installing/#quick-install)
Install:
1. [Download](https://github.com/sourcethemes/academic-kickstart/archive/master.zip) and extract *Academic Kickstart*
2. [Download](https://github.com/gcushen/hugo-academic/archive/master.zip) and extract the *Academic theme* files from the `hugo-academic-master` folder to the `themes/academic/` folder in *Academic Kickstart*
### Install with RStudio
[Install Academic with RStudio](https://sourcethemes.com/academic/docs/install/#install-with-rstudio)
## Demo content
For inspiration, refer to the [Markdown content](https://github.com/gcushen/hugo-academic/tree/master/exampleSite) which powers the [Demo](https://academic-demo.netlify.app).
If you wish to initialise your site with the demo content, copy the contents of the `themes/academic/exampleSite/` folder to your website root folder, overwriting existing files if necessary. The `exampleSite` folder contains an example config file and content to help you get started. The following command can be used to accomplish this:
```bash
cp -av themes/academic/exampleSite/* .
```
## Get Started
[View the guide to Personalize and Deploy your new site](https://sourcethemes.com/academic/docs/get-started/).
## Updating
[View the Update Guide](https://sourcethemes.com/academic/docs/update/).
Feel free to *star* the project on [Github](https://github.com/gcushen/hugo-academic/) and follow [@source_themes](https://twitter.com/source_themes) on Twitter to help keep track of [updates](https://sourcethemes.com/academic/updates).
## License
Copyright 2016-present [George Cushen](https://georgecushen.com).
Released under the [MIT](https://github.com/gcushen/hugo-academic/blob/master/LICENSE.md) license.
[![Analytics](https://ga-beacon.appspot.com/UA-78646709-2/hugo-academic/readme?pixel)](https://github.com/igrigorik/ga-beacon)

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

View File

@ -0,0 +1,68 @@
---
# Display name
title: "{{ replace .Name "-" " " | title }}"
# Username (this should match the folder name and the name on publications)
authors:
- "{{ urlize .Name }}"
# Is this the primary user of the site?
superuser: false
# Role/position (e.g., Professor of Artificial Intelligence)
role:
# Organizations/Affiliations
organizations:
- name:
url: ""
# Short bio (displayed in user profile at end of posts)
bio:
# List each interest with a dash
interests:
- Interest 1
- Interest 2
education:
courses:
- course: Title course 1
institution: Name of Institution
year: 2012
- course: Title course 1
institution: Name of Institution
year: 2012
# Social/Academic Networking
# For available icons, see: https://sourcethemes.com/academic/docs/page-builder/#icons
# For an email link, use "fas" icon pack, "envelope" icon, and a link in the
# form "mailto:your-email@example.com" or "#contact" for contact widget.
social:
- icon: envelope
icon_pack: fas
link: '#contact' # For a direct email link, use "mailto:test@example.org".
- icon: twitter
icon_pack: fab
link: https://twitter.com/USERNAME
- icon: google-scholar
icon_pack: ai
link: https://scholar.google.com/citations?user=PERSON-ID
- icon: github
icon_pack: fab
link: https://github.com/USERNAME
# Link to a PDF of your resume/CV from the About widget.
# To enable, copy your resume/CV to `static/files/cv.pdf` and uncomment the lines below.
# - icon: cv
# icon_pack: ai
# link: files/cv.pdf
# Enter email to display Gravatar (if Gravatar enabled in Config)
email: ""
# Organizational groups that you belong to (for People widget)
# Set this to `[]` or comment out if you are not using People widget.
user_groups:
- Group 1
- Group 2
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,29 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
subtitle: ""
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
lastmod: {{ .Date }}
featured: false
draft: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---

View File

@ -0,0 +1,23 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
linktitle: "{{ replace .Name "-" " " | title }}"
summary:
date: {{ .Date }}
lastmod: {{ .Date }}
draft: false # Is this a draft? true/false
toc: true # Show table of contents? true/false
type: docs # Do not modify.
# Add menu entry to sidebar.
# - Substitute `example` with the name of your course/documentation folder.
# - name: Declare this menu item as a parent with ID `name`.
# - parent: Reference a parent ID if this page is a child.
# - weight: Position of link in menu.
menu:
example:
name: YourParentID
# parent: YourParentID
weight: 1
---

View File

@ -0,0 +1,48 @@
+++
# A section created with the Blank widget.
widget = "blank" # See https://sourcethemes.com/academic/docs/page-builder/
headless = true # This file represents a page section.
active = true # Activate this widget? true/false
weight = 1 # Order that this section will appear.
# Note: a full width section format can be enabled by commenting out the `title` and `subtitle` with a `#`.
title = "{{ replace .Name "-" " " | title }}"
subtitle = ""
[design]
# Choose how many columns the section has. Valid values: 1 or 2.
columns = "1"
[design.background]
# Apply a background color, gradient, or image.
# Uncomment (by removing `#`) an option to apply it.
# Choose a light or dark text color by setting `text_color_light`.
# Any HTML color name or Hex value is valid.
# Background color.
# color = "navy"
# Background gradient.
# gradient_start = "DeepSkyBlue"
# gradient_end = "SkyBlue"
# Background image.
# image = "image.jpg" # Name of image in `static/img/`.
# image_darken = 0.6 # Darken the image? Range 0-1 where 0 is transparent and 1 is opaque.
# Text color (true=light or false=dark).
# text_color_light = true
[design.spacing]
# Customize the section spacing. Order is top, right, bottom, left.
# padding = ["0px", "0px", "0px", "0px"]
[advanced]
# Custom CSS.
css_style = ""
# CSS class.
css_class = ""
+++
[**Add some elements here**](https://sourcethemes.com/academic/docs/writing-markdown-latex/)

View File

@ -0,0 +1,29 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
subtitle: ""
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
lastmod: {{ .Date }}
featured: false
draft: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---

View File

@ -0,0 +1,41 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
# Optional external URL for project (replaces project detail page).
external_link: ""
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
url_code: ""
url_pdf: ""
url_slides: ""
url_video: ""
# Slides (optional).
# Associate this project with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides = "example-slides"` references `content/slides/example-slides.md`.
# Otherwise, set `slides = ""`.
slides: ""
---

View File

@ -0,0 +1,69 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
authors: []
date: {{ .Date }}
doi: ""
# Schedule page publish date (NOT publication's date).
publishDate: {{ .Date }}
# Publication type.
# Legend: 0 = Uncategorized; 1 = Conference paper; 2 = Journal article;
# 3 = Preprint / Working Paper; 4 = Report; 5 = Book; 6 = Book section;
# 7 = Thesis; 8 = Patent
publication_types: ["0"]
# Publication name and optional abbreviated publication name.
publication: ""
publication_short: ""
abstract: ""
# Summary. An optional shortened abstract.
summary: ""
tags: []
categories: []
featured: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
url_pdf:
url_code:
url_dataset:
url_poster:
url_project:
url_slides:
url_source:
url_video:
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Associated Projects (optional).
# Associate this publication with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `internal-project` references `content/project/internal-project/index.md`.
# Otherwise, set `projects: []`.
projects: []
# Slides (optional).
# Associate this publication with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides: "example"` references `content/slides/example/index.md`.
# Otherwise, set `slides: ""`.
slides: ""
---

View File

@ -0,0 +1,26 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
summary: ""
authors: []
tags: []
categories: []
date: {{ .Date }}
slides:
# Choose a theme from https://github.com/hakimel/reveal.js#theming
theme: black
# Choose a code highlighting style (if highlighting enabled in `params.toml`)
# Light style: github. Dark style: dracula (default).
highlight_style: dracula
---
# Title
Author Name
---
## Slide 2
...

View File

@ -0,0 +1,68 @@
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "{{ replace .Name "-" " " | title }}"
event:
event_url:
location:
address:
street:
city:
region:
postcode:
country:
summary:
abstract:
# Talk start and end times.
# End time can optionally be hidden by prefixing the line with `#`.
date: {{ .Date }}
date_end: {{ .Date }}
all_day: false
# Schedule page publish date (NOT talk date).
publishDate: {{ .Date }}
authors: []
tags: []
# Is this a featured talk? (true/false)
featured: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Custom links (optional).
# Uncomment and edit lines below to show custom links.
# links:
# - name: Follow
# url: https://twitter.com
# icon_pack: fab
# icon: twitter
# Optional filename of your slides within your talk's folder or a URL.
url_slides:
url_code:
url_pdf:
url_video:
# Markdown Slides (optional).
# Associate this talk with Markdown slides.
# Simply enter your slide deck's filename without extension.
# E.g. `slides = "example-slides"` references `content/slides/example-slides.md`.
# Otherwise, set `slides = ""`.
slides: ""
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---

View File

@ -0,0 +1,31 @@
/*************************************************
* Reveal JS
**************************************************/
/* This is a copy of MathJax's `.mjx-chtml` with font-family added to override `.reveal span`. */
/* See https://github.com/hakimel/reveal.js/issues/1924 */
.reveal span.mjx-chtml {
display: inline-block;
line-height: 0;
text-indent: 0;
text-align: left;
text-transform: none;
font-style: normal;
font-weight: normal;
font-size: 100%;
font-size-adjust: none;
letter-spacing: normal;
word-wrap: normal;
word-spacing: normal;
white-space: nowrap;
float: none;
direction: ltr;
max-width: none;
max-height: none;
min-width: 0;
min-height: 0;
border: 0;
margin: 0;
padding: 1px 0;
font-family: MJXc-TeX-math-I,MJXc-TeX-math-Ix,MJXc-TeX-math-Iw;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -0,0 +1,185 @@
/*************************************************
* Academic
* https://github.com/gcushen/hugo-academic
*
* In-built Fuse based search algorithm.
**************************************************/
/* ---------------------------------------------------------------------------
* Configuration.
* --------------------------------------------------------------------------- */
// Configure Fuse.
let fuseOptions = {
shouldSort: true,
includeMatches: true,
tokenize: true,
threshold: search_config.threshold, // Set to ~0.3 for parsing diacritics and CJK languages.
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: search_config.minLength, // Set to 1 for parsing CJK languages.
keys: [
{name:'title', weight:0.99}, /* 1.0 doesn't work o_O */
{name:'summary', weight:0.6},
{name:'authors', weight:0.5},
{name:'content', weight:0.2},
{name:'tags', weight:0.5},
{name:'categories', weight:0.5}
]
};
// Configure summary.
let summaryLength = 60;
/* ---------------------------------------------------------------------------
* Functions.
* --------------------------------------------------------------------------- */
// Get query from URI.
function getSearchQuery(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
}
// Set query in URI without reloading the page.
function updateURL(url) {
if (history.replaceState) {
window.history.replaceState({path:url}, '', url);
}
}
// Pre-process new search query.
function initSearch(force, fuse) {
let query = $("#search-query").val();
// If query deleted, clear results.
if ( query.length < 1) {
$('#search-hits').empty();
}
// Check for timer event (enter key not pressed) and query less than minimum length required.
if (!force && query.length < fuseOptions.minMatchCharLength)
return;
// Do search.
$('#search-hits').empty();
searchAcademic(query, fuse);
let newURL = window.location.protocol + "//" + window.location.host + window.location.pathname + '?q=' + encodeURIComponent(query) + window.location.hash;
updateURL(newURL);
}
// Perform search.
function searchAcademic(query, fuse) {
let results = fuse.search(query);
// console.log({"results": results});
if (results.length > 0) {
$('#search-hits').append('<h3 class="mt-0">' + results.length + ' ' + i18n.results + '</h3>');
parseResults(query, results);
} else {
$('#search-hits').append('<div class="search-no-results">' + i18n.no_results + '</div>');
}
}
// Parse search results.
function parseResults(query, results) {
$.each( results, function(key, value) {
let content_key = value.item.section;
let content = "";
let snippet = "";
let snippetHighlights = [];
// Show abstract in results for content types where the abstract is often the primary content.
if (["publication", "talk"].includes(content_key)) {
content = value.item.summary;
} else {
content = value.item.content;
}
if ( fuseOptions.tokenize ) {
snippetHighlights.push(query);
} else {
$.each( value.matches, function(matchKey, matchValue) {
if (matchValue.key == "content") {
let start = (matchValue.indices[0][0]-summaryLength>0) ? matchValue.indices[0][0]-summaryLength : 0;
let end = (matchValue.indices[0][1]+summaryLength<content.length) ? matchValue.indices[0][1]+summaryLength : content.length;
snippet += content.substring(start, end);
snippetHighlights.push(matchValue.value.substring(matchValue.indices[0][0], matchValue.indices[0][1]-matchValue.indices[0][0]+1));
}
});
}
if (snippet.length < 1) {
snippet += value.item.summary; // Alternative fallback: `content.substring(0, summaryLength*2);`
}
// Load template.
let template = $('#search-hit-fuse-template').html();
// Localize content types.
if (content_key in content_type) {
content_key = content_type[content_key];
}
// Parse template.
let templateData = {
key: key,
title: value.item.title,
type: content_key,
relpermalink: value.item.relpermalink,
snippet: snippet
};
let output = render(template, templateData);
$('#search-hits').append(output);
// Highlight search terms in result.
$.each( snippetHighlights, function(hlKey, hlValue){
$("#summary-"+key).mark(hlValue);
});
});
}
function render(template, data) {
// Replace placeholders with their values.
let key, find, re;
for (key in data) {
find = '\\{\\{\\s*' + key + '\\s*\\}\\}'; // Expect placeholder in the form `{{x}}`.
re = new RegExp(find, 'g');
template = template.replace(re, data[key]);
}
return template;
}
/* ---------------------------------------------------------------------------
* Initialize.
* --------------------------------------------------------------------------- */
// If Academic's in-built search is enabled and Fuse loaded, then initialize it.
if (typeof Fuse === 'function') {
// Wait for Fuse to initialize.
$.getJSON(search_config.indexURI, function (search_index) {
let fuse = new Fuse(search_index, fuseOptions);
// On page load, check for search query in URL.
if (query = getSearchQuery('q')) {
$("body").addClass('searching');
$('.search-results').css({opacity: 0, visibility: "visible"}).animate({opacity: 1},200);
$("#search-query").val(query);
$("#search-query").focus();
initSearch(true, fuse);
}
// On search box key up, process query.
$('#search-query').keyup(function (e) {
clearTimeout($.data(this, 'searchTimer')); // Ensure only one timer runs!
if (e.keyCode == 13) {
initSearch(true, fuse);
} else {
$(this).data('searchTimer', setTimeout(function () {
initSearch(false, fuse);
}, 250));
}
});
});
}

View File

@ -0,0 +1,797 @@
/*************************************************
* Academic
* https://github.com/gcushen/hugo-academic
*
* Core JS functions and initialization.
**************************************************/
(function ($) {
/* ---------------------------------------------------------------------------
* Responsive scrolling for URL hashes.
* --------------------------------------------------------------------------- */
// Dynamically get responsive navigation bar height for offsetting Scrollspy.
function getNavBarHeight() {
let $navbar = $('#navbar-main');
let navbar_offset = $navbar.outerHeight();
console.debug('Navbar height: ' + navbar_offset);
return navbar_offset;
}
/**
* Responsive hash scrolling.
* Check for a URL hash as an anchor.
* If it exists on current page, scroll to it responsively.
* If `target` argument omitted (e.g. after event), assume it's the window's hash.
*/
function scrollToAnchor(target) {
// If `target` is undefined or HashChangeEvent object, set it to window's hash.
// Decode the hash as browsers can encode non-ASCII characters (e.g. Chinese symbols).
target = (typeof target === 'undefined' || typeof target === 'object') ? decodeURIComponent(window.location.hash) : target;
// If target element exists, scroll to it taking into account fixed navigation bar offset.
if ($(target).length) {
// Escape special chars from IDs, such as colons found in Markdown footnote links.
target = '#' + $.escapeSelector(target.substring(1)); // Previously, `target = target.replace(/:/g, '\\:');`
let elementOffset = Math.ceil($(target).offset().top - getNavBarHeight()); // Round up to highlight right ID!
$('body').addClass('scrolling');
$('html, body').animate({
scrollTop: elementOffset
}, 600, function () {
$('body').removeClass('scrolling');
});
} else {
console.debug('Cannot scroll to target `#' + target + '`. ID not found!');
}
}
// Make Scrollspy responsive.
function fixScrollspy() {
let $body = $('body');
let data = $body.data('bs.scrollspy');
if (data) {
data._config.offset = getNavBarHeight();
$body.data('bs.scrollspy', data);
$body.scrollspy('refresh');
}
}
function removeQueryParamsFromUrl() {
if (window.history.replaceState) {
let urlWithoutSearchParams = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.hash;
window.history.replaceState({path: urlWithoutSearchParams}, '', urlWithoutSearchParams);
}
}
// Check for hash change event and fix responsive offset for hash links (e.g. Markdown footnotes).
window.addEventListener("hashchange", scrollToAnchor);
/* ---------------------------------------------------------------------------
* Add smooth scrolling to all links inside the main navbar.
* --------------------------------------------------------------------------- */
$('#navbar-main li.nav-item a.nav-link').on('click', function (event) {
// Store requested URL hash.
let hash = this.hash;
// If we are on a widget page and the navbar link is to a section on the same page.
if (this.pathname === window.location.pathname && hash && $(hash).length && ($(".js-widget-page").length > 0)) {
// Prevent default click behavior.
event.preventDefault();
// Use jQuery's animate() method for smooth page scrolling.
// The numerical parameter specifies the time (ms) taken to scroll to the specified hash.
let elementOffset = Math.ceil($(hash).offset().top - getNavBarHeight()); // Round up to highlight right ID!
// Uncomment to debug.
// let scrollTop = $(window).scrollTop();
// let scrollDelta = (elementOffset - scrollTop);
// console.debug('Scroll Delta: ' + scrollDelta);
$('html, body').animate({
scrollTop: elementOffset
}, 800);
}
});
/* ---------------------------------------------------------------------------
* Hide mobile collapsable menu on clicking a link.
* --------------------------------------------------------------------------- */
$(document).on('click', '.navbar-collapse.show', function (e) {
//get the <a> element that was clicked, even if the <span> element that is inside the <a> element is e.target
let targetElement = $(e.target).is('a') ? $(e.target) : $(e.target).parent();
if (targetElement.is('a') && targetElement.attr('class') != 'dropdown-toggle') {
$(this).collapse('hide');
}
});
/* ---------------------------------------------------------------------------
* Filter publications.
* --------------------------------------------------------------------------- */
// Active publication filters.
let pubFilters = {};
// Search term.
let searchRegex;
// Filter values (concatenated).
let filterValues;
// Publication container.
let $grid_pubs = $('#container-publications');
// Initialise Isotope.
$grid_pubs.isotope({
itemSelector: '.isotope-item',
percentPosition: true,
masonry: {
// Use Bootstrap compatible grid layout.
columnWidth: '.grid-sizer'
},
filter: function () {
let $this = $(this);
let searchResults = searchRegex ? $this.text().match(searchRegex) : true;
let filterResults = filterValues ? $this.is(filterValues) : true;
return searchResults && filterResults;
}
});
// Filter by search term.
let $quickSearch = $('.filter-search').keyup(debounce(function () {
searchRegex = new RegExp($quickSearch.val(), 'gi');
$grid_pubs.isotope();
}));
// Debounce input to prevent spamming filter requests.
function debounce(fn, threshold) {
let timeout;
threshold = threshold || 100;
return function debounced() {
clearTimeout(timeout);
let args = arguments;
let _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
}
// Flatten object by concatenating values.
function concatValues(obj) {
let value = '';
for (let prop in obj) {
value += obj[prop];
}
return value;
}
$('.pub-filters').on('change', function () {
let $this = $(this);
// Get group key.
let filterGroup = $this[0].getAttribute('data-filter-group');
// Set filter for group.
pubFilters[filterGroup] = this.value;
// Combine filters.
filterValues = concatValues(pubFilters);
// Activate filters.
$grid_pubs.isotope();
// If filtering by publication type, update the URL hash to enable direct linking to results.
if (filterGroup == "pubtype") {
// Set hash URL to current filter.
let url = $(this).val();
if (url.substr(0, 9) == '.pubtype-') {
window.location.hash = url.substr(9);
} else {
window.location.hash = '';
}
}
});
// Filter publications according to hash in URL.
function filter_publications() {
let urlHash = window.location.hash.replace('#', '');
let filterValue = '*';
// Check if hash is numeric.
if (urlHash != '' && !isNaN(urlHash)) {
filterValue = '.pubtype-' + urlHash;
}
// Set filter.
let filterGroup = 'pubtype';
pubFilters[filterGroup] = filterValue;
filterValues = concatValues(pubFilters);
// Activate filters.
$grid_pubs.isotope();
// Set selected option.
$('.pubtype-select').val(filterValue);
}
/* ---------------------------------------------------------------------------
* Google Maps or OpenStreetMap via Leaflet.
* --------------------------------------------------------------------------- */
function initMap() {
if ($('#map').length) {
let map_provider = $('#map-provider').val();
let lat = $('#map-lat').val();
let lng = $('#map-lng').val();
let zoom = parseInt($('#map-zoom').val());
let address = $('#map-dir').val();
let api_key = $('#map-api-key').val();
if (map_provider == 1) {
let map = new GMaps({
div: '#map',
lat: lat,
lng: lng,
zoom: zoom,
zoomControl: true,
zoomControlOpt: {
style: 'SMALL',
position: 'TOP_LEFT'
},
panControl: false,
streetViewControl: false,
mapTypeControl: false,
overviewMapControl: false,
scrollwheel: true,
draggable: true
});
map.addMarker({
lat: lat,
lng: lng,
click: function (e) {
let url = 'https://www.google.com/maps/place/' + encodeURIComponent(address) + '/@' + lat + ',' + lng + '/';
window.open(url, '_blank')
},
title: address
})
} else {
let map = new L.map('map').setView([lat, lng], zoom);
if (map_provider == 3 && api_key.length) {
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: api_key
}).addTo(map);
} else {
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
}
let marker = L.marker([lat, lng]).addTo(map);
let url = lat + ',' + lng + '#map=' + zoom + '/' + lat + '/' + lng + '&layers=N';
marker.bindPopup(address + '<p><a href="https://www.openstreetmap.org/directions?engine=osrm_car&route=' + url + '">Routing via OpenStreetMap</a></p>');
}
}
}
/* ---------------------------------------------------------------------------
* GitHub API.
* --------------------------------------------------------------------------- */
function printLatestRelease(selector, repo) {
$.getJSON('https://api.github.com/repos/' + repo + '/tags').done(function (json) {
let release = json[0];
$(selector).append(' ' + release.name);
}).fail(function (jqxhr, textStatus, error) {
let err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
}
/* ---------------------------------------------------------------------------
* Toggle search dialog.
* --------------------------------------------------------------------------- */
function toggleSearchDialog() {
if ($('body').hasClass('searching')) {
// Clear search query and hide search modal.
$('[id=search-query]').blur();
$('body').removeClass('searching compensate-for-scrollbar');
// Remove search query params from URL as user has finished searching.
removeQueryParamsFromUrl();
// Prevent fixed positioned elements (e.g. navbar) moving due to scrollbars.
$('#fancybox-style-noscroll').remove();
} else {
// Prevent fixed positioned elements (e.g. navbar) moving due to scrollbars.
if (!$('#fancybox-style-noscroll').length && document.body.scrollHeight > window.innerHeight) {
$('head').append(
'<style id="fancybox-style-noscroll">.compensate-for-scrollbar{margin-right:' +
(window.innerWidth - document.documentElement.clientWidth) +
'px;}</style>'
);
$('body').addClass('compensate-for-scrollbar');
}
// Show search modal.
$('body').addClass('searching');
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
$('#search-query').focus();
}
}
/* ---------------------------------------------------------------------------
* Change Theme Mode (0: Day, 1: Night, 2: Auto).
* --------------------------------------------------------------------------- */
function canChangeTheme() {
// If the theme changer component is present, then user is allowed to change the theme variation.
return $('.js-theme-selector').length;
}
function getThemeMode() {
return parseInt(localStorage.getItem('dark_mode') || 2);
}
function changeThemeModeClick(newMode) {
console.info('Request to set theme.');
if (!canChangeTheme()) {
console.info('Cannot set theme - admin disabled theme selector.');
return;
}
let isDarkTheme;
switch (newMode) {
case 0:
localStorage.setItem('dark_mode', '1');
isDarkTheme = 1;
console.info('User changed theme variation to Dark.');
showActiveTheme(0);
break;
case 1:
localStorage.setItem('dark_mode', '2');
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = 1;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the dark variation is allowed by admin.
isDarkTheme = 0;
} else {
isDarkTheme = isSiteThemeDark; // Use the site's default theme variation based on `light` in the theme file.
}
console.info('User changed theme variation to Auto.');
showActiveTheme(1);
break;
default:
localStorage.setItem('dark_mode', '0');
isDarkTheme = 0;
console.info('User changed theme variation to Light.');
showActiveTheme(2);
break;
}
renderThemeVariation(isDarkTheme);
}
function showActiveTheme(mode){
switch (mode) {
case 0:
// Dark.
$('.js-set-theme-light').removeClass('dropdown-item-active');
$('.js-set-theme-dark').addClass('dropdown-item-active');
$('.js-set-theme-auto').removeClass('dropdown-item-active');
break;
case 1:
// Auto.
$('.js-set-theme-light').removeClass('dropdown-item-active');
$('.js-set-theme-dark').removeClass('dropdown-item-active');
$('.js-set-theme-auto').addClass('dropdown-item-active');
break;
default:
// Light.
$('.js-set-theme-light').addClass('dropdown-item-active');
$('.js-set-theme-dark').removeClass('dropdown-item-active');
$('.js-set-theme-auto').removeClass('dropdown-item-active');
break;
}
}
function getThemeVariation() {
if (!canChangeTheme()) {
return isSiteThemeDark; // Use the site's default theme variation based on `light` in the theme file.
}
let currentThemeMode = getThemeMode();
let isDarkTheme;
switch (currentThemeMode) {
case 0:
isDarkTheme = 0;
break;
case 1:
isDarkTheme = 1;
break;
default:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = 1;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the dark variation is allowed by admin.
isDarkTheme = 0;
} else {
isDarkTheme = isSiteThemeDark; // Use the site's default theme variation based on `light` in the theme file.
}
break;
}
return isDarkTheme;
}
/**
* Render theme variation (day or night).
*
* @param {int} isDarkTheme - TODO: convert to boolean.
* @param {boolean} init
* @returns {undefined}
*/
function renderThemeVariation(isDarkTheme, init = false) {
// Is code highlighting enabled in site config?
const codeHlEnabled = $('link[title=hl-light]').length > 0;
const codeHlLight = $('link[title=hl-light]')[0];
const codeHlDark = $('link[title=hl-dark]')[0];
const diagramEnabled = $('script[title=mermaid]').length > 0;
// Check if re-render required.
if (!init) {
// If request to render light when light variation already rendered, return.
// If request to render dark when dark variation already rendered, return.
if ((isDarkTheme === 0 && !$('body').hasClass('dark')) || (isDarkTheme === 1 && $('body').hasClass('dark'))) {
return;
}
}
if (isDarkTheme === 0) {
if (!init) {
// Only fade in the page when changing the theme variation.
$('body').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 500);
}
$('body').removeClass('dark');
if (codeHlEnabled) {
codeHlLight.disabled = false;
codeHlDark.disabled = true;
}
if (diagramEnabled) {
if (init) {
mermaid.initialize({theme: 'default', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
} else if (isDarkTheme === 1) {
if (!init) {
// Only fade in the page when changing the theme variation.
$('body').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 500);
}
$('body').addClass('dark');
if (codeHlEnabled) {
codeHlLight.disabled = true;
codeHlDark.disabled = false;
}
if (diagramEnabled) {
if (init) {
mermaid.initialize({theme: 'dark', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
}
}
function initThemeVariation() {
// If theme changer component present, set its icon according to the theme mode (day, night, or auto).
if (canChangeTheme) {
let themeMode = getThemeMode();
switch (themeMode) {
case 0:
showActiveTheme(2);
console.info('Initialize theme variation to Light.');
break;
case 1:
showActiveTheme(0);
console.info('Initialize theme variation to Dark.');
break;
default:
showActiveTheme(1);
console.info('Initialize theme variation to Auto.');
break;
}
}
// Render the day or night theme.
let isDarkTheme = getThemeVariation();
renderThemeVariation(isDarkTheme, true);
}
/* ---------------------------------------------------------------------------
* Normalize Bootstrap Carousel Slide Heights.
* --------------------------------------------------------------------------- */
function normalizeCarouselSlideHeights() {
$('.carousel').each(function () {
// Get carousel slides.
let items = $('.carousel-item', this);
// Reset all slide heights.
items.css('min-height', 0);
// Normalize all slide heights.
let maxHeight = Math.max.apply(null, items.map(function () {
return $(this).outerHeight()
}).get());
items.css('min-height', maxHeight + 'px');
})
}
/* ---------------------------------------------------------------------------
* Fix Hugo's Goldmark output and Mermaid code blocks.
* --------------------------------------------------------------------------- */
/**
* Fix Hugo's Goldmark output.
*/
function fixHugoOutput() {
// Fix Goldmark table of contents.
// - Must be performed prior to initializing ScrollSpy.
$('#TableOfContents').addClass('nav flex-column');
$('#TableOfContents li').addClass('nav-item');
$('#TableOfContents li a').addClass('nav-link');
// Fix Goldmark task lists (remove bullet points).
$("input[type='checkbox'][disabled]").parents('ul').addClass('task-list');
}
/**
* Fix Mermaid.js clash with Highlight.js.
* Refactor Mermaid code blocks as divs to prevent Highlight parsing them and enable Mermaid to parse them.
*/
function fixMermaid() {
let mermaids = [];
[].push.apply(mermaids, document.getElementsByClassName('language-mermaid'));
for (let i = 0; i < mermaids.length; i++) {
$(mermaids[i]).unwrap('pre'); // Remove <pre> wrapper.
$(mermaids[i]).replaceWith(function () {
// Convert <code> block to <div> and add `mermaid` class so that Mermaid will parse it.
return $("<div />").append($(this).contents()).addClass('mermaid');
});
}
}
/* ---------------------------------------------------------------------------
* On document ready.
* --------------------------------------------------------------------------- */
$(document).ready(function () {
fixHugoOutput();
fixMermaid();
// Initialise code highlighting if enabled for this page.
// Note: this block should be processed after the Mermaid code-->div conversion.
if (code_highlighting) {
hljs.initHighlighting();
}
// Initialize theme variation.
initThemeVariation();
// Change theme mode.
$('.js-set-theme-light').click(function (e) {
e.preventDefault();
changeThemeModeClick(2);
});
$('.js-set-theme-dark').click(function (e) {
e.preventDefault();
changeThemeModeClick(0);
});
$('.js-set-theme-auto').click(function (e) {
e.preventDefault();
changeThemeModeClick(1);
});
// Live update of day/night mode on system preferences update (no refresh required).
// Note: since we listen only for *dark* events, we won't detect other scheme changes such as light to no-preference.
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addListener((e) => {
if (!canChangeTheme()) {
// Changing theme variation is not allowed by admin.
return;
}
const darkModeOn = e.matches;
console.log(`OS dark mode preference changed to ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
let currentThemeVariation = parseInt(localStorage.getItem('dark_mode') || 2);
let isDarkTheme;
if (currentThemeVariation === 2) {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes.
isDarkTheme = 1;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes.
isDarkTheme = 0;
} else {
// The visitor does not have a day or night preference, so use the theme's default setting.
isDarkTheme = isSiteThemeDark;
}
renderThemeVariation(isDarkTheme);
}
});
});
/* ---------------------------------------------------------------------------
* On window loaded.
* --------------------------------------------------------------------------- */
$(window).on('load', function () {
// Filter projects.
$('.projects-container').each(function (index, container) {
let $container = $(container);
let $section = $container.closest('section');
let layout;
if ($section.find('.isotope').hasClass('js-layout-row')) {
layout = 'fitRows';
} else {
layout = 'masonry';
}
$container.imagesLoaded(function () {
// Initialize Isotope after all images have loaded.
$container.isotope({
itemSelector: '.isotope-item',
layoutMode: layout,
masonry: {
gutter: 20
},
filter: $section.find('.default-project-filter').text()
});
// Filter items when filter link is clicked.
$section.find('.project-filters a').click(function () {
let selector = $(this).attr('data-filter');
$container.isotope({filter: selector});
$(this).removeClass('active').addClass('active').siblings().removeClass('active all');
return false;
});
// If window hash is set, scroll to hash.
// Placing this within `imagesLoaded` prevents scrolling to the wrong location due to dynamic image loading
// affecting page layout and position of the target anchor ID.
// Note: If there are multiple project widgets on a page, ideally only perform this once after images
// from *all* project widgets have finished loading.
if (window.location.hash) {
scrollToAnchor();
}
});
});
// Enable publication filter for publication index page.
if ($('.pub-filters-select')) {
filter_publications();
// Useful for changing hash manually (e.g. in development):
// window.addEventListener('hashchange', filter_publications, false);
}
// Scroll to top of page.
$('.back-to-top').click(function (event) {
event.preventDefault();
$('html, body').animate({
'scrollTop': 0
}, 800, function () {
window.location.hash = "";
});
});
// Load citation modal on 'Cite' click.
$('.js-cite-modal').click(function (e) {
e.preventDefault();
let filename = $(this).attr('data-filename');
let modal = $('#modal');
modal.find('.modal-body code').load(filename, function (response, status, xhr) {
if (status == 'error') {
let msg = "Error: ";
$('#modal-error').html(msg + xhr.status + " " + xhr.statusText);
} else {
$('.js-download-cite').attr('href', filename);
}
});
modal.modal('show');
});
// Copy citation text on 'Copy' click.
$('.js-copy-cite').click(function (e) {
e.preventDefault();
// Get selection.
let range = document.createRange();
let code_node = document.querySelector('#modal .modal-body');
range.selectNode(code_node);
window.getSelection().addRange(range);
try {
// Execute the copy command.
document.execCommand('copy');
} catch (e) {
console.log('Error: citation copy failed.');
}
// Remove selection.
window.getSelection().removeRange(range);
});
// Initialise Google Maps if necessary.
initMap();
// Print latest version of GitHub projects.
let githubReleaseSelector = '.js-github-release';
if ($(githubReleaseSelector).length > 0)
printLatestRelease(githubReleaseSelector, $(githubReleaseSelector).data('repo'));
// On search icon click toggle search dialog.
$('.js-search').click(function (e) {
e.preventDefault();
toggleSearchDialog();
});
$(document).on('keydown', function (e) {
if (e.which == 27) {
// `Esc` key pressed.
if ($('body').hasClass('searching')) {
toggleSearchDialog();
}
} else if (e.which == 191 && e.shiftKey == false && !$('input,textarea').is(':focus')) {
// `/` key pressed outside of text input.
e.preventDefault();
toggleSearchDialog();
}
});
});
// Normalize Bootstrap carousel slide heights.
$(window).on('load resize orientationchange', normalizeCarouselSlideHeights);
// Automatic main menu dropdowns on mouse over.
$('body').on('mouseenter mouseleave', '.dropdown', function (e) {
var dropdown = $(e.target).closest('.dropdown');
var menu = $('.dropdown-menu', dropdown);
dropdown.addClass('show');
menu.addClass('show');
setTimeout(function () {
dropdown[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
menu[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
}, 300);
// Re-initialize Scrollspy with dynamic navbar height offset.
fixScrollspy();
if (window.location.hash) {
// When accessing homepage from another page and `#top` hash is set, show top of page (no hash).
if (window.location.hash == "#top") {
window.location.hash = ""
} else if (!$('.projects-container').length) {
// If URL contains a hash and there are no dynamically loaded images on the page,
// immediately scroll to target ID taking into account responsive offset.
// Otherwise, wait for `imagesLoaded()` to complete before scrolling to hash to prevent scrolling to wrong
// location.
scrollToAnchor();
}
}
// Call `fixScrollspy` when window is resized.
let resizeTimer;
$(window).resize(function () {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(fixScrollspy, 200);
});
});
})(jQuery);

View File

@ -0,0 +1,72 @@
/*************************************************
* Academic
* https://github.com/gcushen/hugo-academic
*
* Algolia based search algorithm.
**************************************************/
if ((typeof instantsearch === 'function') && $('#search-box').length) {
function getTemplate(templateName) {
return document.querySelector(`#${templateName}-template`).innerHTML;
}
const options = {
appId: algoliaConfig.appId,
apiKey: algoliaConfig.apiKey,
indexName: algoliaConfig.indexName,
routing: true,
searchParameters: {
hitsPerPage: 10
},
searchFunction: function (helper) {
let searchResults = document.querySelector('#search-hits')
if (helper.state.query === '') {
searchResults.style.display = 'none';
return;
}
helper.search();
searchResults.style.display = 'block';
}
};
const search = instantsearch(options);
// Initialize search box.
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
autofocus: false,
reset: true,
poweredBy: algoliaConfig.poweredBy,
placeholder: i18n.placeholder
})
);
// Initialize search results.
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#search-hits',
escapeHits: true,
templates: {
empty: '<div class="search-no-results">' + i18n.no_results + '</div>',
item: getTemplate('search-hit-algolia')
},
cssClasses: {
showmoreButton: 'btn btn-outline-primary'
}
})
);
// On render search results, localize the content type metadata.
search.on('render', function () {
$('.search-hit-type').each(function (index) {
let content_key = $(this).text();
if (content_key in content_type) {
$(this).text(content_type[content_key]);
}
});
});
// Start search.
search.start();
}

View File

@ -0,0 +1,16 @@
// MathJax Configuration
//
// v2 to v3 upgrade notes:
// - The CommonHTML.linebreaks option is not yet implemented (but may be in a future release)
// - The TeX.noUndefined.attributes option is not yet implemented (but may be in a future release)
window.MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$', '$$'], ['\\[', '\\]']],
processEscapes: false,
packages: {'[+]': ['noerrors']}
},
loader: {
load: ['[tex]/noerrors']
}
};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,118 @@
/*************************************************
* Card component
**************************************************/
.card-simple {
background: #fff;
box-shadow: 0 1px 4px rgba(0,0,0,.04);
border: 1px solid rgba(0,0,0,.09);
border-radius: 3px;
margin-top: 20px;
padding: 15px 20px 15px 20px;
}
.card-simple:first-of-type {
margin-top: 0;
}
.card-simple p.read-more {
margin: 0;
}
.dark .card-simple {
background: rgb(40, 42, 54);
box-shadow: 0 1px 4px rgba(0,0,0,.04);
border: 1px solid rgb(68, 71, 90);
}
.card {
margin-bottom: 1.5rem;
overflow: hidden;
text-overflow: ellipsis;
background: #fff;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
transition: all 0.2s ease-out;
}
.card .card-image {
display: block;
position: relative;
min-height: 100px;
}
.card h4 {
font-size: 0.9rem;
font-weight: 700;
line-height: 1.5;
text-transform: uppercase;
}
.card h4 a {
color: #000;
border-bottom: solid 1px transparent;
}
.card h4 a:hover {
color: #000;
border-bottom: solid 1px #000;
text-decoration: none;
}
.card .card-text {
padding: 0.75rem 1rem 0.75rem;
}
.card .card-text p {
color: rgba(0,0,0,0.54);
font-size: 0.75rem;
}
.dark .card-text p {
color: rgb(248, 248, 242);
}
.card p:last-child {
margin-bottom: 0;
}
.card .card-image.hover-overlay:before {
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
content: " ";
opacity: 0;
transition: all 0.2s ease-out;
}
.card .card-image.hover-overlay:after {
display: block;
position: absolute;
left: 0;
top: 50%;
width: 100%;
transform: translate(0, -50%);
opacity: 0;
transition: all 0.2s ease-out;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
content: '\f0c1';
text-align: center;
font-size: 3rem;
color: #666;
}
.card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.card:hover .card-image.hover-overlay:before {
opacity: 0.8;
}
.card:hover .card-image.hover-overlay:after {
opacity: 0.6;
}

View File

@ -0,0 +1,340 @@
/*************************************************
* Page content
**************************************************/
article {
animation: intro 0.3s both;
animation-delay: 0.15s;
}
.article-container {
max-width: 760px;
padding: 0 20px 0 20px;
margin: 0 auto 0 auto;
}
.page-subtitle {
font-size: 1.15rem;
color: rgba(0,0,0,.54);
margin-bottom: 1rem;
}
.dark .page-subtitle {
color: rgba(255,255,255,0.54);
}
.article-header {
position: relative; /* Required for caption positioning */
clear: both;
}
.article-banner {
width: 100%;
height: auto;
}
.featured-image-wrapper {
position: relative;
padding-left: 0; /* Override container padding. */
padding-right: 0; /* Override container padding. */
}
.featured-image {
position: relative;
width: 100%;
display: block;
margin: 0 auto;
}
.article-header-caption {
position: absolute;
bottom: 0;
right: 0;
margin: 0 auto;
padding: 2px 5px;
color: #fff;
font-size: .7em;
background: #000;
text-align: right;
z-index: 5;
opacity: 0.65;
border-radius: 5px 0 0 0;
}
@media (min-width: 64em) {
.article-header-caption {
padding: 5px 10px;
}
}
.article-header-caption a {
color: #fff;
text-decoration: none;
}
.article-title {
font-size: 1.75rem;
}
.article-title a {
color: #151515;
transition: color 0.6s ease;
}
.dark .text-muted {
color: rgba(255,255,255,0.54) !important;
}
.article-metadata {
margin-bottom: 15px;
overflow: hidden;
font-size: 14px;
letter-spacing: 0.03em;
color: rgba(0,0,0,0.54);
}
.dark .article-metadata {
color: rgba(255,255,255,0.54);
}
.stream-meta.article-metadata {
margin-bottom: 5px;
}
/* For article page only, not lists. */
article .article-metadata {
margin-bottom: 20px;
}
.article-metadata a {
color: rgba(0,0,0,.54);
}
.dark .article-metadata a {
color: rgba(255,255,255,0.54);
}
.article-metadata a:hover {
color: $sta-primary;
}
.article-metadata .author-notes {
cursor: help;
vertical-align: super;
font-size: 0.7em;
}
.article-categories {
white-space: nowrap; /* Keep category icon on same line as category links, otherwise context lost. */
}
.middot-divider {
padding-right: .45em;
padding-left: .45em;
font-size: 15px;
}
.middot-divider::after {
content: '\00B7';
}
.article-style img,
.article-style video {
margin-left: auto;
margin-right: auto;
margin-top: 2rem;
margin-bottom: 2rem;
padding: 0;
}
.article-style td img,
.article-style td video {
margin-top: 0;
margin-bottom: 0;
}
.article-style figure {
margin-top: 2rem;
margin-bottom: 2rem;
}
.article-style figure img {
margin-top: 0;
margin-bottom: 0;
}
/*************************************************
* Publications
**************************************************/
.pub-banner {
max-width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
}
.pub-row-heading {
font-weight: bold;
}
#container-publications {
display: block;
position: relative;
overflow: hidden;
}
.li-cite-author {
font-size: 1em;
color: inherit;
}
.li-cite-author a {
color: inherit;
}
.dark .li-cite-author a {
color: rgb(248, 248, 242);
}
/*************************************************
* Content widgets
**************************************************/
.content-widget-hr {
margin-top: 1.2rem;
padding-top: 1.2rem;
border-top: 1px solid rgba(0,0,0,.05);
}
.dark .content-widget-hr {
border-top: 1px solid rgba(255,255,255,.05);
}
/*************************************************
* Tags
**************************************************/
.article-tags {
margin-top: 1.2rem;
}
/*************************************************
* Sharing
**************************************************/
.share-box {
margin-top: 0.7rem;
}
ul.share {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
ul.share li {
display: inline-flex;
margin-right: 8px;
}
ul.share li:last-of-type {
margin-right: 0;
}
ul.share li i {
display: block;
width: 30px;
height: 30px;
line-height: 30px;
font-size: 22px;
text-align: center;
transition: all 150ms ease-in-out;
}
ul.share li a {
text-decoration: none !important;
color: rgba(0, 0, 0, 0.84);
}
.dark ul.share li a {
color: rgba(255, 255, 255, 0.84);
}
ul.share li:hover i {
transform: scale(1.2)
}
/*************************************************
* Author profile card
**************************************************/
.author-card .avatar {
width: 60px;
height: 60px;
}
.author-card .card-title {
margin-top: 0;
margin-bottom: 15px;
font-weight: 600;
color: rgba(0, 0, 0, 0.84);
}
.author-card .card-title a {
color: rgba(0, 0, 0, 0.84);
}
.dark .author-card .card-title,
.dark .author-card .card-title a {
color: rgba(255, 255, 255, 0.84);
}
.author-card p {
margin-bottom: 5px;
}
.author-card .card-subtitle {
font-weight: 300;
font-size: 0.8rem;
color: rgba(0, 0, 0, 0.54);
margin-bottom: 7px;
}
.dark .author-card .card-subtitle {
color: rgba(255, 255, 255, 0.54);
}
.author-card .card-text {
color: rgba(0, 0, 0, 0.76);
font-size: 0.8rem;
margin-bottom: 4px;
}
.dark .author-card .card-text {
color: rgba(255, 255, 255, 0.76);
}
/*************************************************
* Comments
**************************************************/
#comments {
padding-top: 1rem;
}
/*************************************************
* Related content
**************************************************/
.article-widget {
padding-top: 1.2rem; /* Match .content-widget-hr */
}
.article-widget h3 {
margin-top: 0;
}

View File

@ -0,0 +1,139 @@
/*************************************************
* Dark themed components
**************************************************/
body.dark,
.dark .docs-toc-link,
.dark .docs-sidebar .nav > li:not(.active) > a,
.dark .modal button.close,
.dark input,
.dark .form-control,
.dark .form-control:focus {
color: rgb(248, 248, 242);
background: $sta-dark-background;
}
.dark .form-control {
background-color: rgb(68, 71, 90);
}
.dark .form-control:focus {
background-color: rgb(68, 71, 90);
border-color: $sta-primary;
box-shadow: 0 0 0 .2rem $sta-primary-dark;
}
.dark h1,
.dark h2,
.dark h3,
.dark h4,
.dark h5,
.dark h6 {
color: rgb(152, 166, 173);
}
.dark pre,
.dark code {
color: rgb(139, 233, 253);
background-color: rgb(68, 71, 90);
}
.dark pre {
background-color: rgb(68, 71, 90);
border-color: rgb(68, 71, 90);
}
.dark .markup-quote {
background-image: linear-gradient(to bottom, rgba(233, 231, 245, 0.2), rgba(233, 231, 245, 0.2));
}
.dark #MathJax_Zoom {
background-color: rgb(68, 71, 90) !important;
}
.dark table table {
background-color: rgb(40, 42, 54);
}
/* Table Striped */
.dark table > tbody > tr:nth-child(odd) > td,
.dark table > tbody > tr:nth-child(odd) > th {
background-color: rgb(50, 52, 64);
}
/* Table Hover */
.dark table > tbody > tr:hover > td,
.dark table > tbody > tr:hover > th {
background-color: rgb(60, 62, 74);
}
.dark .article-title a {
color: #fff;
}
.dark .portrait-title h2 {
color: #fff;
}
.dark .portrait-title h3 {
color: rgba(255, 255, 255, 0.54);
}
.dark ul.ul-edu li .description p.institution {
color: rgba(255, 255, 255, 0.6);
}
.dark .pub-icon {
color: rgba(255, 255, 255, 0.54);
}
.dark .talk-metadata {
color: rgba(255, 255, 255, 0.54);
}
.dark .pagination li > a, .pagination li > span {
background-color: rgb(40, 42, 54);
border: 1px solid #ddd;
}
.dark .card {
background: #343a40;
}
.dark .card h4 a {
color: $sta-primary;
border-bottom: solid 1px transparent;
}
.dark .card .card-image.hover-overlay::before {
background: #666;
}
.dark .card .card-image.hover-overlay::after {
color: #fff;
}
.dark select {
background: rgb(40, 42, 54);
color: rgb(248, 248, 242);
}
.dark .badge-light {
color: rgba(255, 255, 255, .68);
background: rgba(255, 255, 255, .2);
}
.dark .badge-light[href]:focus,
.dark .badge-light[href]:hover {
background: rgba(255, 255, 255, .3);
}
.dark a.badge:focus,
.dark a.badge:hover {
color: rgba(255, 255, 255, .68);
}
.dark .btn-primary,
.dark .btn.btn-primary.active {
color: initial;
}

View File

@ -0,0 +1,261 @@
/*************************************************
* Documentation layout
**************************************************/
.docs-article-container {
max-width: 760px;
}
/* Documentation: article footer. */
.docs .body-footer {
border-top: 1px solid #e8e8e8;
margin-top: 30px;
padding-top: 10px;
font-size: 14px;
color: #707070;
}
/* Docs content. */
.docs-content {
order: 1;
position: relative;
}
.docs-content>h2[id],
.docs-content>h3[id],
.docs-content>h4[id] {
pointer-events: none;
}
.docs-content>ol li,
.docs-content>ul li {
margin-bottom: .25rem;
}
/* Docs search. */
.docs-search {
position: relative;
padding: 1rem 15px;
margin-right: -15px;
margin-left: -15px;
border-bottom: 1px solid rgba(0, 0, 0, .05);
}
.docs-search .form-control:focus {
border-color: $sta-primary;
box-shadow: 0 0 0 3px $sta-primary-light;
}
/* Docs sidebar. */
.docs-sidebar {
order: 0;
border-bottom: 1px solid rgba(0, 0, 0, .1)
}
@media (min-width:768px) {
.docs-sidebar {
border-right: 1px solid rgba(0, 0, 0, .1)
}
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-sidebar {
position: -webkit-sticky;
position: sticky;
top: 50px;
z-index: 10;
height: calc(100vh - 50px)
}
}
}
@media (min-width:1200px) {
.docs-sidebar {
border-right: 1px solid rgba(0, 0, 0, .1)
}
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-sidebar {
position: -webkit-sticky;
position: sticky;
top: 70px;
z-index: 10;
height: calc(100vh - 70px)
}
}
}
@media (min-width:1200px) {
.docs-sidebar {
flex: 0 1 320px
}
}
/* Docs sidebar li>a. */
.docs-sidebar .nav>li>a {
display: block;
padding: .25rem 1.5rem;
font-size: 0.8rem;
color: rgba(0, 0, 0, .65);
}
.docs-sidebar .nav>li>a:hover {
color: rgba(0, 0, 0, .85);
text-decoration: none;
background-color: transparent;
}
.docs-sidebar .docs-toc-item.active a,
.docs-sidebar .nav>.active:hover>a,
.docs-sidebar .nav>.active>a {
font-weight: bold;
color: $sta-primary;
background-color: transparent;
}
/* Docs links. */
.docs-toggle {
line-height: 1;
font-size: 1.2rem;
color: $sta-primary;
background-color: transparent;
}
.docs-links {
padding-top: 1rem;
padding-bottom: 1rem;
margin-right: -15px;
margin-left: -15px;
}
@media (min-width:768px) {
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-links {
max-height: calc(100vh - 5rem - 70px);
overflow-y: auto;
}
}
}
@media (min-width:768px) {
.docs-links {
display: block!important;
}
}
/* Docs TOC. */
.docs-toc {
order: 2;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
font-size: .875rem
}
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-toc {
position: -webkit-sticky;
position: sticky;
top: 70px;
height: calc(100vh - 70px);
overflow-y: auto
}
}
/* Docs TOC item links. */
.docs-toc-link {
display: block;
padding: .25rem 1.5rem;
font-weight: bold;
color: rgba(0, 0, 0, .65);
}
.docs-toc-link:hover {
color: rgba(0, 0, 0, .85);
text-decoration: none;
}
.docs-toc-item.active {
margin-bottom: 1rem;
}
.docs-toc-item.active:not(:first-child) {
margin-top: 1rem;
}
.docs-toc-item.active>.docs-toc-link {
color: rgba(0, 0, 0, .85);
}
.docs-toc-item.active>.docs-toc-link:hover {
background-color: transparent;
}
.docs-sidenav {
display: block;
}
/* Docs TOC nav. */
.docs-toc-title {
color: #b5b5b5;
font-size: .875rem;
font-weight: 600;
padding-left: calc(1.5rem + 1px);
}
#TableOfContents {
padding-left: 0;
border-left: 1px solid #eee;
}
#TableOfContents ul,
ul.toc-top {
padding-left: 0;
}
// TOC indentation for each level.
#TableOfContents ul ul {
padding-left: 0.8rem;
}
#TableOfContents li {
display: block;
}
#TableOfContents li a,
.toc-top li a {
display: block;
padding: .125rem 1.5rem;
color: #99979c;
font-size: 0.7rem;
}
#TableOfContents li a:hover,
.toc-top li a:hover {
color: $sta-primary;
text-decoration: none;
}
/* ScrollSpy active link style. */
#TableOfContents li a.active {
color: $sta-primary;
font-weight: 700;
}
/* Docs achnorjs links. */
.anchorjs-link {
font-weight: 400;
color: $sta-primary-dark;
transition: color .16s linear;
}
.anchorjs-link:hover {
color: $sta-primary;
text-decoration: none;
}

View File

@ -0,0 +1,18 @@
.footer-license-icons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
list-style: none;
height: auto;
width: auto;
font-size: 0; // Hack to remove space characters between icons without using UL.
text-decoration: none;
}
.footer-license-icons img {
display: inline-flex;
margin-right: 8px;
height: 22px;
vertical-align: text-bottom;
}

View File

@ -0,0 +1,6 @@
/* Mermaid.js div */
div.mermaid {
width: 100%;
text-align: center;
margin-bottom: 1rem;
}

View File

@ -0,0 +1,60 @@
/*************************************************
* List items
**************************************************/
.view-list-item {
margin-bottom: 1rem;
}
.pub-icon {
color: rgba(0, 0, 0, 0.54);
font-size: 0.81em;
padding-right: 6px;
}
.view-list-item .article-metadata {
margin-bottom: 0;
}
.pub-list-item .pub-abstract {
font-size: 1rem;
}
.pub-list-item .btn-links {
padding-top: 10px;
}
/*************************************************
* Compact (stream) list view
**************************************************/
.media.stream-item {
margin-bottom: 2rem;
}
.media.stream-item .article-title,
.card-simple .article-title {
font-size: 1.2rem;
}
.media.stream-item .article-style,
.card-simple .article-style {
margin-top: 2px;
font-size: 0.8rem;
}
.media.stream-item .stream-meta {
margin-top: 12px;
}
.media.stream-item img {
max-width: 150px;
height: auto;
object-fit: cover;
}
@media screen and (max-width: 768px) {
.media.stream-item img {
max-width: 80px;
}
}

View File

@ -0,0 +1,206 @@
/*************************************************
* Navigation bar
**************************************************/
.navbar {
height: 70px;
background: $sta-menu-primary;
box-shadow: 0 0.125rem 0.25rem 0 rgba(0,0,0,.11);
font-size: #{$sta-font-size-small}px;
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 1030;
// Remove Bootstrap's navbar v-padding and assign v-padding to logo separately to maximise logo size.
// Otherwise, Bootstrap's navbar v-padding causes issue with logo fitting within fixed 50px height bar in md-lg sizes.
padding: 0 1rem;
.nav-item {
// For z-index compatibility with logo on mobile layout, otherwise nav-item can't be clicked when logo present.
position: relative;
}
@include media-breakpoint-down(md) {
height: 50px;
.navbar-nav-scroll {
width: 100%;
overflow: hidden;
.navbar-nav {
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
}
}
.navbar-nav {
display: flex;
.nav-link {
color: rgba($sta-menu-text, .85);
&.active,
&:hover,
&:focus {
color: $sta-menu-text;
}
&.active {
font-weight: bold !important;
color: $sta-menu-text-active !important;
}
}
}
.dropdown-menu {
font-size: #{$sta-font-size-small}px;
}
// Note: dedicated `dropdown-item-active` class to prevent ScrollSpy removing `active` class from language chooser.
.dropdown-item.active,
.dropdown-item-active {
font-weight: bold;
color: $sta-menu-text-active !important;
}
}
.dark .navbar {
box-shadow: 0 0.125rem 0.25rem 0 rgba(255, 255, 255, .11);
}
// Remove Bootstrap's border from Toggle button.
.navbar-toggler {
border: 0 !important;
position: relative; // For z-index clickable mobile logo.
z-index: 1030;
}
.navbar-toggler:focus,
.navbar-toggler:active {
outline: none !important;
box-shadow: none !important;
}
@include media-breakpoint-down(md) { /* Match breakpoint for i18n dropdown in navbar.html. */
.i18n-dropdown .nav-link::after {
// Remove dropdown arrow on small devices (when language name isn't displayed).
content: none;
}
}
// Prevent language and theme selectors rendering off page.
.i18n-dropdown .dropdown-menu,
.theme-dropdown .dropdown-menu {
/* Use style from uncollapsable dropdowns to prevent dropdown going off page. */
position: absolute;
/* Below style from .dropdown-menu-right to prevent dropdown going off page. */
right: 0;
left: auto;
}
// Allow user to horizontally scroll.
// Commented out this feature as it causes dropdowns to appear within the menu bar.
// TODO: re-enable in a way that doesn't break dropdowns.
/*
.navbar .collapse {
overflow-x: auto;
}
*/
.navbar-brand {
// Set v-padding to 5px to align with 50/70px responsive max navbar heights.
padding-top: 5px;
padding-bottom: 5px;
font-weight: bold;
position: relative;
z-index: 1030; // For z-index clickable mobile logo.
}
// Dynamically fit logo image to space available.
// No need to explicitly set a size for each breakpoint.
// See https://caniuse.com/#feat=mdn-css_properties_width_stretch .
.navbar-brand img {
width: auto;
height: -moz-available;
height: -webkit-fill-available;
height: -webkit-stretch;
height: stretch;
max-height: 60px; // For lg+ responsive sizing. 60px height +10px v-padding = 70px
max-width: fit-content; // Must override default responsive image style.
}
#navbar-main .main-menu-item ul li .nav-link {
color: $sta-menu-text;
}
@include media-breakpoint-down(md) {
// Used in conjunction with mobile .navbar-brand to center logo on mobile.
.navbar-brand-mobile-wrapper {
position: absolute;
left: 0;
right: 0;
}
.navbar-brand {
// Center logo in mobile navbar.
margin: 0 auto;
}
.navbar-brand img {
max-height: 40px; // 40px height + 10px v-padding = 50px.
}
.navbar-toggler {
border-color: transparent; // Remove Bootstrap's border from Toggle button.
}
#navbar-main .main-menu-item {
text-align: left !important;
padding-left: 0;
}
.navbar-collapse {
z-index: 1031 !important; // Appear just over navbar.
position: absolute;
left: 0;
top: 50px;
width: 100%;
background-color: $sta-menu-primary;
text-align: center !important;
}
#navbar-main .main-menu-item .nav-item {
padding: 10px 15px !important;
}
#navbar-main .main-menu-item .nav-item .nav-link {
padding: 5px 15px !important;
}
}
ul.nav-icons {
list-style-type: none;
font-size: 18px;
padding: 0.5rem 0 0.5rem 0;
margin: 0;
}
ul.nav-icons li {
display: inline;
padding-right: 1rem;
}
ul.nav-icons li:last-of-type {
padding-right: 0;
}
ul.nav-icons li.nav-item a.nav-link {
padding: 0;
}
.dropdown-menu {
background-color: $sta-menu-primary !important;
color: $sta-menu-text !important;
z-index: 1032; // I18n dropdown over mobile expanded menu.
}
.dropdown-item {
background-color: $sta-menu-primary !important;
color: $sta-menu-text !important;
}

View File

@ -0,0 +1,602 @@
/*************************************************
* Academic's Core
**************************************************/
html {
font-family: $sta-font-body, sans-serif;
font-size: #{$sta-font-size-small}px;
color: rgba(0,0,0,0.8);
line-height: 1.65;
}
@media screen and (min-width: 58em) {
html {
font-size: #{$sta-font-size}px;
}
}
body {
font-family: inherit;
font-size: 1rem;
line-height: inherit;
color: inherit;
background-color: $sta-background;
margin-top: 70px; /* Offset body content by navbar height. */
padding-top: 0;
counter-reset: captions;
}
@include media-breakpoint-down(md) { /* Match max-width of .nav-bar query. */
body {
margin-top: 50px; /* Offset body content by navbar height. */
}
}
.max-width-640 {
max-width: 640px;
}
.margin-auto {
margin-left: auto;
margin-right: auto;
}
.center-text {
text-align: center;
}
/* Body text */
p {
margin-top: 0;
margin-bottom: 1rem;
}
/* Lists */
ul, ol, dl {
margin-top: 0;
margin-bottom: 1rem;
}
ul.task-list {
list-style: none;
}
ul.task-list li input[type="checkbox"] {
margin-right: 0.5rem;
}
/* Navigation bar text */
.navbar-light {
font-family: $sta-font-nav, sans-serif;
font-weight: 400;
line-height: 1.25;
text-rendering: optimizeLegibility;
}
/* Headings */
h1, h2, h3, h4, h5, h6 {
font-family: $sta-font-heading, sans-serif;
font-weight: 400;
margin-top: 1rem;
margin-bottom: .5rem;
line-height: 1.25;
color: #313131;
text-rendering: optimizeLegibility;
/* Ensure long words do not overflow into content. */
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-word;
/* Add a hyphen where the word breaks (use `&shy;` to insert a soft-hyphen in a word). */
-webkit-hyphens: manual;
-ms-hyphens: manual;
hyphens: manual;
}
h1 {
font-size: 2.25rem;
}
h2 {
margin-top: 1rem;
font-size: 1.5rem;
}
h3 {
font-weight: 700;
margin-top: 1.5rem;
font-size: 1.25rem;
}
h4, h5, h6 {
font-weight: 700;
margin-top: 1rem;
font-size: 1rem;
}
a,
h3.article-title a:hover {
color: $sta-link;
text-decoration: none;
transition: color 0.6s ease;
}
a:hover,
a:focus {
color: $sta-link-hover;
}
img,
video {
height: auto;
max-width: 100%;
display: block;
}
video {
width: 100%;
height: auto;
max-height: 400px;
}
.img-responsive {
/* Extend Bootstrap declaration with centering. */
margin: 0 auto;
}
// Center all figure images by default.
figure img {
@extend .margin-auto;
}
// Center all figure captions by default.
figcaption {
display: block;
margin-top: 0.75em;
margin-bottom: 1.65rem;
line-height: 1.4;
font-size: 0.76rem;
text-align: center;
}
figcaption.numbered:before {
font-weight: 700;
text-transform: uppercase;
content: attr(data-pre) counter(captions) attr(data-post);
}
figcaption.numbered {
counter-increment: captions;
}
pre,
code {
font-family: $sta-font-mono, monospace;
color: #c7254e;
background-color: #f9f2f4;
}
pre {
margin: 0 0 1rem 0;
background-color: rgb(248, 248, 248); /* Match default highlight theme. */
border-color: rgb(248, 248, 248);
font-size: 0.7rem;
border-radius: 4px;
}
pre code {
white-space: pre; /* Override Bootstrap to preserve line breaks in code. */
overflow-x: auto;
}
hr {
border: 0;
height: 1px;
background: #333;
background-image: linear-gradient(to right, #ccc, #333, #ccc);
}
/* Quotes */
blockquote {
padding: .5rem 1rem;
margin: .8rem 0;
color: #7a7a7a;
border-left: .25rem solid #e5e5e5;
}
blockquote p:last-child {
margin-bottom: 0;
}
@media (min-width: 30em) {
blockquote {
padding-right: 5rem;
padding-left: 1.25rem;
}
}
.markup-quote {
background-color: transparent;
background-image: linear-gradient(to bottom, rgba(233, 231, 245, 1), rgba(233, 231, 245, 1));
}
.space-below {
margin-bottom: 50px;
}
@media screen and (max-width: 768px) {
.space-below {
margin-bottom: 10px;
}
}
.universal-wrapper {
margin: 0 auto;
padding-right: 1rem;
padding-left: 1rem;
padding-top: 0.1rem;
width: 100%;
}
@media only screen and (min-width: 1001px) {
.universal-wrapper {
width: 1000px;
}
}
small,
.small {
font-size: .75em;
}
.responsive-wrap iframe {
max-width: 100%;
}
/*************************************************
* Modals.
**************************************************/
.modal-content {
background: $sta-background;
}
.modal-title {
margin: 0; /* Override default h5 margin. */
}
.modal-content pre {
margin: 0;
}
.modal-header {
border: 0;
color: rgba(0,0,0,0.8);
}
.modal-footer {
border: 0;
}
#modal-error {
color: red;
}
/*************************************************
* Gallery.
**************************************************/
.gallery {
margin: 0.5em -4px 1.5em -4px;
font-size: 0;
}
a[data-fancybox] {
text-decoration: none;
cursor: zoom-in;
}
.gallery a[data-fancybox] img {
height: 250px;
width: auto;
max-width: inherit;
display: inherit;
margin: 0;
padding: 4px;
box-shadow: none;
vertical-align: inherit;
}
.fancybox-caption {
font-size: 1rem;
line-height: 1.5rem;
text-align: center;
}
/*************************************************
* Pager.
**************************************************/
.post-nav {
margin-top: 1rem;
font-size: 0.8rem;
}
.post-nav-item {
hyphens: auto;
word-wrap: break-word;
padding: 11px 0 12px;
width: 100%;
}
.post-nav-item a {
color: #2b2b2b;
line-height: 1.7;
text-transform: none;
}
.post-nav-item .meta-nav {
color: #767676;
font-weight: 900;
line-height: 2;
text-transform: uppercase;
}
.dark .post-nav-item a {
color: #ddd;
}
/*************************************************
* Footer
**************************************************/
footer {
margin: 4rem 0 0;
padding: 2rem 0;
width: 100%;
}
footer p {
font-size: 0.75rem;
text-align: center;
}
site-footer,
footer a.back-to-top i {
color: rgba(0,0,0,0.54);
}
.dark site-footer,
.dark footer a.back-to-top i,
.dark .docs .body-footer {
color: rgba(255,255,255,0.54);
}
/**************************************************
* Tags/Labels
**************************************************/
.badge-light {
border: none;
color: rgba(0,0,0,.68);
background: rgba(0,0,0,.05);
font-weight: normal;
border-radius: 3px;
padding: 5px 10px;
margin-right: 8px;
margin-bottom: 8px;
}
.article-tags > .badge-light:last-child {
margin-right: 0;
}
.badge-light[href]:focus,
.badge-light[href]:hover {
background: rgba(0,0,0,.1);
}
a.badge:focus,
a.badge:hover {
color: rgba(0,0,0,.68);
}
.tag-cloud a {
display: inline-block;
position: relative;
margin: 5px 10px;
word-wrap: break-word;
transition-duration: .2s;
transition-property: transform;
transition-timing-function: ease-out;
}
.tag-cloud a:active,
.tag-cloud a:focus,
.tag-cloud a:hover {
color: $sta-primary-dark;
transform: scale(1.2);
}
.dark .tag-cloud a:active,
.dark .tag-cloud a:focus,
.dark .tag-cloud a:hover {
color: $sta-primary-light;
}
/*************************************************
* Button size override
*************************************************/
.btn {
padding: .5rem;
font-size: .8rem;
line-height: .5;
border-radius: .3rem;
}
.btn-links .btn {
padding: 5px .5rem 5px .5rem;
line-height: 1;
}
.btn.btn-sm {
padding: 5px .4rem 5px .4rem;
font-size: .6rem;
border-radius: .2rem;
}
/*************************************************
* Toolbar Buttons
**************************************************/
.btn-toolbar .btn {
font-size: 0.9rem;
padding: 10px 14px 9px;
border: none;
}
.btn-toolbar .btn:first-child {
border-radius: 6px 0 0 6px;
}
.btn-toolbar .btn:last-child {
border-radius: 0 6px 6px 0;
}
.btn-toolbar .btn.btn-primary:hover,
.btn-toolbar .btn.btn-primary:focus {
background-color: $sta-primary-light !important;
}
.btn-toolbar .btn.btn-primary:active,
.btn-toolbar .btn.btn-primary.active {
background-color: $sta-primary-dark !important;
}
.btn-primary:not(:disabled):not(.disabled).active:focus,
.btn-primary:not(:disabled):not(.disabled):active:focus,
.show > .btn-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 .2rem $sta-primary-light;
}
/*************************************************
* Tables
**************************************************/
/* Based on Bootstrap's `table-responsive` style. */
table {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
margin-bottom: 1rem;
font-size: 0.8rem;
}
table > thead > tr > th,
table > tbody > tr > th,
table > tfoot > tr > th,
table > thead > tr > td,
table > tbody > tr > td,
table > tfoot > tr > td {
padding: 8px;
line-height: 1.43;
vertical-align: top;
border-top: 1px solid #ddd;
}
table > thead > tr > th {
vertical-align: bottom;
border-bottom: 2px solid #ddd;
}
table > caption + thead > tr:first-child > th,
table > colgroup + thead > tr:first-child > th,
table > thead:first-child > tr:first-child > th,
table > caption + thead > tr:first-child > td,
table > colgroup + thead > tr:first-child > td,
table > thead:first-child > tr:first-child > td {
border-top: 0;
}
table > tbody + tbody {
border-top: 2px solid #ddd;
}
table table {
background-color: #fff;
}
/* Table Striped */
table > tbody > tr:nth-child(odd) > td,
table > tbody > tr:nth-child(odd) > th {
background-color: #f9f9f9;
}
/* Table Hover */
table > tbody > tr:hover > td,
table > tbody > tr:hover > th {
background-color: #e5e5e5;
}
/*************************************************
* Article Alerts (Shortcode) and Asides (Mmark)
**************************************************/
/* Style asides as Bootstrap alerts. */
.article-style aside {
@extend .alert;
}
/* Asides use <p> block element whereas alerts use <div>. */
.article-style aside p,
div.alert > div {
position: relative;
display: block;
font-size: 1rem;
margin-left: 2rem;
margin-top: 0;
margin-bottom: 0;
}
div.alert div > * {
margin-bottom: .5rem; /* Use smaller paragraph spacing than usual. */
}
div.alert div > :last-child {
margin-bottom: 0;
}
.article-style aside p::before,
div.alert > div:first-child::before {
position: absolute;
top: -0.5rem;
left: -2rem;
font-size: 1.5rem;
color: #209cee;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
content: '\f05a';
width: 1.5rem;
text-align: center;
}
div.alert-warning > div:first-child::before {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
color: #ff3860;
content: '\f071';
}
.article-style aside a,
div.alert a {
color: currentColor;
text-decoration: none;
border-bottom: solid 1px currentColor;
}
.article-style aside,
.alert-note {
color: #12537e;
background-color: #f6fbfe;
border-color: #209cee;
}
.alert-warning {
color: #cd0930;
background-color: #fff5f7;
border-color: #ff3860;
}

View File

@ -0,0 +1,9 @@
/*************************************************
* Style for right to left (RTL) languages.
**************************************************/
html[dir="rtl"] {
body {
text-align: right;
}
}

View File

@ -0,0 +1,137 @@
/*************************************************
* Search
**************************************************/
.search-results {
transform: scale(0);
-webkit-transform: scale(0);
background-color: $sta-background;
bottom: 0;
left: 0;
right: 0;
top: 0;
overflow: scroll;
position: fixed;
visibility: hidden;
z-index: -99;
}
.dark .search-results {
background-color: $sta-dark-background;
}
.searching {
overflow: hidden;
}
.searching .search-results {
transform: scale(1);
-webkit-transform: scale(1);
visibility: visible;
z-index: 1031; /* Highest index, higher than navbar. */
}
.searching #search-box #search-query {
width: 100%;
}
.search-results > .container {
padding-top: 70px; /* Navbar height. */
}
@media screen and (max-width: 1200px) {
.search-results > .container {
padding-top: 50px; /* Navbar height. */
}
}
.search-header {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: $sta-background;
padding-top: 2rem;
padding-bottom: 1rem;
}
.dark .search-header {
background-color: $sta-dark-background;
}
.search-header h1 {
margin: 0;
line-height: 1;
}
.col-search-close {
text-align: right;
}
.search-header i {
font-size: 2rem;
line-height: 1;
}
#search-box {
position: relative; /* Required for search icon positioning. */
margin-bottom: 0.5rem;
}
#search-box::before {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
content: "\f002";
font-size: 1rem;
opacity: 0.25;
line-height: 1rem;
position: absolute;
left: 0.7rem;
top: 0.6rem;
overflow-x: hidden;
}
#search-box #search-query {
border: 1px solid #dedede;
border-radius: 1rem;
padding: 1rem 1rem 1rem 2rem; /* Wider left padding for search icon to fit in. */
width: 250px;
line-height: 1rem;
height: 1rem;
font-size: 0.8rem;
}
.search-hit em {
font-style: normal;
background-color: #FFE0B2;
color: #E65100;
border-bottom: 1px solid #E65100;
}
.search-hit-type {
margin-bottom: 0 !important; /* Override .article-metadata margin. */
text-transform: capitalize;
}
.search-hit-description {
font-size: 0.7rem;
}
/* Load more results button - hide when there are no more results. */
#search-hits button[disabled] {
display: none;
}
.form-control:focus {
border-color: $sta-primary;
box-shadow: 0 0 0 .2rem $sta-primary-light;
}
/* DARK themed components. */
/* Algolia search input */
.dark .ais-search-box--input {
background-color: $sta-dark-background;;
}
.dark #search-query {
background-color: $sta-dark-background;;
}

View File

@ -0,0 +1,574 @@
/*************************************************
* Page Builder: sections and widgets
**************************************************/
@keyframes intro {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.home-section {
background-color: $sta-home-section-odd;
padding: 110px 0 110px 0;
animation: intro 0.3s both;
animation-delay: 0.15s;
}
/* Override dark colors that may be inherited from body.dark */
.home-section.dark,
.home-section.dark h1,
.home-section.dark h2,
.home-section.dark h3,
.home-section.dark a:not(.btn) {
color: rgb(248, 248, 242);
}
/* Underline links in dark sections to separate them from text */
.home-section.dark a:not(.btn):not(.hero-cta-alt) {
text-decoration: underline;
}
/* Revert Alert Box Link style (.home-section.dark style above should not be applied to it) */
.home-section.dark .alert a {
color: inherit !important;
text-decoration: inherit !important;
}
/* Big underline style for links in dark sections */
/* Disabled as it's an experimental style that requires CSS NOT Selector Level 4 (only in Safari) */
/*
.home-section.dark.big-underline a:not(.btn):not(.hero-cta-alt):not(.alert a) {
text-decoration: none;
position: relative;
}
.home-section.dark.big-underline a:not(.btn):not(.hero-cta-alt):not(.alert a):after {
background: #fff;
content: "";
height: 2px;
left: 0;
right: 0;
position: absolute;
top: 100%;
}*/
/* Default background image properties for home sections. */
.home-section.bg-image {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Create a parallax-like scrolling effect. */
.parallax {
height: 100%;
background-attachment: fixed;
}
.home-section:first-of-type {
padding-top: 50px;
}
.home-section:nth-of-type(even) {
background-color: $sta-home-section-even;
}
.dark .home-section {
background-color: $sta-dark-home-section-odd;
}
.dark .home-section:nth-of-type(even) {
background-color: $sta-dark-home-section-even;
}
@media screen and (max-width: 768px) {
.home-section {
padding: 60px 0 60px 0;
}
.home-section:first-of-type {
padding-top: 40px;
}
}
.section-heading h1 {
margin: 0 0 10px 0;
}
.section-heading p {
font-weight: 400;
font-size: 1.1rem;
color: #b2b2b2;
}
/*************************************************
* Widgets (common)
**************************************************/
.see-all {
margin-top: 2rem;
text-transform: uppercase;
}
/* Reset code highlighting style in Alerts when Alert is child of a `.dark` widget, but Alert should be light.` */
/* But will this affect page which should have dark Alert? */
.dark .alert pre,
.dark .alert code {
color: initial;
background-color: initial;
}
/*************************************************
* Hero Widget
**************************************************/
.wg-hero {
padding: 3em 0;
clear: both;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
animation: intro 0.3s both;
animation-delay: 0s;
animation-delay: 0.25s;
}
.hero-title {
font-size: 2.7rem;
margin-top: 0;
line-height: 1;
}
.hero-lead {
max-width: 768px;
font-size: 1.35rem;
}
.wg-hero.dark .hero-title,
.wg-hero.dark .hero-lead,
.wg-hero.dark .hero-cta-alt,
.wg-hero.dark .hero-note > * {
color: #fff;
/*text-shadow: 1px 1px 4px rgba(0,0,0,0.5);*/ /* Uncomment to standout on complicated backgrounds. */
}
.wg-hero.dark a:not(.wg-hero .btn) {
color: #fff;
}
.wg-hero .hero-lead a {
text-decoration: underline;
}
.wg-hero .cta-btns {
margin-bottom: 16px;
}
.wg-hero .btn {
padding: .6em 2.1em;
}
.wg-hero.dark .btn {
color: $sta-primary-dark;
}
a.hero-cta-alt {
display: inline-block;
position: relative;
transition-duration: .2s;
transition-property: transform;
transition-timing-function: ease-out;
font-size: 1.1rem;
}
a.hero-cta-alt:active,
a.hero-cta-alt:focus,
a.hero-cta-alt:hover {
transform: scale(1.1);
}
.wg-hero .btn-lg {
font-size: 1.1rem;
}
.wg-hero .hero-note {
font-size: 0.8rem;
}
.hero-media {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
text-align: center;
}
/*************************************************
* Slider Widget
**************************************************/
/* Clear `.home-section` as padding and animation interferes with Slider's layout and animations. */
.home-section.wg-slider {
padding: 0;
animation: none;
animation-delay: unset;
}
/* The Slider widget reuses the Hero widget's `.wg-hero` class.
* We must remove the `animation` and `clear` in this instance or
* multiple slides can be `.active` at once. */
.carousel-inner .wg-hero {
animation: none;
clear: none;
}
/*************************************************
* Featurette Widget
**************************************************/
.featurette {
font-size: 0.8rem;
line-height: 1.5;
color: #555;
text-align: center;
}
.featurette h3 {
margin-top: 0;
margin-bottom: 5px;
font-weight: 400;
color: #333;
}
.dark .featurette,
.dark .featurette h3 {
color: #fff;
}
.featurette-icon {
display: block;
width: 100%;
color: $sta-primary;
font-size: 3rem;
text-align: center;
}
/*************************************************
* About widget
**************************************************/
#profile {
text-align: center;
padding: 30px 10px;
position: relative;
}
.avatar {
width: 270px;
height: 270px;
margin: 0 auto;
object-fit: cover;
}
// Use smaller avatar size in About widget on small devices.
@include media-breakpoint-down(sm) {
.wg-about .avatar {
width: 200px;
height: 200px;
}
}
.avatar-circle {
border-radius: 50%;
}
.avatar-square {
border-radius: 3px;
}
.portrait-title h2 {
font-size: 1.75em;
font-weight: 300;
color: #000000;
margin: 20px 0 10px 0;
}
.portrait-title h3 {
font-size: 1rem;
font-weight: 300;
color: rgba(0,0,0, 0.54);
margin: 0px 0 10px 0;
}
ul.network-icon {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
list-style: none;
padding: 0;
margin: 0;
}
#profile .network-icon {
margin-top: 30px;
}
.network-icon li {
margin-right: 10px;
}
.network-icon li:last-of-type {
margin-right: 0;
}
.network-icon li:hover {
transform: scale(1.2)
}
.big-icon {
font-size: 2rem;
}
ul.ul-interests li {
font-size: 0.9rem;
}
ul.ul-edu {
list-style: none;
}
ul.ul-edu li {
position: relative;
padding: 0px 15px 4px 3px;
}
ul.ul-edu li .description p {
margin: 0;
}
ul.ul-edu li .description p.course {
font-size: 0.9rem;
}
ul.ul-edu li .description p.institution {
font-size: 0.75rem;
color: rgba(0,0,0,0.6);
}
/*************************************************
* Experience
**************************************************/
.exp-title {
text-transform: none !important;
}
.exp-company {
font-weight: normal !important;
text-transform: none !important;
}
.exp-meta {
font-size: 0.8rem;
}
.experience .card-text,
.experience .card-text p {
color: #000 !important;
font-size: 0.75rem !important;
}
.dark .experience .text-muted {
color: rgba(255, 255, 255, 0.8) !important;
}
.dark .experience .card-text,
.dark .experience .card-text p {
color: rgb(248, 248, 242) !important;
}
.card .card-text ul {
margin-top: -1rem;
margin-bottom: 0rem;
}
.experience .m-2 .border,
.experience .col.border-right {
border-color: $sta-primary !important;
}
.experience .m-2 .border.exp-fill {
background-color: $sta-primary !important;
}
/*************************************************
* Talks
**************************************************/
.talk-metadata {
color: #4b4f56;
font-size: 0.8rem;
}
/*************************************************
* Projects
**************************************************/
.project-widget-simple li {
margin-bottom: 1rem;
}
.project-widget-simple li:last-of-type {
margin-bottom: 0;
}
.project-widget-simple .project-title {
margin-bottom: 6px;
}
.project-widget-simple .project-summary {
font-size: 0.9rem;
margin-bottom: 0.4rem;
}
.projects-container {
display: block;
position: relative;
/*margin-top: 5rem;*/
overflow: hidden;
}
.project-toolbar{
margin-bottom: 2rem;
}
.project-card {
position: relative;
width: calc(33.3% - 2*20px); /* Fluid 3 columns (inc. 20px gutter) */
}
@media screen and (max-width: 1199px) {
.project-card {
width: calc(50% - 20px); /* Fluid 2 columns (inc. 20px gutter) */
}
}
@media screen and (max-width: 768px) {
.project-card {
width: 100%; /* 1 column */
}
}
.project-item {
margin-bottom: 1.5rem;
}
.project-card.project-item {
margin: 0 0 20px 0; /* Set to Isotope's gutter size */
}
.project-card .card {
margin: 0; /* Remove default card margin and use Isotope gutter */
}
.project-showcase .project-item {
margin-bottom: 3rem;
}
.project-item:last-of-type {
margin-bottom: 0;
}
.isotope-item {
z-index: 2;
}
.isotope-item:hover{
z-index: 3;
}
/*************************************************
* Accomplishments
**************************************************/
.card.course {
margin-bottom: 1rem; /* More compact spacing than Experience widget as typically more items here. */
}
.card.course:last-of-type {
margin-bottom: 0;
}
.course .card-subtitle a {
border-bottom: solid 1px transparent;
}
.course .card-subtitle a:hover {
border-bottom: solid 1px;
text-decoration: none;
}
/*************************************************
* People widget
**************************************************/
.people-widget {
font-size: 0.8rem;
text-align: center;
}
.people-widget .portrait-title h2 {
font-size: 1rem;
}
.people-widget .portrait-title h3 {
font-size: 0.7rem;
}
.people-widget .avatar {
width: 80%;
max-width: 150px;
height: auto;
}
@media (min-width: 576px) {
.people-widget .col-sm-auto {
width: 30%;
}
}
@media (min-width: 992px) {
.people-widget .col-sm-auto {
width: 20%;
}
}
/*************************************************
* Contact
**************************************************/
.contact-widget .fa-ul {
margin-left: 3.14285714rem; /* Must be > `fa-2x` icon size. */
}
.contact-widget .fa-li {
position: absolute;
left: -3.14285714rem; /* Negative of `.contact-widget .fa-ul` margin. */
width: 2rem; /* Match `fa-2x` icon size. */
top: 0.14285714em; /* Default FA value. */
text-align: center;
}
.contact-widget li {
padding-top: 0.8rem; /* Align text with bottom of `fa-2x` icon. */
margin-bottom: 0.3rem;
}
.contact-widget li:last-of-type {
margin-bottom: 0;
}
#map {
height: 350px;
width: 100%;
}

View File

@ -0,0 +1,20 @@
/*************************************************
* Academic: The Website Builder for Hugo
* Designed by @GeorgeCushen
* https://sourcethemes.com/academic/
* License: https://github.com/gcushen/hugo-academic/blob/master/LICENSE.md
**************************************************/
@import "root";
@import "icons";
@import "footer";
@import "nav";
@import "card";
@import "search";
@import "content";
@import "listings";
@import "widgets";
@import "docs";
@import "dark";
@import "integrations";
@import "rtl";

View File

@ -0,0 +1,13 @@
.svg-icon {
display: inline-flex;
align-self: center;
}
.svg-icon {
height:0.9em;
width:0.9em;
}
.svg-icon.svg-baseline {
bottom: 0.1em;
line-height: 1;
position: relative;
}

View File

@ -0,0 +1,23 @@
/* Set Bootstrap variables */
// Set colors.
$primary: $sta-primary;
$text-muted: rgba(0,0,0,0.54);
// Container widths - override XL default of `1140px`.
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1200px
);
$navbar-toggler-padding-x: 0;
$navbar-toggler-font-size: 18px;
$navbar-brand-font-size: 1.2rem;
$navbar-light-color: $sta-menu-text;
$navbar-light-active-color: $sta-menu-text-active;
$navbar-light-brand-color: $sta-menu-title;
$navbar-light-brand-hover-color: $navbar-light-active-color;
$navbar-light-toggler-border-color: transparent;

View File

@ -0,0 +1 @@
// Override this file to add your own SCSS styling.

View File

@ -0,0 +1,41 @@
{{- $scr := .Scratch -}}
{{- $site := $scr.Get "site" -}}
{{/* Don't use partialCached as can error when admin changes theme config whilst `hugo server` is running. */}}
{{- partial "functions/parse_theme" . -}}
$sta-darken-percentage: 10%;
$sta-lighten-percentage: 10%;
$sta-font-size: {{ $scr.Get "font_size" }};
$sta-font-size-small: {{ $scr.Get "font_size_small" }};
$sta-font-body: "{{ $scr.Get "body_font" }}";
$sta-font-heading: "{{ $scr.Get "heading_font" }}";
$sta-font-nav: "{{ $scr.Get "nav_font" }}";
$sta-font-mono: "{{ $scr.Get "mono_font" }}";
$sta-primary: {{ $scr.Get "primary" }};
$sta-primary-light: lighten($sta-primary, $sta-lighten-percentage);
$sta-primary-dark: darken($sta-primary, $sta-darken-percentage);
$sta-link: {{ $scr.Get "link" }};
$sta-link-hover: {{ $scr.Get "link_hover" }};
$sta-menu-primary: {{ $scr.Get "menu_primary" }};
$sta-menu-text: {{ $scr.Get "menu_text" }};
$sta-menu-text-active: {{ $scr.Get "menu_text_active" }};
$sta-menu-title: {{ $scr.Get "menu_title" }};
$sta-background: {{ $scr.Get "background" }};
$sta-dark-background: {{ $scr.Get "dark_background" }};
$sta-home-section-odd: {{ $scr.Get "home_section_odd" }};
$sta-home-section-even: {{ $scr.Get "home_section_even" }};
$sta-dark-home-section-odd: {{ $scr.Get "dark_home_section_odd" }};
$sta-dark-home-section-even: {{ $scr.Get "dark_home_section_even" }};
@import "bootstrap_variables";
@import "vendor/bootstrap/bootstrap";
@import "academic/academic";
@import "custom";

View File

@ -0,0 +1,51 @@
//
// Base styles
//
.alert {
position: relative;
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include 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} {
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
}
}

View File

@ -0,0 +1,54 @@
// 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;
@include font-size($badge-font-size);
font-weight: $badge-font-weight;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius($badge-border-radius);
@include transition($badge-transition);
@at-root a#{&} {
@include hover-focus() {
text-decoration: none;
}
}
// 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;
@include border-radius($badge-pill-border-radius);
}
// Colors
//
// Contextual variations (linked badges get darker on :hover).
@each $color, $value in $theme-colors {
.badge-#{$color} {
@include badge-variant($value);
}
}

View File

@ -0,0 +1,42 @@
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include 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: escape-svg($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;
}
}

View File

@ -0,0 +1,163 @@
// 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: 1 1 auto;
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
@include hover() {
z-index: 1;
}
&:focus,
&:active,
&.active {
z-index: 1;
}
}
}
// 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 {
// Prevent double borders when buttons are next to each other
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-right-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include 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 * .75;
padding-left: $btn-padding-x * .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 * .75;
padding-left: $btn-padding-x-sm * .75;
}
.btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * .75;
padding-left: $btn-padding-x-lg * .75;
}
// The clickable button for toggling the menu
// Set the same inset shadow as the :active state
.btn-group.show .dropdown-toggle {
@include box-shadow($btn-active-box-shadow);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
@include 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:not(:first-child),
> .btn-group:not(:first-child) {
margin-top: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-bottom-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include 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;
}
}
}

View File

@ -0,0 +1,139 @@
// stylelint-disable selector-no-qualifying-type
//
// Base styles
//
.btn {
display: inline-block;
font-family: $btn-font-family;
font-weight: $btn-font-weight;
color: $body-color;
text-align: center;
white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
user-select: none;
background-color: transparent;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
@include transition($btn-transition);
@include hover() {
color: $body-color;
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;
@include box-shadow(none);
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active {
@include box-shadow($btn-active-box-shadow);
&:focus {
@include 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} {
@include button-variant($value, $value);
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include 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;
text-decoration: $link-decoration;
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
&:focus,
&.focus {
text-decoration: $link-hover-decoration;
box-shadow: none;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
pointer-events: none;
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-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%;
}
}

View File

@ -0,0 +1,278 @@
//
// Base styles
//
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: $card-height;
word-wrap: break-word;
background-color: $card-bg;
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group:first-child {
.list-group-item:first-child {
@include border-top-radius($card-border-radius);
}
}
> .list-group:last-child {
.list-group-item:last-child {
@include 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;
// Workaround for the image size bug in IE
// See: https://github.com/twbs/bootstrap/pull/28855
min-height: 1px;
padding: $card-spacer-x;
color: $card-color;
}
.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 {
@include 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>
color: $card-cap-color;
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
&:first-child {
@include 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 {
@include 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,
.card-img-top,
.card-img-bottom {
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius($card-inner-border-radius);
}
.card-img,
.card-img-bottom {
@include border-bottom-radius($card-inner-border-radius);
}
// Card deck
.card-deck {
.card {
margin-bottom: $card-deck-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
margin-right: -$card-deck-margin;
margin-left: -$card-deck-margin;
.card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-right: $card-deck-margin;
margin-bottom: 0; // Override the default
margin-left: $card-deck-margin;
}
}
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: $card-group-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
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 {
&:not(:last-child) {
@include border-right-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-left-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-left-radius: 0;
}
}
}
}
}
}
//
// Columns
//
.card-columns {
.card {
margin-bottom: $card-columns-margin;
}
@include 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 {
overflow: hidden;
&:not(:last-of-type) {
border-bottom: 0;
@include border-bottom-radius(0);
}
&:not(:first-of-type) {
@include border-top-radius(0);
}
> .card-header {
@include border-radius(0);
margin-bottom: -$card-border-width;
}
}
}

View File

@ -0,0 +1,197 @@
// Notes on the classes:
//
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
// we're preventing all actions instead
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
// the active slide is heading.
// 3. .active.carousel-item is the current slide.
// 4. .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.
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
// is the upcoming slide in transition.
.carousel {
position: relative;
}
.carousel.pointer-event {
touch-action: pan-y;
}
.carousel-inner {
position: relative;
width: 100%;
overflow: hidden;
@include clearfix();
}
.carousel-item {
position: relative;
display: none;
float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: block;
}
.carousel-item-next:not(.carousel-item-left),
.active.carousel-item-right {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-right),
.active.carousel-item-left {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item {
opacity: 0;
transition-property: opacity;
transform: none;
}
.carousel-item.active,
.carousel-item-next.carousel-item-left,
.carousel-item-prev.carousel-item-right {
z-index: 1;
opacity: 1;
}
.active.carousel-item-left,
.active.carousel-item-right {
z-index: 0;
opacity: 0;
@include transition(opacity 0s $carousel-transition-duration);
}
}
//
// Left/right controls for nav
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// 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;
@include transition($carousel-control-transition);
// Hover/focus state
@include hover-focus() {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
}
}
.carousel-control-prev {
left: 0;
@if $enable-gradients {
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
}
}
.carousel-control-next {
right: 0;
@if $enable-gradients {
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .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: no-repeat 50% / 100% 100%;
}
.carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg);
}
.carousel-control-next-icon {
background-image: escape-svg($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: 0;
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 {
box-sizing: content-box;
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: $carousel-indicator-active-bg;
background-clip: padding-box;
// Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: .5;
@include transition($carousel-indicator-transition);
}
.active {
opacity: 1;
}
}
// 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;
}

View File

@ -0,0 +1,41 @@
.close {
float: right;
@include font-size($close-font-size);
font-weight: $close-font-weight;
line-height: 1;
color: $close-color;
text-shadow: $close-text-shadow;
opacity: .5;
// Override <a>'s hover style
@include hover() {
color: $close-color;
text-decoration: none;
}
&:not(:disabled):not(.disabled) {
@include hover-focus() {
opacity: .75;
}
}
}
// 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-next-line selector-no-qualifying-type
button.close {
padding: 0;
background-color: transparent;
border: 0;
appearance: none;
}
// Future-proof disabling of clicks on `<a>` elements
// stylelint-disable-next-line selector-no-qualifying-type
a.close.disabled {
pointer-events: none;
}

View File

@ -0,0 +1,48 @@
// Inline code
code {
@include font-size($code-font-size);
color: $code-color;
word-wrap: 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;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
@include box-shadow($kbd-box-shadow);
kbd {
padding: 0;
@include font-size(100%);
font-weight: $nested-kbd-font-weight;
@include box-shadow(none);
}
}
// Blocks of code
pre {
display: block;
@include font-size($code-font-size);
color: $pre-color;
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: $pre-scrollable-max-height;
overflow-y: scroll;
}

View File

@ -0,0 +1,521 @@
// 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: $font-size-base * $line-height-base;
padding-left: $custom-control-gutter + $custom-control-indicator-size;
}
.custom-control-inline {
display: inline-flex;
margin-right: $custom-control-spacer-x;
}
.custom-control-input {
position: absolute;
left: 0;
z-index: -1; // Put the input behind the label so it doesn't overlay text
width: $custom-control-indicator-size;
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
opacity: 0;
&:checked ~ .custom-control-label::before {
color: $custom-control-indicator-checked-color;
border-color: $custom-control-indicator-checked-border-color;
@include gradient-bg($custom-control-indicator-checked-bg);
@include 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
@if $enable-shadows {
box-shadow: $input-box-shadow, $input-focus-box-shadow;
} @else {
box-shadow: $custom-control-indicator-focus-box-shadow;
}
}
&:focus:not(:checked) ~ .custom-control-label::before {
border-color: $custom-control-indicator-focus-border-color;
}
&:not(:disabled):active ~ .custom-control-label::before {
color: $custom-control-indicator-active-color;
background-color: $custom-control-indicator-active-bg;
border-color: $custom-control-indicator-active-border-color;
@include box-shadow($custom-control-indicator-active-box-shadow);
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled],
&: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;
color: $custom-control-label-color;
vertical-align: top;
cursor: $custom-control-cursor;
// Background-color and (when enabled) gradient
&::before {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
pointer-events: none;
content: "";
background-color: $custom-control-indicator-bg;
border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
@include box-shadow($custom-control-indicator-box-shadow);
}
// Foreground (icon)
&::after {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
content: "";
background: no-repeat 50% / #{$custom-control-indicator-bg-size};
}
}
// Checkboxes
//
// Tweak just a few things for checkboxes.
.custom-checkbox {
.custom-control-label::before {
@include border-radius($custom-checkbox-indicator-border-radius);
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
}
}
.custom-control-input:indeterminate ~ .custom-control-label {
&::before {
border-color: $custom-checkbox-indicator-indeterminate-border-color;
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
}
&::after {
background-image: escape-svg($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 {
// stylelint-disable-next-line property-blacklist
border-radius: $custom-radio-indicator-border-radius;
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-radio-indicator-icon-checked);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
background-color: $custom-control-indicator-checked-disabled-bg;
}
}
}
// switches
//
// Tweak a few things for switches
.custom-switch {
padding-left: $custom-switch-width + $custom-control-gutter;
.custom-control-label {
&::before {
left: -($custom-switch-width + $custom-control-gutter);
width: $custom-switch-width;
pointer-events: all;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
}
&::after {
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
width: $custom-switch-indicator-size;
height: $custom-switch-indicator-size;
background-color: $custom-control-indicator-border-color;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
@include transition(transform .15s ease-in-out, $custom-forms-transition);
}
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-color: $custom-control-indicator-bg;
transform: translateX($custom-switch-width - $custom-control-indicator-size);
}
}
.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;
font-family: $custom-select-font-family;
@include font-size($custom-select-font-size);
font-weight: $custom-select-font-weight;
line-height: $custom-select-line-height;
color: $custom-select-color;
vertical-align: middle;
background: $custom-select-bg $custom-select-background;
border: $custom-select-border-width solid $custom-select-border-color;
@include border-radius($custom-select-border-radius, 0);
@include 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 {
display: none;
}
// Remove outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $custom-select-color;
}
}
.custom-select-sm {
height: $custom-select-height-sm;
padding-top: $custom-select-padding-y-sm;
padding-bottom: $custom-select-padding-y-sm;
padding-left: $custom-select-padding-x-sm;
@include font-size($custom-select-font-size-sm);
}
.custom-select-lg {
height: $custom-select-height-lg;
padding-top: $custom-select-padding-y-lg;
padding-bottom: $custom-select-padding-y-lg;
padding-left: $custom-select-padding-x-lg;
@include 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;
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .custom-file-label,
&: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[data-browse]::after {
content: attr(data-browse);
}
}
.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;
font-family: $custom-file-font-family;
font-weight: $custom-file-font-weight;
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;
@include border-radius($custom-file-border-radius);
@include 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";
@include gradient-bg($custom-file-button-bg);
border-left: inherit;
@include 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%;
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
padding: 0; // Need to reset padding
background-color: transparent;
appearance: none;
&:focus {
outline: none;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
}
&::-moz-focus-outer {
border: 0;
}
&::-webkit-slider-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include 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;
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-moz-range-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include 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?
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: 0; // Edge specific
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include 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 / 2;
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-fill-lower {
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&::-ms-fill-upper {
margin-right: 15px; // arbitrary?
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&:disabled {
&::-webkit-slider-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-webkit-slider-runnable-track {
cursor: default;
}
&::-moz-range-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-moz-range-track {
cursor: default;
}
&::-ms-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
}
}
.custom-control-label::before,
.custom-file-label,
.custom-select {
@include transition($custom-forms-transition);
}

View File

@ -0,0 +1,191 @@
// The dropdown wrapper (`<div>`)
.dropup,
.dropright,
.dropdown,
.dropleft {
position: relative;
}
.dropdown-toggle {
white-space: nowrap;
// Generate the caret automatically
@include 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
@include font-size($dropdown-font-size);
color: $dropdown-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;
@include border-radius($dropdown-border-radius);
@include box-shadow($dropdown-box-shadow);
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-left {
right: auto;
left: 0;
}
.dropdown-menu#{$infix}-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 {
@include caret(up);
}
}
.dropright {
.dropdown-menu {
top: 0;
right: auto;
left: 100%;
margin-top: 0;
margin-left: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(right);
&::after {
vertical-align: 0;
}
}
}
.dropleft {
.dropdown-menu {
top: 0;
right: 100%;
left: auto;
margin-top: 0;
margin-right: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(left);
&::before {
vertical-align: 0;
}
}
}
// When enabled Popper.js, reset basic dropdown position
// stylelint-disable-next-line no-duplicate-selectors
.dropdown-menu {
&[x-placement^="top"],
&[x-placement^="right"],
&[x-placement^="bottom"],
&[x-placement^="left"] {
right: auto;
bottom: auto;
}
}
// Dividers (basically an `<hr>`) within the dropdown
.dropdown-divider {
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
}
// 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
// Prevent dropdown overflow if there's no padding
// See https://github.com/twbs/bootstrap/pull/27703
@if $dropdown-padding-y == 0 {
&:first-child {
@include border-top-radius($dropdown-inner-border-radius);
}
&:last-child {
@include border-bottom-radius($dropdown-inner-border-radius);
}
}
@include hover-focus() {
color: $dropdown-link-hover-color;
text-decoration: none;
@include gradient-bg($dropdown-link-hover-bg);
}
&.active,
&:active {
color: $dropdown-link-active-color;
text-decoration: none;
@include gradient-bg($dropdown-link-active-bg);
}
&.disabled,
&:disabled {
color: $dropdown-link-disabled-color;
pointer-events: none;
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
@include 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;
}

View File

@ -0,0 +1,338 @@
// stylelint-disable selector-no-qualifying-type
//
// Textual form controls
//
.form-control {
display: block;
width: 100%;
height: $input-height;
padding: $input-padding-y $input-padding-x;
font-family: $input-font-family;
@include font-size($input-font-size);
font-weight: $input-font-weight;
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.
@include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow);
@include transition($input-transition);
// Unstyle the caret on `<select>`s in IE10+.
&::-ms-expand {
background-color: transparent;
border: 0;
}
// Remove select outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $input-color;
}
// Customize the `:focus` state to imitate native WebKit styles.
@include form-control-focus($ignore-warning: true);
// 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 {
&: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: add($input-padding-y, $input-border-width);
padding-bottom: add($input-padding-y, $input-border-width);
margin-bottom: 0; // Override the `<label>/<legend>` default
@include font-size(inherit); // Override the `<legend>` default
line-height: $input-line-height;
}
.col-form-label-lg {
padding-top: add($input-padding-y-lg, $input-border-width);
padding-bottom: add($input-padding-y-lg, $input-border-width);
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
}
.col-form-label-sm {
padding-top: add($input-padding-y-sm, $input-border-width);
padding-bottom: add($input-padding-y-sm, $input-border-width);
@include font-size($input-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: $input-padding-y 0;
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
@include font-size($input-font-size);
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.
//
// Repeated in `_input_group.scss` to avoid Sass extend issues.
.form-control-sm {
height: $input-height-sm;
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.form-control-lg {
height: $input-height-lg;
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
// stylelint-disable-next-line no-duplicate-selectors
select.form-control {
&[size],
&[multiple] {
height: auto;
}
}
textarea.form-control {
height: auto;
}
// 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: -$form-grid-gutter-width / 2;
margin-left: -$form-grid-gutter-width / 2;
> .col,
> [class*="col-"] {
padding-right: $form-grid-gutter-width / 2;
padding-left: $form-grid-gutter-width / 2;
}
}
// 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;
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .form-check-label,
&: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.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
// 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
@include 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;
flex-shrink: 0;
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;
}
}
}

View File

@ -0,0 +1,134 @@
// 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.
@mixin _assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
// 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
// Used to ensure the min-width of the lowest breakpoint starts at 0.
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
$values: map-values($map);
$first-value: nth($values, 1);
@if $first-value != 0 {
@warn "First breakpoint in #{$map-name} 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;
}
// See https://codepen.io/kevinweber/pen/dXWoRw
@function escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $escaped-characters {
$string: str-replace($string, $char, $encoded);
}
}
@return $string;
}
// Color contrast
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
$r: red($color);
$g: green($color);
$b: blue($color);
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
@if ($yiq >= $yiq-contrasted-threshold) {
@return $dark;
} @else {
@return $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);
}
// Return valid calc
@function add($value1, $value2, $return-calc: true) {
@if $value1 == null {
@return $value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 + $value2;
}
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
}
@function subtract($value1, $value2, $return-calc: true) {
@if $value1 == null and $value2 == null {
@return null;
}
@if $value1 == null {
@return -$value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 - $value2;
}
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
}

View File

@ -0,0 +1,69 @@
// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.
@if $enable-grid-classes {
// Single container class with breakpoint max-widths
.container {
@include make-container();
@include make-container-max-widths();
}
// 100% wide container at all breakpoints
.container-fluid {
@include make-container();
}
// Responsive containers that are 100% wide until a breakpoint
@each $breakpoint, $container-max-width in $container-max-widths {
.container-#{$breakpoint} {
@extend .container-fluid;
}
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
%responsive-container-#{$breakpoint} {
max-width: $container-max-width;
}
@each $name, $width in $grid-breakpoints {
@if ($container-max-width > $width or $breakpoint == $name) {
.container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
}
}
}
}
}
// Row
//
// Rows contain your columns.
@if $enable-grid-classes {
.row {
@include 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 {
@include make-grid-columns();
}

View File

@ -0,0 +1,42 @@
// 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 {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include 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 {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}

View File

@ -0,0 +1,191 @@
// 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,
> .form-control-plaintext,
> .custom-select,
> .custom-file {
position: relative; // For focus state's z-index
flex: 1 1 0%;
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
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;
}
// Bring the custom file input above the label
> .custom-file .custom-file-input:focus {
z-index: 4;
}
> .form-control,
> .custom-select {
&:not(:last-child) { @include border-right-radius(0); }
&:not(:first-child) { @include 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 { @include border-right-radius(0); }
&:not(:first-child) .custom-file-label { @include 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;
&:focus {
z-index: 3;
}
}
.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
@include font-size($input-font-size); // 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;
@include 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:not(textarea),
.input-group-lg > .custom-select {
height: $input-height-lg;
}
.input-group-lg > .form-control,
.input-group-lg > .custom-select,
.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 {
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
.input-group-sm > .form-control:not(textarea),
.input-group-sm > .custom-select {
height: $input-height-sm;
}
.input-group-sm > .form-control,
.input-group-sm > .custom-select,
.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 {
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .custom-select,
.input-group-sm > .custom-select {
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
}
// 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) {
@include 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) {
@include border-left-radius(0);
}

View File

@ -0,0 +1,17 @@
.jumbotron {
padding: $jumbotron-padding ($jumbotron-padding / 2);
margin-bottom: $jumbotron-padding;
color: $jumbotron-color;
background-color: $jumbotron-bg;
@include border-radius($border-radius-lg);
@include media-breakpoint-up(sm) {
padding: ($jumbotron-padding * 2) $jumbotron-padding;
}
}
.jumbotron-fluid {
padding-right: 0;
padding-left: 0;
@include border-radius(0);
}

View File

@ -0,0 +1,158 @@
// 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
@include hover-focus() {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
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;
color: $list-group-color;
background-color: $list-group-bg;
border: $list-group-border-width solid $list-group-border-color;
&:first-child {
@include border-top-radius($list-group-border-radius);
}
&:last-child {
@include border-bottom-radius($list-group-border-radius);
}
&.disabled,
&:disabled {
color: $list-group-disabled-color;
pointer-events: none;
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;
}
& + & {
border-top-width: 0;
&.active {
margin-top: -$list-group-border-width;
border-top-width: $list-group-border-width;
}
}
}
// Horizontal
//
// Change the layout of list group items from vertical (default) to horizontal.
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.list-group-horizontal#{$infix} {
flex-direction: row;
.list-group-item {
&:first-child {
@include border-bottom-left-radius($list-group-border-radius);
@include border-top-right-radius(0);
}
&:last-child {
@include border-top-right-radius($list-group-border-radius);
@include border-bottom-left-radius(0);
}
&.active {
margin-top: 0;
}
& + .list-group-item {
border-top-width: $list-group-border-width;
border-left-width: 0;
&.active {
margin-left: -$list-group-border-width;
border-left-width: $list-group-border-width;
}
}
}
}
}
}
// 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-width: 0;
border-left-width: 0;
@include border-radius(0);
&:first-child {
border-top-width: 0;
}
}
&:last-child {
.list-group-item:last-child {
border-bottom-width: 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 {
@include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
}

View File

@ -0,0 +1,8 @@
.media {
display: flex;
align-items: flex-start;
}
.media-body {
flex: 1;
}

View File

@ -0,0 +1,47 @@
// Toggles
//
// Used in conjunction with global variables to enable certain theme features.
// Vendor
@import "vendor/rfs";
// Deprecate
@import "mixins/deprecate";
// 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";

View File

@ -0,0 +1,239 @@
// .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
.modal-open {
// Kill the scroll on the body
overflow: hidden;
.modal {
overflow-x: hidden;
overflow-y: auto;
}
}
// Container that the modal scrolls within
.modal {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal;
display: none;
width: 100%;
height: 100%;
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
}
// 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 & {
@include transition($modal-transition);
transform: $modal-fade-transform;
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
}
.modal-dialog-scrollable {
display: flex; // IE10/11
max-height: subtract(100%, $modal-dialog-margin * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11
overflow: hidden;
}
.modal-header,
.modal-footer {
flex-shrink: 0;
}
.modal-body {
overflow-y: auto;
}
}
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: subtract(100%, $modal-dialog-margin * 2);
// Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
&::before {
display: block; // IE10
height: subtract(100vh, $modal-dialog-margin * 2);
content: "";
}
// Ensure `.modal-body` shows scrollbar (IE10/11)
&.modal-dialog-scrollable {
flex-direction: column;
justify-content: center;
height: 100%;
.modal-content {
max-height: none;
}
&::before {
content: none;
}
}
}
// 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
color: $modal-content-color;
pointer-events: auto;
background-color: $modal-content-bg;
background-clip: padding-box;
border: $modal-content-border-width solid $modal-content-border-color;
@include border-radius($modal-content-border-radius);
@include box-shadow($modal-content-box-shadow-xs);
// Remove focus outline from opened modal
outline: 0;
}
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal-backdrop;
width: 100vw;
height: 100vh;
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;
@include border-top-radius($modal-content-inner-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-y) (-$modal-header-padding-x) (-$modal-header-padding-y) 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 there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: $modal-inner-padding;
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-wrap: wrap;
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 - $modal-footer-margin-between / 2;
border-top: $modal-footer-border-width solid $modal-footer-border-color;
@include border-bottom-radius($modal-content-inner-border-radius);
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
// stylelint-disable-next-line selector-max-universal
> * {
margin: $modal-footer-margin-between / 2;
}
}
// 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
@include 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-scrollable {
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
}
}
.modal-dialog-centered {
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
&::before {
height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
}
}
.modal-content {
@include box-shadow($modal-content-box-shadow-sm-up);
}
.modal-sm { max-width: $modal-sm; }
}
@include media-breakpoint-up(lg) {
.modal-lg,
.modal-xl {
max-width: $modal-lg;
}
}
@include media-breakpoint-up(xl) {
.modal-xl { max-width: $modal-xl; }
}

View File

@ -0,0 +1,120 @@
// Base class
//
// Kickstart any navigation component with a set of style resets. Works with
// `<nav>`s, `<ul>`s or `<ol>`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;
@include hover-focus() {
text-decoration: none;
}
// Disabled state lightens text
&.disabled {
color: $nav-link-disabled-color;
pointer-events: none;
cursor: default;
}
}
//
// 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;
@include border-top-radius($nav-tabs-border-radius);
@include 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
@include border-top-radius(0);
}
}
//
// Pills
//
.nav-pills {
.nav-link {
@include 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;
}
}

View File

@ -0,0 +1,324 @@
// 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-flex-properties {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
.container,
.container-fluid {
@extend %container-flex-properties;
}
@each $breakpoint, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
@extend %container-flex-properties;
}
}
}
// 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;
@include font-size($navbar-brand-font-size);
line-height: inherit;
white-space: nowrap;
@include 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;
@include 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
@include border-radius($navbar-toggler-border-radius);
@include hover-focus() {
text-decoration: none;
}
}
// 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} {
@include media-breakpoint-down($breakpoint) {
%container-navbar-expand-#{$breakpoint} {
padding-right: 0;
padding-left: 0;
}
> .container,
> .container-fluid {
@extend %container-navbar-expand-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-navbar-expand-#{$breakpoint};
}
}
}
@include 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-nesting-#{$breakpoint} {
flex-wrap: nowrap;
}
> .container,
> .container-fluid {
@extend %container-nesting-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-nesting-#{$breakpoint};
}
}
.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-brand-color;
@include hover-focus() {
color: $navbar-light-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-light-color;
@include 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: escape-svg($navbar-light-toggler-icon-bg);
}
.navbar-text {
color: $navbar-light-color;
a {
color: $navbar-light-active-color;
@include hover-focus() {
color: $navbar-light-active-color;
}
}
}
}
// White links against a dark background
.navbar-dark {
.navbar-brand {
color: $navbar-dark-brand-color;
@include hover-focus() {
color: $navbar-dark-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-dark-color;
@include 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: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {
color: $navbar-dark-color;
a {
color: $navbar-dark-active-color;
@include hover-focus() {
color: $navbar-dark-active-color;
}
}
}
}

View File

@ -0,0 +1,73 @@
.pagination {
display: flex;
@include list-unstyled();
@include 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: 3;
outline: $pagination-focus-outline;
box-shadow: $pagination-focus-box-shadow;
}
}
.page-item {
&:first-child {
.page-link {
margin-left: 0;
@include border-left-radius($border-radius);
}
}
&:last-child {
.page-link {
@include border-right-radius($border-radius);
}
}
&.active .page-link {
z-index: 3;
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 {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
}

View File

@ -0,0 +1,170 @@
.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.
@include reset-text();
@include 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;
@include border-radius($popover-border-radius);
@include box-shadow($popover-box-shadow);
.arrow {
position: absolute;
display: block;
width: $popover-arrow-width;
height: $popover-arrow-height;
margin: 0 $popover-border-radius;
&::before,
&::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-popover-top {
margin-bottom: $popover-arrow-height;
> .arrow {
bottom: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
bottom: 0;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-outer-color;
}
&::after {
bottom: $popover-border-width;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-color;
}
}
}
.bs-popover-right {
margin-left: $popover-arrow-height;
> .arrow {
left: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
left: 0;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-outer-color;
}
&::after {
left: $popover-border-width;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-color;
}
}
}
.bs-popover-bottom {
margin-top: $popover-arrow-height;
> .arrow {
top: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
top: 0;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
border-bottom-color: $popover-arrow-outer-color;
}
&::after {
top: $popover-border-width;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
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: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
right: 0;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
border-left-color: $popover-arrow-outer-color;
}
&::after {
right: $popover-border-width;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
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
@include 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%);
@include border-top-radius($popover-inner-border-radius);
&:empty {
display: none;
}
}
.popover-body {
padding: $popover-body-padding-y $popover-body-padding-x;
color: $popover-body-color;
}

View File

@ -0,0 +1,141 @@
// stylelint-disable declaration-no-important, selector-no-qualifying-type
// Source: https://github.com/h5bp/main.css/blob/master/src/_print.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:
// https://web.archive.org/web/20180815150934/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
}
}

View File

@ -0,0 +1,46 @@
// Disable animation if transitions are disabled
@if $enable-transitions {
@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
@include font-size($progress-font-size);
background-color: $progress-bg;
@include border-radius($progress-border-radius);
@include box-shadow($progress-box-shadow);
}
.progress-bar {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
color: $progress-bar-color;
text-align: center;
white-space: nowrap;
background-color: $progress-bar-bg;
@include transition($progress-bar-transition);
}
.progress-bar-striped {
@include gradient-striped();
background-size: $progress-height $progress-height;
}
@if $enable-transitions {
.progress-bar-animated {
animation: progress-bar-stripes $progress-bar-animation-timing;
@if $enable-prefers-reduced-motion-media-query {
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
}
}

View File

@ -0,0 +1,482 @@
// 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. 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
-webkit-tap-highlight-color: rgba($black, 0); // 5
}
// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
// TODO: remove in v5
// stylelint-disable-next-line selector-list-comma-newline-after
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
// 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 `inherit` value on things like `<th>` elements.
body {
margin: 0; // 1
font-family: $font-family-base;
@include 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
}
// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline
// on elements that programmatically receive focus but wouldn't normally show a visible
// focus outline. In general, this would mean that the outline is only applied if the
// interaction that led to the element receiving programmatic focus was a keyboard interaction,
// or the browser has somehow determined that the user is primarily a keyboard user and/or
// wants focus outlines to always be presented.
//
// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/
[tabindex="-1"]:focus:not(:focus-visible) {
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-next-line selector-list-comma-newline-after
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: $headings-margin-bottom;
}
// 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. Duplicate behavior to the data-* attribute for our tooltip plugin
// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
// 3. Add explicit cursor to indicate changed behavior.
// 4. Remove the bottom border in Firefox 39-.
// 5. Prevent the text-decoration to be skipped.
abbr[title],
abbr[data-original-title] { // 1
text-decoration: underline; // 2
text-decoration: underline dotted; // 2
cursor: help; // 3
border-bottom: 0; // 4
text-decoration-skip-ink: none; // 5
}
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;
}
b,
strong {
font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari
}
small {
@include 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;
@include 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.
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// 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]) {
color: inherit;
text-decoration: none;
@include hover() {
color: inherit;
text-decoration: none;
}
}
//
// Code
//
pre,
code,
kbd,
samp {
font-family: $font-family-monospace;
@include 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;
}
//
// 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 {
// Workaround for the SVG overflow bug in IE10/11 is still required.
// See https://github.com/twbs/bootstrap/issues/26878
overflow: hidden;
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 {
// stylelint-disable-next-line property-blacklist
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;
@include 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
}
// Remove the inheritance of word-wrap in Safari.
//
// Details at https://github.com/twbs/bootstrap/issues/24990
select {
word-wrap: normal;
}
// 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,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
}
// Opinionated: add "hand" cursor to non-disabled button elements.
@if $enable-pointer-cursor-for-buttons {
button,
[type="button"],
[type="reset"],
[type="submit"] {
&:not(:disabled) {
cursor: pointer;
}
}
}
// 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;
@include 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 in Chrome and Safari on macOS.
//
[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;
}

View File

@ -0,0 +1,20 @@
// Do not forget to update getting-started/theming.md!
: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)};
}

View File

@ -0,0 +1,55 @@
//
// Rotating border
//
@keyframes spinner-border {
to { transform: rotate(360deg); }
}
.spinner-border {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: text-bottom;
border: $spinner-border-width solid currentColor;
border-right-color: transparent;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
animation: spinner-border .75s linear infinite;
}
.spinner-border-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
border-width: $spinner-border-width-sm;
}
//
// Growing circle
//
@keyframes spinner-grow {
0% {
transform: scale(0);
}
50% {
opacity: 1;
}
}
.spinner-grow {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: text-bottom;
background-color: currentColor;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
opacity: 0;
animation: spinner-grow .75s linear infinite;
}
.spinner-grow-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
}

View File

@ -0,0 +1,185 @@
//
// Basic Bootstrap table
//
.table {
width: 100%;
margin-bottom: $spacer;
color: $table-color;
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;
}
}
//
// 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 {
@include hover() {
color: $table-hover-color;
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 {
@include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));
}
@include 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(#{$table-striped-order}) {
background-color: $table-dark-accent-bg;
}
}
&.table-hover {
tbody tr {
@include hover() {
color: $table-dark-hover-color;
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} {
@include media-breakpoint-down($breakpoint) {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
// Prevent double border on horizontal scroll due to use of `display: block;`
> .table-bordered {
border: 0;
}
}
}
}
}

View File

@ -0,0 +1,44 @@
.toast {
max-width: $toast-max-width;
overflow: hidden; // cheap rounded corners on nested items
@include font-size($toast-font-size);
color: $toast-color;
background-color: $toast-background-color;
background-clip: padding-box;
border: $toast-border-width solid $toast-border-color;
box-shadow: $toast-box-shadow;
backdrop-filter: blur(10px);
opacity: 0;
@include border-radius($toast-border-radius);
&:not(:last-child) {
margin-bottom: $toast-padding-x;
}
&.showing {
opacity: 1;
}
&.show {
display: block;
opacity: 1;
}
&.hide {
display: none;
}
}
.toast-header {
display: flex;
align-items: center;
padding: $toast-padding-y $toast-padding-x;
color: $toast-header-color;
background-color: $toast-header-background-color;
background-clip: padding-box;
border-bottom: $toast-border-width solid $toast-header-border-color;
}
.toast-body {
padding: $toast-padding-x; // apply to both vertical and horizontal
}

View File

@ -0,0 +1,115 @@
// 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.
@include reset-text();
@include 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;
@include border-radius($tooltip-border-radius);
}

View File

@ -0,0 +1,20 @@
.fade {
@include transition($transition-fade);
&:not(.show) {
opacity: 0;
}
}
.collapse {
&:not(.show) {
display: none;
}
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
@include transition($transition-collapse);
}

View File

@ -0,0 +1,125 @@
// 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 { @include font-size($h1-font-size); }
h2, .h2 { @include font-size($h2-font-size); }
h3, .h3 { @include font-size($h3-font-size); }
h4, .h4 { @include font-size($h4-font-size); }
h5, .h5 { @include font-size($h5-font-size); }
h6, .h6 { @include font-size($h6-font-size); }
.lead {
@include font-size($lead-font-size);
font-weight: $lead-font-weight;
}
// Type display classes
.display-1 {
@include font-size($display1-size);
font-weight: $display1-weight;
line-height: $display-line-height;
}
.display-2 {
@include font-size($display2-size);
font-weight: $display2-weight;
line-height: $display-line-height;
}
.display-3 {
@include font-size($display3-size);
font-weight: $display3-weight;
line-height: $display-line-height;
}
.display-4 {
@include 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 {
@include font-size($small-font-size);
font-weight: $font-weight-normal;
}
mark,
.mark {
padding: $mark-padding;
background-color: $mark-bg;
}
//
// Lists
//
.list-unstyled {
@include list-unstyled();
}
// Inline turns list items into inline-block
.list-inline {
@include list-unstyled();
}
.list-inline-item {
display: inline-block;
&:not(:last-child) {
margin-right: $list-inline-padding;
}
}
//
// Misc
//
// Builds on `abbr`
.initialism {
@include font-size(90%);
text-transform: uppercase;
}
// Blockquotes
.blockquote {
margin-bottom: $spacer;
@include font-size($blockquote-font-size);
}
.blockquote-footer {
display: block;
@include font-size($blockquote-small-font-size);
color: $blockquote-small-color;
&::before {
content: "\2014\00A0"; // em dash, nbsp
}
}

View File

@ -0,0 +1,17 @@
@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/overflow";
@import "utilities/position";
@import "utilities/screenreaders";
@import "utilities/shadows";
@import "utilities/sizing";
@import "utilities/stretched-link";
@import "utilities/spacing";
@import "utilities/text";
@import "utilities/visibility";

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*!
* Bootstrap Grid v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
html {
box-sizing: border-box;
-ms-overflow-style: scrollbar;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
@import "functions";
@import "variables";
@import "mixins/breakpoints";
@import "mixins/grid-framework";
@import "mixins/grid";
@import "grid";
@import "utilities/display";
@import "utilities/flex";
@import "utilities/spacing";

View File

@ -0,0 +1,12 @@
/*!
* Bootstrap Reboot v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "reboot";

View File

@ -0,0 +1,44 @@
/*!
* Bootstrap v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "root";
@import "reboot";
@import "type";
@import "images";
@import "code";
@import "grid";
@import "tables";
@import "forms";
@import "buttons";
@import "transitions";
@import "dropdown";
@import "button-group";
@import "input-group";
@import "custom-forms";
@import "nav";
@import "navbar";
@import "card";
@import "breadcrumb";
@import "pagination";
@import "badge";
@import "jumbotron";
@import "alert";
@import "progress";
@import "media";
@import "list-group";
@import "close";
@import "toasts";
@import "modal";
@import "tooltip";
@import "popover";
@import "carousel";
@import "spinners";
@import "utilities";
@import "print";

View File

@ -0,0 +1,13 @@
@mixin alert-variant($background, $border, $color) {
color: $color;
@include gradient-bg($background);
border-color: $border;
hr {
border-top-color: darken($border, 5%);
}
.alert-link {
color: darken($color, 10%);
}
}

View File

@ -0,0 +1,22 @@
// stylelint-disable declaration-no-important
// Contextual backgrounds
@mixin bg-variant($parent, $color, $ignore-warning: false) {
#{$parent} {
background-color: $color !important;
}
a#{$parent},
button#{$parent} {
@include hover-focus() {
background-color: darken($color, 10%) !important;
}
}
@include deprecate("The `bg-variant` mixin", "v4.4.0", "v5", $ignore-warning);
}
@mixin bg-gradient-variant($parent, $color) {
#{$parent} {
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
}
}

View File

@ -0,0 +1,17 @@
@mixin badge-variant($bg) {
color: color-yiq($bg);
background-color: $bg;
@at-root a#{&} {
@include hover-focus() {
color: color-yiq($bg);
background-color: darken($bg, 10%);
}
&:focus,
&.focus {
outline: 0;
box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);
}
}
}

View File

@ -0,0 +1,63 @@
// stylelint-disable property-blacklist
// Single side border-radius
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
@if $enable-rounded {
border-radius: $radius;
}
@else if $fallback-border-radius != false {
border-radius: $fallback-border-radius;
}
}
@mixin border-top-radius($radius) {
@if $enable-rounded {
border-top-left-radius: $radius;
border-top-right-radius: $radius;
}
}
@mixin border-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: $radius;
border-bottom-right-radius: $radius;
}
}
@mixin border-bottom-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
}
}
@mixin border-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: $radius;
border-bottom-left-radius: $radius;
}
}
@mixin border-top-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: $radius;
}
}
@mixin border-top-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: $radius;
}
}
@mixin border-bottom-right-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: $radius;
}
}
@mixin border-bottom-left-radius($radius) {
@if $enable-rounded {
border-bottom-left-radius: $radius;
}
}

View File

@ -0,0 +1,20 @@
@mixin box-shadow($shadow...) {
@if $enable-shadows {
$result: ();
@if (length($shadow) == 1) {
// We can pass `@include box-shadow(none);`
$result: $shadow;
} @else {
// Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;`
@for $i from 1 through length($shadow) {
@if nth($shadow, $i) != "none" {
$result: append($result, nth($shadow, $i), "comma");
}
}
}
@if (length($result) > 0) {
box-shadow: $result;
}
}
}

Some files were not shown because too many files have changed in this diff Show More