First website draft

This commit is contained in:
DeathByDenim 2023-05-26 11:30:43 -04:00
parent 99788087a4
commit cfc422b30d
Signed by: DeathByDenim
GPG Key ID: 4A475283D925365B
247 changed files with 19974 additions and 0 deletions

20
_config.yml Normal file
View File

@ -0,0 +1,20 @@
title: "onFOSS"
description: >
onFOSS is an online, "Free (as Freedom) and Open Source" LAN-Party. The goal is to get people together, enjoying the art of computer games and having a great time in these days. The FOSS community is a place of being open minded and acceptance to all different kinds of people with the focus of fully transparent systems and protecting individuals. So it does not matter if you are on Windows, Mac or Linux and it is also NOT necessary to have a PC MASTERRACE setup to run those games.
url: https://onfoss.org
content:
domain_name: "onfoss.org"
play_domain_name: "play.onfoss.org"
ssl: true
defaults:
-
scope:
path: ""
type: "posts"
values:
layout: "post"
plugins:
- jekyll-feed

99
_data/events.yml Normal file
View File

@ -0,0 +1,99 @@
- date: 2023-05-06T12:00:00UTC
intro: "onFOSS-LAN hosted by hribhrib"
games:
- time: "12:00"
title: "Get and chill together"
- time: "13:00"
title: "OpenSpades"
- time: "14:30"
title: "Blockbomber"
- time: "15:30"
title: "Break"
- time: "16:00"
title: "Xonotic"
tournament: true
- time: "18:00"
title: "Break"
- time: "18:30"
title: "OpenHV"
- time: "20:00"
title: "Mindustry"
- date: 2022-12-17T14:00:00UTC
intro: "onFOSS-LAN hosted by DeathByDenim"
games:
- time: "14:00"
title: "Get together"
- time: "14:30"
title: "Doom (ODAMEX) XMAS mod"
- time: "15:15"
title: "Teeworlds"
- time: "16:00"
title: "OpenSpades"
- time: "17:00"
title: "Break"
- time: "18:00"
title: "Lix"
- time: "18:30"
title: "Free Play!"
extras: ["Shattered Paradise"]
- date: 2022-07-02T14:00:00UTC
intro: "onFOSS-LAN hosted by DeathByDenim"
games:
- time: "14:00"
title: "OpenSoldat"
- time: "15:00"
title: "Lix"
- time: "16:00"
title: "Teeworlds DDrace"
- time: "17:00"
title: "Free play!"
extras: ["OpenSpades", "OpenHV"]
- date: 2022-03-19T14:00:00UTC
intro: "onFOSS-LAN hosted by DeathByDenim"
games:
- time: "14:00"
title: "Armagetron Advanced"
- time: "15:00"
title: "Xonotic - Battle Royale"
- time: "16:00"
title: "Lix"
- time: "16:30"
title: "Free play!"
extras: ["Hedgewars", "SuperTuxKart (Race and Soccer modes)"]
content: |
<p>
Additionally, there was a fundraiser to help the people suffering
from the war in Ukraine &#x1F1FA;&#x1F1E6;. I matched your donation
(up to $500 total) and additionally, the government of Canada
&#x1F1E8;&#x1F1E6; will match mine until 18 March. So, that's triple
the value for any donation you make. It doesn't have to be to the
Canadian Red Cross, you probably have a local equivalent.
</p>
<p>
<em>UPDATE (2022-03-08)</em>: Canada reached the $10M already so they are not
doubling anymore. I'll still double but this means your amount won't
count as triple anymore.
</p>
<p>
<em>UPDATE (2022-03-13)</em>: Canada increased the limit to $30M, so
any donation you make is once again tripled.
</p>
<p>
<em>UPDATE (2022-03-14)</em>: Oh, never mind, this goal has already
been reached. Anyway, I'll still match what you donate!
</p>
<p>
<em>UPDATE (2022-03-19)</em>: Donations are closed. A total amount
of &euro;40 was collected and the equivalent of CAD 55.64 was
donated to the Canadian Red Cross.
</p>
<p>List of donations:</p>
<ul>
<li>Anonymous: &euro;40</li>
</ul>
- date: 2022-02-12T15:00UTC
intro: "Session to test if it all works as intended"
games:
- title: "OpenSpades"
- title: "OpenHV"
- title: "Xonotic"

118
_data/games.yml Normal file
View File

