@@ -1,171 +0,0 @@
|
||||
---
|
||||
title: General usage
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
## How to use the library
|
||||
|
||||
Each implementation generally provides two different clients, which will be the access point for the API's. First of is the rest client, which is typically available via [ExchangeName]RestClient, and a socket client, which is generally named [ExchangeName]SocketClient. For example `BinanceRestClient` and `BinanceSocketClient`.
|
||||
|
||||
## Rest client
|
||||
The rest client gives access to the Rest endpoint of the API. Rest endpoints are accessed by sending an HTTP request and receiving a response. The client is split in different sub-clients, which are named API Clients. These API clients are then again split in different topics. Typically a Rest client will look like this:
|
||||
|
||||
- [ExchangeName]RestClient
|
||||
- SpotApi
|
||||
- Account
|
||||
- ExchangeData
|
||||
- Trading
|
||||
- FuturesApi
|
||||
- Account
|
||||
- ExchangeData
|
||||
- Trading
|
||||
|
||||
This rest client has 2 different API clients, the `SpotApi` and the `FuturesApi`, each offering their own set of endpoints.
|
||||
|
||||
*Requesting ticker info on the spot API*
|
||||
```csharp
|
||||
var client = new KucoinClient();
|
||||
var tickersResult = kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
|
||||
```
|
||||
|
||||
Structuring the client like this should make it easier to find endpoints and allows for separate options and functionality for different API clients. For example, some API's have totally separate API's for futures, with different base addresses and different API credentials, while other API's have implemented this in the same API. Either way, this structure can facilitate a similar interface.
|
||||
|
||||
### Rest API client
|
||||
The Api clients are parts of the total API with a common identifier. In the previous example, it separates the Spot and the Futures API. This again is then separated into topics. Most Rest clients implement the following structure:
|
||||
|
||||
**Account**
|
||||
Endpoints related to the user account. This can for example be endpoints for accessing account settings, or getting account balances. The endpoints in this topic will require API credentials to be provided in the client options.
|
||||
|
||||
**ExchangeData**
|
||||
Endpoints related to exchange data. Exchange data can be tied to the exchange, for example retrieving the symbols supported by the exchange and what the trading rules are, or can be more general market endpoints, such as getting the most recent trades for a symbol.
|
||||
These endpoints generally don't require API credentials as they are publicly available.
|
||||
|
||||
**Trading**
|
||||
Endpoints related to trading. These are endpoints for placing and retrieving orders and retrieving trades made by the user. The endpoints in this topic will require API credentials to be provided in the client options.
|
||||
|
||||
### Processing request responses
|
||||
Each request will return a WebCallResult<T> with the following properties:
|
||||
`RequestHeaders`: The headers send to the server in the request message
|
||||
`RequestMethod`: The Http method of the request
|
||||
`RequestUrl`: The url the request was send to
|
||||
`ResponseLength`: The length in bytes of the response message
|
||||
`ResponseTime`: The duration between sending the request and receiving the response
|
||||
`ResponseHeaders`: The headers returned from the server
|
||||
`ResponseStatusCode`: The status code as returned by the server
|
||||
`Success`: Whether or not the call was successful. If successful the `Data` property will contain the resulting data, if not successful the `Error` property will contain more details about what the issue was
|
||||
`Error`: Details on what went wrong with a call. Only filled when `Success` == `false`
|
||||
`OriginalData`: Will contain the originally received unparsed data if this has been enabled in the client options
|
||||
`Data`: Data returned by the server, only available if `Success` == `true`
|
||||
|
||||
When processing the result of a call it should always be checked for success. Not doing so will result in `NullReference` exceptions when the call fails for whatever reason.
|
||||
|
||||
*Check call result*
|
||||
```csharp
|
||||
var callResult = await kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
|
||||
if(!callResult.Success)
|
||||
{
|
||||
Console.WriteLine("Request failed: " + callResult.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Result: " + callResult.Data);
|
||||
```
|
||||
|
||||
## Socket client
|
||||
The socket client gives access to the websocket API of an exchange. Websocket API's offer streams to which updates are pushed to which a client can listen, and sometimes also allow request/response communication.
|
||||
Just like the Rest client is divided in Rest Api clients, the Socket client is divided into Socket Api clients, each with their own range of API functionality. Socket Api clients are generally not divided into topics since the number of methods isn't as big as with the Rest client. To use the Kucoin client as example again, it looks like this:
|
||||
|
||||
```csharp
|
||||
|
||||
- KucoinSocketClient
|
||||
- SpotStreams
|
||||
- FuturesStreams
|
||||
|
||||
```
|
||||
*Subscribing to updates for all tickers on the Spot Api*
|
||||
```csharp
|
||||
var subscribeResult = kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
```
|
||||
|
||||
Subscribe methods always require a data handler parameter, which is the method which will be called when an update is received from the server. This can be the name of a method or a lambda expression.
|
||||
|
||||
*Method reference*
|
||||
```csharp
|
||||
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
|
||||
private static void DataHandler(DataEvent<KucoinStreamTick> updateData)
|
||||
{
|
||||
// Process updateData
|
||||
}
|
||||
```
|
||||
|
||||
*Lambda*
|
||||
```csharp
|
||||
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(updateData =>
|
||||
{
|
||||
// Process updateData
|
||||
});
|
||||
```
|
||||
|
||||
All updates are wrapped in a `DataEvent<>` object, which contain the following properties:
|
||||
`Timestamp`: The timestamp when the data was received (not send!)
|
||||
`OriginalData`: Will contain the originally received unparsed data if this has been enabled in the client options
|
||||
`Topic`: Will contain the topic of the update, which is typically the symbol or asset the update is for
|
||||
`Data`: Contains the received update data.
|
||||
|
||||
*[WARNING] Do not use `using` statements in combination with constructing a `SocketClient` without blocking the thread. Doing so will dispose the `SocketClient` instance when the subscription is done, which will result in the connection getting closed. Instead assign the socket client to a variable outside of the method scope.*
|
||||
|
||||
### Processing subscribe responses
|
||||
Subscribing to a stream will return a `CallResult<UpdateSubscription>` object. This should be checked for success the same way as a [rest request](#processing-request-responses). The `UpdateSubscription` object can be used to listen for connection events of the socket connection.
|
||||
```csharp
|
||||
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
if(!subscriptionResult.Success)
|
||||
{
|
||||
Console.WriteLine("Failed to connect: " + subscriptionResult.Error);
|
||||
return;
|
||||
}
|
||||
subscriptionResult.Data.ConnectionLost += () =>
|
||||
{
|
||||
Console.WriteLine("Connection lost");
|
||||
};
|
||||
subscriptionResult.Data.ConnectionRestored += (time) =>
|
||||
{
|
||||
Console.WriteLine("Connection restored");
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Unsubscribing
|
||||
When no longer interested in specific updates there are a few ways to unsubscribe.
|
||||
|
||||
**Close subscription**
|
||||
Subscribing to an update stream will respond with an `UpdateSubscription` object. You can call the `CloseAsync()` method on this to no longer receive updates from that subscription:
|
||||
```csharp
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
await subscriptionResult.Data.CloseAsync();
|
||||
```
|
||||
|
||||
**Cancellation token**
|
||||
Passing in a `CancellationToken` as parameter in the subscribe method will allow you to cancel subscriptions by canceling the token. This can be useful when you need to cancel some streams but not others. In this example, both `BTC-USDT` and `ETH-USDT` streams get canceled, while the `KCS-USDT` stream remains active.
|
||||
```csharp
|
||||
var cts = new CancellationTokenSource();
|
||||
var subscriptionResult1 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler, cts.Token);
|
||||
var subscriptionResult2 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("ETH-USDT", DataHandler, cts.Token);
|
||||
var subscriptionResult3 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("KCS-USDT", DataHandler);
|
||||
Console.ReadLine();
|
||||
cts.Cancel();
|
||||
```
|
||||
|
||||
**Client unsubscribe**
|
||||
Subscriptions can also be closed by calling the `UnsubscribeAsync` method on the client, while providing either the `UpdateSubscription` object or the subscription id:
|
||||
```csharp
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler);
|
||||
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data);
|
||||
// OR
|
||||
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data.Id);
|
||||
```
|
||||
|
||||
When you need to unsubscribe all current subscriptions on a client you can call `UnsubscribeAllAsync` on the client to unsubscribe all streams and close all connections.
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
title: FAQ
|
||||
nav_order: 12
|
||||
---
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### I occasionally get a NullReferenceException, what's wrong?
|
||||
You probably don't check the result status of a call and just assume the data is always there. `NullReferenceExecption`s will happen when you have code like this `var symbol = client.GetTickersAync().Result.Data.Symbol` because the `Data` property is null when the call fails. Instead check if the call is successful like this:
|
||||
```csharp
|
||||
var tickerResult = await client.GetTickersAync();
|
||||
if(!tickerResult.Success)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle result, it is now safe to access the Data property
|
||||
var symbol = tickerResult.Data.Symbol;
|
||||
}
|
||||
```
|
||||
|
||||
### The socket client stops sending updates after a little while
|
||||
You probably didn't keep a reference to the socket client and it got disposed.
|
||||
Instead of subscribing like this:
|
||||
```csharp
|
||||
private void SomeMethod()
|
||||
{
|
||||
var socketClient = new BinanceSocketClient();
|
||||
socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
|
||||
// Handle data
|
||||
});
|
||||
}
|
||||
```
|
||||
Subscribe like this:
|
||||
```csharp
|
||||
private BinanceSocketClient _socketClient = new BinanceSocketClient();
|
||||
|
||||
// .. rest of the class
|
||||
|
||||
private void SomeMethod()
|
||||
{
|
||||
_socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
|
||||
// Handle data
|
||||
});
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Can I use the TestNet/US/other API with this library
|
||||
Yes, generally these are all supported and can be configured by setting the Environment in the client options. Some known environments should be available in the [Exchange]Environment class. For example:
|
||||
```csharp
|
||||
var client = new BinanceRestClient(options =>
|
||||
{
|
||||
options.Environment = BinanceEnvironment.Testnet;
|
||||
});
|
||||
```
|
||||
|
||||
### How are timezones handled / Timestamps are off by xx
|
||||
Exchange API's treat all timestamps as UTC, both incoming and outgoing. The client libraries do no conversion so be sure to use UTC as well.
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
title: Glossary
|
||||
nav_order: 11
|
||||
---
|
||||
## Terms and definitions
|
||||
|
||||
|Definition|Synonyms|Meaning|
|
||||
|----------|--------|-------|
|
||||
|Symbol|Market|An asset pair, for example `BTC-ETH`|
|
||||
|Asset|Currency, Coin|A coin for which you can hold balance and which makes up Symbols. For example both `BTC`, `ETH` or `USD`|
|
||||
|Trade|Execution, fill|The (partial) execution of an order. Orders can have multiple trades|
|
||||
|Quantity|Amount, Size|The amount of asset|
|
||||
|Fee|Commission|The fee paid for an order or trade|
|
||||
|Kline|Candlestick, OHLC|K-line data, used for candlestick charts. Contains Open/High/Low/Close/Volume|
|
||||
|KlineInterval|The time period of a single kline|
|
||||
|Open order|Active order, Unexecuted order|An order which has not yet been fully filled|
|
||||
|Closed order|Completed order, executed order|An order which is no longer active. Can be canceled or fully filled|
|
||||
|Network|Chain|The network of an asset. For example `ETH` allows multiple networks like `ERC20` and `BEP2`|
|
||||
|Order book|Market depth|A list of (the top rows of) the current best bids and asks|
|
||||
|Ticker|Stats|Statistics over the last 24 hours|
|
||||
|Client implementation|Library|An implementation of the `CrytpoExchange.Net` library. For example `Binance.Net` or `Bybit.Net`|
|
||||
|
||||
### Other naming conventions
|
||||
#### PlaceOrderAsync
|
||||
Methods for creating an order are always named `PlaceOrderAsync`, with and optional additional name for the type of order, for example `PlaceMarginOrderAsync`.
|
||||
|
||||
#### GetOrdersAsync/GetOpenOrdersAsync/GetClosedOrdersAsync
|
||||
`GetOpenOrdersAsync` only retrieves orders which are still active, `GetClosedOrdersAsync` only retrieves orders which are canceled/closed. `GetOrdersAsync` retrieves both open and closed orders.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: Creating an implementation
|
||||
nav_order: 8
|
||||
---
|
||||
|
||||
TODO
|
||||
@@ -1,145 +0,0 @@
|
||||
---
|
||||
title: Common interfaces
|
||||
nav_order: 7
|
||||
---
|
||||
|
||||
## Shared interfaces
|
||||
Clients have a common interface implementation to allow a shared code base to use the same functionality for different exchanges. The interface is implemented at the `API` level, for example:
|
||||
```csharp
|
||||
var binanceClient = new BinanceClient();
|
||||
ISpotClient spotClient = binanceClient.SpotApi.CommonSpotClient;
|
||||
IFuturesClient futuresClient = binanceClient.UsdFuturesApi.CommonFuturesClient;
|
||||
```
|
||||
|
||||
For examples on this see the Examples folder.
|
||||
|
||||
## ISpotClient
|
||||
The `ISpotClient` interface is implemented on Spot API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `ISpotClient` interface will be available via the `CommonSpotClient` property on the Api client.
|
||||
The spot client has the following members:
|
||||
|
||||
*Properties*
|
||||
```csharp
|
||||
// The name of the exchange this client interacts with
|
||||
string ExchangeName { get; }
|
||||
```
|
||||
|
||||
*Events*
|
||||
```csharp
|
||||
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderPlaced;
|
||||
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderCanceled;
|
||||
|
||||
```
|
||||
|
||||
*Methods*
|
||||
```csharp
|
||||
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
|
||||
string GetSymbolName(string baseAsset, string quoteAsset);
|
||||
|
||||
// Get a list of symbols (trading pairs) on the exchange
|
||||
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
|
||||
|
||||
// Get the ticker (24 hour stats) for a symbol
|
||||
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
|
||||
|
||||
// Get a list of tickers for all symbols
|
||||
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
|
||||
|
||||
// Get a list klines (candlesticks) for a symbol
|
||||
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
|
||||
|
||||
// Get the order book for a symbol
|
||||
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
|
||||
|
||||
// Get a list of most recent trades
|
||||
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
|
||||
|
||||
// Get balances
|
||||
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
|
||||
|
||||
// Place an order
|
||||
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, string? accountId = null);
|
||||
|
||||
// Get order by order id
|
||||
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get the trades for an order
|
||||
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get a list of open orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
|
||||
|
||||
// Get a list of closed orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
|
||||
|
||||
// Cancel an active order
|
||||
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
|
||||
```
|
||||
|
||||
## IFuturesClient
|
||||
The `IFuturesClient` interface is implemented on Futures API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `IFuturesClient` interface will be available via the `CommonFuturesClient` property on the Api client.
|
||||
The spot client has the following members:
|
||||
|
||||
*Properties*
|
||||
```csharp
|
||||
// The name of the exchange this client interacts with
|
||||
string ExchangeName { get; }
|
||||
```
|
||||
|
||||
*Events*
|
||||
```csharp
|
||||
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderPlaced;
|
||||
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderCanceled;
|
||||
|
||||
```
|
||||
|
||||
*Methods*
|
||||
```csharp
|
||||
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
|
||||
string GetSymbolName(string baseAsset, string quoteAsset);
|
||||
|
||||
// Get a list of symbols (trading pairs) on the exchange
|
||||
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
|
||||
|
||||
// Get the ticker (24 hour stats) for a symbol
|
||||
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
|
||||
|
||||
// Get a list of tickers for all symbols
|
||||
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
|
||||
|
||||
// Get a list klines (candlesticks) for a symbol
|
||||
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
|
||||
|
||||
// Get the order book for a symbol
|
||||
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
|
||||
|
||||
// Get a list of most recent trades
|
||||
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
|
||||
|
||||
// Get balances
|
||||
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
|
||||
|
||||
// Get current open positions
|
||||
Task<WebCallResult<IEnumerable<Position>>> GetPositionsAsync();
|
||||
|
||||
// Place an order
|
||||
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, int? leverage = null, string? accountId = null);
|
||||
|
||||
// Get order by order id
|
||||
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get the trades for an order
|
||||
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get a list of open orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
|
||||
|
||||
// Get a list of closed orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
|
||||
|
||||
// Cancel an active order
|
||||
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
|
||||
```
|
||||
@@ -1,150 +0,0 @@
|
||||
---
|
||||
title: Logging
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
## Configuring logging
|
||||
The library offers extensive logging, which depends on the dotnet `Microsoft.Extensions.Logging.ILogger` interface. This should provide ease of use when connecting the library logging to your existing logging implementation.
|
||||
|
||||
*Configure logging to write to the console*
|
||||
```csharp
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
services
|
||||
.AddBinance()
|
||||
.AddLogging(options =>
|
||||
{
|
||||
options.SetMinimumLevel(LogLevel.Trace);
|
||||
options.AddConsole();
|
||||
});
|
||||
```
|
||||
|
||||
The library provides a TraceLogger ILogger implementation which writes log messages using `Trace.WriteLine`, but any other logging library can be used.
|
||||
|
||||
*Configure logging to use trace logging*
|
||||
```csharp
|
||||
IServiceCollection serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddBinance()
|
||||
.AddLogging(options =>
|
||||
{
|
||||
options.SetMinimumLevel(LogLevel.Trace);
|
||||
options.AddProvider(new TraceLoggerProvider());
|
||||
});
|
||||
```
|
||||
|
||||
### Using an external logging library and dotnet DI
|
||||
|
||||
With for example an ASP.Net Core or Blazor project the logging can be configured by the dependency container, which can then automatically be used be the clients.
|
||||
The next example shows how to use Serilog. This assumes the `Serilog.AspNetCore` package (https://github.com/serilog/serilog-aspnetcore) is installed.
|
||||
|
||||
*Using serilog:*
|
||||
```csharp
|
||||
using Binance.Net;
|
||||
using Serilog;
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddBinance();
|
||||
builder.Host.UseSerilog();
|
||||
var app = builder.Build();
|
||||
|
||||
// startup
|
||||
|
||||
app.Run();
|
||||
```
|
||||
|
||||
### Logging without dotnet DI
|
||||
If you don't have a dependency injection service available because you are for example working on a simple console application you have 2 options for logging.
|
||||
|
||||
#### Create a ServiceCollection manually and get the client from the service provider
|
||||
|
||||
```csharp
|
||||
IServiceCollection serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddBinance();
|
||||
serviceCollection.AddLogging(options =>
|
||||
{
|
||||
options.SetMinimumLevel(LogLevel.Trace);
|
||||
options.AddConsole();
|
||||
}).BuildServiceProvider();
|
||||
|
||||
var client = serviceCollection.GetRequiredService<IBinanceRestClient>();
|
||||
|
||||
```
|
||||
|
||||
#### Create a LoggerFactory manually
|
||||
|
||||
```csharp
|
||||
var logFactory = new LoggerFactory();
|
||||
logFactory.AddProvider(new ConsoleLoggerProvider());
|
||||
var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options => { });
|
||||
```
|
||||
|
||||
## Providing logging for issues
|
||||
A big debugging tool when opening an issue on Github is providing logging of what data caused the issue. This can be provided two ways, via the `OriginalData` property of the call result or data event, or collecting the Trace logging.
|
||||
### OriginalData
|
||||
This is only useful when there is an issue in deserialization. So either a call result is giving a Deserialization error, or the result has a value that is unexpected. If that is the issue, please provide the original data that is received so the deserialization issue can be resolved based on the received data.
|
||||
By default the `OriginalData` property in the `WebCallResult`/`DataEvent` object is not filled as saving the original data has a (very small) performance penalty. To save the original data in the `OriginalData` property the `OutputOriginalData` option should be set to `true` in the client options.
|
||||
*Enabled output data*
|
||||
```csharp
|
||||
var client = new BinanceClient(options =>
|
||||
{
|
||||
options.OutputOriginalData = true
|
||||
});
|
||||
```
|
||||
|
||||
*Accessing original data*
|
||||
```csharp
|
||||
// Rest request
|
||||
var tickerResult = await client.SpotApi.ExchangeData.GetTickersAsync();
|
||||
var originallyReceivedData = tickerResult.OriginalData;
|
||||
|
||||
// Socket update
|
||||
await client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => {
|
||||
var originallyRecievedData = update.OriginalData;
|
||||
});
|
||||
```
|
||||
|
||||
### Trace logging
|
||||
Trace logging, which is the most verbose log level, will show everything the library does and includes the data that was send and received.
|
||||
Output data will look something like this:
|
||||
```
|
||||
2021-12-17 10:40:42:296 | Debug | Binance | Client configuration: LogLevel: Trace, Writers: 1, OutputOriginalData: False, Proxy: -, AutoReconnect: True, ReconnectInterval: 00:00:05, MaxReconnectTries: , MaxResubscribeTries: 5, MaxConcurrentResubscriptionsPerSocket: 5, SocketResponseTimeout: 00:00:10, SocketNoDataTimeout: 00:00:00, SocketSubscriptionsCombineTarget: , CryptoExchange.Net: v5.0.0.0, Binance.Net: v8.0.0.0
|
||||
2021-12-17 10:40:42:410 | Debug | Binance | [15] Creating request for https://api.binance.com/api/v3/ticker/24hr
|
||||
2021-12-17 10:40:42:439 | Debug | Binance | [15] Sending GET request to https://api.binance.com/api/v3/ticker/24hr?symbol=BTCUSDT with headers Accept=[application/json], X-MBX-APIKEY=[XXX]
|
||||
2021-12-17 10:40:43:024 | Debug | Binance | [15] Response received in 571ms: {"symbol":"BTCUSDT","priceChange":"-1726.47000000","priceChangePercent":"-3.531","weightedAvgPrice":"48061.51544204","prevClosePrice":"48901.44000000","lastPrice":"47174.97000000","lastQty":"0.00352000","bidPrice":"47174.96000000","bidQty":"0.65849000","askPrice":"47174.97000000","askQty":"0.13802000","openPrice":"48901.44000000","highPrice":"49436.43000000","lowPrice":"46749.55000000","volume":"33136.69765000","quoteVolume":"1592599905.80360790","openTime":1639647642763,"closeTime":1639734042763,"firstId":1191596486,"lastId":1192649611,"count":1053126}
|
||||
```
|
||||
When opening an issue, please provide this logging when available.
|
||||
|
||||
### Example of serilog config and minimal API's
|
||||
|
||||
```csharp
|
||||
using Binance.Net;
|
||||
using Binance.Net.Interfaces.Clients;
|
||||
using Serilog;
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddBinance();
|
||||
builder.Host.UseSerilog();
|
||||
var app = builder.Build();
|
||||
|
||||
// startup
|
||||
|
||||
app.Urls.Add("http://localhost:3000");
|
||||
|
||||
app.MapGet("/price/{symbol}", async (string symbol) =>
|
||||
{
|
||||
var client = app.Services.GetRequiredService<IBinanceRestClient>();
|
||||
var result = await client.SpotApi.ExchangeData.GetPriceAsync(symbol);
|
||||
return result.Data.Price;
|
||||
});
|
||||
|
||||
app.Run();
|
||||
```
|
||||
@@ -1,73 +0,0 @@
|
||||
---
|
||||
title: Migrate v5 to v6
|
||||
nav_order: 10
|
||||
---
|
||||
|
||||
## Migrating from version 5 to version 6
|
||||
When updating your code from version 5 implementations to version 6 implementations you will encounter some breaking changes. Here is the general outline of changes made in the CryptoExchange.Net library. For more specific changes for each library visit the library migration guide.
|
||||
|
||||
*NOTE when updating it is not possible to have some client implementations use a V5 version and some clients a V6. When updating all libraries should be migrated*
|
||||
|
||||
## Rest client name
|
||||
To be more clear about different clients for different API's the rest client implementations have been renamed from [Exchange]Client to [Exchange]RestClient. This makes it more clear that it only implements the Rest API and the [Exchange]SocketClient the Socket API.
|
||||
|
||||
## Options
|
||||
Option parameters have been changed to a callback instead of an options object. This makes processing of the options easier and is in line with how dotnet handles option configurations.
|
||||
|
||||
**BaseAddress**
|
||||
The BaseAddress option has been replaced by the Environment option. The Environment options allows for selection/switching between different trade environments more easily. For example the environment can be switched between a testnet and live by changing only a single line instead of having to change all BaseAddresses.
|
||||
|
||||
**LogLevel/LogWriters**
|
||||
The logging options have been removed and are now inherited by the DI configuration. See [Logging](https://jkorf.github.io/CryptoExchange.Net/Logging.html) for more info.
|
||||
|
||||
**HttpClient**
|
||||
The HttpClient will now be received by the DI container instead of having to pass it manually. When not using DI it is still possible to provide a HttpClient, but it is now located in the client constructor.
|
||||
|
||||
*V5*
|
||||
```csharp
|
||||
var client = new BinanceClient(new BinanceClientOptions(){
|
||||
OutputOriginalData = true,
|
||||
SpotApiOptions = new RestApiOptions {
|
||||
BaseAddress = BinanceApiAddresses.TestNet.RestClientAddress
|
||||
}
|
||||
// Other options
|
||||
});
|
||||
```
|
||||
|
||||
*V6*
|
||||
```csharp
|
||||
var client = new BinanceClient(options => {
|
||||
options.OutputOriginalData = true;
|
||||
options.Environment = BinanceEnvironment.Testnet;
|
||||
// Other options
|
||||
});
|
||||
```
|
||||
|
||||
## Socket api name
|
||||
As socket API's are often more than just streams to subscribe to the name of the socket API clients have been changed from [Topic]Streams to [Topic]Api which matches the rest API client names. For example `SpotStreams` has become `SpotApi`, so `binanceSocketClient.UsdFuturesStreams.SubscribeXXX` has become `binanceSocketClient.UsdFuturesApi.SubscribeXXX`.
|
||||
|
||||
## Add[Exchange] extension method
|
||||
With the change in options providing the DI extension methods for the IServiceCollection have also been changed slightly. Also the socket clients will now be registered as Singleton by default instead of Scoped.
|
||||
|
||||
*V5*
|
||||
```csharp
|
||||
builder.Services.AddKucoin((restOpts, socketOpts) =>
|
||||
{
|
||||
restOpts.LogLevel = LogLevel.Debug;
|
||||
restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
|
||||
socketOpts.LogLevel = LogLevel.Debug;
|
||||
socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
|
||||
}, ServiceLifetime.Singleton);
|
||||
```
|
||||
|
||||
*V6*
|
||||
```csharp
|
||||
builder.Services.AddKucoin((restOpts) =>
|
||||
{
|
||||
restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
|
||||
},
|
||||
(socketOpts) =>
|
||||
{
|
||||
socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
|
||||
});
|
||||
```
|
||||
@@ -1,133 +0,0 @@
|
||||
---
|
||||
title: Client options
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
## Setting client options
|
||||
|
||||
Each implementation can be configured using client options. There are 2 ways to provide these, either via `[client].SetDefaultOptions([options]);`, or in the constructor of the client. The examples here use the `BinanceClient`, but usage is the same for each client.
|
||||
|
||||
*Set the default options to use for new clients*
|
||||
```csharp
|
||||
|
||||
BinanceClient.SetDefaultOptions(options =>
|
||||
{
|
||||
options.OutputOriginalData = true;
|
||||
options.ApiCredentials = new ApiCredentials("KEY", "SECRET");
|
||||
// Override the api credentials for the Spot API
|
||||
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
*Set the options to use for a single new client*
|
||||
```csharp
|
||||
|
||||
var client = new BinanceClient(options =>
|
||||
{
|
||||
options.OutputOriginalData = true;
|
||||
options.ApiCredentials = new ApiCredentials("KEY", "SECRET");
|
||||
// Override the api credentials for the Spot API
|
||||
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
When calling `SetDefaultOptions` each client created after that will use the options that were set, unless the specific option is overriden in the options that were provided to the client. Consider the following example:
|
||||
```csharp
|
||||
|
||||
BinanceClient.SetDefaultOptions(options =>
|
||||
{
|
||||
options.OutputOriginalData = true;
|
||||
});
|
||||
|
||||
var client = new BinanceClient(options =>
|
||||
{
|
||||
options.OutputOriginalData = false;
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
The client instance will have the following options:
|
||||
`OutputOriginalData = false`
|
||||
|
||||
## Api options
|
||||
The options are divided in two categories. The basic options, which will apply to everything the client does, and the Api options, which is limited to the specific API client (see [Clients](https://jkorf.github.io/CryptoExchange.Net/Clients.html)).
|
||||
|
||||
```csharp
|
||||
|
||||
var client = new BinanceRestClient(options =>
|
||||
{
|
||||
options.ApiCredentials = new ApiCredentials("GENERAL-KEY", "GENERAL-SECRET"),
|
||||
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
The options provided in the SpotApiOptions are only applied to the SpotApi (`client.SpotApi.XXX` endpoints), while the base options are applied to everything. This means that the spot endpoints will use the "SPOT-KEY" credentials, while all other endpoints (`client.UsdFuturesApi.XXX` / `client.CoinFuturesApi.XXX`) will use the "GENERAL-KEY" credentials.
|
||||
|
||||
## CryptoExchange.Net options definitions
|
||||
All clients have access to the following options, specific implementations might have additional options.
|
||||
|
||||
**Base client options**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`OutputOriginalData`|If set to `true` the originally received Json data will be output as well as the deserialized object. For `RestClient` calls the data will be in the `WebCallResult<T>.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent<T>.OriginalData` property when receiving an update. | `false`
|
||||
|`ApiCredentials`| The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). Note that this is a `default` value for all API clients, and can be overridden per API client. See the `Base Api client options`| `null`
|
||||
|`Proxy`|The proxy to use for connecting to the API.| `null`
|
||||
|`RequestTimeout`|The timeout for client requests to the server| `TimeSpan.FromSeconds(20)`
|
||||
|
||||
**Rest client options (extension of base client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time sure is to be in sync.|`true`|
|
||||
|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed| `TimeSpan.FromHours(1)`
|
||||
|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment`
|
||||
|
||||
**Socket client options (extension of base client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`AutoReconnect`|Whether or not the socket should attempt to automatically reconnect when disconnected.|`true`
|
||||
|`ReconnectInterval`|The time to wait between connection tries when reconnecting.|`TimeSpan.FromSeconds(5)`
|
||||
|`SocketResponseTimeout`|The time in which a response is expected on a request before giving a timeout.|`TimeSpan.FromSeconds(10)`
|
||||
|`SocketNoDataTimeout`|If no data is received after this timespan then assume the connection is dropped. This is mainly used for API's which have some sort of ping/keepalive system. For example; the Bitfinex API will sent a heartbeat message every 15 seconds, so the `SocketNoDataTimeout` could be set to 20 seconds. On API's without such a mechanism this might not work because there just might not be any update while still being fully connected. | `default(TimeSpan)` (no timeout)
|
||||
|`SocketSubscriptionsCombineTarget`|The amount of subscriptions that should be made on a single socket connection. Not all exchanges support multiple subscriptions on a single socket. Setting this to a higher number increases subscription speed because not every subscription needs to connect to the server, but having more subscriptions on a single connection will also increase the amount of traffic on that single connection, potentially leading to issues.| Depends on implementation
|
||||
|`MaxConcurrentResubscriptionsPerSocket`|The maximum number of concurrent resubscriptions per socket when resubscribing after reconnecting|5
|
||||
|`MaxSocketConnections`|The maximum amount of distinct socket connections|`null`
|
||||
|`DelayAfterConnect`|The time to wait before sending messages after connecting to the server.|`TimeSpan.Zero`
|
||||
|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment`
|
||||
|
||||
**Base Api client options**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`ApiCredentials`|The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). Setting ApiCredentials on the Api Options will override any default ApiCredentials on the `Base client options`| `null`
|
||||
|`OutputOriginalData`|If set to `true` the originally received Json data will be output as well as the deserialized object. For `RestClient` calls the data will be in the `WebCallResult<T>.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent<T>.OriginalData` property when receiving an update.|False
|
||||
|
||||
**Options for Rest Api Client (extension of base api client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`RateLimiters`|A list of `IRateLimiter`s to use.|`new List<IRateLimiter>()`|
|
||||
|`RateLimitingBehaviour`|What should happen when a rate limit is reached.|`RateLimitingBehaviour.Wait`|
|
||||
|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time is sure to be in sync. Overrides the Rest client options `AutoTimestamp` option if set|`null`|
|
||||
|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed. Overrides the Rest client options `TimestampRecalculationInterval` option if set| `TimeSpan.FromHours(1)`
|
||||
|
||||
**Options for Socket Api Client (extension of base api client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`SocketNoDataTimeout`|If no data is received after this timespan then assume the connection is dropped. This is mainly used for API's which have some sort of ping/keepalive system. For example; the Bitfinex API will sent a heartbeat message every 15 seconds, so the `SocketNoDataTimeout` could be set to 20 seconds. On API's without such a mechanism this might not work because there just might not be any update while still being fully connected. Overrides the Socket client options `SocketNoDataTimeout` option if set | `default(TimeSpan)` (no timeout)
|
||||
|`MaxSocketConnections`|The maximum amount of distinct socket connections. Overrides the Socket client options `MaxSocketConnections` option if set |`null`
|
||||
|
||||
## Credentials
|
||||
Credentials are supported in 3 formats in the base library:
|
||||
|
||||
|Type|Description|Example|
|
||||
|----|-----------|-------|
|
||||
|`Hmac`|An API key + secret combination. The API key is send with the request and the secret is used to sign requests. This is the default authentication method on all exchanges. |`options.ApiCredentials = new ApiCredentials("51231f76e-9c503548-8fabs3f-rfgf12mkl3", "556be32-d563ba53-faa2dfd-b3n5c", CredentialType.Hmac);`|
|
||||
|`RsaPem`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in .pem format and is only supported in .netstandard2.1 due to limitations of the framework|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", ""-----BEGIN PRIVATE KEY-----[PRIVATEKEY]-----END PRIVATE KEY-----", CredentialType.RsaPem);`|
|
||||
|`RsaXml`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in xml format and is supported in .netstandard2.0 and .netstandard2.1, but it might mean the private key needs to be converted from the original format to xml|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", "<RSAKeyValue>[PRIVATEKEY]</RSAKeyValue>", CredentialType.RsaXml);`|
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
title: Order books
|
||||
nav_order: 6
|
||||
---
|
||||
|
||||
## Locally synced order book
|
||||
Each exchange implementation provides an order book implementation. These implementations will provide a client side order book and will take care of synchronization with the server, and will handle reconnecting and resynchronizing in case of a dropped connection.
|
||||
Order book implementations are named as `[ExchangeName][Type]SymbolOrderBook`, for example `BinanceSpotSymbolOrderBook`.
|
||||
|
||||
## Usage
|
||||
Start the book synchronization by calling the `StartAsync` method. This returns whether the book is successfully synchronized and started. You can listen to the `OnStatusChange` event to be notified of when the status of a book changes. Note that the order book is only synchronized with the server when the state is `Synced`. When the order book has been started and the state changes from `Synced` to `Reconnecting` the book will automatically reconnect and resync itself.
|
||||
|
||||
*Start an order book and print the top 3 rows*
|
||||
```csharp
|
||||
|
||||
var book = new BinanceSpotSymbolOrderBook("BTCUSDT");
|
||||
book.OnStatusChange += (oldState, newState) => Console.WriteLine($"State changed from {oldState} to {newState}");
|
||||
var startResult = await book.StartAsync();
|
||||
if (!startResult.Success)
|
||||
{
|
||||
Console.WriteLine("Failed to start order book: " + startResult.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
Console.Clear();
|
||||
Console.WriteLine(book.ToString(3);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Accessing bids/asks
|
||||
You can access the current Bid/Ask lists using the responding properties:
|
||||
`var currentBidList = book.Bids;`
|
||||
`var currentAskList = book.Asks;`
|
||||
|
||||
Note that these will return copies of the internally synced lists when accessing the properties, and when accessing them in sequence like above does mean that the lists may not be in sync with eachother since they're accessed at different points in time.
|
||||
When you need both lists in sync you should access the `Book` property.
|
||||
`var (currentBidList, currentAskList) = book.Book;`
|
||||
|
||||
Because copies of the lists are made when accessing the bids/asks properties the performance impact should be considered. When only the current best ask/bid info is needed you can access the `BestOffers` property.
|
||||
`var (bestBid, bestAsk) = book.BestOffers;`
|
||||
|
||||
### Events
|
||||
The following events are available on the symbol order book:
|
||||
`book.OnStatusChange`: The book has changed state. This happens during connecting, the connection was lost or the order book was detected to be out of sync. The asks/bids are only the actual with the server when state is `Synced`.
|
||||
`book.OnOrderBookUpdate`: The book has changed, the arguments contain the changed entries.
|
||||
`book.OnBestOffersChanged`: The best offer (best bid, best ask) has changed.
|
||||
|
||||
```csharp
|
||||
|
||||
book.OnStatusChange += (oldStatus, newStatus) => { Console.WriteLine($"State changed from {oldStatus} to {newStatus}"); };
|
||||
book.OnOrderBookUpdate += (bidsAsks) => { Console.WriteLine($"Order book changed: {bidsAsks.Asks.Count()} asks, {bidsAsks.Bids.Count()} bids"); };
|
||||
book.OnBestOffersChanged += (bestOffer) => { Console.WriteLine($"Best offer changed, best bid: {bestOffer.BestBid.Price}, best ask: {bestOffer.BestAsk.Price}"); };
|
||||
|
||||
```
|
||||
|
||||
### Order book factory
|
||||
Each exchange implementation also provides an order book factory for creating ISymbolOrderBook instances. The naming convention for the factory is `[Exchange]OrderBookFactory`, for example `BinanceOrderBookFactory`. This type will be automatically added when using DI and can be used to facilitate easier testing.
|
||||
|
||||
*Creating an order book using the order book factory*
|
||||
```csharp
|
||||
var factory = services.GetRequiredService<IKucoinOrderBookFactory>();
|
||||
var book = factory.CreateSpot("ETH-USDT");
|
||||
var startResult = await book.StartAsync();
|
||||
```
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
title: Rate limiting
|
||||
nav_order: 9
|
||||
---
|
||||
|
||||
## Rate limiting
|
||||
The library has build in rate limiting. These rate limits can be configured per client. Some client implementations where the exchange has clear rate limits will also have a default rate limiter already set up.
|
||||
Rate limiting is configured in the client options, and can be set on a specific client or for all clients by either providing it in the constructor for a client, or by using the `SetDefaultOptions` on a client.
|
||||
|
||||
What to do when a limit is reached can be configured with the `RateLimitingBehaviour` client options, which has 2 possible options. Setting it to `Fail` will cause a request to fail without sending it. Setting it to `Wait` will cause the request to wait until the request can be send in accordance to the rate limiter.
|
||||
|
||||
A rate limiter can be configured in the options like so:
|
||||
```csharp
|
||||
new ClientOptions
|
||||
{
|
||||
RateLimitingBehaviour = RateLimitingBehaviour.Wait,
|
||||
RateLimiters = new List<IRateLimiter>
|
||||
{
|
||||
new RateLimiter()
|
||||
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This will add a rate limiter for 50 requests per 10 seconds.
|
||||
A rate limiter can have multiple limits:
|
||||
```csharp
|
||||
new RateLimiter()
|
||||
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
|
||||
.AddEndpointLimit("/api/order", 10, TimeSpan.FromSeconds(2))
|
||||
```
|
||||
This adds another limit of 10 requests per 2 seconds in addition to the 50 requests per 10 seconds limit.
|
||||
These are the available rate limit configurations:
|
||||
|
||||
### AddTotalRateLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|
||||
A rate limit for the total amount of requests for all requests send from the client.
|
||||
|
||||
### AddEndpointLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|endpoint|The endpoint this limit is for|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|method|The HTTP method this limit is for. Defaults to all methods|
|
||||
|excludeFromOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
|
||||
|
||||
A rate limit for all requests send to a specific endpoint. Requests that do not fully match the endpoint will not be counted to this limit.
|
||||
|
||||
### AddPartialEndpointLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|endpoint|The partial endpoint this limit is for. Partial means that a request will match this limiter when a part of the request URI path matches this endpoint|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|method|The HTTP method this limit is for. Defaults to all methods|
|
||||
|countPerEndpoint|Whether all requests matching the endpoint pattern should be combined for this limit or each endpoint has its own limit|
|
||||
|ignoreOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
|
||||
|
||||
A rate limit for a partial endpoint. Requests will be counted towards this limit if the request path contains the endpoint. For example request `/api/v2/test` will match when the partial endpoint limit is set for `/api/v2`.
|
||||
|
||||
### AddApiKeyLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|onlyForSignedRequests|Whether this rate limit should only be counter for signed/authenticated requests|
|
||||
|excludeFromTotalRateLimit|Whether requests counted for this rate limited should not be counted towards the total rate limit|
|
||||
|
||||
A rate limit for an API key. Requests with the same API key will be grouped and limited.
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Blue
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #007bff;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #006adb;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #007bff;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #007bff;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #007bff !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #007bff;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #007bff;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #007bff;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #007bff;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #007bff !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #007bff !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #006adb !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #006adb !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #007bff !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #006adb;
|
||||
border-color: #006adb;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #006adb;
|
||||
border-color: #006adb;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #006adb;
|
||||
border-color: #006adb;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #007bff;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #006adb;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Brown
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #795548;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #795548;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #63453b;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #795548;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #795548;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #795548;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #795548;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #795548 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #795548;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #795548;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #795548;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #795548;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #795548;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #795548;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #795548;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #795548;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #795548;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #795548;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #795548 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #795548 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #63453b !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #63453b !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #795548 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #795548;
|
||||
border-color: #795548;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #63453b;
|
||||
border-color: #63453b;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #63453b;
|
||||
border-color: #63453b;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #63453b;
|
||||
border-color: #63453b;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #795548;
|
||||
border-color: #795548;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #795548;
|
||||
border-color: #795548;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #795548;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #795548;
|
||||
border-color: #795548;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #795548;
|
||||
border-color: #795548;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #795548;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #63453b;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Cyan
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #17a2b8;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #138698;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #17a2b8;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #17a2b8;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #17a2b8 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #17a2b8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #17a2b8;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #17a2b8;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #17a2b8;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #17a2b8;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #17a2b8;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #17a2b8 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #17a2b8 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #138698 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #138698 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #17a2b8 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #17a2b8;
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #138698;
|
||||
border-color: #138698;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #138698;
|
||||
border-color: #138698;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #138698;
|
||||
border-color: #138698;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #17a2b8;
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #17a2b8;
|
||||
border-color: #17a2b8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #17a2b8;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #17a2b8;
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #17a2b8;
|
||||
border-color: #17a2b8;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #17a2b8;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #138698;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Green
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #28a745;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #218a39;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #28a745;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #28a745;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #28a745 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #28a745;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #28a745;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #28a745;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #28a745;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #28a745;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #28a745 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #28a745 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #218a39 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #218a39 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #28a745 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #218a39;
|
||||
border-color: #218a39;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #218a39;
|
||||
border-color: #218a39;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #218a39;
|
||||
border-color: #218a39;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #28a745;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #218a39;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Indigo
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #6610f2;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #6610f2;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #570bd3;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #6610f2;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #6610f2;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #6610f2;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #6610f2;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #6610f2 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #6610f2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #6610f2;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #6610f2;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #6610f2;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #6610f2;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #6610f2;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #6610f2;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #6610f2;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #6610f2;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #6610f2;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #6610f2 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #6610f2 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #570bd3 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #570bd3 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #6610f2 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #6610f2;
|
||||
border-color: #6610f2;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #570bd3;
|
||||
border-color: #570bd3;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #570bd3;
|
||||
border-color: #570bd3;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #570bd3;
|
||||
border-color: #570bd3;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #6610f2;
|
||||
border-color: #6610f2;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #6610f2;
|
||||
border-color: #6610f2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #6610f2;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #6610f2;
|
||||
border-color: #6610f2;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #6610f2;
|
||||
border-color: #6610f2;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #6610f2;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #570bd3;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Orange
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #fd7e14;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #fd7e14;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #eb6c02;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #fd7e14;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #fd7e14;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #fd7e14 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #fd7e14;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #fd7e14;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #fd7e14;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #fd7e14;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #fd7e14;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #fd7e14;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #fd7e14;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #fd7e14;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #fd7e14;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #fd7e14;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #fd7e14 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #fd7e14 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #eb6c02 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #eb6c02 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #fd7e14 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #fd7e14;
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #eb6c02;
|
||||
border-color: #eb6c02;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #eb6c02;
|
||||
border-color: #eb6c02;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #eb6c02;
|
||||
border-color: #eb6c02;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #fd7e14;
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #fd7e14;
|
||||
border-color: #fd7e14;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #fd7e14;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #fd7e14;
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #fd7e14;
|
||||
border-color: #fd7e14;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #fd7e14;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #eb6c02;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Purple
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #6f42c1;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #5f37a8;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #6f42c1;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #6f42c1;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #6f42c1 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #6f42c1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #6f42c1;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #6f42c1;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #6f42c1;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #6f42c1;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #6f42c1;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #6f42c1 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #6f42c1 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #5f37a8 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #5f37a8 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #6f42c1 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #6f42c1;
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #5f37a8;
|
||||
border-color: #5f37a8;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #5f37a8;
|
||||
border-color: #5f37a8;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #5f37a8;
|
||||
border-color: #5f37a8;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #6f42c1;
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #6f42c1;
|
||||
border-color: #6f42c1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #6f42c1;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #6f42c1;
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #6f42c1;
|
||||
border-color: #6f42c1;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #6f42c1;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #5f37a8;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Red
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #dc3545;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #ca2333;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #dc3545;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #dc3545;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #dc3545;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #dc3545;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #dc3545 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #dc3545;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #dc3545;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #dc3545;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #ca2333 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #ca2333 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #ca2333;
|
||||
border-color: #ca2333;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #ca2333;
|
||||
border-color: #ca2333;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #ca2333;
|
||||
border-color: #ca2333;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #dc3545;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #ca2333;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Teal
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #20c997;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #1baa80;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #20c997;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #20c997;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #20c997;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #20c997;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #20c997 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #20c997;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #20c997;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #20c997;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #20c997;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #20c997;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #20c997;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #20c997 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #20c997 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #1baa80 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #1baa80 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #20c997 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #20c997;
|
||||
border-color: #20c997;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #1baa80;
|
||||
border-color: #1baa80;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #1baa80;
|
||||
border-color: #1baa80;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #1baa80;
|
||||
border-color: #1baa80;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #20c997;
|
||||
border-color: #20c997;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #20c997;
|
||||
border-color: #20c997;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #20c997;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #20c997;
|
||||
border-color: #20c997;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #20c997;
|
||||
border-color: #20c997;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #20c997;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #1baa80;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*============================
|
||||
COLOR Yellow
|
||||
==============================*/
|
||||
::selection {
|
||||
background: #ffc107;
|
||||
}
|
||||
|
||||
a, a:focus {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #f7b900;
|
||||
}
|
||||
|
||||
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
|
||||
color: #ffc107;
|
||||
}
|
||||
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
|
||||
color: #ffc107;
|
||||
}
|
||||
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
|
||||
border-color: #ffc107;
|
||||
}
|
||||
|
||||
/*=== Side Navigation ===*/
|
||||
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
|
||||
border-color: #ffc107;
|
||||
}
|
||||
|
||||
/* Accordion & Toggle */
|
||||
.accordion .card-header a:hover.collapsed {
|
||||
color: #ffc107 !important;
|
||||
}
|
||||
.accordion:not(.accordion-alternate) .card-header a {
|
||||
background-color: #ffc107;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
background-color: #ffc107;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link:not(.active):hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
.nav-tabs.flex-column .nav-item .nav-link.active {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
#footer .nav .nav-item .nav-link:focus {
|
||||
color: #ffc107;
|
||||
}
|
||||
#footer .nav .nav-link:hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
#footer .footer-copyright .nav .nav-link:hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
/* Back to Top */
|
||||
#back-to-top:hover {
|
||||
background-color: #ffc107;
|
||||
}
|
||||
|
||||
/* Extras */
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: #ffc107 !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: #ffc107 !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: #f7b900 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #8e9a9d !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: #dee3e4 !important;
|
||||
}
|
||||
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
|
||||
background-color: #f7b900 !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: #ffc107 !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #f7b900;
|
||||
border-color: #f7b900;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
|
||||
background-color: #f7b900;
|
||||
border-color: #f7b900;
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus {
|
||||
background-color: #f7b900;
|
||||
border-color: #f7b900;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
|
||||
color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
}
|
||||
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
|
||||
background-color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: #ffc107;
|
||||
}
|
||||
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before {
|
||||
background-color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #ffc107;
|
||||
}
|
||||
.page-link:hover {
|
||||
color: #f7b900;
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
================================================================
|
||||
* Template: iDocs - One Page Documentation HTML Template
|
||||
* Written by: Harnish Design - (http://www.harnishdesign.net)
|
||||
* Description: Main Custom Script File
|
||||
================================================================
|
||||
*/
|
||||
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
// Preloader
|
||||
$(window).on('load', function () {
|
||||
$('.lds-ellipsis').fadeOut(); // will first fade out the loading animation
|
||||
$('.preloader').delay(333).fadeOut('slow'); // will fade out the white DIV that covers the website.
|
||||
$('body').delay(333);
|
||||
});
|
||||
|
||||
/*-------------------------------
|
||||
Primary Menu
|
||||
--------------------------------- */
|
||||
|
||||
// Dropdown show on hover
|
||||
$('.primary-menu ul.navbar-nav li.dropdown, .login-signup ul.navbar-nav li.dropdown').on("mouseover", function() {
|
||||
if ($(window).width() > 991) {
|
||||
$(this).find('> .dropdown-menu').stop().slideDown('fast');
|
||||
$(this).bind('mouseleave', function() {
|
||||
$(this).find('> .dropdown-menu').stop().css('display', 'none');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// When dropdown going off to the out of the screen.
|
||||
$('.primary-menu ul.navbar-nav .dropdown-menu').each(function() {
|
||||
var menu = $('#header .container-fluid').offset();
|
||||
var dropdown = $(this).parent().offset();
|
||||
|
||||
var i = (dropdown.left + $(this).outerWidth()) - (menu.left + $('#header .container-fluid').outerWidth());
|
||||
|
||||
if (i > 0) {
|
||||
$(this).css('margin-left', '-' + (i + 5) + 'px');
|
||||
}
|
||||
});
|
||||
$(function () {
|
||||
$(".dropdown li").on('mouseenter mouseleave', function (e) {
|
||||
if ($(window).width() > 991) {
|
||||
var elm = $('.dropdown-menu', this);
|
||||
var off = elm.offset();
|
||||
var l = off.left;
|
||||
var w = elm.width();
|
||||
var docW = $(window).width();
|
||||
var isEntirelyVisible = (l + w + 30 <= docW);
|
||||
if (!isEntirelyVisible) {
|
||||
$(elm).addClass('dropdown-menu-right');
|
||||
} else {
|
||||
$(elm).removeClass('dropdown-menu-right');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// DropDown Arrow
|
||||
$('.primary-menu ul.navbar-nav').find('a.dropdown-toggle').append($('<i />').addClass('arrow'));
|
||||
|
||||
|
||||
// Mobile Collapse Nav
|
||||
$('.primary-menu .navbar-nav .dropdown-toggle[href="#"], .primary-menu .dropdown-toggle[href!="#"] .arrow').on('click', function(e) {
|
||||
if ($(window).width() < 991) {
|
||||
e.preventDefault();
|
||||
var $parentli = $(this).closest('li');
|
||||
$parentli.siblings('li').find('.dropdown-menu:visible').slideUp();
|
||||
$parentli.find('> .dropdown-menu').stop().slideToggle();
|
||||
$parentli.siblings('li').find('a .arrow.show').toggleClass('show');
|
||||
$parentli.find('> a .arrow').toggleClass('show');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Mobile Menu
|
||||
$('.navbar-toggler').on('click', function() {
|
||||
$(this).toggleClass('show');
|
||||
});
|
||||
|
||||
|
||||
/*------------------------
|
||||
Side Navigation
|
||||
-------------------------- */
|
||||
|
||||
$('#sidebarCollapse').on('click', function () {
|
||||
$('#sidebarCollapse span:nth-child(3)').toggleClass('w-50');
|
||||
$('.idocs-navigation').toggleClass('active');
|
||||
});
|
||||
|
||||
|
||||
/*------------------------
|
||||
Sections Scroll
|
||||
-------------------------- */
|
||||
|
||||
$('.smooth-scroll,.idocs-navigation a').on('click', function() {
|
||||
event.preventDefault();
|
||||
var sectionTo = $(this).attr('href');
|
||||
$('html, body').stop().animate({
|
||||
scrollTop: $(sectionTo).offset().top - 120}, 1000, 'easeInOutExpo');
|
||||
});
|
||||
|
||||
/*-----------------------------
|
||||
Magnific Popup
|
||||
------------------------------- */
|
||||
|
||||
// Image on Modal
|
||||
$('.popup-img').each(function() {
|
||||
$(this).magnificPopup({
|
||||
type: "image",
|
||||
tLoading: '<div class="preloader"><div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>',
|
||||
closeOnContentClick: !0,
|
||||
mainClass: "mfp-fade",
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// YouTube/Viemo Video & Gmaps
|
||||
$('.popup-youtube, .popup-vimeo, .popup-gmaps').each(function() {
|
||||
$(this).magnificPopup({
|
||||
type: 'iframe',
|
||||
mainClass: 'mfp-fade',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*------------------------
|
||||
Highlight Js
|
||||
-------------------------- */
|
||||
|
||||
hljs.initHighlightingOnLoad();
|
||||
|
||||
|
||||
/*------------------------
|
||||
tooltips
|
||||
-------------------------- */
|
||||
$('[data-toggle=\'tooltip\']').tooltip({container: 'body'});
|
||||
|
||||
|
||||
/*------------------------
|
||||
Scroll to top
|
||||
-------------------------- */
|
||||
$(function () {
|
||||
$(window).on('scroll', function(){
|
||||
if ($(this).scrollTop() > 400) {
|
||||
$('#back-to-top').fadeIn();
|
||||
} else {
|
||||
$('#back-to-top').fadeOut();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#back-to-top').on("click", function() {
|
||||
$('html, body').animate({scrollTop:0}, 'slow');
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
})(jQuery)
|
||||
@@ -0,0 +1,537 @@
|
||||
/* =================================== */
|
||||
/* 5. Elements
|
||||
/* =================================== */
|
||||
|
||||
/*=== 5.1 List Style ===*/
|
||||
|
||||
.list-style-1 > li {
|
||||
position: relative;
|
||||
list-style-type: none;
|
||||
line-height: 24px;
|
||||
&:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: -15px;
|
||||
border-color: #000;
|
||||
border-top: 1px solid;
|
||||
border-right: 1px solid;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(45deg);
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
.list-style-2{padding:0;}
|
||||
|
||||
.list-style-2 > li {
|
||||
list-style-type: none;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.list-style-2.list-style-light > li {
|
||||
border-bottom: 1px solid rgba(250,250,250,0.12);
|
||||
}
|
||||
|
||||
/*=== 5.2 Changelog ===*/
|
||||
|
||||
.changelog {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
.badge {
|
||||
width: 90px;
|
||||
margin-right: 10px;
|
||||
border-radius: .20rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
li {
|
||||
line-height: 1.8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 5.3 Accordion & Toggle ===*/
|
||||
.accordion {
|
||||
.card {
|
||||
border: none;
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 1rem;
|
||||
background-color: transparent;
|
||||
}
|
||||
.card-header {
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
a {
|
||||
font-size: 16px;
|
||||
font-weight:normal;
|
||||
padding: 1rem 1.25rem 1rem 2.25rem;
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
&:hover{
|
||||
text-decoration:none;
|
||||
}
|
||||
&:hover.collapsed {
|
||||
color: $primary-color!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:not(.accordion-alternate) .card-header a {
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
&.collapsed {
|
||||
background-color: #f1f2f4;
|
||||
color: #4c4d4d;
|
||||
}
|
||||
|
||||
}
|
||||
.card-header a {
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: " ";
|
||||
left: 20px;
|
||||
top: calc(50% + 2px);
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-color: #CCC;
|
||||
border-top: 2px solid;
|
||||
border-right: 2px solid;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
@include transition(all 0.2s ease);
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
&.collapsed:before {
|
||||
top: calc(50% - 2px);
|
||||
-webkit-transform: translate(-50%, -50%) rotate(135deg);
|
||||
transform: translate(-50%, -50%) rotate(135deg);
|
||||
}
|
||||
}
|
||||
.card-body {
|
||||
line-height: 26px;
|
||||
}
|
||||
&.arrow-right .card-header a{
|
||||
padding-left:1.25rem;
|
||||
&:before {
|
||||
right: 15px;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
&.accordion-alternate {
|
||||
.card {
|
||||
margin: 0;
|
||||
}
|
||||
.card-header a {
|
||||
padding-left: 1.40rem;
|
||||
border-top: 1px solid #e4e9ec;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.card:first-of-type .card-header a {
|
||||
border-top: 0px;
|
||||
}
|
||||
.card-header a {
|
||||
&:before {
|
||||
left: 6px;
|
||||
}
|
||||
&.collapsed {
|
||||
color: #4c4d4d;
|
||||
}
|
||||
}
|
||||
.card-body {
|
||||
padding: 0rem 0 1rem 1.25rem;
|
||||
}
|
||||
&.arrow-right .card-header a{
|
||||
padding-left:0;
|
||||
&:before {
|
||||
right: 0px;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
&.toggle .card-header a {
|
||||
&:before {
|
||||
content: "-";
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
height: auto;
|
||||
top: calc(50% + 2px);
|
||||
width: auto;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(180deg);
|
||||
transform: translate(-50%, -50%) rotate(180deg);
|
||||
}
|
||||
&.collapsed:before {
|
||||
content: "+";
|
||||
top: calc(50% - 1px);
|
||||
-webkit-transform: translate(-50%, -50%) rotate(0deg);
|
||||
transform: translate(-50%, -50%) rotate(0deg);
|
||||
}
|
||||
}
|
||||
&.accordion-alternate.style-2 {
|
||||
.card-header a {
|
||||
&:before {
|
||||
right: 2px;
|
||||
left: auto;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(135deg);
|
||||
transform: translate(-50%, -50%) rotate(135deg);
|
||||
top: 50%;
|
||||
}
|
||||
&.collapsed:before {
|
||||
-webkit-transform: translate(-50%, -50%) rotate(45deg);
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
padding-left: 0px;
|
||||
}
|
||||
.card-body {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
&.accordion-alternate.popularRoutes {
|
||||
.card-header {
|
||||
.nav {
|
||||
margin-top: 3px;
|
||||
a {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
a {
|
||||
padding: 0px 8px 0px 0px;
|
||||
border: none;
|
||||
font-size: inherit;
|
||||
&:before {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
h5 {
|
||||
cursor: pointer;
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: " ";
|
||||
right: 0px;
|
||||
top: 24px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
opacity: 0.6;
|
||||
border-top: 2px solid;
|
||||
border-right: 2px solid;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
-webkit-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
&.collapsed:before {
|
||||
top: 24px;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(135deg);
|
||||
transform: translate(-50%, -50%) rotate(135deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.card-body {
|
||||
padding: 0;
|
||||
}
|
||||
.card {
|
||||
border-bottom: 2px solid #e4e9ec;
|
||||
padding: 15px 0px;
|
||||
}
|
||||
.routes-list {
|
||||
margin: 1rem 0px 0px 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
a {
|
||||
color: inherit;
|
||||
display: -ms-flexbox !important;
|
||||
display: flex !important;
|
||||
-ms-flex-align: center !important;
|
||||
align-items: center !important;
|
||||
&:hover {
|
||||
color: #0071cc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 5.4 Nav */
|
||||
|
||||
.nav .nav-item .nav-link{color: #222222;}
|
||||
.nav.nav-light .nav-item .nav-link{color: #ddd;}
|
||||
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover{color: $primary-color;}
|
||||
|
||||
|
||||
.nav-pills .nav-link:not(.active):hover{color: $primary-color;}
|
||||
.nav-pills .nav-link.active,.nav-pills.nav-light .nav-link.active, .nav-pills .show > .nav-link{color:#fff;}
|
||||
|
||||
.nav.nav-separator .nav-item .nav-link{position:relative;}
|
||||
.nav.nav-separator .nav-item + .nav-item .nav-link:after{
|
||||
height: 14px;
|
||||
width: 1px;
|
||||
content: ' ';
|
||||
background-color: rgba(0,0,0,0.2);
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
@include translateY(-7px);
|
||||
}
|
||||
.nav.nav-separator.nav-separator-light .nav-item + .nav-item .nav-link:after{
|
||||
background-color: rgba(250,250,250,0.2);
|
||||
}
|
||||
|
||||
.nav.nav-sm .nav-item .nav-link{font-size:14px;}
|
||||
|
||||
|
||||
/*=== 5.5 Tabs ===*/
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid #d7dee3;
|
||||
.nav-item .nav-link {
|
||||
border:0;
|
||||
background: transparent;
|
||||
|
||||
position: relative;
|
||||
border-radius: 0;
|
||||
padding:0.6rem 1rem;
|
||||
color: #7b8084;
|
||||
white-space: nowrap !important;
|
||||
&.active {
|
||||
&:after {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
content: ' ';
|
||||
background-color: $primary-color;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 0;
|
||||
@include translateY(-3px);
|
||||
}
|
||||
color: #0c2f55;
|
||||
}
|
||||
&:not(.active):hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
&.flex-column {
|
||||
border-right: 1px solid #d7dee3;
|
||||
border-bottom: 0px;
|
||||
padding: 1.5rem 0;
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
border: 1px solid #d7dee3;
|
||||
border-right: 0px;
|
||||
background-color: #f6f7f8;
|
||||
font-size: 14px;
|
||||
padding: 0.75rem 1rem;
|
||||
color: #535b61;
|
||||
}
|
||||
&:first-of-type .nav-link {
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
&:last-of-type .nav-link {
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.nav-link.active {
|
||||
&:after {
|
||||
height: 100%;
|
||||
width: 2px;
|
||||
background: #fff;
|
||||
right: -1px;
|
||||
left: auto;
|
||||
}
|
||||
background-color: transparent;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-tabs:not(.flex-column) {
|
||||
.nav-item {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.nav-tabs .nav-item .nav-link {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
margin-right: 10px;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 5.6 Popup Img ===*/
|
||||
.popup-img img{@include transition(all 0.2s ease-in-out);}
|
||||
.popup-img:hover img{
|
||||
opacity:0.8;
|
||||
cursor: -webkit-zoom-in;
|
||||
cursor: -moz-zoom-in;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
|
||||
/*=== 5.7 Featured Box ===*/
|
||||
.featured-box {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
h3, h4 {
|
||||
font-size: 1.25rem;
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
&:not(.style-5) .featured-box-icon {
|
||||
display: inline-block;
|
||||
font-size: 48px;
|
||||
min-width: 55px;
|
||||
min-height: 55px;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.8rem;
|
||||
color: #4c4d4d;
|
||||
border-radius: 0;
|
||||
}
|
||||
&.style-1, &.style-2, &.style-3 {
|
||||
padding-left: 50px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
&.style-1 .featured-box-icon, &.style-2 .featured-box-icon, &.style-3 .featured-box-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-bottom: 0;
|
||||
font-size: 30px;
|
||||
-ms-flex-pack: center !important;
|
||||
justify-content: center !important;
|
||||
text-align: center;
|
||||
}
|
||||
&.style-2 p {
|
||||
margin-left: -50px;
|
||||
}
|
||||
&.style-3 {
|
||||
padding-left: 90px;
|
||||
padding-top: 0px;
|
||||
.featured-box-icon {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
-ms-flex-negative: 0;
|
||||
flex-shrink: 0;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
&.style-4 {
|
||||
text-align: center;
|
||||
.featured-box-icon {
|
||||
margin: 0 auto 24px;
|
||||
margin: 0 auto 1.5rem;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
text-align: center;
|
||||
-ms-flex-negative: 0;
|
||||
flex-shrink: 0;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
@include box-shadow(0px 0px 50px rgba(0, 0, 0, 0.03));
|
||||
}
|
||||
}
|
||||
|
||||
&.style-5 {
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
border: 1px solid #f0f2f3;
|
||||
@include box-shadow(0px 2px 5px rgba(0, 0, 0, 0.05));
|
||||
@include transition(all 0.3s ease-in-out);
|
||||
&:hover {
|
||||
border: 1px solid #ebeded;
|
||||
@include box-shadow(0px 5px 1.5rem rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
h3 {
|
||||
background: #f1f5f6;
|
||||
font-size: 16px;
|
||||
padding: 8px 0;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.featured-box-icon {
|
||||
font-size: 50px;
|
||||
margin: 44px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@mixin featured-box-reverse {
|
||||
text-align:right;
|
||||
&.style-1, &.style-2{
|
||||
padding-right:50px;
|
||||
padding-left:0px;
|
||||
.featured-box-icon{
|
||||
left:auto;
|
||||
right:0px;
|
||||
}
|
||||
}
|
||||
&.style-2 p{
|
||||
margin-right: -50px;
|
||||
margin-left:0;
|
||||
}
|
||||
&.style-3{
|
||||
padding-left:0;
|
||||
padding-right:90px;
|
||||
.featured-box-icon{
|
||||
left:auto;
|
||||
right:0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.featured-box.featured-box-reverse{
|
||||
@include featured-box-reverse;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xs) {
|
||||
.featured-box.featured-box-reverse-sm{
|
||||
@include featured-box-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
.featured-box.featured-box-reverse-md{
|
||||
@include featured-box-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.featured-box.featured-box-reverse-lg{
|
||||
@include featured-box-reverse;
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-up(lg) {
|
||||
.featured-box.featured-box-reverse-xl{
|
||||
@include featured-box-reverse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
/* =================================== */
|
||||
/* Extras
|
||||
/* =================================== */
|
||||
|
||||
/* Bootstrap Specific */
|
||||
|
||||
.form-control, .custom-select {
|
||||
border-color: #dae1e3;
|
||||
font-size: 16px;
|
||||
color: #656565;
|
||||
}
|
||||
|
||||
.form-control:not(.form-control-sm) {
|
||||
padding: .810rem .96rem;
|
||||
height:inherit;
|
||||
}
|
||||
|
||||
.form-control-sm{font-size:14px;}
|
||||
|
||||
.icon-inside {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: calc(50% - 11px);
|
||||
pointer-events: none;
|
||||
font-size: 18px;
|
||||
font-size: 1.125rem;
|
||||
color: #c4c3c3;
|
||||
z-index:3;
|
||||
}
|
||||
.form-control-sm + .icon-inside {
|
||||
font-size: 0.875rem !important;
|
||||
font-size: 14px;
|
||||
top: calc(50% - 13px);
|
||||
}
|
||||
|
||||
select.form-control:not([size]):not([multiple]):not(.form-control-sm) {
|
||||
height: auto;
|
||||
padding-top: .700rem;
|
||||
padding-bottom: .700rem;
|
||||
}
|
||||
.custom-select:not(.custom-select-sm){
|
||||
height:calc(3.05rem + 2px);
|
||||
padding-top: .700rem;
|
||||
padding-bottom: .700rem;}
|
||||
.col-form-label-sm{font-size:13px;}
|
||||
.custom-select-sm{padding-left:5px!important; font-size:14px;}
|
||||
.custom-select:not(.custom-select-sm).border-0{height:3.00rem;}
|
||||
|
||||
.form-control:focus, .custom-select:focus{
|
||||
@include box-shadow(0 0 5px rgba(128, 189, 255, 0.5));
|
||||
}
|
||||
.form-control:focus[readonly]{box-shadow:none;}
|
||||
|
||||
.input-group-text {
|
||||
border-color: #dae1e3;
|
||||
background-color:#f1f5f6;
|
||||
color: #656565;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
&::-webkit-input-placeholder {
|
||||
color: #b1b4b6;
|
||||
}
|
||||
&:-moz-placeholder {
|
||||
/* FF 4-18 */
|
||||
color: #b1b4b6;
|
||||
}
|
||||
&::-moz-placeholder {
|
||||
/* FF 19+ */
|
||||
color: #b1b4b6;
|
||||
}
|
||||
&:-ms-input-placeholder, &::-ms-input-placeholder {
|
||||
/* IE 10+ */
|
||||
color: #b1b4b6;
|
||||
}
|
||||
}
|
||||
|
||||
/* Form Dark */
|
||||
.form-dark {
|
||||
.form-control, .custom-select {
|
||||
border-color: #232a31;
|
||||
background:#232a31;
|
||||
color: #fff;
|
||||
}
|
||||
.form-control:focus{border-color: #80bdff!important;}
|
||||
.form-control {
|
||||
&::-webkit-input-placeholder {
|
||||
color: #777b7f;
|
||||
}
|
||||
&:-moz-placeholder {
|
||||
/* FF 4-18 */
|
||||
color: #777b7f;
|
||||
}
|
||||
&::-moz-placeholder {
|
||||
/* FF 19+ */
|
||||
color: #777b7f;
|
||||
}
|
||||
&:-ms-input-placeholder, &::-ms-input-placeholder {
|
||||
/* IE 10+ */
|
||||
color: #777b7f;
|
||||
}
|
||||
}
|
||||
.custom-select {
|
||||
color: #777b7f;
|
||||
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(250,250,250,0.3)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
|
||||
background-size: 13px 15px;
|
||||
border-color: #232a31;
|
||||
background-color:#232a31;
|
||||
}
|
||||
.icon-inside {
|
||||
color: #777b7f;
|
||||
}
|
||||
}
|
||||
|
||||
/* Input with only bottom border */
|
||||
.form-border {
|
||||
.form-control {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 0px;
|
||||
padding-left: 0px!important;
|
||||
color: rgba(0, 0, 0, 1);
|
||||
&::-webkit-input-placeholder {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
&:-moz-placeholder {
|
||||
/* FF 4-18 */
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
&::-moz-placeholder {
|
||||
/* FF 19+ */
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
&:-ms-input-placeholder, &::-ms-input-placeholder {
|
||||
/* IE 10+ */
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
.custom-select {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 0px;
|
||||
padding-left: 0px;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(0,0,0,0.3)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
|
||||
background-size: 13px 15px;
|
||||
}
|
||||
.form-control:focus, .custom-select:focus {
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.form-control:not(output):-moz-ui-invalid, .custom-select:not(output):-moz-ui-invalid {
|
||||
&:not(:focus), &:-moz-focusring:not(:focus) {
|
||||
border-bottom: 2px solid #b00708;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
}
|
||||
}
|
||||
.icon-inside {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
select option {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.form-border-light {
|
||||
.form-control {
|
||||
border-bottom: 2px solid rgba(250, 250, 250, 0.3);
|
||||
color: rgba(250, 250, 250, 1);
|
||||
&::-webkit-input-placeholder {
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
&:-moz-placeholder {
|
||||
/* FF 4-18 */
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
&::-moz-placeholder {
|
||||
/* FF 19+ */
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
&:-ms-input-placeholder, &::-ms-input-placeholder {
|
||||
/* IE 10+ */
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
}
|
||||
.custom-select {
|
||||
border-bottom: 2px solid rgba(250, 250, 250, 0.3);
|
||||
color: rgba(250, 250, 250, 1);
|
||||
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(250,250,250,0.6)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
|
||||
background-size: 13px 15px;
|
||||
}
|
||||
.form-control:focus, .custom-select:focus {
|
||||
border-bottom: 2px solid rgba(250, 250, 250, 0.8);
|
||||
}
|
||||
.icon-inside {
|
||||
color: #999;
|
||||
}
|
||||
select option {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-append .btn, .input-group-prepend .btn {
|
||||
@include box-shadow(none);
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
.input-group-append .btn:hover, .input-group-prepend .btn:hover {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.input-group > {
|
||||
.input-group-append > .btn, .input-group-prepend > .btn {
|
||||
padding: 0 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bg-primary, .badge-primary {
|
||||
background-color: $primary-color !important;
|
||||
}
|
||||
.bg-secondary {
|
||||
background-color: $secondary-color !important;
|
||||
}
|
||||
|
||||
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
|
||||
color: $primary-color !important;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: $primary-color-hover !important;
|
||||
}
|
||||
.text-secondary{
|
||||
color: $secondary-color !important;
|
||||
}
|
||||
|
||||
.text-light{
|
||||
color:#dee3e4!important;
|
||||
}
|
||||
.text-body{
|
||||
color: $text-color !important;
|
||||
}
|
||||
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover{background-color: $primary-color-hover!important;}
|
||||
|
||||
.border-primary {
|
||||
border-color: $primary-color !important;
|
||||
}
|
||||
.border-secondary {
|
||||
border-color: $secondary-color !important;
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
background-color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
&:hover {
|
||||
background-color: $primary-color-hover;
|
||||
border-color: $primary-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active{
|
||||
background-color: $primary-color-hover;
|
||||
border-color: $primary-color-hover;
|
||||
|
||||
}
|
||||
|
||||
.btn-primary.focus, .btn-primary:focus{
|
||||
background-color: $primary-color-hover;
|
||||
border-color: $primary-color-hover;
|
||||
}
|
||||
|
||||
.btn-primary:not(:disabled):not(.disabled).active:focus, .btn-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-primary.dropdown-toggle:focus{
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: $secondary-color;
|
||||
border-color: $secondary-color;
|
||||
}
|
||||
|
||||
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active{
|
||||
color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
&:hover {
|
||||
background-color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-secondary{
|
||||
color: $secondary-color;
|
||||
border-color: $secondary-color;
|
||||
&:hover {
|
||||
background-color: $secondary-color;
|
||||
border-color: $secondary-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-bar,
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active{
|
||||
background-color: $primary-color;
|
||||
}
|
||||
.page-item.active .page-link,
|
||||
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label::before,
|
||||
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
|
||||
.custom-control-input:checked ~ .custom-control-label:before{
|
||||
background-color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
.list-group-item.active{
|
||||
background-color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
.page-link {
|
||||
color: $primary-color;
|
||||
&:hover {
|
||||
color: $primary-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
|
||||
.page-link {
|
||||
border: none;
|
||||
border-radius: 0.25rem;
|
||||
margin: 0 0.22rem;
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
&:hover {
|
||||
background-color: #e9eff0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Vertical Multilple input group */
|
||||
|
||||
.vertical-input-group .input-group {
|
||||
&:first-child {
|
||||
padding-bottom: 0;
|
||||
* {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
&:last-child {
|
||||
padding-top: 0;
|
||||
* {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
&:not(:last-child):not(:first-child) {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
* {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
&:not(:first-child) * {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* styles-switcher */
|
||||
#styles-switcher {
|
||||
background: #fff;
|
||||
width: 202px;
|
||||
position: fixed;
|
||||
top: 35%;
|
||||
z-index: 99;
|
||||
padding: 20px;
|
||||
left: -202px;
|
||||
ul {
|
||||
padding: 0;
|
||||
li {
|
||||
list-style-type: none;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin: 4px 2px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
transition: all .2s ease-in-out;
|
||||
&.blue {
|
||||
background: #007bff;
|
||||
}
|
||||
&.brown {
|
||||
background: #795548;
|
||||
}
|
||||
&.purple {
|
||||
background: #6f42c1;
|
||||
}
|
||||
&.indigo {
|
||||
background: #6610f2;
|
||||
}
|
||||
&.red {
|
||||
background: #dc3545;
|
||||
}
|
||||
&.orange {
|
||||
background: #fd7e14;
|
||||
}
|
||||
&.yellow {
|
||||
background: #ffc107;
|
||||
}
|
||||
&.green {
|
||||
background: #28a745;
|
||||
}
|
||||
&.teal {
|
||||
background: #20c997;
|
||||
}
|
||||
&.cyan {
|
||||
background: #17a2b8;
|
||||
}
|
||||
&.active {
|
||||
transform: scale(0.7);
|
||||
cursor:default;
|
||||
}
|
||||
}
|
||||
}
|
||||
.switcher-toggle {
|
||||
position: absolute;
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-size: 1.25rem;
|
||||
border-radius: 0px 4px 4px 0;
|
||||
right: -40px;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
#reset-color{background: #e83e8c;}
|
||||
}
|
||||
|
||||
input:-internal-autofill-selected {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#styles-switcher.right{left:auto; right: -202px;}
|
||||
#styles-switcher.right .switcher-toggle{right: auto; left: -40px; border-radius: 4px 0px 0px 4px;}
|
||||
@@ -0,0 +1,188 @@
|
||||
/* =================================== */
|
||||
/* 6. Footer
|
||||
/* =================================== */
|
||||
|
||||
#footer {
|
||||
background: #fff;
|
||||
color: #252b33;
|
||||
margin-left:260px;
|
||||
padding: 66px 0px;
|
||||
padding: 4.125rem 0;
|
||||
.nav {
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
line-height: 12px;
|
||||
margin: 0;
|
||||
.nav-link {
|
||||
color: #252b33;
|
||||
-webkit-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
&:focus {
|
||||
color: $primary-color;
|
||||
-webkit-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
&:first-child .nav-link {
|
||||
padding-left: 0px;
|
||||
}
|
||||
&:last-child .nav-link{
|
||||
padding-right: 0px;
|
||||
}
|
||||
}
|
||||
.nav-link:hover {
|
||||
color: $primary-color;
|
||||
-webkit-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
.footer-copyright {
|
||||
border-top: 1px solid #e2e8ea;
|
||||
padding: 0px 0px;
|
||||
color: #67727c;
|
||||
.nav {
|
||||
.nav-item .nav-link {
|
||||
color: #67727c;
|
||||
}
|
||||
.nav-link:hover {
|
||||
color: $primary-color;
|
||||
-webkit-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav.flex-column .nav-item {
|
||||
padding: 0px;
|
||||
.nav-link {
|
||||
margin: 0.7rem 0px;
|
||||
}
|
||||
}
|
||||
&.footer-text-light {
|
||||
color: rgba(250, 250, 250, 0.8);
|
||||
.nav .nav-item .nav-link {
|
||||
color: rgba(250, 250, 250, 0.8);
|
||||
&:hover {
|
||||
color: rgba(250, 250, 250, 1);
|
||||
}
|
||||
}
|
||||
.footer-copyright {
|
||||
border-color: rgba(250, 250, 250, 0.15);
|
||||
color: rgba(250, 250, 250, 0.5);
|
||||
}
|
||||
&:not(.bg-primary) .social-icons-light.social-icons li a {
|
||||
color: rgba(250, 250, 250, 0.8);
|
||||
&:hover {
|
||||
color: rgba(250, 250, 250, 1);
|
||||
}
|
||||
}
|
||||
&.bg-primary {
|
||||
color: #fff;
|
||||
.nav .nav-item .nav-link {
|
||||
color: #fff;
|
||||
&:hover {
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
}
|
||||
.footer-copyright {
|
||||
border-color: rgba(250, 250, 250, 0.15);
|
||||
color: rgba(250, 250, 250, 0.9);
|
||||
}
|
||||
:not(.social-icons) a {
|
||||
color: #fff;
|
||||
&:hover {
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
#footer {
|
||||
margin-left:0px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 6.1 Social Icons ===*/
|
||||
.social-icons {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
li {
|
||||
margin: 0px 6px;
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
a {
|
||||
display: block;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
width: 26px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: #4d555a;
|
||||
text-decoration: none;
|
||||
@include transition(all 0.2s ease);
|
||||
}
|
||||
i {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
&.social-icons-sm li{
|
||||
margin: 0px 4px;
|
||||
}
|
||||
&.social-icons-sm li a {
|
||||
font-size: 15px;
|
||||
width:22px;
|
||||
}
|
||||
&.social-icons-lg li a {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
line-height:34px;
|
||||
font-size: 22px;
|
||||
}
|
||||
&.social-icons-light li a {
|
||||
color: #eee;
|
||||
}
|
||||
&.social-icons-muted li a {
|
||||
color: #aab1b8;
|
||||
}
|
||||
li:hover {
|
||||
a {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 6.2 Back to Top ===*/
|
||||
#back-to-top {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1030;
|
||||
bottom: 8px;
|
||||
right: 10px;
|
||||
background-color: rgba(0, 0, 0, 0.22);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
line-height: 34px;
|
||||
border-radius:3px;
|
||||
@include transition(all 0.3s ease-in-out);
|
||||
@include box-shadow(0px 5px 15px rgba(0, 0, 0, 0.15));
|
||||
&:hover {
|
||||
background-color: $primary-color;
|
||||
@include box-shadow(0px 5px 15px rgba(0, 0, 0, 0.25));
|
||||
@include transition(all 0.3s ease-in-out);
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
#back-to-top {z-index: 1029;}
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
/* =================================== */
|
||||
/* 4. Header
|
||||
/* =================================== */
|
||||
|
||||
#header {
|
||||
@include transition(all .5s ease);
|
||||
.navbar {
|
||||
padding: 0px;
|
||||
min-height:70px;
|
||||
}
|
||||
.logo {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-item-align: stretch;
|
||||
align-self: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 4.1 Main Navigation ===*/
|
||||
|
||||
.navbar-light .navbar-nav {
|
||||
.active > .nav-link {
|
||||
color: #0c2f55;
|
||||
}
|
||||
.nav-link {
|
||||
&.active, &.show {
|
||||
color: #0c2f55;
|
||||
}
|
||||
}
|
||||
.show > .nav-link {
|
||||
color: #0c2f55;
|
||||
}
|
||||
}
|
||||
|
||||
.primary-menu {
|
||||
display: -webkit-box !important;
|
||||
display: -ms-flexbox !important;
|
||||
display: flex !important;
|
||||
height: auto !important;
|
||||
-webkit-box-ordinal-group: 0;
|
||||
-ms-flex-item-align: stretch;
|
||||
align-self: stretch;
|
||||
background: #fff;
|
||||
border-bottom:1px solid #efefef;
|
||||
&.bg-transparent {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
border-bottom: 1px solid rgba(250, 250, 250, 0.3);
|
||||
}
|
||||
&.sticky-on{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1020;
|
||||
left: 0;
|
||||
@include box-shadow(0px 0px 10px rgba(0, 0, 0, 0.05));
|
||||
-webkit-animation: slide-down 0.7s;
|
||||
-moz-animation: slide-down 0.7s;
|
||||
animation: slide-down 0.7s;
|
||||
@-webkit-keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
|
||||
@-moz-keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
|
||||
@keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
|
||||
|
||||
.none-on-sticky{
|
||||
display:none!important;
|
||||
}
|
||||
}
|
||||
|
||||
ul.navbar-nav > li {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
+ li {
|
||||
margin-left: 2px;
|
||||
}
|
||||
a {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
> a:not(.btn) {
|
||||
height: 70px;
|
||||
padding:0px 0.85em;
|
||||
color: #252b33;
|
||||
@include transition(all .2s ease);
|
||||
position: relative;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
&:hover > a:not(.btn), & > a.active:not(.btn) {
|
||||
color: $primary-color;
|
||||
text-decoration:none;
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
a.btn{padding: 0.4rem 1.4rem;}
|
||||
&.dropdown {
|
||||
.dropdown-menu li {
|
||||
> a:not(.btn) {
|
||||
padding: 8px 0px;
|
||||
background-color: transparent;
|
||||
text-transform: none;
|
||||
color: #777;
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
&:hover > a:not(.btn) {
|
||||
color: $primary-color;
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
}
|
||||
&:hover > a:after {
|
||||
clear: both;
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent #fff transparent;
|
||||
position: absolute;
|
||||
border-width: 0px 7px 6px 7px;
|
||||
bottom: 0px;
|
||||
left: 50%;
|
||||
margin: 0 0 0 -5px;
|
||||
z-index: 1022;
|
||||
}
|
||||
.dropdown-menu {
|
||||
@include box-shadow(0px 0px 12px rgba(0, 0, 0, 0.176));
|
||||
border: 0px none;
|
||||
padding: 10px 15px;
|
||||
min-width: 220px;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
z-index:1021;
|
||||
}
|
||||
> .dropdown-toggle .arrow {
|
||||
display: none;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.dropdown-menu-right {
|
||||
left: auto !important;
|
||||
right: 100% !important;
|
||||
}
|
||||
ul.navbar-nav > li {
|
||||
&.dropdown-mega {
|
||||
position: static;
|
||||
> .dropdown-menu {
|
||||
width: 100%;
|
||||
padding: 20px 20px;
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
.dropdown-mega-content > .row > div {
|
||||
padding: 5px 5px 5px 20px;
|
||||
border-right: 1px solid #eee;
|
||||
&:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
.sub-title {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
margin-top: 1rem;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.dropdown-mega-submenu {
|
||||
list-style-type: none;
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
a.btn{font-size:14px; padding: 0.65rem 2rem; text-transform:uppercase;}
|
||||
&.dropdown {
|
||||
.dropdown-menu {
|
||||
.dropdown-menu {
|
||||
left: 100%;
|
||||
margin-top: -40px;
|
||||
}
|
||||
.dropdown-toggle:after {
|
||||
border-top: .4em solid transparent;
|
||||
border-right: 0;
|
||||
border-bottom: 0.4em solid transparent;
|
||||
border-left: 0.4em solid;
|
||||
}
|
||||
}
|
||||
.dropdown-toggle .arrow {
|
||||
position: absolute;
|
||||
min-width: 30px;
|
||||
height: 100%;
|
||||
right: 0px;
|
||||
top: 0;
|
||||
@include transition(all .2s ease);
|
||||
&:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
border-color: #000;
|
||||
border-top: 1px solid;
|
||||
border-right: 1px solid;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(45deg);
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dropdown-toggle:after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
&.navbar-line-under-text ul.navbar-nav > li {
|
||||
> a:not(.btn):after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 2px;
|
||||
width: 0;
|
||||
left: 50%;
|
||||
right: 0;
|
||||
bottom: 14px;
|
||||
background-color: transparent;
|
||||
color:#fff;
|
||||
border-bottom: 2px solid $primary-color;
|
||||
@include transition(all .3s ease-in-out);
|
||||
transform: translate(-50%,0) translateZ(0);
|
||||
-webkit-transform: translate(-50%,0) translateZ(0);
|
||||
}
|
||||
& > a:hover:not(.logo):after, & > a.active:after{
|
||||
width:calc(100% - 0.99em);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*== Color Options ==*/
|
||||
|
||||
.primary-menu.navbar-text-light .navbar-toggler span {background:#fff;}
|
||||
|
||||
.primary-menu.navbar-text-light .navbar-nav > li{
|
||||
> a:not(.btn) {
|
||||
color: #fff;
|
||||
}
|
||||
&:hover > a:not(.btn), & > a.active:not(.btn) {
|
||||
color: rgba(250, 250, 250, 0.75);
|
||||
}
|
||||
}
|
||||
|
||||
.primary-menu.navbar-text-light.navbar-line-under-text .navbar-nav > li{
|
||||
& > a:not(.logo):after, & > a.active:after{
|
||||
border-color:rgba(250, 250, 250, 0.60);
|
||||
}
|
||||
}
|
||||
|
||||
.primary-menu {
|
||||
&.navbar-dropdown-dark ul.navbar-nav > li {
|
||||
&.dropdown {
|
||||
.dropdown-menu {
|
||||
background-color: #252A2C;
|
||||
color: #fff;
|
||||
.dropdown-menu {
|
||||
background-color: #272c2e;
|
||||
}
|
||||
}
|
||||
&:hover > a:after {
|
||||
border-color: transparent transparent #252A2C transparent;
|
||||
}
|
||||
.dropdown-menu li {
|
||||
> a:not(.btn) {
|
||||
color: rgba(250, 250, 250, 0.8);
|
||||
}
|
||||
&:hover > a:not(.btn) {
|
||||
color: rgba(250, 250, 250, 1);
|
||||
font-weight:600;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.dropdown-mega .dropdown-mega-content > .row > div {
|
||||
border-color: #3a3a3a;
|
||||
}
|
||||
}
|
||||
&.navbar-dropdown-primary ul.navbar-nav > li {
|
||||
&.dropdown {
|
||||
.dropdown-menu {
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
.dropdown-menu {
|
||||
background-color: $primary-color;
|
||||
}
|
||||
}
|
||||
&:hover > a:after {
|
||||
border-color: transparent transparent $primary-color transparent;
|
||||
}
|
||||
.dropdown-menu li {
|
||||
> a:not(.btn) {
|
||||
color: rgba(250, 250, 250, 0.95);
|
||||
}
|
||||
&:hover > a:not(.btn) {
|
||||
color: rgba(250, 250, 250, 1);
|
||||
font-weight:600;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.dropdown-mega .dropdown-mega-content > .row > div {
|
||||
border-color: rgba(250, 250, 250, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Hamburger Menu Button */
|
||||
.navbar-toggler {
|
||||
width: 25px;
|
||||
height: 30px;
|
||||
padding: 10px;
|
||||
margin: 18px 15px;
|
||||
position: relative;
|
||||
border:none;
|
||||
@include rotate(0deg);
|
||||
@include transition(.5s ease-in-out);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: #3c3636;
|
||||
border-radius: 2px;
|
||||
opacity: 1;
|
||||
left: 0;
|
||||
@include rotate(0deg);
|
||||
@include transition(.25s ease-in-out);
|
||||
&:nth-child(1) {
|
||||
top: 7px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
top: 14px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
top: 21px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
|
||||
}
|
||||
}
|
||||
&.show span {
|
||||
&:nth-child(1) {
|
||||
top: 4px;
|
||||
left: 3px;
|
||||
@include rotate(45deg);
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 0%;
|
||||
opacity: 0;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
top: 22px;
|
||||
left: 3px;
|
||||
@include rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.navbar-accordion{position:initial;}
|
||||
|
||||
|
||||
// For Responsive Navbar
|
||||
@mixin navbar-responsive {
|
||||
|
||||
.navbar-collapse {
|
||||
position: absolute;
|
||||
top: 99%;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background: #fff;
|
||||
margin-top: 0px;
|
||||
z-index: 1000;
|
||||
@include box-shadow(0px 0px 15px rgba(0, 0, 0, 0.1));
|
||||
.navbar-nav {
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: 65vh;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
ul.navbar-nav {
|
||||
li {
|
||||
display: block;
|
||||
border-bottom: 1px solid #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
+ li {
|
||||
margin-left: 0px;
|
||||
}
|
||||
&.dropdown > .dropdown-toggle > .arrow.show:after {
|
||||
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
> a:hover:after, > a.active:after {
|
||||
content: none!important;
|
||||
width:0px!important;
|
||||
}
|
||||
&.dropdown{
|
||||
> .dropdown-toggle .arrow {
|
||||
display: block;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> li {
|
||||
> a:not(.btn) {
|
||||
height: auto;
|
||||
padding: 8px 0;
|
||||
position: relative;
|
||||
}
|
||||
&.dropdown {
|
||||
.dropdown-menu li > a:not(.btn) {
|
||||
padding: 8px 0;
|
||||
position: relative;
|
||||
}
|
||||
&:hover > a:after {
|
||||
content: none;
|
||||
}
|
||||
.dropdown-toggle .arrow:after {
|
||||
-webkit-transform: translate(-50%, -50%) rotate(134deg);
|
||||
transform: translate(-50%, -50%) rotate(134deg);
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
}
|
||||
}
|
||||
> li {
|
||||
&.dropdown .dropdown-menu {
|
||||
margin: 0;
|
||||
@include box-shadow(none);
|
||||
border: none;
|
||||
padding: 0px 0px 0px 15px;
|
||||
.dropdown-menu {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
&.dropdown-mega {
|
||||
.dropdown-mega-content > .row > div {
|
||||
padding: 0px 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.navbar-text-light .navbar-collapse{background:rgba(0,0,0,0.95);}
|
||||
|
||||
&.navbar-text-light .navbar-collapse ul.navbar-nav li{
|
||||
border-color:rgba(250,250,250,0.15);
|
||||
}
|
||||
|
||||
|
||||
&.navbar-dropdown-dark .navbar-collapse {
|
||||
background-color: #252A2C;
|
||||
}
|
||||
|
||||
&.navbar-dropdown-primary .navbar-collapse {
|
||||
background-color: $primary-color;
|
||||
}
|
||||
|
||||
&.navbar-dropdown-primary ul.navbar-nav > li.dropdown .dropdown-menu .dropdown-menu {
|
||||
background-color: $primary-color;
|
||||
}
|
||||
&.navbar-dropdown-dark ul.navbar-nav {
|
||||
li {
|
||||
border-color: #444;
|
||||
}
|
||||
> li {
|
||||
> a {
|
||||
color: #a3a2a2;
|
||||
}
|
||||
&:hover > a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.navbar-dropdown-primary ul.navbar-nav {
|
||||
li {
|
||||
border-color: rgba(250, 250, 250, 0.2);
|
||||
}
|
||||
> li {
|
||||
> a {
|
||||
color: rgba(250, 250, 250, 0.8);
|
||||
}
|
||||
&:hover > a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.navbar-expand-none{
|
||||
@include navbar-responsive;
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.navbar-expand-sm{
|
||||
@include navbar-responsive;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.navbar-expand-md{
|
||||
@include navbar-responsive;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.navbar-expand-lg{
|
||||
@include navbar-responsive;
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-down(lg) {
|
||||
.navbar-expand-xl{
|
||||
@include navbar-responsive;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/* =================================== */
|
||||
/* 2. Helpers Classes
|
||||
/* =================================== */
|
||||
|
||||
/* Box Shadow */
|
||||
.shadow-md {
|
||||
@include box-shadow(0px 0px 50px -35px rgba(0, 0, 0, 0.4)!important);
|
||||
}
|
||||
|
||||
/* Border Radius */
|
||||
|
||||
.rounded-lg{
|
||||
border-radius: 0.6rem !important;
|
||||
}
|
||||
|
||||
.rounded-top-0{
|
||||
border-top-left-radius:0px!important;
|
||||
border-top-right-radius:0px!important;
|
||||
}
|
||||
.rounded-bottom-0{
|
||||
border-bottom-left-radius:0px!important;
|
||||
border-bottom-right-radius:0px!important;
|
||||
}
|
||||
.rounded-left-0{
|
||||
border-top-left-radius:0px!important;
|
||||
border-bottom-left-radius:0px!important;
|
||||
}
|
||||
.rounded-right-0{border-top-right-radius:0px!important;
|
||||
border-bottom-right-radius:0px!important;
|
||||
}
|
||||
|
||||
|
||||
/* Border Size */
|
||||
|
||||
.border-1{
|
||||
border-width:1px!important;
|
||||
}
|
||||
.border-2{
|
||||
border-width:2px!important;
|
||||
}
|
||||
.border-3{
|
||||
border-width:3px!important;
|
||||
}
|
||||
.border-4{
|
||||
border-width:4px!important;
|
||||
}
|
||||
.border-5{
|
||||
border-width:5px!important;
|
||||
}
|
||||
|
||||
/* Text Size */
|
||||
.text-0 {
|
||||
font-size: 11px !important;
|
||||
font-size: 0.6875rem !important;
|
||||
}
|
||||
.text-1 {
|
||||
font-size: 12px !important;
|
||||
font-size: 0.75rem !important;
|
||||
}
|
||||
.text-2 {
|
||||
font-size: 14px !important;
|
||||
font-size: 0.875rem !important;
|
||||
}
|
||||
.text-3 {
|
||||
font-size: 16px !important;
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
.text-4 {
|
||||
font-size: 18px !important;
|
||||
font-size: 1.125rem !important;
|
||||
}
|
||||
.text-5 {
|
||||
font-size: 21px !important;
|
||||
font-size: 1.3125rem !important;
|
||||
}
|
||||
.text-6 {
|
||||
font-size: 24px !important;
|
||||
font-size: 1.50rem !important;
|
||||
}
|
||||
.text-7 {
|
||||
font-size: 28px !important;
|
||||
font-size: 1.75rem !important;
|
||||
}
|
||||
.text-8 {
|
||||
font-size: 32px !important;
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
.text-9 {
|
||||
font-size: 36px !important;
|
||||
font-size: 2.25rem !important;
|
||||
}
|
||||
.text-10 {
|
||||
font-size: 40px !important;
|
||||
font-size: 2.50rem !important;
|
||||
}
|
||||
.text-11 {
|
||||
@include rfs(44, true);
|
||||
}
|
||||
.text-12 {
|
||||
@include rfs(48, true);
|
||||
}
|
||||
.text-13 {
|
||||
@include rfs(52, true);
|
||||
}
|
||||
.text-14 {
|
||||
@include rfs(56, true);
|
||||
}
|
||||
.text-15 {
|
||||
@include rfs(60, true);
|
||||
}
|
||||
.text-16 {
|
||||
@include rfs(64, true);
|
||||
}
|
||||
.text-17 {
|
||||
@include rfs(72, true);
|
||||
}
|
||||
.text-18 {
|
||||
@include rfs(80, true);
|
||||
}
|
||||
.text-19 {
|
||||
@include rfs(84, true);
|
||||
}
|
||||
.text-20 {
|
||||
@include rfs(92, true);
|
||||
}
|
||||
.text-21 {
|
||||
@include rfs(104, true);
|
||||
}
|
||||
.text-22 {
|
||||
@include rfs(112, true);
|
||||
}
|
||||
.text-23 {
|
||||
@include rfs(124, true);
|
||||
}
|
||||
.text-24 {
|
||||
@include rfs(132, true);
|
||||
}
|
||||
.text-25 {
|
||||
@include rfs(144, true);
|
||||
}
|
||||
|
||||
.text-11, .text-12, .text-13, .text-14, .text-15, .text-16, .text-17, .text-18, .text-19, .text-20, .text-21, .text-22, .text-23, .text-24, .text-25{
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
|
||||
/* Line height */
|
||||
.line-height-07 {
|
||||
line-height: 0.7 !important;
|
||||
}
|
||||
|
||||
.line-height-1 {
|
||||
line-height: 1 !important;
|
||||
}
|
||||
|
||||
.line-height-2 {
|
||||
line-height: 1.2 !important;
|
||||
}
|
||||
|
||||
.line-height-3 {
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
.line-height-4 {
|
||||
line-height: 1.6 !important;
|
||||
}
|
||||
|
||||
.line-height-5 {
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
/* Font Weight */
|
||||
.font-weight-100 {
|
||||
font-weight: 100 !important;
|
||||
}
|
||||
|
||||
.font-weight-200 {
|
||||
font-weight: 200 !important;
|
||||
}
|
||||
|
||||
.font-weight-300 {
|
||||
font-weight: 300 !important;
|
||||
}
|
||||
|
||||
.font-weight-400 {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
.font-weight-500 {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.font-weight-600 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
.font-weight-700 {
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
.font-weight-800 {
|
||||
font-weight: 800 !important;
|
||||
}
|
||||
.font-weight-900 {
|
||||
font-weight: 900 !important;
|
||||
}
|
||||
|
||||
/* Opacity */
|
||||
.opacity-0 {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.opacity-1 {
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.opacity-2 {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.opacity-3 {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.opacity-4 {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.opacity-5 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.opacity-6 {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.opacity-7 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.opacity-8 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.opacity-9 {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.opacity-10 {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Background light */
|
||||
.bg-light-1 {
|
||||
background-color: $gray-200 !important;
|
||||
}
|
||||
|
||||
.bg-light-2 {
|
||||
background-color: $gray-300 !important;
|
||||
}
|
||||
|
||||
.bg-light-3 {
|
||||
background-color: $gray-400 !important;
|
||||
}
|
||||
|
||||
.bg-light-4 {
|
||||
background-color: $gray-500 !important;
|
||||
}
|
||||
|
||||
|
||||
/* Background Dark */
|
||||
.bg-dark {
|
||||
background-color: #111418 !important;
|
||||
}
|
||||
|
||||
.bg-dark-1 {
|
||||
background-color: $gray-900 !important;
|
||||
}
|
||||
|
||||
.bg-dark-2 {
|
||||
background-color: $gray-800 !important;
|
||||
}
|
||||
|
||||
.bg-dark-3 {
|
||||
background-color: $gray-700 !important;
|
||||
}
|
||||
|
||||
.bg-dark-4 {
|
||||
background-color: $gray-600 !important;
|
||||
}
|
||||
|
||||
|
||||
/* Progress Bar */
|
||||
.progress-sm {
|
||||
height: 0.5rem !important;
|
||||
}
|
||||
|
||||
.progress-lg {
|
||||
height: 1.5rem !important;
|
||||
}
|
||||
|
||||
hr{
|
||||
border-top:1px solid rgba(16,85,96,.1);
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/* =================================== */
|
||||
/* 3. Layouts
|
||||
/* =================================== */
|
||||
|
||||
#main-wrapper {
|
||||
background:#fff;
|
||||
}
|
||||
|
||||
.box {
|
||||
#main-wrapper {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
@include box-shadow(0px 0px 10px rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
.idocs-navigation {
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.container {
|
||||
max-width: 1170px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== 3.1 Side Navigation ===*/
|
||||
|
||||
.idocs-navigation {
|
||||
position: fixed;
|
||||
top: 70px;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
width: 260px;
|
||||
height: calc(100% - 70px);
|
||||
z-index: 1;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s;
|
||||
> .nav {
|
||||
padding: 30px 0;
|
||||
}
|
||||
.nav {
|
||||
.nav-item {
|
||||
position: relative;
|
||||
}
|
||||
.nav {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
.nav-link {
|
||||
position: relative;
|
||||
padding: 6px 30px;
|
||||
line-height: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nav-item {
|
||||
&:hover > .nav-link, .nav-link.active {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
.nav {
|
||||
.nav-item .nav-link {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
height: 100%;
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.12);
|
||||
width: 1px;
|
||||
top: 0;
|
||||
}
|
||||
&.active:after {
|
||||
border-color: $primary-color;
|
||||
border-width: 2px;
|
||||
}
|
||||
}
|
||||
display: none;
|
||||
border-left: 1px solid regba(0, 0, 0, 0.3);
|
||||
}
|
||||
.nav-item .nav-link.active + .nav {
|
||||
display: block;
|
||||
}
|
||||
.nav {
|
||||
.nav-link {
|
||||
color: #6a6a6a;
|
||||
padding: 4px 30px 4px 45px;
|
||||
font-size: 15px;
|
||||
text-transform: none;
|
||||
}
|
||||
.nav {
|
||||
.nav-link {
|
||||
padding: 4px 30px 4px 60px;
|
||||
font-size: 15px;
|
||||
}
|
||||
.nav-item .nav-link:after {
|
||||
left: 45px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .nav > .nav-item > .nav-link.active:after {
|
||||
position: absolute;
|
||||
content: " ";
|
||||
top: 50%;
|
||||
right: 18px;
|
||||
border-color: #000;
|
||||
border-top: 2px solid;
|
||||
border-right: 2px solid;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
-webkit-transform: translate(-50%, -50%) rotate(45deg);
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
&.docs-navigation-dark .nav {
|
||||
.nav-link {
|
||||
color: rgba(250, 250, 250, 0.85);
|
||||
}
|
||||
.nav {
|
||||
.nav-link {
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
}
|
||||
.nav-item .nav-link {
|
||||
&:after {
|
||||
border-color: rgba(250, 250, 250, 0.2);
|
||||
}
|
||||
&.active:after {
|
||||
border-color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=== 3.2 Docs Content ===*/
|
||||
|
||||
.idocs-content {
|
||||
position: relative;
|
||||
margin-left: 260px;
|
||||
padding: 0px 50px 50px;
|
||||
min-height: 750px;
|
||||
transition: all 0.3s;
|
||||
|
||||
section:first-child {
|
||||
padding-top: 3rem;
|
||||
}
|
||||
ol li, ul li {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.idocs-navigation {
|
||||
margin-left: -260px;
|
||||
|
||||
&.active {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.idocs-content {
|
||||
margin-left:0px;
|
||||
padding:0px;
|
||||
}
|
||||
}
|
||||
|
||||
/*=== 3.3 Section Divider ===*/
|
||||
|
||||
.divider{margin: 4rem 0;}
|
||||
@@ -0,0 +1,31 @@
|
||||
//---------- @mixins ----------//
|
||||
|
||||
@mixin box-shadow($val...) {
|
||||
-webkit-box-shadow: ($val);
|
||||
box-shadow: ($val);
|
||||
}
|
||||
|
||||
@mixin transition($val...) {
|
||||
-webkit-transition: ($val);
|
||||
transition: ($val);
|
||||
}
|
||||
|
||||
@mixin translateY($val...) {
|
||||
-webkit-transform: translateY($val);
|
||||
transform: translateY($val);
|
||||
}
|
||||
|
||||
@mixin translateX($val...) {
|
||||
-webkit-transform: translateX($val);
|
||||
transform: translateX($val);
|
||||
}
|
||||
|
||||
@mixin rotate($val){
|
||||
-webkit-transform: rotate($val);
|
||||
transform: rotate($val);
|
||||
}
|
||||
|
||||
@mixin scale($val){
|
||||
-webkit-transform: scale($val);
|
||||
transform: scale($val);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/* =================================== */
|
||||
/* 1. Basic Style
|
||||
/* =================================== */
|
||||
|
||||
body, html {
|
||||
height:100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: $body-bg;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
/*-------- Preloader --------*/
|
||||
.preloader {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999999999 !important;
|
||||
background-color: #fff;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
.lds-ellipsis {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-top: -40px;
|
||||
margin-left: -40px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
div {
|
||||
position: absolute;
|
||||
top: 33px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
background: #000;
|
||||
animation-timing-function: cubic-bezier(0, 1, 1, 0);
|
||||
&:nth-child(1) {
|
||||
left: 8px;
|
||||
animation: lds-ellipsis1 0.6s infinite;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
left: 8px;
|
||||
animation: lds-ellipsis2 0.6s infinite;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
left: 32px;
|
||||
animation: lds-ellipsis2 0.6s infinite;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
left: 56px;
|
||||
animation: lds-ellipsis3 0.6s infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis1 {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis3 {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis2 {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
100% {
|
||||
transform: translate(24px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Preloader Magnific Popup ----*/
|
||||
.mfp-container .preloader{
|
||||
background: transparent;
|
||||
.lds-ellipsis div{
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: $primary-color;
|
||||
color: #fff;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
code{padding: 2px 5px; background-color: #f9f2f4; border-radius: 4px;}
|
||||
|
||||
form {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: inherit;
|
||||
}
|
||||
a, a:focus {
|
||||
color: $primary-color;
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
a:hover, a:active {
|
||||
color: $primary-color-hover;
|
||||
|
||||
@include transition(all .2s ease);
|
||||
}
|
||||
|
||||
a:focus, a:active,
|
||||
.btn.active.focus,
|
||||
.btn.active:focus,
|
||||
.btn.focus,
|
||||
.btn:active.focus,
|
||||
.btn:active:focus,
|
||||
.btn:focus,
|
||||
button:focus,
|
||||
button:active{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 5px solid #eee;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: $title-color;
|
||||
line-height: 1.5;
|
||||
margin: 0 0 1.5rem 0;
|
||||
font-family:Roboto, sans-serif;
|
||||
}
|
||||
|
||||
h1{font-size:3rem;}
|
||||
|
||||
h2{font-size:2.2rem;}
|
||||
|
||||
dl, ol, ul, pre, blockquote, .table{margin-bottom:1.8rem;}
|
||||
|
||||
/*=== Highlight Js ===*/
|
||||
.hljs {padding: 1.5rem;}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*===========================================================
|
||||
|
||||
Template Name: iDocs - One Page Documentation HTML Template
|
||||
Author: Harnish Design
|
||||
Template URL: http://demo.harnishdesign.net/html/idocs
|
||||
Author URL: https://themeforest.net/user/harnishdesign
|
||||
File Description : Main css file of the template
|
||||
|
||||
=================================================
|
||||
Table of Contents
|
||||
=================================================
|
||||
|
||||
1. Basic
|
||||
2. Helpers Classes
|
||||
3. Layouts
|
||||
3.1 Side Navigation
|
||||
3.2 Docs Content
|
||||
3.3 Section Divider
|
||||
4. Header
|
||||
4.1 Main Navigation
|
||||
5 Elements
|
||||
5.1 List Style
|
||||
5.2 Changelog
|
||||
5.3 Accordion & Toggle
|
||||
5.4 Nav
|
||||
5.5 Tabs
|
||||
5.6 Popup Img
|
||||
5.7 Featured Box
|
||||
6 Footer
|
||||
6.1 Social Icons
|
||||
6.2 Back to Top
|
||||
7 Extra
|
||||
|
||||
=======================================================*/
|
||||
|
||||
//-------------------- Base Colors --------------------//
|
||||
|
||||
$primary-color: #0366d6;
|
||||
$primary-color-hover: darken($primary-color, 7%);
|
||||
$secondary-color: $secondary;
|
||||
|
||||
$body-bg: #dddddd;
|
||||
$text-color: #4c4d4d;
|
||||
$title-color: #252b33;
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
.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 {
|
||||
display: flex;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// 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;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: $btn-white-space;
|
||||
vertical-align: middle;
|
||||
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) {
|
||||
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
|
||||
|
||||
&:active,
|
||||
&.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;
|
||||
}
|
||||
|
||||
&: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%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
//
|
||||
// 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 {
|
||||
border-top: inherit;
|
||||
border-bottom: inherit;
|
||||
|
||||
&:first-child {
|
||||
border-top-width: 0;
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-width: 0;
|
||||
@include border-bottom-radius($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;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
color: $card-cap-color;
|
||||
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;
|
||||
@include border-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
.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 {
|
||||
overflow-anchor: none;
|
||||
|
||||
> .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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
.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;
|
||||
}
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
a.close.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,523 @@
|
||||
// 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;
|
||||
z-index: 1;
|
||||
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 {
|
||||
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
|
||||
}
|
||||
&:indeterminate ~ .custom-control-label::before {
|
||||
@include gradient-bg($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 {
|
||||
@include gradient-bg($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 {
|
||||
@include gradient-bg($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 {
|
||||
@include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
// 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
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
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-header-padding;
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
&.form-control {
|
||||
appearance: none; // Fix appearance for date inputs in Safari
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
// 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") {
|
||||
@if length($map) > 0 {
|
||||
$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 {
|
||||
// Do not escape the url brackets
|
||||
@if str-index($string, "url(") == 1 {
|
||||
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
|
||||
} @else {
|
||||
$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);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// 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,
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Extend each breakpoint which is smaller or equal to the current breakpoint
|
||||
$extend-breakpoint: true;
|
||||
|
||||
@each $name, $width in $grid-breakpoints {
|
||||
@if ($extend-breakpoint) {
|
||||
.container#{breakpoint-infix($name, $grid-breakpoints)} {
|
||||
@extend %responsive-container-#{$breakpoint};
|
||||
}
|
||||
|
||||
// Once the current breakpoint is reached, stop extending
|
||||
@if ($breakpoint == $name) {
|
||||
$extend-breakpoint: false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
// 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 auto;
|
||||
width: 1%;
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// 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;
|
||||
@include border-radius($list-group-border-radius);
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
background-color: $list-group-bg;
|
||||
border: $list-group-border-width solid $list-group-border-color;
|
||||
|
||||
&:first-child {
|
||||
@include border-top-radius(inherit);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-bottom-radius(inherit);
|
||||
}
|
||||
|
||||
&.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 {
|
||||
@include border-radius(0);
|
||||
|
||||
> .list-group-item {
|
||||
border-width: 0 0 $list-group-border-width;
|
||||
|
||||
&: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));
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
.media {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.media-body {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -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";
|
||||
@@ -0,0 +1,240 @@
|
||||
// .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);
|
||||
height: min-content; // Reset height to 0 except on IE
|
||||
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
|
||||
> * {
|
||||
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);
|
||||
height: min-content;
|
||||
}
|
||||
}
|
||||
|
||||
.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; }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// 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;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
|
||||
@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-link,
|
||||
.nav-item {
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-justified {
|
||||
> .nav-link,
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
.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;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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
|
||||
line-height: 0;
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,480 @@
|
||||
// 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]):not([class]) {
|
||||
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;
|
||||
// Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,
|
||||
// making it impossible to interact with the content
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Figures
|
||||
//
|
||||
|
||||
figure {
|
||||
// Apply a consistent margin strategy (matches our type styles).
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Images and content
|
||||
//
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none; // Remove the border on images inside links in IE 10-.
|
||||
}
|
||||
|
||||
svg {
|
||||
// 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
|
||||
}
|
||||
|
||||
// Set the cursor for non-`<button>` buttons
|
||||
//
|
||||
// Details at https://github.com/twbs/bootstrap/pull/30562
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 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-
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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)};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
.toast {
|
||||
// Prevents from shrinking in IE11, when in a flex container
|
||||
// See https://github.com/twbs/bootstrap/issues/28341
|
||||
flex-basis: $toast-max-width;
|
||||
max-width: $toast-max-width;
|
||||
@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;
|
||||
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;
|
||||
@include border-top-radius(subtract($toast-border-radius, $toast-border-width));
|
||||
}
|
||||
|
||||
.toast-body {
|
||||
padding: $toast-padding-x; // apply to both vertical and horizontal
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
@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/interactions";
|
||||
@import "utilities/overflow";
|
||||
@import "utilities/position";
|
||||
@import "utilities/screenreaders";
|
||||
@import "utilities/shadows";
|
||||
@import "utilities/sizing";
|
||||
@import "utilities/spacing";
|
||||
@import "utilities/stretched-link";
|
||||
@import "utilities/text";
|
||||
@import "utilities/visibility";
|
||||
@@ -0,0 +1,29 @@
|
||||
/*!
|
||||
* Bootstrap Grid v4.5.2 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/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";
|
||||
@@ -0,0 +1,12 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.5.2 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/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";
|
||||
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/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";
|
||||
@@ -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%);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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, $ignore-warning: false) {
|
||||
#{$parent} {
|
||||
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
|
||||
}
|
||||
@include deprecate("The `bg-gradient-variant` mixin", "v4.5.0", "v5", $ignore-warning);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// stylelint-disable property-blacklist
|
||||
// Single side border-radius
|
||||
|
||||
// Helper function to replace negative values with 0
|
||||
@function valid-radius($radius) {
|
||||
$return: ();
|
||||
@each $value in $radius {
|
||||
@if type-of($value) == number {
|
||||
$return: append($return, max($value, 0));
|
||||
} @else {
|
||||
$return: append($return, $value);
|
||||
}
|
||||
}
|
||||
@return $return;
|
||||
}
|
||||
|
||||
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
|
||||
@if $enable-rounded {
|
||||
border-radius: valid-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: valid-radius($radius);
|
||||
border-top-right-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-right-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-top-right-radius: valid-radius($radius);
|
||||
border-bottom-right-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-bottom-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-bottom-right-radius: valid-radius($radius);
|
||||
border-bottom-left-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-left-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-top-left-radius: valid-radius($radius);
|
||||
border-bottom-left-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-top-left-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-top-left-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-top-right-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-top-right-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-bottom-right-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-bottom-right-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-bottom-left-radius($radius) {
|
||||
@if $enable-rounded {
|
||||
border-bottom-left-radius: valid-radius($radius);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// Breakpoint viewport sizes and media queries.
|
||||
//
|
||||
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
|
||||
//
|
||||
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
|
||||
//
|
||||
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
|
||||
|
||||
// Name of the next breakpoint, or null for the last breakpoint.
|
||||
//
|
||||
// >> breakpoint-next(sm)
|
||||
// md
|
||||
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// md
|
||||
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
|
||||
// md
|
||||
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
|
||||
$n: index($breakpoint-names, $name);
|
||||
@return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
|
||||
}
|
||||
|
||||
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
|
||||
//
|
||||
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// 576px
|
||||
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
|
||||
$min: map-get($breakpoints, $name);
|
||||
@return if($min != 0, $min, null);
|
||||
}
|
||||
|
||||
// Maximum breakpoint width. Null for the largest (last) breakpoint.
|
||||
// The maximum value is calculated as the minimum of the next one less 0.02px
|
||||
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
|
||||
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
|
||||
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
|
||||
// See https://bugs.webkit.org/show_bug.cgi?id=178261
|
||||
//
|
||||
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// 767.98px
|
||||
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
|
||||
$next: breakpoint-next($name, $breakpoints);
|
||||
@return if($next, breakpoint-min($next, $breakpoints) - .02, null);
|
||||
}
|
||||
|
||||
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
|
||||
// Useful for making responsive utilities.
|
||||
//
|
||||
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// "" (Returns a blank string)
|
||||
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// "-sm"
|
||||
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
|
||||
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
|
||||
}
|
||||
|
||||
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
|
||||
// Makes the @content apply to the given breakpoint and wider.
|
||||
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
|
||||
$min: breakpoint-min($name, $breakpoints);
|
||||
@if $min {
|
||||
@media (min-width: $min) {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
|
||||
// Makes the @content apply to the given breakpoint and narrower.
|
||||
@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
|
||||
$max: breakpoint-max($name, $breakpoints);
|
||||
@if $max {
|
||||
@media (max-width: $max) {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// Media that spans multiple breakpoint widths.
|
||||
// Makes the @content apply between the min and max breakpoints
|
||||
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
|
||||
$min: breakpoint-min($lower, $breakpoints);
|
||||
$max: breakpoint-max($upper, $breakpoints);
|
||||
|
||||
@if $min != null and $max != null {
|
||||
@media (min-width: $min) and (max-width: $max) {
|
||||
@content;
|
||||
}
|
||||
} @else if $max == null {
|
||||
@include media-breakpoint-up($lower, $breakpoints) {
|
||||
@content;
|
||||
}
|
||||
} @else if $min == null {
|
||||
@include media-breakpoint-down($upper, $breakpoints) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Media between the breakpoint's minimum and maximum widths.
|
||||
// No minimum for the smallest breakpoint, and no maximum for the largest one.
|
||||
// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
|
||||
@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
|
||||
$min: breakpoint-min($name, $breakpoints);
|
||||
$max: breakpoint-max($name, $breakpoints);
|
||||
|
||||
@if $min != null and $max != null {
|
||||
@media (min-width: $min) and (max-width: $max) {
|
||||
@content;
|
||||
}
|
||||
} @else if $max == null {
|
||||
@include media-breakpoint-up($name, $breakpoints) {
|
||||
@content;
|
||||
}
|
||||
} @else if $min == null {
|
||||
@include media-breakpoint-down($name, $breakpoints) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// Button variants
|
||||
//
|
||||
// Easily pump out default styles, as well as :hover, :focus, :active,
|
||||
// and disabled options for all buttons
|
||||
|
||||
@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
|
||||
color: color-yiq($background);
|
||||
@include gradient-bg($background);
|
||||
border-color: $border;
|
||||
@include box-shadow($btn-box-shadow);
|
||||
|
||||
@include hover() {
|
||||
color: color-yiq($hover-background);
|
||||
@include gradient-bg($hover-background);
|
||||
border-color: $hover-border;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
color: color-yiq($hover-background);
|
||||
@include gradient-bg($hover-background);
|
||||
border-color: $hover-border;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled comes first so active can properly restyle
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: color-yiq($background);
|
||||
background-color: $background;
|
||||
border-color: $border;
|
||||
// Remove CSS gradients if they're enabled
|
||||
@if $enable-gradients {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active,
|
||||
&:not(:disabled):not(.disabled).active,
|
||||
.show > &.dropdown-toggle {
|
||||
color: color-yiq($active-background);
|
||||
background-color: $active-background;
|
||||
@if $enable-gradients {
|
||||
background-image: none; // Remove the gradient for the pressed/active state
|
||||
}
|
||||
border-color: $active-border;
|
||||
|
||||
&:focus {
|
||||
@if $enable-shadows and $btn-active-box-shadow != none {
|
||||
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
|
||||
color: $color;
|
||||
border-color: $color;
|
||||
|
||||
@include hover() {
|
||||
color: $color-hover;
|
||||
background-color: $active-background;
|
||||
border-color: $active-border;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $color;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active,
|
||||
&:not(:disabled):not(.disabled).active,
|
||||
.show > &.dropdown-toggle {
|
||||
color: color-yiq($active-background);
|
||||
background-color: $active-background;
|
||||
border-color: $active-border;
|
||||
|
||||
&:focus {
|
||||
@if $enable-shadows and $btn-active-box-shadow != none {
|
||||
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Button sizes
|
||||
@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
|
||||
padding: $padding-y $padding-x;
|
||||
@include font-size($font-size);
|
||||
line-height: $line-height;
|
||||
// Manually declare to provide an override to the browser default
|
||||
@include border-radius($border-radius, 0);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
@mixin caret-down() {
|
||||
border-top: $caret-width solid;
|
||||
border-right: $caret-width solid transparent;
|
||||
border-bottom: 0;
|
||||
border-left: $caret-width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret-up() {
|
||||
border-top: 0;
|
||||
border-right: $caret-width solid transparent;
|
||||
border-bottom: $caret-width solid;
|
||||
border-left: $caret-width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret-right() {
|
||||
border-top: $caret-width solid transparent;
|
||||
border-right: 0;
|
||||
border-bottom: $caret-width solid transparent;
|
||||
border-left: $caret-width solid;
|
||||
}
|
||||
|
||||
@mixin caret-left() {
|
||||
border-top: $caret-width solid transparent;
|
||||
border-right: $caret-width solid;
|
||||
border-bottom: $caret-width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret($direction: down) {
|
||||
@if $enable-caret {
|
||||
&::after {
|
||||
display: inline-block;
|
||||
margin-left: $caret-spacing;
|
||||
vertical-align: $caret-vertical-align;
|
||||
content: "";
|
||||
@if $direction == down {
|
||||
@include caret-down();
|
||||
} @else if $direction == up {
|
||||
@include caret-up();
|
||||
} @else if $direction == right {
|
||||
@include caret-right();
|
||||
}
|
||||
}
|
||||
|
||||
@if $direction == left {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
margin-right: $caret-spacing;
|
||||
vertical-align: $caret-vertical-align;
|
||||
content: "";
|
||||
@include caret-left();
|
||||
}
|
||||
}
|
||||
|
||||
&:empty::after {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@mixin clearfix() {
|
||||
&::after {
|
||||
display: block;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Deprecate mixin
|
||||
//
|
||||
// This mixin can be used to deprecate mixins or functions.
|
||||
// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
|
||||
// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
|
||||
@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
|
||||
@if ($enable-deprecation-messages != false and $ignore-warning != true) {
|
||||
@warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// stylelint-disable declaration-no-important
|
||||
|
||||
@mixin float-left() {
|
||||
float: left !important;
|
||||
@include deprecate("The `float-left` mixin", "v4.3.0", "v5");
|
||||
}
|
||||
@mixin float-right() {
|
||||
float: right !important;
|
||||
@include deprecate("The `float-right` mixin", "v4.3.0", "v5");
|
||||
}
|
||||
@mixin float-none() {
|
||||
float: none !important;
|
||||
@include deprecate("The `float-none` mixin", "v4.3.0", "v5");
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
// Form control focus state
|
||||
//
|
||||
// Generate a customized focus state and for any input with the specified color,
|
||||
// which defaults to the `$input-focus-border-color` variable.
|
||||
//
|
||||
// We highly encourage you to not customize the default value, but instead use
|
||||
// this to tweak colors on an as-needed basis. This aesthetic change is based on
|
||||
// WebKit's default styles, but applicable to a wider range of browsers. Its
|
||||
// usability and accessibility should be taken into account with any change.
|
||||
//
|
||||
// Example usage: change the default blue border and shadow to white for better
|
||||
// contrast against a dark gray background.
|
||||
@mixin form-control-focus($ignore-warning: false) {
|
||||
&:focus {
|
||||
color: $input-focus-color;
|
||||
background-color: $input-focus-bg;
|
||||
border-color: $input-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $input-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
@include deprecate("The `form-control-focus()` mixin", "v4.4.0", "v5", $ignore-warning);
|
||||
}
|
||||
|
||||
// This mixin uses an `if()` technique to be compatible with Dart Sass
|
||||
// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
|
||||
@mixin form-validation-state-selector($state) {
|
||||
@if ($state == "valid" or $state == "invalid") {
|
||||
.was-validated #{if(&, "&", "")}:#{$state},
|
||||
#{if(&, "&", "")}.is-#{$state} {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
#{if(&, "&", "")}.is-#{$state} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin form-validation-state($state, $color, $icon) {
|
||||
.#{$state}-feedback {
|
||||
display: none;
|
||||
width: 100%;
|
||||
margin-top: $form-feedback-margin-top;
|
||||
@include font-size($form-feedback-font-size);
|
||||
color: $color;
|
||||
}
|
||||
|
||||
.#{$state}-tooltip {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
display: none;
|
||||
max-width: 100%; // Contain to parent when possible
|
||||
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
|
||||
margin-top: .1rem;
|
||||
@include font-size($form-feedback-tooltip-font-size);
|
||||
line-height: $form-feedback-tooltip-line-height;
|
||||
color: color-yiq($color);
|
||||
background-color: rgba($color, $form-feedback-tooltip-opacity);
|
||||
@include border-radius($form-feedback-tooltip-border-radius);
|
||||
}
|
||||
|
||||
@include form-validation-state-selector($state) {
|
||||
~ .#{$state}-feedback,
|
||||
~ .#{$state}-tooltip {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control {
|
||||
@include form-validation-state-selector($state) {
|
||||
border-color: $color;
|
||||
|
||||
@if $enable-validation-icons {
|
||||
padding-right: $input-height-inner;
|
||||
background-image: escape-svg($icon);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right $input-height-inner-quarter center;
|
||||
background-size: $input-height-inner-half $input-height-inner-half;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $color;
|
||||
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
textarea.form-control {
|
||||
@include form-validation-state-selector($state) {
|
||||
@if $enable-validation-icons {
|
||||
padding-right: $input-height-inner;
|
||||
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
@include form-validation-state-selector($state) {
|
||||
border-color: $color;
|
||||
|
||||
@if $enable-validation-icons {
|
||||
padding-right: $custom-select-feedback-icon-padding-right;
|
||||
background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $color;
|
||||
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
@include form-validation-state-selector($state) {
|
||||
~ .form-check-label {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
~ .#{$state}-feedback,
|
||||
~ .#{$state}-tooltip {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input {
|
||||
@include form-validation-state-selector($state) {
|
||||
~ .custom-control-label {
|
||||
color: $color;
|
||||
|
||||
&::before {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
&:checked {
|
||||
~ .custom-control-label::before {
|
||||
border-color: lighten($color, 10%);
|
||||
@include gradient-bg(lighten($color, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
~ .custom-control-label::before {
|
||||
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
|
||||
}
|
||||
|
||||
&:not(:checked) ~ .custom-control-label::before {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom file
|
||||
.custom-file-input {
|
||||
@include form-validation-state-selector($state) {
|
||||
~ .custom-file-label {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
~ .custom-file-label {
|
||||
border-color: $color;
|
||||
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Gradients
|
||||
|
||||
@mixin gradient-bg($color) {
|
||||
@if $enable-gradients {
|
||||
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;
|
||||
} @else {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal gradient, from left to right
|
||||
//
|
||||
// Creates two color stops, start and end, by specifying a color and position for each color stop.
|
||||
@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
|
||||
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
// Vertical gradient, from top to bottom
|
||||
//
|
||||
// Creates two color stops, start and end, by specifying a color and position for each color stop.
|
||||
@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
|
||||
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {
|
||||
background-image: linear-gradient($deg, $start-color, $end-color);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
|
||||
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
|
||||
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {
|
||||
background-image: radial-gradient(circle, $inner-color, $outer-color);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {
|
||||
background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// Framework grid generation
|
||||
//
|
||||
// Used only by Bootstrap to generate the correct number of grid classes given
|
||||
// any value of `$grid-columns`.
|
||||
|
||||
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
|
||||
// Common properties for all breakpoints
|
||||
%grid-column {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-right: $gutter / 2;
|
||||
padding-left: $gutter / 2;
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($breakpoints) {
|
||||
$infix: breakpoint-infix($breakpoint, $breakpoints);
|
||||
|
||||
@if $columns > 0 {
|
||||
// Allow columns to stretch full width below their breakpoints
|
||||
@for $i from 1 through $columns {
|
||||
.col#{$infix}-#{$i} {
|
||||
@extend %grid-column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col#{$infix},
|
||||
.col#{$infix}-auto {
|
||||
@extend %grid-column;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $breakpoints) {
|
||||
// Provide basic `.col-{bp}` classes for equal-width flexbox columns
|
||||
.col#{$infix} {
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@if $grid-row-columns > 0 {
|
||||
@for $i from 1 through $grid-row-columns {
|
||||
.row-cols#{$infix}-#{$i} {
|
||||
@include row-cols($i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col#{$infix}-auto {
|
||||
@include make-col-auto();
|
||||
}
|
||||
|
||||
@if $columns > 0 {
|
||||
@for $i from 1 through $columns {
|
||||
.col#{$infix}-#{$i} {
|
||||
@include make-col($i, $columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order#{$infix}-first { order: -1; }
|
||||
|
||||
.order#{$infix}-last { order: $columns + 1; }
|
||||
|
||||
@for $i from 0 through $columns {
|
||||
.order#{$infix}-#{$i} { order: $i; }
|
||||
}
|
||||
|
||||
@if $columns > 0 {
|
||||
// `$columns - 1` because offsetting by the width of an entire row isn't possible
|
||||
@for $i from 0 through ($columns - 1) {
|
||||
@if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
|
||||
.offset#{$infix}-#{$i} {
|
||||
@include make-col-offset($i, $columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/// Grid system
|
||||
//
|
||||
// Generate semantic grid columns with these mixins.
|
||||
|
||||
@mixin make-container($gutter: $grid-gutter-width) {
|
||||
width: 100%;
|
||||
padding-right: $gutter / 2;
|
||||
padding-left: $gutter / 2;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@mixin make-row($gutter: $grid-gutter-width) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -$gutter / 2;
|
||||
margin-left: -$gutter / 2;
|
||||
}
|
||||
|
||||
// For each breakpoint, define the maximum width of the container in a media query
|
||||
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
|
||||
@each $breakpoint, $container-max-width in $max-widths {
|
||||
@include media-breakpoint-up($breakpoint, $breakpoints) {
|
||||
max-width: $container-max-width;
|
||||
}
|
||||
}
|
||||
@include deprecate("The `make-container-max-widths` mixin", "v4.5.2", "v5");
|
||||
}
|
||||
|
||||
@mixin make-col-ready($gutter: $grid-gutter-width) {
|
||||
position: relative;
|
||||
// Prevent columns from becoming too narrow when at smaller grid tiers by
|
||||
// always setting `width: 100%;`. This works because we use `flex` values
|
||||
// later on to override this initial width.
|
||||
width: 100%;
|
||||
padding-right: $gutter / 2;
|
||||
padding-left: $gutter / 2;
|
||||
}
|
||||
|
||||
@mixin make-col($size, $columns: $grid-columns) {
|
||||
flex: 0 0 percentage($size / $columns);
|
||||
// Add a `max-width` to ensure content within each column does not blow out
|
||||
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
|
||||
// do not appear to require this.
|
||||
max-width: percentage($size / $columns);
|
||||
}
|
||||
|
||||
@mixin make-col-auto() {
|
||||
flex: 0 0 auto;
|
||||
width: auto;
|
||||
max-width: 100%; // Reset earlier grid tiers
|
||||
}
|
||||
|
||||
@mixin make-col-offset($size, $columns: $grid-columns) {
|
||||
$num: $size / $columns;
|
||||
margin-left: if($num == 0, 0, percentage($num));
|
||||
}
|
||||
|
||||
// Row columns
|
||||
//
|
||||
// Specify on a parent element(e.g., .row) to force immediate children into NN
|
||||
// numberof columns. Supports wrapping to new lines, but does not do a Masonry
|
||||
// style grid.
|
||||
@mixin row-cols($count) {
|
||||
& > * {
|
||||
flex: 0 0 100% / $count;
|
||||
max-width: 100% / $count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Hover mixin and `$enable-hover-media-query` are deprecated.
|
||||
//
|
||||
// Originally added during our alphas and maintained during betas, this mixin was
|
||||
// designed to prevent `:hover` stickiness on iOS-an issue where hover styles
|
||||
// would persist after initial touch.
|
||||
//
|
||||
// For backward compatibility, we've kept these mixins and updated them to
|
||||
// always return their regular pseudo-classes instead of a shimmed media query.
|
||||
//
|
||||
// Issue: https://github.com/twbs/bootstrap/issues/25195
|
||||
|
||||
@mixin hover() {
|
||||
&:hover { @content; }
|
||||
}
|
||||
|
||||
@mixin hover-focus() {
|
||||
&:hover,
|
||||
&:focus {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin plain-hover-focus() {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin hover-focus-active() {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Image Mixins
|
||||
// - Responsive image
|
||||
// - Retina image
|
||||
|
||||
|
||||
// Responsive image
|
||||
//
|
||||
// Keep images from scaling beyond the width of their parents.
|
||||
|
||||
@mixin img-fluid() {
|
||||
// Part 1: Set a maximum relative to the parent
|
||||
max-width: 100%;
|
||||
// Part 2: Override the height to auto, otherwise images will be stretched
|
||||
// when setting a width and height attribute on the img element.
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
||||
// Retina image
|
||||
//
|
||||
// Short retina mixin for setting background-image and -size.
|
||||
|
||||
@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
|
||||
background-image: url($file-1x);
|
||||
|
||||
// Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
|
||||
// but doesn't convert dppx=>dpi.
|
||||
// There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
|
||||
// Compatibility info: https://caniuse.com/#feat=css-media-resolution
|
||||
@media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
|
||||
only screen and (min-resolution: 2dppx) { // Standardized
|
||||
background-image: url($file-2x);
|
||||
background-size: $width-1x $height-1x;
|
||||
}
|
||||
@include deprecate("`img-retina()`", "v4.3.0", "v5");
|
||||
}
|
||||