@ -0,0 +1,118 @@
- name: armagetron
title: "Armagetron Advanced"
description: "Drive your lightcycle and leave a lightwall behind you. Survive as long as you can and try to make other run into walls."
download_link: "http://www.armagetronad.org/downloads.php"
has_console: true
console_output_coloring: "Terminal"
console_initial_command: "players"
console_help_link: "http://wiki.armagetronad.org/index.php?title=Console_Commands"
console_example_commands:
- ["players", "Show current players"]
- ["kick <name>", "Kick the player"]
- ["num_ais <num>", "Set the number of AIs for games with more than one player"]
- ["limit_rounds", "End the match after this number of rounds"]
- name: bzflag
title: "Bzflag"
description: "Drive around in a tank that can jump, trying to shoot your opponents while dodging their bullets."
download_link: "https://www.bzflag.org/downloads/"
has_console: true
console_output_coloring: "Terminal"
console_initial_command: "/playerlist"
console_help_link: "https://wiki.bzflag.org/Slash_Commands"
console_example_commands:
- ["/playerlist", "Display list of players"]
- ["/kick <name>", "Kick the player"]
- ["/gameover", "end the current game"]
- name: hedgewars
title: "Hedgewars"
description: "Worms-like game where your team of hedgehogs needs to destroy the other teams using the ludicrous arsenal at their disposal."
download_link: "https://www.hedgewars.org/download.html"
- name: lix
title: "Lix"
description: "Lemmings-like game where you need to guide your little people to safety despite their best efforts of wandering into things that will kill them."
download_link: "https://github.com/SimonN/LixD#get-lix"
- name: mindustry
title: "Mindustry"
description: "A building and tower defence game where you build up an industry and defences against ever larger waves of enemies."
download_link: "https://github.com/Anuken/Mindustry/releases"
has_console: true
console_output_coloring: "Terminal"
console_initial_command: "status"
console_help_link: "https://mindustrygame.github.io/wiki/servers/#dedicated-server-commands"
console_example_commands:
- ["status", "Display server status"]
- ["runwave", "Trigger the next wave"]
- ["kick <name>", "Kick a person by name"]
- name: minetest
title: "Minetest (Blockbomber)"
description: "The classic Bomberman game in 3D as a mod for Minetest"
download_link: "https://www.minetest.net/downloads/"
- name: odamex
title: "Odamex"
description: "Multiplayer-focused DOOM engine that allows deathmatch, coop, and capture the flag mode. Here we are using the Freedom assets so you don't need a copy of the original game to play."
download_link: "https://odamex.net/"
- name: openhv
title: "OpenHV"
description: "Real-time strategy game where you mine resources and build units to attack and defend."
download_link: "https://github.com/OpenHV/OpenHV/releases"
- name: openspades
title: "OpenSpades"
description: "Mix between a first person shooter and Minecraft. Build defence structures, dig many tunnels or go on the offensive."
warning: "uses potentially non-open assets. Fix is <a href=\"help_openspades.html#nonfreeassets\"> here</a>."
download_link: "https://github.com/yvt/openspades/releases"
- name: shatteredparadise
title: "Shattered Paradise"
description: "Real-time strategy game where you mine resources and build units to attack and defend."
download_link: "https://github.com/ABrandau/Shattered-Paradise-SDK/releases"
- name: opensoldat
title: "OpenSoldat"
description: "Fast-paced 2D side-scrolling shooter game where you have a big gun and a jetpack."
download_link: "https://github.com/opensoldat/opensoldat/releases/"
- name: supertuxkart
title: "SuperTuxKart"
description: "Kart racing game where you can use the various power-ups to give yourself a boost of hinder your opponents."
download_link: "https://supertuxkart.net/Download"
- name: supertuxparty
title: "Super Tux Party"
description: "Turn-based party game where you challenge other player in real-time mini games."
download_link: "https://supertux.party/download/latest/"
- name: teeworlds
title: "Teeworlds"
description: "Fast-paced 2D side-scrolling shooter game where you have a big gun and a grappling hook."
download_link: "https://www.teeworlds.com/?page=downloads"
has_console: true
console_output_coloring: "Terminal"
console_initial_command: "status"
console_help_link: "https://www.teeworlds.com/?page=docs&wiki=server_commands"
console_example_commands:
- ["status", "Display server status"]
- ["change_map <mapname>", "Switch to <mapname>"]
- ["kick <id>", "Kick a person by id"]
- name: ufoai
title: "UFO: Alien Invasion"
description: "Squad-based turn-based tactical strategy game in the tradition of the old X-COM PC games"
download_link: "https://ufoai.org/wiki/Download"
- name: unvanquished
title: "Unvanquished"
description: "First-person shooter of aliens vs humans. There are several classes and it's possible to build structures."
download_link: "https://unvanquished.net/download/"
has_console: true
console_output_coloring: "Daemoned"
console_initial_command: "/status"
console_help_link: "https://wiki.unvanquished.net/wiki/Server/Running#Commands"
console_example_commands:
- ["/listplayers", "List current players in-game"]
- ["/kick <name>", "Kick the player"]
- ["/nextmap", "Go to the next map in the rotation"]
- name: xonotic
title: "Xonotic"
description: "First-person shooter where players compete in a 3D world. It features Battle Royale mode."
download_link: "https://xonotic.org/download/"
has_console: true
console_output_coloring: "Daemoned"
console_initial_command: "who"
console_help_link: "https://gitlab.com/xonotic/xonotic/-/wikis/Basic-server-configuration"
console_example_commands:
- ["who", "List current players in-game"]
- ["kick <name>", "Kick the player"]
- ["gotomap <name>", "Go to the specified map"]

29
_includes/event.html Normal file
View File

@ -0,0 +1,29 @@
<h4>{{ event.date | date: "%A %d %B %Y, %H:%M %Z" }}</h4>
<script>
var event_year = {{ event.date | date: "%Y" }};
var event_month = {{ event.date | date: "%-m" }};
var event_day = {{ event.date | date: "%e" }};
var d = new Date(Date.UTC(event_year, event_month, event_day, {{ event.date | date: "%H" }}, {{ event.date | date: "%M" }}));
document.writeln("<p>(Local time: "+d.toTimeString()+")</p>")
</script>
{% if event.intro %}
<p>{{ event.intro }}</p>
{% endif %}
<ul>
{% for game in event.games %}
{% assign time = game.time | split: ":"%}
{% if game.time %}
<li>{{ game.time }}UTC {{ game.title }}{%if game.tournament %} <a href="tournament.html" class="game-tournament">Tournament</a>{% endif %}<script>d=new Date(Date.UTC(event_year, event_month, event_day, {{ time | slice: 0 }}, {{ time | slice: 1 }}));document.writeln(" ("+ Intl.DateTimeFormat(undefined, {hour: '2-digit', minute: '2-digit', timeZoneName: 'short'}).format(d) + ")")</script></li>
{% else %}
<li>{{ game.title }}{%if game.tournament %} <a href="tournament.html" class="game-tournament">Tournament</a>{% endif %}</li>
{% endif %}
{% if game.extras %}
<ul>
{% for extra in game.extras %}
<li>{{ extra }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
{{ event.content }}

28
_includes/nav.html Normal file
View File

@ -0,0 +1,28 @@
<nav class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<img class="bi me-2" width="40" height="32" src="/assets/img/icon.svg" alt="Site icon">
<span class="fs-4">onFOSS</span>
</a>
<ul class="nav nav-pills">
{% if layout.nav_pill %}
{% assign nav_pill = layout.nav_pill %}
{% else %}
{% assign nav_pill = page.nav_pill %}
{% endif %}
{% case nav_pill %}
{% when "tournament", "news", "schedule", "help", "resources" %}
{% assign home = false %}
{% else %}
{% assign home = true %}
{% endcase %}
<li class="nav-item"><a href="/index.html" class="nav-link {% if home %}active{% endif %}" aria-current="page">Home</a></li>
<li class="nav-item"><a href="/news.html" class="nav-link {% if nav_pill == "news" %}active{% endif %}">News</a></li>
<li class="nav-item"><a href="/tournament.html" class="nav-link {% if nav_pill == "tournament" %}active{% endif %}">Tournament</a></li>
<li class="nav-item"><a href="/schedule.html" class="nav-link {% if nav_pill == "schedule" %}active{% endif %}">Schedule</a></li>
<li class="nav-item"><a href="/help.html" class="nav-link {% if nav_pill == "help" %}active{% endif %}">Help</a></li>
<li class="nav-item"><a href="/resources.html" class="nav-link {% if nav_pill == "resources" %}active{% endif %}">Resources</a></li>
</ul>
</header>
</nav>

18
_layouts/default.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>onFOSS</title>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="icon" href="/assets/img/icon.svg" sizes="any" type="image/svg+xml">
<link rel="alternate" type="application/rss+xml" title="{{ site.content.domain_name }}" href="/feed.xml">
</head>
<body>
{% include nav.html %}
<div class="container">
{{ content }}
</div>
</body>
</html>

15
_layouts/help.html Normal file
View File

@ -0,0 +1,15 @@
---
layout: default
nav_pill: help
---
<link rel="stylesheet" href="assets/css/help.css">
{% assign game = site.data.games | where_exp: "item", "item.name == page.game" | first %}
<h1>{{ game.title }}</h1>
<p>{{ game.description }}</p>
<figure class="figure">
<img src="assets/img/{{ game.name }}.png" alt="Screenshot of {{ game.title }}">
</figure>
<h2>Getting the game</h2>
<div class="download"><a href="{{ game.download_link }}">DOWNLOAD</a></div>
{{ content }}
<p></p>

8
_layouts/post.html Normal file
View File

@ -0,0 +1,8 @@
---
layout: default
nav_pill: news
---
<h1>{{ page.title }}</h1>
<p><strong>{{ post.date | date_to_string }}{% if post.author %} by {{ post.author }}{% endif %}</strong></p>
{{ content }}

View File

@ -0,0 +1,47 @@
---
layout: post
title: "onFOSS: The next generation!"
category: news
---
The "onFOSS-LAN" started as an idea by [hribhrib](https://hribhrib.at) to host a LAN-party-like experience online. Yes, the pun with LAN instead of WAN-party was intended but didn't ripe well, however, what instead did ripe well was the whole Event! Only one year after the first public onFOSS-LAN another host joined the team: [DeathByDenim](http://jarno.ca/). Even more people got together to bring this experience to everyone that was interested in FOSS-Gaming, and group-effort hosting started to sprout, mostly by people of the [LibreGaming](https://libregaming.org/) community.
## Rebranding
To bring the onFOSS-LAN to another level, we announce some changes!
### Changing the name
The onFOSS-LAN will be further renamed to just "onFOSS", also to sound more modern and, furthermore, don't confuse the people with the LAN-pun anymore. Although there were heated discussions about it ;)
### Domain onFOSS.org
One problem persisted, that all the resources and information were spread out with no common "place to go", therefore the [onFOSS.org](https://onfoss.org) Domain was acquired to bring everyone to the same point.
### Making a brand
Also, to support the idea of bringing the people together and bring one uniform branding for every host and advertiser to be recognized, there is an effort to provide media for branding anything. For example, there will be Logos, Icons, Banner,... for everyone to use!
## Restructuring
onFOSS.org will be the new place to go with all the information about the event and further links to all resources and communication channels. Here is a draft of the planned structure in an image:
![Planned Structure](/assets/img/2023-05-24-planned-structure.svg){:class="img-fluid"}
### The Main page
The main-page of [onFOSS.org](https://onfoss.org) will be there for general information, resources, lists of supporters, and further links. Also, the blog that you currently read will also be there. This site will be used for all static and general information.
### The Live page
The famous "play." subdomain, that already was used as the landing page of a current hosted onFOSS, will be stripped down to only have relevant information about the current event like timetable and tournament info. All the redundant information will be elevated into the main page.
## Social Platforms
Another issue was the reachability of the upcoming onFOSS events. Although, there was a XMPP/Matrix channel from provided by the community, it was hard to reach out to new people. Thanks to poVoq over at [FreeGameDev](https://freegamedev.net/) there is now a proper bridged channel which also supports IRC in addition. In addition to that, onFOSS is now providing a RSS-feed (also already this post) to build a foundation for further automation of announcements.
### Mastodon
There will also be a onFOSS representation on a Mastodon instance (Probably: https://floss.social/) to reach out further.
### PeerTube
There were already some videos made from footage of onFOSS events, however again, spread out and not findable anymore once one lost the link. Therefore, we happily announce an official onFOSS video channel on (TBA)
### Unofficial
Due to RSS, the community can make automated announcements on their own that bring further visibility outside the onFOSS-bubble. For example, there is a Discord-Server just for the announcements and not bridged to the main communication channel due to privacy and proprietary concerns, but if someone prefers to get notified over there this is now also possible.
## What now?
This is just the beginning of a new era of onFOSS and be hyped for further events! If you want to help somehow just get in contact with us, otherwise, subscribe to our many channels and stay tuned for the next Host to prepare the next event!
## THANK YOU ALL! <3
Concluding the first official blog-post with the most important stuff: Thank you all for supporting the event in any form, and thank you all for the numerous participants of all events! Without you people, this whole event wouldn't exist, and we wouldn't write this post here. So thank you all and see you on the next onFOSS!

71
_sass/base.scss Normal file
View File

@ -0,0 +1,71 @@
// Custom style matching https://onfoss.libregaming.org/
//$primary: darkorange;
//$secondary: red;
//$body-bg: black;
//$body-color: orange;
//$warning: yellow;
//$font-family-base: Ubuntu Mono, monospace;
//$link-color: #4FBAD5;
//$dark: darkorange;
//$nav-pills-link-active-color: darkblue;
//$nav-pills-link-active-bg: darkorange;
// If you want to provide the Ubuntu font, place those font files in assets/css/font
///* ubuntu-mono-regular - latin */
//@font-face {
//font-family: 'Ubuntu Mono';
//font-style: normal;
//font-weight: 400;
//src: url('font/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
//src: local(''),
//url('font/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
//url('font/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
//url('font/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
//url('font/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
//url('font/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
//}
///* ubuntu-mono-italic - latin */
//@font-face {
//font-family: 'Ubuntu Mono';
//font-style: italic;
//font-weight: 400;
//src: url('font/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
//src: local(''),
//url('font/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
//url('font/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
//url('font/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
//url('font/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
//url('font/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
//}
///* ubuntu-mono-700 - latin */
//@font-face {
//font-family: 'Ubuntu Mono';
//font-style: normal;
//font-weight: 700;
//src: url('font/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
//src: local(''),
//url('font/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
//url('font/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
//url('font/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
//url('font/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
//url('font/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
//}
///* ubuntu-mono-700italic - latin */
//@font-face {
//font-family: 'Ubuntu Mono';
//font-style: italic;
//font-weight: 700;
//src: url('font/ubuntu-mono-v14-latin-700italic.eot'); /* IE9 Compat Modes */
//src: local(''),
//url('font/ubuntu-mono-v14-latin-700italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
//url('font/ubuntu-mono-v14-latin-700italic.woff2') format('woff2'), /* Super Modern Browsers */
//url('font/ubuntu-mono-v14-latin-700italic.woff') format('woff'), /* Modern Browsers */
//url('font/ubuntu-mono-v14-latin-700italic.ttf') format('truetype'), /* Safari, Android, iOS */
//url('font/ubuntu-mono-v14-latin-700italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
//}

View File

@ -0,0 +1,149 @@
//
// Base styles
//
.accordion {
// scss-docs-start accordion-css-vars
--#{$prefix}accordion-color: #{$accordion-color};
--#{$prefix}accordion-bg: #{$accordion-bg};
--#{$prefix}accordion-transition: #{$accordion-transition};
--#{$prefix}accordion-border-color: #{$accordion-border-color};
--#{$prefix}accordion-border-width: #{$accordion-border-width};
--#{$prefix}accordion-border-radius: #{$accordion-border-radius};
--#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
--#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
--#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
--#{$prefix}accordion-btn-color: #{$accordion-button-color};
--#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
--#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
--#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
--#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
--#{$prefix}accordion-btn-focus-border-color: #{$accordion-button-focus-border-color};
--#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
--#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
--#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
--#{$prefix}accordion-active-color: #{$accordion-button-active-color};
--#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
// scss-docs-end accordion-css-vars
}
.accordion-button {
position: relative;
display: flex;
align-items: center;
width: 100%;
padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
@include font-size($font-size-base);
color: var(--#{$prefix}accordion-btn-color);
text-align: left; // Reset button style
background-color: var(--#{$prefix}accordion-btn-bg);
border: 0;
@include border-radius(0);
overflow-anchor: none;
@include transition(var(--#{$prefix}accordion-transition));
&:not(.collapsed) {
color: var(--#{$prefix}accordion-active-color);
background-color: var(--#{$prefix}accordion-active-bg);
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
&::after {
background-image: var(--#{$prefix}accordion-btn-active-icon);
transform: var(--#{$prefix}accordion-btn-icon-transform);
}
}
// Accordion icon
&::after {
flex-shrink: 0;
width: var(--#{$prefix}accordion-btn-icon-width);
height: var(--#{$prefix}accordion-btn-icon-width);
margin-left: auto;
content: "";
background-image: var(--#{$prefix}accordion-btn-icon);
background-repeat: no-repeat;
background-size: var(--#{$prefix}accordion-btn-icon-width);
@include transition(var(--#{$prefix}accordion-btn-icon-transition));
}
&:hover {
z-index: 2;
}
&:focus {
z-index: 3;
border-color: var(--#{$prefix}accordion-btn-focus-border-color);
outline: 0;
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
}
}
.accordion-header {
margin-bottom: 0;
}
.accordion-item {
color: var(--#{$prefix}accordion-color);
background-color: var(--#{$prefix}accordion-bg);
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
&:first-of-type {
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
.accordion-button {
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
}
}
&:not(:first-of-type) {
border-top: 0;
}
// Only set a border-radius on the last item if the accordion is collapsed
&:last-of-type {
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
.accordion-button {
&.collapsed {
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
}
}
.accordion-collapse {
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
}
}
}
.accordion-body {
padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
}
// Flush accordion items
//
// Remove borders and border-radius to keep accordion items edge-to-edge.
.accordion-flush {
.accordion-collapse {
border-width: 0;
}
.accordion-item {
border-right: 0;
border-left: 0;
@include border-radius(0);
&:first-child { border-top: 0; }
&:last-child { border-bottom: 0; }
.accordion-button {
&,
&.collapsed {
@include border-radius(0);
}
}
}
}

View File

@ -0,0 +1,71 @@
//
// Base styles
//
.alert {
// scss-docs-start alert-css-vars
--#{$prefix}alert-bg: transparent;
--#{$prefix}alert-padding-x: #{$alert-padding-x};
--#{$prefix}alert-padding-y: #{$alert-padding-y};
--#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
--#{$prefix}alert-color: inherit;
--#{$prefix}alert-border-color: transparent;
--#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color);
--#{$prefix}alert-border-radius: #{$alert-border-radius};
// scss-docs-end alert-css-vars
position: relative;
padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x);
margin-bottom: var(--#{$prefix}alert-margin-bottom);
color: var(--#{$prefix}alert-color);
background-color: var(--#{$prefix}alert-bg);
border: var(--#{$prefix}alert-border);
@include border-radius(var(--#{$prefix}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: $alert-dismissible-padding-r;
// Adjust close link position
.btn-close {
position: absolute;
top: 0;
right: 0;
z-index: $stretched-link-z-index + 1;
padding: $alert-padding-y * 1.25 $alert-padding-x;
}
}
// scss-docs-start alert-modifiers
// Generate contextual modifier classes for colorizing the alert.
@each $state, $value in $theme-colors {
$alert-background: shift-color($value, $alert-bg-scale);
$alert-border: shift-color($value, $alert-border-scale);
$alert-color: shift-color($value, $alert-color-scale);
@if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {
$alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));
}
.alert-#{$state} {
@include alert-variant($alert-background, $alert-border, $alert-color);
}
}
// scss-docs-end alert-modifiers

View File

@ -0,0 +1,38 @@
// Base class
//
// Requires one of the contextual, color modifier classes for `color` and
// `background-color`.
.badge {
// scss-docs-start badge-css-vars
--#{$prefix}badge-padding-x: #{$badge-padding-x};
--#{$prefix}badge-padding-y: #{$badge-padding-y};
@include rfs($badge-font-size, --#{$prefix}badge-font-size);
--#{$prefix}badge-font-weight: #{$badge-font-weight};
--#{$prefix}badge-color: #{$badge-color};
--#{$prefix}badge-border-radius: #{$badge-border-radius};
// scss-docs-end badge-css-vars
display: inline-block;
padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x);
@include font-size(var(--#{$prefix}badge-font-size));
font-weight: var(--#{$prefix}badge-font-weight);
line-height: 1;
color: var(--#{$prefix}badge-color);
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius(var(--#{$prefix}badge-border-radius));
@include gradient-bg();
// Empty badges collapse automatically
&:empty {
display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}

View File

@ -0,0 +1,40 @@
.breadcrumb {
// scss-docs-start breadcrumb-css-vars
--#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x};
--#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y};
--#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom};
@include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size);
--#{$prefix}breadcrumb-bg: #{$breadcrumb-bg};
--#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius};
--#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color};
--#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x};
--#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color};
// scss-docs-end breadcrumb-css-vars
display: flex;
flex-wrap: wrap;
padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x);
margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom);
@include font-size(var(--#{$prefix}breadcrumb-font-size));
list-style: none;
background-color: var(--#{$prefix}breadcrumb-bg);
@include border-radius(var(--#{$prefix}breadcrumb-border-radius));
}
.breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: var(--#{$prefix}breadcrumb-item-padding-x);
&::before {
float: left; // Suppress inline spacings and underlining of the separator
padding-right: var(--#{$prefix}breadcrumb-item-padding-x);
color: var(--#{$prefix}breadcrumb-divider-color);
content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
}
}
&.active {
color: var(--#{$prefix}breadcrumb-item-active-color);
}
}

View File

@ -0,0 +1,142 @@
// 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
> .btn-check:checked + .btn,
> .btn-check:focus + .btn,
> .btn:hover,
> .btn:focus,
> .btn:active,
> .btn.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 {
@include border-radius($btn-border-radius);
// Prevent double borders when buttons are next to each other
> :not(.btn-check:first-child) + .btn,
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn.dropdown-toggle-split:first-child,
> .btn-group:not(:last-child) > .btn {
@include border-end-radius(0);
}
// The left radius should be 0 if the button is:
// - the "third or more" child
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
> .btn-group:not(:first-child) > .btn {
@include border-start-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,
.dropend &::after {
margin-left: 0;
}
.dropstart &::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 ~ .btn,
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
}

View File

@ -0,0 +1,207 @@
//
// Base styles
//
.btn {
// scss-docs-start btn-css-vars
--#{$prefix}btn-padding-x: #{$btn-padding-x};
--#{$prefix}btn-padding-y: #{$btn-padding-y};
--#{$prefix}btn-font-family: #{$btn-font-family};
@include rfs($btn-font-size, --#{$prefix}btn-font-size);
--#{$prefix}btn-font-weight: #{$btn-font-weight};
--#{$prefix}btn-line-height: #{$btn-line-height};
--#{$prefix}btn-color: #{$body-color};
--#{$prefix}btn-bg: transparent;
--#{$prefix}btn-border-width: #{$btn-border-width};
--#{$prefix}btn-border-color: transparent;
--#{$prefix}btn-border-radius: #{$btn-border-radius};
--#{$prefix}btn-hover-border-color: transparent;
--#{$prefix}btn-box-shadow: #{$btn-box-shadow};
--#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};
--#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);
// scss-docs-end btn-css-vars
display: inline-block;
padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);
font-family: var(--#{$prefix}btn-font-family);
@include font-size(var(--#{$prefix}btn-font-size));
font-weight: var(--#{$prefix}btn-font-weight);
line-height: var(--#{$prefix}btn-line-height);
color: var(--#{$prefix}btn-color);
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null);
user-select: none;
border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);
@include border-radius(var(--#{$prefix}btn-border-radius));
@include gradient-bg(var(--#{$prefix}btn-bg));
@include box-shadow(var(--#{$prefix}btn-box-shadow));
@include transition($btn-transition);
&:hover {
color: var(--#{$prefix}btn-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: var(--#{$prefix}btn-hover-bg);
border-color: var(--#{$prefix}btn-hover-border-color);
}
.btn-check + &:hover {
// override for the checkbox/radio buttons
color: var(--#{$prefix}btn-color);
background-color: var(--#{$prefix}btn-bg);
border-color: var(--#{$prefix}btn-border-color);
}
&:focus-visible {
color: var(--#{$prefix}btn-hover-color);
@include gradient-bg(var(--#{$prefix}btn-hover-bg));
border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
.btn-check:focus-visible + & {
border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
.btn-check:checked + &,
:not(.btn-check) + &:active,
&:first-child:active,
&.active,
&.show {
color: var(--#{$prefix}btn-active-color);
background-color: var(--#{$prefix}btn-active-bg);
// Remove CSS gradients if they're enabled
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-active-border-color);
@include box-shadow(var(--#{$prefix}btn-active-shadow));
&:focus-visible {
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
}
&:disabled,
&.disabled,
fieldset:disabled & {
color: var(--#{$prefix}btn-disabled-color);
pointer-events: none;
background-color: var(--#{$prefix}btn-disabled-bg);
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-disabled-border-color);
opacity: var(--#{$prefix}btn-disabled-opacity);
@include box-shadow(none);
}
}
//
// Alternate buttons
//
// scss-docs-start btn-variant-loops
@each $color, $value in $theme-colors {
.btn-#{$color} {
@if $color == "light" {
@include button-variant(
$value,
$value,
$hover-background: shade-color($value, $btn-hover-bg-shade-amount),
$hover-border: shade-color($value, $btn-hover-border-shade-amount),
$active-background: shade-color($value, $btn-active-bg-shade-amount),
$active-border: shade-color($value, $btn-active-border-shade-amount)
);
} @else if $color == "dark" {
@include button-variant(
$value,
$value,
$hover-background: tint-color($value, $btn-hover-bg-tint-amount),
$hover-border: tint-color($value, $btn-hover-border-tint-amount),
$active-background: tint-color($value, $btn-active-bg-tint-amount),
$active-border: tint-color($value, $btn-active-border-tint-amount)
);
} @else {
@include button-variant($value, $value);
}
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-outline-variant($value);
}
}
// scss-docs-end btn-variant-loops
//
// Link buttons
//
// Make a button look and behave like a link
.btn-link {
--#{$prefix}btn-font-weight: #{$font-weight-normal};
--#{$prefix}btn-color: #{$btn-link-color};
--#{$prefix}btn-bg: transparent;
--#{$prefix}btn-border-color: transparent;
--#{$prefix}btn-hover-color: #{$btn-link-hover-color};
--#{$prefix}btn-hover-border-color: transparent;
--#{$prefix}btn-active-color: #{$btn-link-hover-color};
--#{$prefix}btn-active-border-color: transparent;
--#{$prefix}btn-disabled-color: #{$btn-link-disabled-color};
--#{$prefix}btn-disabled-border-color: transparent;
--#{$prefix}btn-box-shadow: none;
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix(color-contrast($primary), $primary, 15%))};
text-decoration: $link-decoration;
@if $enable-gradients {
background-image: none;
}
&:hover,
&:focus-visible {
text-decoration: $link-hover-decoration;
}
&:focus-visible {
color: var(--#{$prefix}btn-color);
}
&:hover {
color: var(--#{$prefix}btn-hover-color);
}
// 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-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
}

234
_sass/bootstrap/_card.scss Normal file
View File

@ -0,0 +1,234 @@
//
// Base styles
//
.card {
// scss-docs-start card-css-vars
--#{$prefix}card-spacer-y: #{$card-spacer-y};
--#{$prefix}card-spacer-x: #{$card-spacer-x};
--#{$prefix}card-title-spacer-y: #{$card-title-spacer-y};
--#{$prefix}card-border-width: #{$card-border-width};
--#{$prefix}card-border-color: #{$card-border-color};
--#{$prefix}card-border-radius: #{$card-border-radius};
--#{$prefix}card-box-shadow: #{$card-box-shadow};
--#{$prefix}card-inner-border-radius: #{$card-inner-border-radius};
--#{$prefix}card-cap-padding-y: #{$card-cap-padding-y};
--#{$prefix}card-cap-padding-x: #{$card-cap-padding-x};
--#{$prefix}card-cap-bg: #{$card-cap-bg};
--#{$prefix}card-cap-color: #{$card-cap-color};
--#{$prefix}card-height: #{$card-height};
--#{$prefix}card-color: #{$card-color};
--#{$prefix}card-bg: #{$card-bg};
--#{$prefix}card-img-overlay-padding: #{$card-img-overlay-padding};
--#{$prefix}card-group-margin: #{$card-group-margin};
// scss-docs-end card-css-vars
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: var(--#{$prefix}card-height);
word-wrap: break-word;
background-color: var(--#{$prefix}card-bg);
background-clip: border-box;
border: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
@include border-radius(var(--#{$prefix}card-border-radius));
@include box-shadow(var(--#{$prefix}card-box-shadow));
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
}
.card-body {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
padding: var(--#{$prefix}card-spacer-y) var(--#{$prefix}card-spacer-x);
color: var(--#{$prefix}card-color);
}
.card-title {
margin-bottom: var(--#{$prefix}card-title-spacer-y);
}
.card-subtitle {
margin-top: calc(-.5 * var(--#{$prefix}card-title-spacer-y)); // stylelint-disable-line function-disallowed-list
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
&:hover {
text-decoration: if($link-hover-decoration == underline, none, null);
}
+ .card-link {
margin-left: var(--#{$prefix}card-spacer-x);
}
}
//
// Optional textual caps
//
.card-header {
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: var(--#{$prefix}card-cap-color);
background-color: var(--#{$prefix}card-cap-bg);
border-bottom: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
&:first-child {
@include border-radius(var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius) 0 0);
}
}
.card-footer {
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
color: var(--#{$prefix}card-cap-color);
background-color: var(--#{$prefix}card-cap-bg);
border-top: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
&:last-child {
@include border-radius(0 0 var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius));
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
margin-bottom: calc(-1 * var(--#{$prefix}card-cap-padding-y)); // stylelint-disable-line function-disallowed-list
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
border-bottom: 0;
.nav-link.active {
background-color: var(--#{$prefix}card-bg);
border-bottom-color: var(--#{$prefix}card-bg);
}
}
.card-header-pills {
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: var(--#{$prefix}card-img-overlay-padding);
@include border-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-bottom {
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: var(--#{$prefix}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-end-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-start-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-left-radius: 0;
}
}
}
}
}
}

View File

@ -0,0 +1,226 @@
// 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-start and .carousel-item-end is used to indicate where
// the active slide is heading.
// 3. .active.carousel-item is the current slide.
// 4. .active.carousel-item-start and .active.carousel-item-end is the current
// slide in its in-transition state. Only one of these occurs at a time.
// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end
// 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-start),
.active.carousel-item-end {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-end),
.active.carousel-item-start {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item {
opacity: 0;
transition-property: opacity;
transform: none;
}
.carousel-item.active,
.carousel-item-next.carousel-item-start,
.carousel-item-prev.carousel-item-end {
z-index: 1;
opacity: 1;
}
.active.carousel-item-start,