Compare commits
15 commits
main
...
pagetop-wo
| Author | SHA1 | Date | |
|---|---|---|---|
| 64db114eb0 | |||
| 9435678e01 | |||
| 26f1cda831 | |||
| d495c05b96 | |||
| dbf0894894 | |||
| 2202a2350c | |||
| 62219584b0 | |||
| 8d0103c257 | |||
| 1bd97d5705 | |||
| f27790c3a2 | |||
| 6376e3e88c | |||
| 38fd24453e | |||
| 511149caa7 | |||
| 41c4379bc3 | |||
| f9e87058d8 |
3
.gitignore
vendored
|
|
@ -1,6 +1,9 @@
|
||||||
# Ignora directorios de compilación
|
# Ignora directorios de compilación
|
||||||
**/target
|
**/target
|
||||||
|
|
||||||
|
# Ignora directorios de archivos estáticos
|
||||||
|
**/static
|
||||||
|
|
||||||
# Archivos de log
|
# Archivos de log
|
||||||
**/log/*.log*
|
**/log/*.log*
|
||||||
|
|
||||||
|
|
|
||||||
58
Cargo.lock
generated
|
|
@ -20,6 +20,15 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
|
@ -933,7 +942,7 @@ version = "0.4.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
|
checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick 1.1.4",
|
||||||
"bstr",
|
"bstr",
|
||||||
"log",
|
"log",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
|
|
@ -965,6 +974,16 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"bumpalo",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
|
|
@ -1495,6 +1514,17 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minify-js"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1fa5546ee8bd66024113e506cabe4230e76635a094c06ea2051b66021dda92e"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick 0.7.20",
|
||||||
|
"lazy_static",
|
||||||
|
"parse-js",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.9"
|
version = "0.8.9"
|
||||||
|
|
@ -1721,7 +1751,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pagetop",
|
"pagetop",
|
||||||
"pagetop-build",
|
"pagetop-build",
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1731,7 +1760,6 @@ dependencies = [
|
||||||
"pagetop",
|
"pagetop",
|
||||||
"pagetop-build",
|
"pagetop-build",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1739,9 +1767,18 @@ name = "pagetop-build"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"grass",
|
"grass",
|
||||||
|
"minify-js",
|
||||||
"pagetop-statics",
|
"pagetop-statics",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pagetop-htmx"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pagetop",
|
||||||
|
"pagetop-build",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pagetop-macros"
|
name = "pagetop-macros"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -1812,6 +1849,19 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parse-js"
|
||||||
|
version = "0.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2742b5e32dcb5930447ed9f9e401a7dfd883867fc079c4fac44ae8ba3593710e"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick 0.7.20",
|
||||||
|
"bumpalo",
|
||||||
|
"hashbrown 0.13.2",
|
||||||
|
"lazy_static",
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pastey"
|
name = "pastey"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
@ -2094,7 +2144,7 @@ version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick 1.1.4",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ members = [
|
||||||
# Extensions
|
# Extensions
|
||||||
"extensions/pagetop-aliner",
|
"extensions/pagetop-aliner",
|
||||||
"extensions/pagetop-bootsier",
|
"extensions/pagetop-bootsier",
|
||||||
|
"extensions/pagetop-htmx",
|
||||||
"extensions/pagetop-seaorm",
|
"extensions/pagetop-seaorm",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -35,6 +36,7 @@ indexmap = "2.14"
|
||||||
indoc = "2.0"
|
indoc = "2.0"
|
||||||
itoa = "1.0"
|
itoa = "1.0"
|
||||||
mime_guess = "2.0"
|
mime_guess = "2.0"
|
||||||
|
minify-js = "0.6"
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
pastey = "0.2"
|
pastey = "0.2"
|
||||||
path-slash = "0.2"
|
path-slash = "0.2"
|
||||||
|
|
@ -62,6 +64,7 @@ pagetop-statics = { version = "0.1", path = "helpers/pagetop-statics" }
|
||||||
# Extensions
|
# Extensions
|
||||||
pagetop-aliner = { version = "0.1", path = "extensions/pagetop-aliner" }
|
pagetop-aliner = { version = "0.1", path = "extensions/pagetop-aliner" }
|
||||||
pagetop-bootsier = { version = "0.1", path = "extensions/pagetop-bootsier" }
|
pagetop-bootsier = { version = "0.1", path = "extensions/pagetop-bootsier" }
|
||||||
|
pagetop-htmx = { version = "0.1", path = "extensions/pagetop-htmx" }
|
||||||
pagetop-seaorm = { version = "0.0", path = "extensions/pagetop-seaorm" }
|
pagetop-seaorm = { version = "0.0", path = "extensions/pagetop-seaorm" }
|
||||||
# PageTop
|
# PageTop
|
||||||
pagetop = { version = "0.5", path = "." }
|
pagetop = { version = "0.5", path = "." }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
<img src="https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/static/banner.png" />
|
<img src="https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/assets/banner.png" />
|
||||||
|
|
||||||
<h1>PageTop</h1>
|
<h1>PageTop</h1>
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
147
assets/css/basic.css
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
:root {
|
||||||
|
/* Font families */
|
||||||
|
--val-font-sans: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif;
|
||||||
|
--val-font-serif: Georgia,"Times New Roman",serif;
|
||||||
|
--val-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
||||||
|
--val-font-family: var(--val-font-sans);
|
||||||
|
/* Font size */
|
||||||
|
--val-fs--base: 1rem;
|
||||||
|
/* Font weight */
|
||||||
|
--val-fw--base: 400;
|
||||||
|
/* Line height */
|
||||||
|
--val-lh--base: 1.5;
|
||||||
|
/* Colors */
|
||||||
|
--val-color--bg: #fafafa;
|
||||||
|
--val-color--text: #212529;
|
||||||
|
--val-color--text--muted: color-mix(in srgb, var(--val-color--text) 50%, var(--val-color--bg));
|
||||||
|
--val-color--border: #212529;
|
||||||
|
--val-color--primary: #0d6efd;
|
||||||
|
--val-color--danger: #dc3545;
|
||||||
|
--val-color--switch-off: #adb5bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--val-font-family);
|
||||||
|
font-size: var(--val-fs--base);
|
||||||
|
font-weight: var(--val-fw--base);
|
||||||
|
line-height: var(--val-lh--base);
|
||||||
|
color: var(--val-color--text);
|
||||||
|
background-color: var(--val-color--bg);
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Form components
|
||||||
|
*/
|
||||||
|
|
||||||
|
.form-required {
|
||||||
|
color: var(--val-color--danger);
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-text {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--val-color--text--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field > select.form-select,
|
||||||
|
.form-field > input.form-control,
|
||||||
|
.form-field > input.form-range,
|
||||||
|
.form-field > textarea.form-control {
|
||||||
|
display: block;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
margin: 2rem 0 1rem;
|
||||||
|
background: var(--val-color--bg);
|
||||||
|
}
|
||||||
|
fieldset > legend {
|
||||||
|
background-color: var(--val-color--bg);
|
||||||
|
border: 2px groove threedface;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
min-height: 1.5rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.form-check-inline {
|
||||||
|
display: inline-flex;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
.form-check-reverse {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
justify-content: flex-start;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.form-check-input {
|
||||||
|
flex-shrink: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.form-check-label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.form-switch .form-check-input {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 2em;
|
||||||
|
height: 1em;
|
||||||
|
background-color: var(--val-color--switch-off);
|
||||||
|
border-radius: 1em;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color .15s ease-in-out;
|
||||||
|
}
|
||||||
|
.form-switch .form-check-input::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transition: transform .15s ease-in-out;
|
||||||
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, .25);
|
||||||
|
}
|
||||||
|
.form-switch .form-check-input:checked {
|
||||||
|
background-color: var(--val-color--primary);
|
||||||
|
}
|
||||||
|
.form-switch .form-check-input:checked::after {
|
||||||
|
transform: translateX(1em);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled,
|
||||||
|
input:disabled + label {
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
input:disabled + label {
|
||||||
|
color: var(--val-color--text--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Region Footer
|
||||||
|
*/
|
||||||
|
|
||||||
|
.region-footer {
|
||||||
|
padding: .75rem 0 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
@ -389,10 +389,10 @@ body {
|
||||||
.intro-text-body .block {
|
.intro-text-body .block {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.intro-text-body .block__title {
|
.intro-text-body .block-title {
|
||||||
margin: 1em 0 .8em;
|
margin: 1em 0 .8em;
|
||||||
}
|
}
|
||||||
.intro-text-body .block__title span {
|
.intro-text-body .block-title span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 10px 30px 14px;
|
padding: 10px 30px 14px;
|
||||||
margin: 30px 20px 0;
|
margin: 30px 20px 0;
|
||||||
|
|
@ -403,7 +403,7 @@ body {
|
||||||
border-color: orangered;
|
border-color: orangered;
|
||||||
transform: rotate(-3deg) translateY(-25%);
|
transform: rotate(-3deg) translateY(-25%);
|
||||||
}
|
}
|
||||||
.intro-text-body .block__title:before {
|
.intro-text-body .block-title:before {
|
||||||
content: "";
|
content: "";
|
||||||
height: 5px;
|
height: 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -416,7 +416,7 @@ body {
|
||||||
transform: rotate(2deg) translateY(-50%);
|
transform: rotate(2deg) translateY(-50%);
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
}
|
}
|
||||||
.intro-text-body .block__title:after {
|
.intro-text-body .block-title:after {
|
||||||
content: "";
|
content: "";
|
||||||
height: 120%;
|
height: 120%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -427,22 +427,22 @@ body {
|
||||||
background: var(--intro-bg-block-1);
|
background: var(--intro-bg-block-1);
|
||||||
transform: rotate(2deg);
|
transform: rotate(2deg);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+1) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+1) .block-title:after {
|
||||||
background: var(--intro-bg-block-1);
|
background: var(--intro-bg-block-1);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+2) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+2) .block-title:after {
|
||||||
background: var(--intro-bg-block-2);
|
background: var(--intro-bg-block-2);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+3) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+3) .block-title:after {
|
||||||
background: var(--intro-bg-block-3);
|
background: var(--intro-bg-block-3);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+4) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+4) .block-title:after {
|
||||||
background: var(--intro-bg-block-4);
|
background: var(--intro-bg-block-4);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+5) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+5) .block-title:after {
|
||||||
background: var(--intro-bg-block-5);
|
background: var(--intro-bg-block-5);
|
||||||
}
|
}
|
||||||
.intro-text-body .block:nth-of-type(6n+6) .block__title:after {
|
.intro-text-body .block:nth-of-type(6n+6) .block-title:after {
|
||||||
background: var(--intro-bg-block-6);
|
background: var(--intro-bg-block-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
8
build.rs
|
|
@ -1,6 +1,12 @@
|
||||||
use pagetop_build::StaticFilesBundle;
|
use pagetop_build::{StaticFilesBundle, copy_dir};
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
|
// Regenera `static/` desde cero sólo si hay cambios en `assets/`.
|
||||||
|
println!("cargo:rerun-if-changed=assets");
|
||||||
|
let _ = std::fs::remove_dir_all("static");
|
||||||
|
|
||||||
|
copy_dir("assets", "static")?;
|
||||||
|
|
||||||
StaticFilesBundle::from_dir("./static", None)
|
StaticFilesBundle::from_dir("./static", None)
|
||||||
.with_name("assets")
|
.with_name("assets")
|
||||||
.build()
|
.build()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use pagetop::prelude::*;
|
use pagetop::prelude::*;
|
||||||
|
|
||||||
|
use pagetop_bootsier::theme::form;
|
||||||
use pagetop_bootsier::theme::*;
|
use pagetop_bootsier::theme::*;
|
||||||
|
|
||||||
include_locales!(LOC from "examples/locale");
|
include_locales!(LOC from "examples/locale");
|
||||||
|
|
@ -143,17 +144,20 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
.with_value("form-selections"),
|
.with_value("form-selections"),
|
||||||
)
|
)
|
||||||
// Botones de acción.
|
// Botones de acción.
|
||||||
|
.with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop(
|
||||||
|
PropsOp::add_classes(classes::ButtonColor::solid(
|
||||||
|
Color::Primary,
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.with_child(Button::reset(L10n::t("btn_reset", &LOC)).with_prop(
|
||||||
|
PropsOp::add_classes(classes::ButtonColor::outline(
|
||||||
|
Color::Secondary,
|
||||||
|
)),
|
||||||
|
))
|
||||||
.with_child(
|
.with_child(
|
||||||
Button::submit(L10n::t("btn_submit", &LOC))
|
Button::plain(L10n::t("btn_cancel", &LOC)).with_prop(
|
||||||
.with_color(ButtonColor::Background(Color::Primary)),
|
PropsOp::add_classes(classes::ButtonColor::link()),
|
||||||
)
|
),
|
||||||
.with_child(
|
|
||||||
Button::reset(L10n::t("btn_reset", &LOC))
|
|
||||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
|
||||||
.with_color(ButtonColor::Link),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -175,6 +179,7 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
.with_name("name")
|
.with_name("name")
|
||||||
.with_label(L10n::t("label_name", &LOC))
|
.with_label(L10n::t("label_name", &LOC))
|
||||||
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
||||||
|
.with_help_text(L10n::t("help_name", &LOC))
|
||||||
.with_required(true),
|
.with_required(true),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
|
|
@ -185,6 +190,7 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
"placeholder_email",
|
"placeholder_email",
|
||||||
&LOC,
|
&LOC,
|
||||||
))
|
))
|
||||||
|
.with_help_text(L10n::t("help_email", &LOC))
|
||||||
.with_autocomplete(
|
.with_autocomplete(
|
||||||
Some(form::Autocomplete::email()),
|
Some(form::Autocomplete::email()),
|
||||||
)
|
)
|
||||||
|
|
@ -262,194 +268,175 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
.with_value("form-text"),
|
.with_value("form-text"),
|
||||||
)
|
)
|
||||||
// Botones de acción.
|
// Botones de acción.
|
||||||
|
.with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop(
|
||||||
|
PropsOp::add_classes(classes::ButtonColor::solid(
|
||||||
|
Color::Primary,
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.with_child(Button::reset(L10n::t("btn_reset", &LOC)).with_prop(
|
||||||
|
PropsOp::add_classes(classes::ButtonColor::outline(
|
||||||
|
Color::Secondary,
|
||||||
|
)),
|
||||||
|
))
|
||||||
.with_child(
|
.with_child(
|
||||||
Button::submit(L10n::t("btn_submit", &LOC))
|
Button::plain(L10n::t("btn_cancel", &LOC)).with_prop(
|
||||||
.with_color(ButtonColor::Background(Color::Primary)),
|
PropsOp::add_classes(classes::ButtonColor::link()),
|
||||||
)
|
),
|
||||||
.with_child(
|
|
||||||
Button::reset(L10n::t("btn_reset", &LOC))
|
|
||||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
|
||||||
.with_color(ButtonColor::Link),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// Bloque 3: listas de selección y etiquetas flotantes.
|
// Bloque 3: listas de selección y etiquetas flotantes.
|
||||||
.with_child(
|
.with_child(
|
||||||
Block::new()
|
Block::new()
|
||||||
.with_title(L10n::t("block_lists", &LOC))
|
.with_title(
|
||||||
.with_child(
|
if global::SETTINGS.app.theme.eq_ignore_ascii_case("bootsier") {
|
||||||
Form::new()
|
L10n::t("block_lists_floating", &LOC)
|
||||||
.with_id("form-lists")
|
} else {
|
||||||
.with_action("/")
|
L10n::t("block_lists", &LOC)
|
||||||
.with_method(form::Method::Post)
|
},
|
||||||
// Listas de selección (form::select::Field).
|
)
|
||||||
.with_child(
|
.with_child(form_lists()),
|
||||||
form::Fieldset::new()
|
|
||||||
.with_legend(L10n::t("fieldset_select", &LOC))
|
|
||||||
.with_child(
|
|
||||||
form::select::Field::new()
|
|
||||||
.with_name("language")
|
|
||||||
.with_label(L10n::t("label_language", &LOC))
|
|
||||||
.with_item(
|
|
||||||
form::select::Item::new(
|
|
||||||
"",
|
|
||||||
L10n::t("select_choose", &LOC),
|
|
||||||
)
|
|
||||||
.with_selected(true),
|
|
||||||
)
|
|
||||||
.with_group(
|
|
||||||
form::select::Group::new(L10n::t(
|
|
||||||
"select_group_europe",
|
|
||||||
&LOC,
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"es",
|
|
||||||
L10n::t("select_spanish", &LOC),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"fr",
|
|
||||||
L10n::t("select_french", &LOC),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.with_group(
|
|
||||||
form::select::Group::new(L10n::t(
|
|
||||||
"select_group_americas",
|
|
||||||
&LOC,
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"en",
|
|
||||||
L10n::t("select_english", &LOC),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"pt",
|
|
||||||
L10n::t("select_portuguese", &LOC),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.with_item(
|
|
||||||
form::select::Item::new(
|
|
||||||
"xx",
|
|
||||||
L10n::t("select_disabled", &LOC),
|
|
||||||
)
|
|
||||||
.with_disabled(true),
|
|
||||||
)
|
|
||||||
.with_required(true),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
form::select::Field::new()
|
|
||||||
.with_name("technologies")
|
|
||||||
.with_label(L10n::t("label_technologies", &LOC))
|
|
||||||
.with_item(
|
|
||||||
form::select::Item::new(
|
|
||||||
"rust",
|
|
||||||
L10n::n("Rust"),
|
|
||||||
)
|
|
||||||
.with_selected(true),
|
|
||||||
)
|
|
||||||
.with_item(
|
|
||||||
form::select::Item::new(
|
|
||||||
"python",
|
|
||||||
L10n::n("Python"),
|
|
||||||
)
|
|
||||||
.with_selected(true),
|
|
||||||
)
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"javascript",
|
|
||||||
L10n::n("JavaScript"),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"go",
|
|
||||||
L10n::n("Go"),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"typescript",
|
|
||||||
L10n::n("TypeScript"),
|
|
||||||
))
|
|
||||||
.with_multiple(true)
|
|
||||||
.with_rows(Some(4))
|
|
||||||
.with_help_text(L10n::t("help_technologies", &LOC)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// Etiquetas flotantes.
|
|
||||||
.with_child(
|
|
||||||
form::Fieldset::new()
|
|
||||||
.with_legend(L10n::t("fieldset_floating", &LOC))
|
|
||||||
.with_child(
|
|
||||||
form::input::Field::text()
|
|
||||||
.with_name("fl_name")
|
|
||||||
.with_label(L10n::t("label_name", &LOC))
|
|
||||||
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
|
||||||
.with_floating_label(true)
|
|
||||||
.with_required(true),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
form::Textarea::new()
|
|
||||||
.with_name("fl_comment")
|
|
||||||
.with_label(L10n::t("label_comment", &LOC))
|
|
||||||
.with_placeholder(L10n::t(
|
|
||||||
"placeholder_comment",
|
|
||||||
&LOC,
|
|
||||||
))
|
|
||||||
.with_floating_label(true),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
form::select::Field::new()
|
|
||||||
.with_name("fl_country")
|
|
||||||
.with_label(L10n::t("label_country", &LOC))
|
|
||||||
.with_item(
|
|
||||||
form::select::Item::new(
|
|
||||||
"",
|
|
||||||
L10n::t("select_choose", &LOC),
|
|
||||||
)
|
|
||||||
.with_selected(true),
|
|
||||||
)
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"de",
|
|
||||||
L10n::t("select_germany", &LOC),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"es",
|
|
||||||
L10n::t("select_spain", &LOC),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"fr",
|
|
||||||
L10n::t("select_france", &LOC),
|
|
||||||
))
|
|
||||||
.with_item(form::select::Item::new(
|
|
||||||
"pt",
|
|
||||||
L10n::t("select_portugal", &LOC),
|
|
||||||
))
|
|
||||||
.with_floating_label(true)
|
|
||||||
.with_required(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// Campo oculto (form::Hidden).
|
|
||||||
.with_child(
|
|
||||||
form::Hidden::new()
|
|
||||||
.with_name("origin")
|
|
||||||
.with_value("form-lists"),
|
|
||||||
)
|
|
||||||
// Botones de acción.
|
|
||||||
.with_child(
|
|
||||||
Button::submit(L10n::t("btn_submit", &LOC))
|
|
||||||
.with_color(ButtonColor::Background(Color::Primary)),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
Button::reset(L10n::t("btn_reset", &LOC))
|
|
||||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
|
||||||
)
|
|
||||||
.with_child(
|
|
||||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
|
||||||
.with_color(ButtonColor::Link),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.render()
|
.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn form_lists() -> Form {
|
||||||
|
let mut form = Form::new()
|
||||||
|
.with_id("form-lists")
|
||||||
|
.with_action("/")
|
||||||
|
.with_method(form::Method::Post)
|
||||||
|
// Listas de selección (form::select::Field).
|
||||||
|
.with_child(
|
||||||
|
form::Fieldset::new()
|
||||||
|
.with_legend(L10n::t("fieldset_select", &LOC))
|
||||||
|
.with_child(
|
||||||
|
form::select::Field::new()
|
||||||
|
.with_name("language")
|
||||||
|
.with_label(L10n::t("label_language", &LOC))
|
||||||
|
.with_item(
|
||||||
|
form::select::Item::new("", L10n::t("select_choose", &LOC))
|
||||||
|
.with_selected(true),
|
||||||
|
)
|
||||||
|
.with_group(
|
||||||
|
form::select::Group::new(L10n::t("select_group_europe", &LOC))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"es",
|
||||||
|
L10n::t("select_spanish", &LOC),
|
||||||
|
))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"fr",
|
||||||
|
L10n::t("select_french", &LOC),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.with_group(
|
||||||
|
form::select::Group::new(L10n::t("select_group_americas", &LOC))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"en",
|
||||||
|
L10n::t("select_english", &LOC),
|
||||||
|
))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"pt",
|
||||||
|
L10n::t("select_portuguese", &LOC),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.with_item(
|
||||||
|
form::select::Item::new("xx", L10n::t("select_disabled", &LOC))
|
||||||
|
.with_disabled(true),
|
||||||
|
)
|
||||||
|
.with_required(true),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
|
form::select::Field::new()
|
||||||
|
.with_name("technologies")
|
||||||
|
.with_label(L10n::t("label_technologies", &LOC))
|
||||||
|
.with_item(
|
||||||
|
form::select::Item::new("rust", L10n::n("Rust")).with_selected(true),
|
||||||
|
)
|
||||||
|
.with_item(
|
||||||
|
form::select::Item::new("python", L10n::n("Python"))
|
||||||
|
.with_selected(true),
|
||||||
|
)
|
||||||
|
.with_item(form::select::Item::new("javascript", L10n::n("JavaScript")))
|
||||||
|
.with_item(form::select::Item::new("go", L10n::n("Go")))
|
||||||
|
.with_item(form::select::Item::new("typescript", L10n::n("TypeScript")))
|
||||||
|
.with_multiple(true)
|
||||||
|
.with_rows(Some(4))
|
||||||
|
.with_help_text(L10n::t("help_technologies", &LOC)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Etiquetas flotantes: solo disponibles con el tema Bootsier.
|
||||||
|
if global::SETTINGS.app.theme.eq_ignore_ascii_case("bootsier") {
|
||||||
|
form = form.with_child(
|
||||||
|
form::Fieldset::new()
|
||||||
|
.with_legend(L10n::t("fieldset_floating", &LOC))
|
||||||
|
.with_child(
|
||||||
|
form::input::Field::text()
|
||||||
|
.with_name("fl_name")
|
||||||
|
.with_label(L10n::t("label_name", &LOC))
|
||||||
|
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
||||||
|
.with_floating_label(true)
|
||||||
|
.with_required(true),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
|
form::Textarea::new()
|
||||||
|
.with_name("fl_comment")
|
||||||
|
.with_label(L10n::t("label_comment", &LOC))
|
||||||
|
.with_placeholder(L10n::t("placeholder_comment", &LOC))
|
||||||
|
.with_floating_label(true),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
|
form::select::Field::new()
|
||||||
|
.with_name("fl_country")
|
||||||
|
.with_label(L10n::t("label_country", &LOC))
|
||||||
|
.with_item(
|
||||||
|
form::select::Item::new("", L10n::t("select_choose", &LOC))
|
||||||
|
.with_selected(true),
|
||||||
|
)
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"de",
|
||||||
|
L10n::t("select_germany", &LOC),
|
||||||
|
))
|
||||||
|
.with_item(form::select::Item::new("es", L10n::t("select_spain", &LOC)))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"fr",
|
||||||
|
L10n::t("select_france", &LOC),
|
||||||
|
))
|
||||||
|
.with_item(form::select::Item::new(
|
||||||
|
"pt",
|
||||||
|
L10n::t("select_portugal", &LOC),
|
||||||
|
))
|
||||||
|
.with_floating_label(true)
|
||||||
|
.with_required(true),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
form
|
||||||
|
// Campo oculto (form::Hidden).
|
||||||
|
.with_child(
|
||||||
|
form::Hidden::new()
|
||||||
|
.with_name("origin")
|
||||||
|
.with_value("form-lists"),
|
||||||
|
)
|
||||||
|
// Botones de acción.
|
||||||
|
.with_child(
|
||||||
|
Button::submit(L10n::t("btn_submit", &LOC)).with_prop(PropsOp::add_classes(
|
||||||
|
classes::ButtonColor::solid(Color::Primary),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
|
Button::reset(L10n::t("btn_reset", &LOC)).with_prop(PropsOp::add_classes(
|
||||||
|
classes::ButtonColor::outline(Color::Secondary),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
|
Button::plain(L10n::t("btn_cancel", &LOC))
|
||||||
|
.with_prop(PropsOp::add_classes(classes::ButtonColor::link())),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[pagetop::main]
|
#[pagetop::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
Application::prepare(&FormControls).run()?.await
|
Application::prepare(&FormControls).run()?.await
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ title = Form controls
|
||||||
slogan = Bootsier form components showcase
|
slogan = Bootsier form components showcase
|
||||||
block_selections = Checkboxes, switches and radio buttons
|
block_selections = Checkboxes, switches and radio buttons
|
||||||
block_text = Text fields, multiline and range
|
block_text = Text fields, multiline and range
|
||||||
block_lists = Select lists and floating labels
|
block_lists = Selection lists
|
||||||
|
block_lists_floating = Select lists and floating labels
|
||||||
|
|
||||||
fieldset_text = Text fields
|
fieldset_text = Text fields
|
||||||
label_name = Full name
|
label_name = Full name
|
||||||
|
|
@ -16,6 +17,8 @@ label_url = Website
|
||||||
placeholder_url = https://example.com
|
placeholder_url = https://example.com
|
||||||
label_search = Search
|
label_search = Search
|
||||||
placeholder_search = Search term...
|
placeholder_search = Search term...
|
||||||
|
help_name = Enter your full name as it appears on your ID.
|
||||||
|
help_email = We will only use your email to send important notifications.
|
||||||
|
|
||||||
fieldset_textarea = Multiline text
|
fieldset_textarea = Multiline text
|
||||||
label_comment = Comment
|
label_comment = Comment
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ title = Controles de formulario
|
||||||
slogan = Componentes Bootsier para formularios
|
slogan = Componentes Bootsier para formularios
|
||||||
block_selections = Casillas, interruptores y botones de opción
|
block_selections = Casillas, interruptores y botones de opción
|
||||||
block_text = Campos de texto, multilínea y rango
|
block_text = Campos de texto, multilínea y rango
|
||||||
block_lists = Listas de selección y etiquetas flotantes
|
block_lists = Listas de selección
|
||||||
|
block_lists_floating = Listas de selección y etiquetas flotantes
|
||||||
|
|
||||||
fieldset_text = Campos de texto
|
fieldset_text = Campos de texto
|
||||||
label_name = Nombre completo
|
label_name = Nombre completo
|
||||||
|
|
@ -16,6 +17,8 @@ label_url = Sitio web
|
||||||
placeholder_url = https://ejemplo.com
|
placeholder_url = https://ejemplo.com
|
||||||
label_search = Búsqueda
|
label_search = Búsqueda
|
||||||
placeholder_search = Término de búsqueda...
|
placeholder_search = Término de búsqueda...
|
||||||
|
help_name = Introduce tu nombre completo tal como aparece en tu documento de identidad.
|
||||||
|
help_email = Solo usaremos tu correo para enviarte notificaciones importantes.
|
||||||
|
|
||||||
fieldset_textarea = Texto multilínea
|
fieldset_textarea = Texto multilínea
|
||||||
label_comment = Comentario
|
label_comment = Comentario
|
||||||
|
|
|
||||||
|
|
@ -80,10 +80,9 @@ impl Extension for SuperMenu {
|
||||||
))
|
))
|
||||||
.with_item(navbar::Item::nav(
|
.with_item(navbar::Item::nav(
|
||||||
Nav::new()
|
Nav::new()
|
||||||
.with_classes(
|
.with_prop(PropsOp::add_classes(
|
||||||
ClassesOp::Add,
|
|
||||||
classes::Margin::with(Side::Start, ScaleSize::Auto).to_class(),
|
classes::Margin::with(Side::Start, ScaleSize::Auto).to_class(),
|
||||||
)
|
))
|
||||||
.with_item(nav::Item::link(L10n::t("menus_item_sign_up", &LOC), |cx| {
|
.with_item(nav::Item::link(L10n::t("menus_item_sign_up", &LOC), |cx| {
|
||||||
cx.route("/auth/sign-up")
|
cx.route("/auth/sign-up")
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,5 @@ authors.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
pagetop.workspace = true
|
pagetop.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio.workspace = true
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pagetop-build.workspace = true
|
pagetop-build.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 🧭 Sobre PageTop
|
## Sobre PageTop
|
||||||
|
|
||||||
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
||||||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||||
configurables, basadas en HTML, CSS y JavaScript.
|
configurables, basadas en HTML, CSS y JavaScript.
|
||||||
|
|
||||||
|
## Guía rápida
|
||||||
## ⚡️ Guía rápida
|
|
||||||
|
|
||||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||||
|
|
||||||
|
|
@ -44,11 +43,6 @@ impl Extension for MyApp {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::main]
|
|
||||||
async fn main() -> std::io::Result<()> {
|
|
||||||
Application::prepare(&MyApp).run()?.await
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Y **selecciona el tema en la configuración** de la aplicación:
|
Y **selecciona el tema en la configuración** de la aplicación:
|
||||||
|
|
@ -67,10 +61,10 @@ use pagetop_aliner::Aliner;
|
||||||
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
Page::new(request)
|
Page::new(request)
|
||||||
.with_theme(&Aliner)
|
.with_theme(&Aliner)
|
||||||
.add_child(
|
.with_child(
|
||||||
Block::new()
|
Block::new()
|
||||||
.with_title(L10n::l("sample_title"))
|
.with_title(L10n::l("sample_title"))
|
||||||
.add_child(Html::with(|cx| html! {
|
.with_child(Html::with(|cx| html! {
|
||||||
p { (L10n::l("sample_content").using(cx)) }
|
p { (L10n::l("sample_content").using(cx)) }
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
@ -78,15 +72,13 @@ async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Advertencia
|
||||||
## 🚧 Advertencia
|
|
||||||
|
|
||||||
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
||||||
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
||||||
hasta que se libere la versión **1.0.0**.
|
hasta que se libere la versión **1.0.0**.
|
||||||
|
|
||||||
|
## Licencia
|
||||||
## 📜 Licencia
|
|
||||||
|
|
||||||
El código está disponible bajo una doble licencia:
|
El código está disponible bajo una doble licencia:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@
|
||||||
|
|
||||||
<h1>PageTop Aliner</h1>
|
<h1>PageTop Aliner</h1>
|
||||||
|
|
||||||
<p>Tema para <strong>PageTop</strong> que muestra esquemáticamente la composición de las páginas HTML.</p>
|
<p>Tema de <strong>PageTop</strong> que muestra esquemáticamente la composición de las páginas HTML.</p>
|
||||||
|
|
||||||
[](https://docs.rs/pagetop-aliner)
|
[](https://docs.rs/pagetop-aliner)
|
||||||
[](https://crates.io/crates/pagetop-aliner)
|
[](https://crates.io/crates/pagetop-aliner)
|
||||||
[](https://crates.io/crates/pagetop-aliner)
|
[](https://crates.io/crates/pagetop-aliner)
|
||||||
[](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner#licencia)
|
[](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner#licencia)
|
||||||
|
|
||||||
<br>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Sobre PageTop
|
## Sobre PageTop
|
||||||
|
|
@ -19,8 +18,7 @@
|
||||||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||||
configurables, basadas en HTML, CSS y JavaScript.
|
configurables, basadas en HTML, CSS y JavaScript.
|
||||||
|
|
||||||
|
## Guía rápida
|
||||||
# ⚡️ Guía rápida
|
|
||||||
|
|
||||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||||
|
|
||||||
|
|
@ -46,11 +44,6 @@ impl Extension for MyApp {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::main]
|
|
||||||
async fn main() -> std::io::Result<()> {
|
|
||||||
Application::prepare(&MyApp).run()?.await
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Y **selecciona el tema en la configuración** de la aplicación:
|
Y **selecciona el tema en la configuración** de la aplicación:
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,5 @@ authors.workspace = true
|
||||||
pagetop.workspace = true
|
pagetop.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio.workspace = true
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pagetop-build.workspace = true
|
pagetop-build.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 🧭 Sobre PageTop
|
## Sobre PageTop
|
||||||
|
|
||||||
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
||||||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||||
configurables, basadas en HTML, CSS y JavaScript.
|
configurables, basadas en HTML, CSS y JavaScript.
|
||||||
|
|
||||||
|
## Guía rápida
|
||||||
## ⚡️ Guía rápida
|
|
||||||
|
|
||||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||||
|
|
||||||
|
|
@ -44,11 +43,6 @@ impl Extension for MyApp {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::main]
|
|
||||||
async fn main() -> std::io::Result<()> {
|
|
||||||
Application::prepare(&MyApp).run()?.await
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Y **selecciona el tema en la configuración** de la aplicación:
|
Y **selecciona el tema en la configuración** de la aplicación:
|
||||||
|
|
@ -67,10 +61,10 @@ use pagetop_bootsier::Bootsier;
|
||||||
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
Page::new(request)
|
Page::new(request)
|
||||||
.with_theme(&Bootsier)
|
.with_theme(&Bootsier)
|
||||||
.add_child(
|
.with_child(
|
||||||
Block::new()
|
Block::new()
|
||||||
.with_title(L10n::l("sample_title"))
|
.with_title(L10n::l("sample_title"))
|
||||||
.add_child(Html::with(|cx| html! {
|
.with_child(Html::with(|cx| html! {
|
||||||
p { (L10n::l("sample_content").using(cx)) }
|
p { (L10n::l("sample_content").using(cx)) }
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
@ -78,22 +72,19 @@ async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Créditos
|
||||||
## 📚 Créditos
|
|
||||||
|
|
||||||
Este *crate* integra la biblioteca de estilos [Bootstrap 5.3.8](https://getbootstrap.com/) para
|
Este *crate* integra la biblioteca de estilos [Bootstrap 5.3.8](https://getbootstrap.com/) para
|
||||||
definir el comportamiento, la apariencia y los componentes de la interfaz. Bootstrap se distribuye
|
definir el comportamiento, la apariencia y los componentes de la interfaz. Bootstrap se distribuye
|
||||||
bajo licencia [MIT](https://github.com/twbs/bootstrap/blob/main/LICENSE).
|
bajo licencia [MIT](https://github.com/twbs/bootstrap/blob/main/LICENSE).
|
||||||
|
|
||||||
|
## Advertencia
|
||||||
## 🚧 Advertencia
|
|
||||||
|
|
||||||
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
||||||
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
||||||
hasta que se libere la versión **1.0.0**.
|
hasta que se libere la versión **1.0.0**.
|
||||||
|
|
||||||
|
## Licencia
|
||||||
## 📜 Licencia
|
|
||||||
|
|
||||||
El código está disponible bajo una doble licencia:
|
El código está disponible bajo una doble licencia:
|
||||||
|
|
||||||
|
|
|
||||||
84
extensions/pagetop-bootsier/assets/_bootsier-custom.scss
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Bootsier CSS rules: self-hosted fonts, form components, and regions.
|
||||||
|
|
||||||
|
// Self-hosted Source Sans 3 (SIL OFL 1.1), served from /bootsier/fonts.
|
||||||
|
// Required by AdminLTE 4, which declares it as the primary font family in $font-family-sans-serif.
|
||||||
|
@font-face {
|
||||||
|
font-family: "Source Sans 3";
|
||||||
|
src: url("/bootsier/fonts/bootsier.font.woff2") format("woff2");
|
||||||
|
font-weight: 200 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Source Sans 3";
|
||||||
|
src: url("/bootsier/fonts/bootsier.font.italic.woff2") format("woff2");
|
||||||
|
font-weight: 200 900;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Font-relative top offset to keep the skip-link hidden at any font size.
|
||||||
|
.skip-link {
|
||||||
|
top: -3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required field indicator in forms.
|
||||||
|
.form-required {
|
||||||
|
color: var(--bs-danger);
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form field with consistent bottom margin.
|
||||||
|
.form-field {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fieldset with border and floating legend.
|
||||||
|
fieldset {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||||
|
border-radius: var(--bs-border-radius);
|
||||||
|
padding: 2rem 1rem 1rem;
|
||||||
|
margin: 2rem 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset > legend {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 1rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: var(--bs-secondary-color);
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||||
|
border-radius: var(--bs-border-radius);
|
||||||
|
padding: 0.125rem 0.75rem;
|
||||||
|
font-size: ($font-size-sm + $font-size-base) / 2;
|
||||||
|
font-weight: var(--bs-font-weight-normal);
|
||||||
|
line-height: 1.25;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 75%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fieldset-description {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gap between group label and first inline check.
|
||||||
|
.form-label + .form-check-inline {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Footer region.
|
||||||
|
.region-footer {
|
||||||
|
padding: 0.75rem 0 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
5
extensions/pagetop-bootsier/assets/_bootsier-icons.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Bootstrap Icons v1.13.1, fonts served from /bootsier/fonts.
|
||||||
|
|
||||||
|
$bootstrap-icons-font: "bootsier.icons";
|
||||||
|
$bootstrap-icons-font-dir: "/bootsier/fonts";
|
||||||
|
@import "bootstrap-icons-1.13.1/bootstrap-icons";
|
||||||
|
|
@ -1,80 +1,14 @@
|
||||||
// Enable CSS Grid
|
// Bootstrap utility extensions. Imported just before utilities/api so variable changes take effect.
|
||||||
|
|
||||||
|
// CSS Grid (Bootstrap 5): disable legacy grid classes and enable native CSS Grid.
|
||||||
$enable-grid-classes: false;
|
$enable-grid-classes: false;
|
||||||
$enable-cssgrid: true;
|
$enable-cssgrid: true;
|
||||||
|
|
||||||
// Opacity
|
// Extend the $utilities map with additional classes.
|
||||||
.bg-opacity-0 {
|
|
||||||
--bs-bg-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-opacity-0 {
|
|
||||||
--bs-border-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-opacity-0 {
|
|
||||||
--bs-text-opacity: 0;
|
|
||||||
}
|
|
||||||
.text-opacity-10 {
|
|
||||||
--bs-text-opacity: 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FORMS
|
|
||||||
|
|
||||||
// Required field indicator
|
|
||||||
.form-required {
|
|
||||||
color: var(--bs-danger);
|
|
||||||
margin: 0 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Form fields
|
|
||||||
.form-field {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fieldset
|
|
||||||
fieldset {
|
|
||||||
position: relative;
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
|
||||||
border-radius: var(--bs-border-radius);
|
|
||||||
padding: 2rem 1rem 1rem;
|
|
||||||
margin: 2rem 0 1rem;
|
|
||||||
}
|
|
||||||
fieldset > legend {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 1rem;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
|
||||||
border-radius: var(--bs-border-radius);
|
|
||||||
padding: 0.125rem 0.75rem;
|
|
||||||
font-size: $font-size-sm;
|
|
||||||
line-height: 1.25;
|
|
||||||
width: fit-content;
|
|
||||||
max-width: 75%;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.fieldset-description {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check buttons, gap between label and first inline check
|
|
||||||
.form-label + .form-check-inline {
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extending utilities
|
|
||||||
$utilities: map-merge(
|
$utilities: map-merge(
|
||||||
$utilities,
|
$utilities,
|
||||||
(
|
(
|
||||||
// Individual border widths
|
// Individual border widths per side.
|
||||||
"border-top": (
|
"border-top": (
|
||||||
property: border-top-width,
|
property: border-top-width,
|
||||||
class: border-top,
|
class: border-top,
|
||||||
|
|
@ -95,7 +29,7 @@ $utilities: map-merge(
|
||||||
class: border-start,
|
class: border-start,
|
||||||
values: $border-widths
|
values: $border-widths
|
||||||
),
|
),
|
||||||
// Individual rounded values
|
// Individual corner radii.
|
||||||
"rounded-top-start": (
|
"rounded-top-start": (
|
||||||
property: border-top-left-radius,
|
property: border-top-left-radius,
|
||||||
class: rounded-top-start,
|
class: rounded-top-start,
|
||||||
|
|
@ -156,11 +90,18 @@ $utilities: map-merge(
|
||||||
pill: var(--#{$prefix}border-radius-pill)
|
pill: var(--#{$prefix}border-radius-pill)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
// Opacity: add missing values (0 for bg/border/text; 10 for text) not in Bootstrap defaults.
|
||||||
|
"bg-opacity": map-merge(
|
||||||
|
map-get($utilities, "bg-opacity"),
|
||||||
|
(values: map-merge(map-get(map-get($utilities, "bg-opacity"), "values"), (0: 0)))
|
||||||
|
),
|
||||||
|
"border-opacity": map-merge(
|
||||||
|
map-get($utilities, "border-opacity"),
|
||||||
|
(values: map-merge(map-get(map-get($utilities, "border-opacity"), "values"), (0: 0)))
|
||||||
|
),
|
||||||
|
"text-opacity": map-merge(
|
||||||
|
map-get($utilities, "text-opacity"),
|
||||||
|
(values: map-merge(map-get(map-get($utilities, "text-opacity"), "values"), (0: 0, 10: .1)))
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Region Footer
|
|
||||||
.region-footer {
|
|
||||||
padding: .75rem 0 3rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Bootsier overrides for Bootstrap variables. Imported before bootstrap/scss/variables
|
||||||
|
// so that Bootstrap's !default declarations do not override these values.
|
||||||
|
|
||||||
|
$font-size-base: 1.125rem;
|
||||||
1081
extensions/pagetop-bootsier/assets/adminlte-4.0.0/js/adminlte.js
Normal file
7
extensions/pagetop-bootsier/assets/adminlte-4.0.0/js/adminlte.min.js
vendored
Normal file
|
|
@ -0,0 +1,337 @@
|
||||||
|
/* ==========================================================================
|
||||||
|
AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Skip Links - WCAG 2.4.1: Bypass Blocks */
|
||||||
|
.skip-link {
|
||||||
|
position: absolute;
|
||||||
|
top: -40px;
|
||||||
|
left: 6px;
|
||||||
|
z-index: 999999;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--bs-white);
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--bs-primary);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
top: 0;
|
||||||
|
outline: 3px solid var(--bs-warning);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--bs-white);
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--bs-primary-emphasis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced Focus Indicators - WCAG 2.4.7: Focus Visible */
|
||||||
|
.focus-enhanced {
|
||||||
|
&:focus {
|
||||||
|
outline: 3px solid var(--bs-focus-ring-color, #0d6efd);
|
||||||
|
outline-offset: 2px;
|
||||||
|
box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* High Contrast Mode Support */
|
||||||
|
@media (prefers-contrast: high) {
|
||||||
|
.card {
|
||||||
|
border: 2px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-color: currentcolor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduced Motion Support - WCAG 2.3.3: Animation from Interactions */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
transition-duration: .01ms !important;
|
||||||
|
animation-duration: .01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade {
|
||||||
|
opacity: 1 !important;
|
||||||
|
/* stylelint-disable-next-line property-disallowed-list */
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse {
|
||||||
|
/* stylelint-disable-next-line property-disallowed-list */
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal.fade .modal-dialog {
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Screen Reader Only Content */
|
||||||
|
.sr-only {
|
||||||
|
position: absolute !important;
|
||||||
|
width: 1px !important;
|
||||||
|
height: 1px !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: -1px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
clip: rect(0, 0, 0, 0) !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sr-only-focusable:focus {
|
||||||
|
position: static !important;
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
padding: inherit !important;
|
||||||
|
margin: inherit !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
clip: auto !important;
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus Trap Utilities */
|
||||||
|
.focus-trap {
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessible Color Combinations - WCAG 1.4.3: Contrast (Minimum) */
|
||||||
|
.text-accessible-primary {
|
||||||
|
color: #003d82; /* 4.5:1 contrast on white */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-success {
|
||||||
|
color: #0f5132; /* 4.5:1 contrast on white */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-danger {
|
||||||
|
color: #842029; /* 4.5:1 contrast on white */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-warning {
|
||||||
|
color: #664d03; /* 4.5:1 contrast on white */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARIA Live Regions */
|
||||||
|
.live-region {
|
||||||
|
position: absolute;
|
||||||
|
left: -10000px;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.live-region-visible {
|
||||||
|
position: static;
|
||||||
|
left: auto;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced Error States - WCAG 3.3.1: Error Identification */
|
||||||
|
.form-control.is-invalid {
|
||||||
|
border-color: var(--bs-danger);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--bs-danger);
|
||||||
|
box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.invalid-feedback {
|
||||||
|
&[role="alert"] {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target Size - WCAG 2.5.8: Target Size (Minimum) */
|
||||||
|
.touch-target {
|
||||||
|
min-width: 44px;
|
||||||
|
min-height: 44px;
|
||||||
|
|
||||||
|
&.touch-target-small {
|
||||||
|
min-width: 24px;
|
||||||
|
min-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table Accessibility */
|
||||||
|
.table-accessible {
|
||||||
|
th {
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: var(--bs-secondary-bg);
|
||||||
|
|
||||||
|
&[scope="col"] {
|
||||||
|
border-bottom: 2px solid var(--bs-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[scope="row"] {
|
||||||
|
border-right: 2px solid var(--bs-border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
padding: .75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--bs-secondary);
|
||||||
|
text-align: left;
|
||||||
|
caption-side: top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation Landmarks */
|
||||||
|
nav[role="navigation"] {
|
||||||
|
&:not([aria-label]):not([aria-labelledby]) {
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
left: -10000px;
|
||||||
|
content: "Navigation";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form Fieldset Styling */
|
||||||
|
fieldset {
|
||||||
|
padding: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid var(--bs-border-color);
|
||||||
|
|
||||||
|
legend {
|
||||||
|
padding: 0 .5rem;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading States */
|
||||||
|
.loading[aria-busy="true"] {
|
||||||
|
position: relative;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-left: -10px;
|
||||||
|
content: "";
|
||||||
|
border: 2px solid var(--bs-primary);
|
||||||
|
border-top-color: transparent;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
&::after {
|
||||||
|
border-top-color: var(--bs-primary);
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark Mode Accessibility */
|
||||||
|
[data-bs-theme="dark"] {
|
||||||
|
.text-accessible-primary {
|
||||||
|
color: #6ea8fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-success {
|
||||||
|
color: #75b798;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-danger {
|
||||||
|
color: #f1aeb5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-accessible-warning {
|
||||||
|
color: #ffda6a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Accessibility */
|
||||||
|
@media print {
|
||||||
|
.skip-link,
|
||||||
|
.btn,
|
||||||
|
.nav-link {
|
||||||
|
color: #000 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[href^="http"]::after {
|
||||||
|
font-size: .8em;
|
||||||
|
content: " (" attr(href) ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Layout Fix - Ensure sidebar and main content are both visible */
|
||||||
|
.app-wrapper {
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-rows: auto 1fr auto !important;
|
||||||
|
grid-template-columns: auto 1fr !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-overlay {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-sidebar {
|
||||||
|
position: static !important;
|
||||||
|
display: block !important;
|
||||||
|
min-width: 200px !important;
|
||||||
|
max-width: 200px !important;
|
||||||
|
max-height: none !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-header {
|
||||||
|
position: static !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-main {
|
||||||
|
width: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-footer {
|
||||||
|
position: static !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
.app-content {
|
||||||
|
padding: $lte-content-padding-y $lte-content-padding-x;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// Core: Main Footer
|
||||||
|
//
|
||||||
|
|
||||||
|
.app-footer {
|
||||||
|
grid-area: #{$lte-prefix}app-footer;
|
||||||
|
width: inherit;
|
||||||
|
max-width: 100vw;
|
||||||
|
min-height: 3rem;
|
||||||
|
padding: $lte-app-footer-padding;
|
||||||
|
color: $lte-app-footer-color;
|
||||||
|
background-color: $lte-app-footer-bg;
|
||||||
|
border-top: $lte-app-footer-border-top;
|
||||||
|
@include transition($lte-transition-speed $lte-transition-fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-footer {
|
||||||
|
.app-footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: $lte-zindex-fixed-footer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When layout-fixed is used, app-main has overflow: auto which prevents
|
||||||
|
// position: sticky from working on the footer. Ensure the grid keeps the
|
||||||
|
// footer pinned at the bottom while app-main scrolls independently.
|
||||||
|
&.layout-fixed {
|
||||||
|
.app-main {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// Core: Main Header
|
||||||
|
//
|
||||||
|
|
||||||
|
.app-header {
|
||||||
|
z-index: $lte-zindex-app-header;
|
||||||
|
grid-area: #{$lte-prefix}app-header;
|
||||||
|
max-width: 100vw;
|
||||||
|
border-bottom: $lte-app-header-bottom-border;
|
||||||
|
@include transition($lte-transition-speed $lte-transition-fn);
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
position: relative;
|
||||||
|
height: $nav-link-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navbar badge
|
||||||
|
.navbar-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 9px;
|
||||||
|
right: 5px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: .6rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-header {
|
||||||
|
.app-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: $lte-zindex-fixed-header;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixes #6020: when only `fixed-header` is used (without `layout-fixed`),
|
||||||
|
// the sidebar — including its branding — used to scroll with the page
|
||||||
|
// because nothing made it sticky. Pin the sidebar so the brand and menu
|
||||||
|
// stay visible while the page content scrolls beneath the fixed header.
|
||||||
|
// Only applied on `sidebar-expand-*` breakpoints, since the mobile sidebar
|
||||||
|
// is an off-canvas overlay that handles its own positioning.
|
||||||
|
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||||
|
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||||
|
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||||
|
|
||||||
|
&.sidebar-expand#{$infix} {
|
||||||
|
@include media-breakpoint-up($next) {
|
||||||
|
.app-sidebar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
max-height: 100vh;
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
.app-main {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
grid-area: #{$lte-prefix}app-main;
|
||||||
|
max-width: 100vw;
|
||||||
|
padding-bottom: $lte-app-main-padding-bottom;
|
||||||
|
@include transition($lte-transition-speed $lte-transition-fn);
|
||||||
|
|
||||||
|
.app-content-header {
|
||||||
|
padding: 1rem $lte-content-padding-x;
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content-top-area,
|
||||||
|
.app-content-bottom-area {
|
||||||
|
color: $lte-app-content-bottom-area-color;
|
||||||
|
background-color: $lte-app-content-bottom-area-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content-top-area {
|
||||||
|
padding: $lte-app-content-top-area-padding-y $lte-app-content-top-area-padding-x;
|
||||||
|
border-bottom: $lte-app-content-top-area-top-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content-bottom-area {
|
||||||
|
padding: $lte-app-content-bottom-area-padding-y $lte-app-content-bottom-area-padding-x;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: $lte-app-content-bottom-area-margin-bottom;
|
||||||
|
border-top: $lte-app-content-bottom-area-top-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,619 @@
|
||||||
|
.app-sidebar {
|
||||||
|
--#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg};
|
||||||
|
--#{$lte-prefix}sidebar-color: #{$lte-sidebar-color};
|
||||||
|
--#{$lte-prefix}sidebar-hover-color: #{$lte-sidebar-hover-color};
|
||||||
|
--#{$lte-prefix}sidebar-active-color: #{$lte-sidebar-active-color};
|
||||||
|
--#{$lte-prefix}sidebar-menu-active-bg: #{$lte-sidebar-menu-active-bg};
|
||||||
|
--#{$lte-prefix}sidebar-menu-active-color: #{$lte-sidebar-menu-active-color};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-bg: #{$lte-sidebar-submenu-bg};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-color: #{$lte-sidebar-submenu-color};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-hover-color: #{$lte-sidebar-submenu-hover-color};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-hover-bg: #{$lte-sidebar-submenu-hover-bg};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-active-color: #{$lte-sidebar-submenu-active-color};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-active-bg: #{$lte-sidebar-submenu-active-bg};
|
||||||
|
--#{$lte-prefix}sidebar-header-color: #{$lte-sidebar-header-color};
|
||||||
|
|
||||||
|
z-index: $lte-zindex-sidebar;
|
||||||
|
grid-area: #{$lte-prefix}app-sidebar;
|
||||||
|
min-width: var(--#{$lte-prefix}sidebar-width);
|
||||||
|
max-width: var(--#{$lte-prefix}sidebar-width);
|
||||||
|
@include transition($lte-sidebar-transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-brand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: $lte-app-header-height;
|
||||||
|
padding: $lte-brand-link-padding-y $lte-brand-link-padding-x;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: $navbar-brand-font-size;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-bottom: $lte-brand-link-border-buttom solid var(--#{$prefix}border-color);
|
||||||
|
@include transition(width $lte-transition-speed $lte-transition-fn);
|
||||||
|
|
||||||
|
.brand-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.brand-image {
|
||||||
|
float: left;
|
||||||
|
width: auto;
|
||||||
|
max-height: 33px;
|
||||||
|
line-height: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-image-xs {
|
||||||
|
float: left;
|
||||||
|
width: auto;
|
||||||
|
max-height: 33px;
|
||||||
|
margin-top: -.1rem;
|
||||||
|
line-height: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-image-xl {
|
||||||
|
width: auto;
|
||||||
|
max-height: 40px;
|
||||||
|
line-height: .8;
|
||||||
|
|
||||||
|
&.single {
|
||||||
|
margin-top: -.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-text {
|
||||||
|
margin-left: .5rem;
|
||||||
|
color: rgba(var(--#{$prefix}emphasis-color-rgb), .8);
|
||||||
|
@include transition(flex $lte-transition-speed $lte-transition-fn, width $lte-transition-speed $lte-transition-fn);
|
||||||
|
&:hover {
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
padding-top: $lte-sidebar-padding-y;
|
||||||
|
padding-right: $lte-sidebar-padding-x;
|
||||||
|
padding-bottom: $lte-sidebar-padding-y;
|
||||||
|
padding-left: $lte-sidebar-padding-x;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
@include scrollbar-color-gray();
|
||||||
|
@include scrollbar-width-thin();
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
p {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nav-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 1.5rem;
|
||||||
|
max-width: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar Menu. First level links
|
||||||
|
.sidebar-menu > .nav-item {
|
||||||
|
// links
|
||||||
|
> .nav-link {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-color);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-hover-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-menu-active-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-menu-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open state
|
||||||
|
&.menu-open > .nav-link {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-hover-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-hover-bg);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-menu-active-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-menu-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First Level Submenu
|
||||||
|
> .nav-treeview {
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-submenu-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section Heading
|
||||||
|
.nav-header {
|
||||||
|
display: inline;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--#{$lte-prefix}sidebar-header-color);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All links within the sidebar menu
|
||||||
|
a {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All submenus
|
||||||
|
.nav-treeview {
|
||||||
|
> .nav-item {
|
||||||
|
> .nav-link {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-submenu-color);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-submenu-hover-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-submenu-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--#{$lte-prefix}sidebar-submenu-active-color);
|
||||||
|
background-color: var(--#{$lte-prefix}sidebar-submenu-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar navigation menu
|
||||||
|
.sidebar-menu {
|
||||||
|
// All levels
|
||||||
|
.nav-item {
|
||||||
|
> .nav-link {
|
||||||
|
margin-bottom: .2rem;
|
||||||
|
|
||||||
|
.nav-arrow {
|
||||||
|
@include transition(transform $lte-transition-fn $lte-transition-speed);
|
||||||
|
transform: translateY(-50%) #{"/*rtl:append:rotate(180deg)*/"};
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All levels
|
||||||
|
.nav-link > .nav-badge,
|
||||||
|
.nav-link > p > .nav-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 1rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link > .nav-arrow,
|
||||||
|
.nav-link > p > .nav-arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
@include transition(width $lte-transition-fn $lte-transition-speed);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline;
|
||||||
|
padding-left: .5rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-header {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding: $nav-link-padding-y ($nav-link-padding-y * 1.5);
|
||||||
|
font-size: .9rem;
|
||||||
|
@include transition(width $lte-transition-fn $lte-transition-speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tree view menu
|
||||||
|
.nav-treeview {
|
||||||
|
display: none;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-open {
|
||||||
|
> .nav-treeview {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .nav-link {
|
||||||
|
.nav-arrow {
|
||||||
|
transform: translateY(-50%) rotate(90deg) #{"/*rtl:ignore*/"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override: ensure badges/arrows are aligned to the end (right in LTR, left in RTL)
|
||||||
|
.nav-link > .nav-badge,
|
||||||
|
.nav-link > p > .nav-badge,
|
||||||
|
.nav-link > .nav-arrow,
|
||||||
|
.nav-link > p > .nav-arrow {
|
||||||
|
right: 1rem !important; // place at end in LTR
|
||||||
|
left: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-indent {
|
||||||
|
.nav-treeview {
|
||||||
|
padding-left: $lte-sidebar-padding-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-compact.nav-indent {
|
||||||
|
.nav-treeview {
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
padding-left: $lte-sidebar-padding-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-mini.sidebar-collapse.nav-indent {
|
||||||
|
.app-sidebar:hover {
|
||||||
|
.nav-treeview {
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
padding-left: $lte-sidebar-padding-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-collapse {
|
||||||
|
&.nav-compact.nav-indent {
|
||||||
|
.nav-treeview {
|
||||||
|
.nav-item {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-compact .nav-link {
|
||||||
|
@include border-radius(0);
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A fix for text overflow while transitioning from sidebar mini to full sidebar
|
||||||
|
.sidebar-menu,
|
||||||
|
.sidebar-menu > .nav-header,
|
||||||
|
.sidebar-menu .nav-link {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logo style
|
||||||
|
.logo-xs,
|
||||||
|
.logo-xl {
|
||||||
|
position: absolute;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&.brand-image-xs {
|
||||||
|
top: 12px;
|
||||||
|
left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.brand-image-xl {
|
||||||
|
top: 6px;
|
||||||
|
left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-xs {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
&.brand-image-xl {
|
||||||
|
top: 8px;
|
||||||
|
left: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-link {
|
||||||
|
&.logo-switch {
|
||||||
|
&::before {
|
||||||
|
content: "\00a0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-mini.sidebar-collapse {
|
||||||
|
.app-sidebar {
|
||||||
|
min-width: $lte-sidebar-mini-width;
|
||||||
|
max-width: $lte-sidebar-mini-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the sidebar headers
|
||||||
|
.sidebar-menu .nav-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu {
|
||||||
|
.nav-link {
|
||||||
|
width: $lte-sidebar-mini-width - $lte-sidebar-padding-x * 2;
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nav-badge,
|
||||||
|
.nav-arrow {
|
||||||
|
display: none;
|
||||||
|
animation-name: fadeOut;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-text {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .nav-link p,
|
||||||
|
.brand-text,
|
||||||
|
.logo-xl,
|
||||||
|
.nav-arrow {
|
||||||
|
visibility: hidden;
|
||||||
|
animation-name: fadeOut;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.logo-xs {
|
||||||
|
display: inline-block;
|
||||||
|
visibility: visible;
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.sidebar-without-hover) {
|
||||||
|
.app-sidebar:hover {
|
||||||
|
min-width: var(--#{$lte-prefix}sidebar-width);
|
||||||
|
max-width: var(--#{$lte-prefix}sidebar-width);
|
||||||
|
|
||||||
|
.sidebar-menu .nav-header {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .nav-link {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .nav-link p,
|
||||||
|
.brand-text,
|
||||||
|
.logo-xl {
|
||||||
|
width: auto;
|
||||||
|
margin-left: 0;
|
||||||
|
visibility: visible;
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-text {
|
||||||
|
display: inline;
|
||||||
|
max-width: inherit;
|
||||||
|
margin-left: .5rem;
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-badge,
|
||||||
|
.nav-arrow {
|
||||||
|
display: inline-block;
|
||||||
|
visibility: visible;
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation-delay: $lte-transition-speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link p {
|
||||||
|
padding-left: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-xs {
|
||||||
|
visibility: hidden;
|
||||||
|
animation-name: fadeOut;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-collapse:not(.sidebar-mini) {
|
||||||
|
.app-sidebar {
|
||||||
|
margin-left: calc(var(--#{$lte-prefix}sidebar-width) * -1); // stylelint-disable-line function-disallowed-list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-expand {
|
||||||
|
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||||
|
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||||
|
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||||
|
|
||||||
|
/* stylelint-disable-next-line scss/selector-no-union-class-name */
|
||||||
|
&#{$infix} {
|
||||||
|
@include media-breakpoint-up($next) {
|
||||||
|
&.layout-fixed {
|
||||||
|
.app-main-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.app-sidebar-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.app-main {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.app-sidebar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
max-height: 100vh;
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.sidebar-open {
|
||||||
|
.nav-link > .nav-badge,
|
||||||
|
.nav-link > p > .nav-badge {
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation-delay: $lte-transition-speed;
|
||||||
|
}
|
||||||
|
.nav-link > .nav-arrow,
|
||||||
|
.nav-link > p > .nav-arrow {
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation-delay: $lte-transition-speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-down($next) {
|
||||||
|
$max: breakpoint-max($next);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
content: "#{$max}";
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
max-height: 100vh;
|
||||||
|
margin-left: calc(var(--#{$lte-prefix}sidebar-width) * -1); // stylelint-disable-line function-disallowed-list
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.sidebar-open {
|
||||||
|
.app-sidebar {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: $lte-zindex-sidebar-overlay;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
visibility: visible;
|
||||||
|
background-color: rgba(0, 0, 0, .2);
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .nav-link p,
|
||||||
|
.app-sidebar .brand-text,
|
||||||
|
.app-sidebar .logo-xs,
|
||||||
|
.app-sidebar .logo-xl {
|
||||||
|
@include transition(margin-left $lte-transition-speed linear, opacity $lte-transition-speed ease, visibility $lte-transition-speed ease);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To prevent onload transition and animation
|
||||||
|
.app-loaded {
|
||||||
|
&.sidebar-mini.sidebar-collapse {
|
||||||
|
.sidebar-menu .nav-link p,
|
||||||
|
.brand-text {
|
||||||
|
animation-duration: $lte-transition-speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body:not(.app-loaded) {
|
||||||
|
.app-header,
|
||||||
|
.app-sidebar,
|
||||||
|
.app-main,
|
||||||
|
.app-footer {
|
||||||
|
@include transition(none !important);
|
||||||
|
animation-duration: 0s !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.hold-transition {
|
||||||
|
.app-header,
|
||||||
|
.app-sidebar,
|
||||||
|
.app-main,
|
||||||
|
.app-footer,
|
||||||
|
.nav-arrow,
|
||||||
|
.nav-badge {
|
||||||
|
@include transition(none !important);
|
||||||
|
animation-duration: 0s !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $enable-dark-mode {
|
||||||
|
@include color-mode(dark) {
|
||||||
|
&.app-sidebar,
|
||||||
|
.app-sidebar {
|
||||||
|
--#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg-dark};
|
||||||
|
--#{$lte-prefix}sidebar-color: #{$lte-sidebar-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-hover-color: #{$lte-sidebar-hover-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-active-color: #{$lte-sidebar-active-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-menu-active-bg: #{$lte-sidebar-menu-active-bg-dark};
|
||||||
|
--#{$lte-prefix}sidebar-menu-active-color: #{$lte-sidebar-menu-active-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-bg: #{$lte-sidebar-submenu-bg-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-color: #{$lte-sidebar-submenu-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-hover-color: #{$lte-sidebar-submenu-hover-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-hover-bg: #{$lte-sidebar-submenu-hover-bg-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-active-color: #{$lte-sidebar-submenu-active-color-dark};
|
||||||
|
--#{$lte-prefix}sidebar-submenu-active-bg: #{$lte-sidebar-submenu-active-bg-dark};
|
||||||
|
--#{$lte-prefix}sidebar-header-color: #{$lte-sidebar-header-color-dark};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// Core: Layout
|
||||||
|
//
|
||||||
|
|
||||||
|
.app-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-header"
|
||||||
|
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-main"
|
||||||
|
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-footer";
|
||||||
|
grid-template-rows: min-content 1fr min-content;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-gap: 0;
|
||||||
|
align-content: stretch;
|
||||||
|
align-items: stretch;
|
||||||
|
max-width: 100vw;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Callouts
|
||||||
|
//
|
||||||
|
|
||||||
|
.callout {
|
||||||
|
--#{$prefix}link-color-rgb: var(--#{$lte-prefix}callout-link);
|
||||||
|
--#{$prefix}code-color: var(--#{$lte-prefix}callout-code-color);
|
||||||
|
|
||||||
|
padding: 1.25rem;
|
||||||
|
color: var(--#{$lte-prefix}callout-color, inherit);
|
||||||
|
background-color: var(--#{$lte-prefix}callout-bg, var(--bs-gray-100));
|
||||||
|
border-left: .25rem solid var(--#{$lte-prefix}callout-border, var(--bs-gray-300));
|
||||||
|
|
||||||
|
.callout-link {
|
||||||
|
font-weight: $lte-callout-link-font-weight;
|
||||||
|
color: var(--#{$prefix}callout-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .callout {
|
||||||
|
margin-top: -.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variations
|
||||||
|
@each $name, $color in $theme-colors {
|
||||||
|
.callout-#{$name} {
|
||||||
|
--#{$lte-prefix}callout-color: var(--#{$prefix}#{$name}-text-emphasis);
|
||||||
|
--#{$lte-prefix}callout-bg: var(--#{$prefix}#{$name}-bg-subtle);
|
||||||
|
--#{$lte-prefix}callout-border: var(--#{$prefix}#{$name}-border-subtle);
|
||||||
|
--#{$prefix}callout-link-color: var(--#{$prefix}#{$name}-text-emphasis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,311 @@
|
||||||
|
//
|
||||||
|
// Component: Cards
|
||||||
|
//
|
||||||
|
|
||||||
|
// Color variants
|
||||||
|
.card {
|
||||||
|
@include box-shadow($lte-card-shadow);
|
||||||
|
|
||||||
|
&[class*="card-"]:not(.card-outline),
|
||||||
|
&[class*="text-bg-"]:not(.card-outline) {
|
||||||
|
> .card-header {
|
||||||
|
color: var(--#{$lte-prefix}card-variant-color);
|
||||||
|
background-color: var(--#{$lte-prefix}card-variant-bg);
|
||||||
|
|
||||||
|
.btn-tool {
|
||||||
|
--#{$prefix}btn-color: rgba(var(--#{$lte-prefix}card-variant-color-rgb), .8);
|
||||||
|
--#{$prefix}btn-hover-color: var(--#{$lte-prefix}card-variant-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.card-outline {
|
||||||
|
border-top: 3px solid var(--#{$lte-prefix}card-variant-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.maximized-card {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: $zindex-modal-backdrop;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
|
||||||
|
&.was-collapsed .card-body {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-lte-toggle="card-collapse"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-lte-icon="maximize"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header,
|
||||||
|
.card-footer {
|
||||||
|
@include border-radius(0 !important);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.maximized-card) {
|
||||||
|
[data-lte-icon="minimize"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapsed mode
|
||||||
|
&.collapsed-card {
|
||||||
|
// Use > .card-header to scope to direct card only, not nested cards
|
||||||
|
> .card-header [data-lte-icon="collapse"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .card-body,
|
||||||
|
> .card-footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.collapsed-card) {
|
||||||
|
// Use > .card-header to scope to direct card only, not nested cards
|
||||||
|
> .card-header [data-lte-icon="expand"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.nav.flex-column {
|
||||||
|
> li {
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid $card-border-color;
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixed height to 300px
|
||||||
|
&.height-control {
|
||||||
|
.card-body {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-end {
|
||||||
|
border-right: 1px solid $card-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-start {
|
||||||
|
border-left: 1px solid $card-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.card-tabs {
|
||||||
|
&:not(.card-outline) {
|
||||||
|
> .card-header {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
&:first-child .nav-link {
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.card-outline {
|
||||||
|
.nav-item {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
&:first-child .nav-link {
|
||||||
|
margin-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-tools {
|
||||||
|
margin: .3rem .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.expanding-card).collapsed-card {
|
||||||
|
.card-header {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.expanding-card {
|
||||||
|
.card-header {
|
||||||
|
.nav-tabs {
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.card-outline-tabs {
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
.nav-item {
|
||||||
|
&:first-child .nav-link {
|
||||||
|
margin-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
border-top: 3px solid transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-top: 3px solid $nav-tabs-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
&:hover {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-tools {
|
||||||
|
margin: .5rem .5rem .3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.expanding-card).collapsed-card .card-header {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.expanding-card {
|
||||||
|
.card-header {
|
||||||
|
.nav-tabs {
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maximized Card Body Scroll fix
|
||||||
|
html.maximized-card {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add clearfix to header, body and footer
|
||||||
|
.card-header,
|
||||||
|
.card-body,
|
||||||
|
.card-footer {
|
||||||
|
@include clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box header
|
||||||
|
.card-header {
|
||||||
|
position: relative;
|
||||||
|
padding: (($card-spacer-y * .5) * 2) $card-spacer-x;
|
||||||
|
background-color: transparent;
|
||||||
|
border-bottom: 1px solid $card-border-color;
|
||||||
|
|
||||||
|
@if $enable-rounded {
|
||||||
|
@include border-top-radius($border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-card & {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .card-tools {
|
||||||
|
float: right;
|
||||||
|
margin-right: -$card-spacer-x * .5;
|
||||||
|
|
||||||
|
.input-group,
|
||||||
|
.nav,
|
||||||
|
.pagination {
|
||||||
|
margin-top: -$card-spacer-y * .4;
|
||||||
|
margin-bottom: -$card-spacer-y * .4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-toggle="tooltip"] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
float: left;
|
||||||
|
margin: 0;
|
||||||
|
font-size: $lte-card-title-font-size;
|
||||||
|
font-weight: $lte-card-title-font-weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box Tools Buttons
|
||||||
|
.btn-tool {
|
||||||
|
--#{$prefix}btn-padding-x: .5rem;
|
||||||
|
--#{$prefix}btn-padding-y: .25rem;
|
||||||
|
|
||||||
|
&:not(.btn-tool-custom) {
|
||||||
|
--#{$prefix}btn-color: var(--#{$prefix}tertiary-color);
|
||||||
|
--#{$prefix}btn-bg: transparent;
|
||||||
|
--#{$prefix}btn-box-shadow: none;
|
||||||
|
--#{$prefix}btn-hover-color: var(--#{$prefix}secondary-color);
|
||||||
|
--#{$prefix}btn-active-border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin: -$card-spacer-y 0;
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $name, $color in $theme-colors {
|
||||||
|
.card-#{$name},
|
||||||
|
.bg-#{$name},
|
||||||
|
.text-bg-#{$name} {
|
||||||
|
--#{$lte-prefix}card-variant-bg: #{$color};
|
||||||
|
--#{$lte-prefix}card-variant-bg-rgb: #{to-rgb($color)};
|
||||||
|
--#{$lte-prefix}card-variant-color: #{color-contrast($color)};
|
||||||
|
--#{$lte-prefix}card-variant-color-rgb: #{to-rgb(color-contrast($color))};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box Body
|
||||||
|
.card-body {
|
||||||
|
// Tables within the box body
|
||||||
|
> .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
> thead > tr > th,
|
||||||
|
> thead > tr > td {
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
.compact-mode {
|
||||||
|
.app-header {
|
||||||
|
max-height: $lte-app-header-height-compact;
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
max-height: $nav-link-height-compact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
--bs-nav-link-padding-y: .25rem;
|
||||||
|
--bs-nav-link-padding-x: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.sidebar-mini.sidebar-collapse {
|
||||||
|
.app-sidebar:not(:hover) {
|
||||||
|
min-width: $lte-sidebar-mini-width-compact;
|
||||||
|
max-width: $lte-sidebar-mini-width-compact;
|
||||||
|
|
||||||
|
.sidebar-menu {
|
||||||
|
.nav-link {
|
||||||
|
width: $lte-sidebar-mini-width-compact - $lte-sidebar-padding-x * 2 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-xs,
|
||||||
|
.logo-xl {
|
||||||
|
max-height: $lte-app-header-height-compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-image {
|
||||||
|
width: $nav-link-height-compact;
|
||||||
|
height: $nav-link-height-compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-brand {
|
||||||
|
height: $lte-app-header-height-compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-footer {
|
||||||
|
padding: $lte-app-footer-padding-compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
.nav-icon {
|
||||||
|
min-width: 1.1rem;
|
||||||
|
max-width: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
//
|
||||||
|
// Component: Direct Chat
|
||||||
|
//
|
||||||
|
|
||||||
|
.direct-chat {
|
||||||
|
.card-body {
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.chat-pane-open {
|
||||||
|
.direct-chat-contacts {
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&.timestamp-light {
|
||||||
|
.direct-chat-timestamp {
|
||||||
|
color: rgba(var(--#{$prefix}body-color-rgb), .65);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.timestamp-dark {
|
||||||
|
.direct-chat-timestamp {
|
||||||
|
color: rgba(var(--#{$prefix}body-color-rgb), .9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-messages {
|
||||||
|
height: 250px;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: auto;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-msg,
|
||||||
|
.direct-chat-text {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-msg {
|
||||||
|
@include clearfix();
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-messages,
|
||||||
|
.direct-chat-contacts {
|
||||||
|
@include transition(transform .5s ease-in-out);
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-text {
|
||||||
|
@if $enable-rounded {
|
||||||
|
@include border-radius($border-radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin: 5px 0 0 50px;
|
||||||
|
color: $lte-direct-chat-default-font-color;
|
||||||
|
background-color: $lte-direct-chat-default-msg-bg;
|
||||||
|
border: 1px solid $lte-direct-chat-default-msg-border-color;
|
||||||
|
|
||||||
|
//Create the arrow
|
||||||
|
&::after,
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 100%;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
content: " ";
|
||||||
|
border: solid transparent;
|
||||||
|
border-right-color: $lte-direct-chat-default-msg-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
margin-top: -5px;
|
||||||
|
border-width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
margin-top: -6px;
|
||||||
|
border-width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end & {
|
||||||
|
margin-right: 50px;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
&::after,
|
||||||
|
&::before {
|
||||||
|
right: auto;
|
||||||
|
left: 100%;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-left-color: $lte-direct-chat-default-msg-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-img {
|
||||||
|
@include border-radius(50%);
|
||||||
|
float: left;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
.end & {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-infos {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-name {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-timestamp {
|
||||||
|
color: rgba(var(--#{$prefix}body-color-rgb), .75);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Direct chat contacts pane
|
||||||
|
.direct-chat-contacts-open {
|
||||||
|
.direct-chat-contacts {
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-contacts {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 250px;
|
||||||
|
overflow: auto;
|
||||||
|
color: var(--#{$prefix}body-bg);
|
||||||
|
background-color: var(--#{$prefix}body-color);
|
||||||
|
transform: translate(101%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.direct-chat-contacts-light {
|
||||||
|
background-color: var(--#{$prefix}light-bg-subtle);
|
||||||
|
|
||||||
|
.contacts-list-name {
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-date {
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-msg {
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Contacts list -- for displaying contacts in direct chat contacts pane
|
||||||
|
.contacts-list {
|
||||||
|
@include list-unstyled();
|
||||||
|
|
||||||
|
> li {
|
||||||
|
@include clearfix();
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid rgba($black, .2);
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-img {
|
||||||
|
@include border-radius(50%);
|
||||||
|
float: left;
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-info {
|
||||||
|
margin-left: 45px;
|
||||||
|
color: var(--#{$prefix}body-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-name,
|
||||||
|
.contacts-list-status {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-name {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-status {
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-date {
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--#{$prefix}secondary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contacts-list-msg {
|
||||||
|
color: var(--#{$prefix}secondary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.end > .direct-chat-text {
|
||||||
|
color: var(--#{$lte-prefix}direct-chat-color);
|
||||||
|
background-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||||
|
border-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||||
|
|
||||||
|
&::after,
|
||||||
|
&::before {
|
||||||
|
border-left-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color variants
|
||||||
|
@each $name, $color in $theme-colors {
|
||||||
|
.direct-chat-#{$name} {
|
||||||
|
--#{$lte-prefix}direct-chat-color: #{color-contrast($color)};
|
||||||
|
--#{$lte-prefix}direct-chat-bg: #{$color};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,820 @@
|
||||||
|
//
|
||||||
|
// Component: Docs
|
||||||
|
//
|
||||||
|
// Visual treatment for documentation pages. Body class `.docs-page` opts in.
|
||||||
|
// Demo pages are not affected.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Inline code blocks rendered by MDX (Astro highlight default class)
|
||||||
|
.astro-code {
|
||||||
|
padding: .75rem;
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-page {
|
||||||
|
// Constrain the docs card to a comfortable reading width.
|
||||||
|
// Tables and code blocks inside can still scroll horizontally if needed.
|
||||||
|
.app-content > .container-fluid {
|
||||||
|
max-width: 60rem; // ~960px
|
||||||
|
|
||||||
|
@include media-breakpoint-up(xxl) {
|
||||||
|
max-width: 64rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Card body — breathing room + prose typography.
|
||||||
|
// Only applied inside docs content cards so demo-page card content
|
||||||
|
// stays unchanged.
|
||||||
|
//
|
||||||
|
.card > .card-body {
|
||||||
|
padding: 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
padding: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Heading hierarchy. The MDX content in src/html/components/docs/ uses
|
||||||
|
// ##### (h5) as the dominant section heading and ###### (h6) as a
|
||||||
|
// sub-heading (most visible in FAQ.mdx, where h5 is a topic and h6 is
|
||||||
|
// a question). Style h5 as a major section and h6 as a sub-section so
|
||||||
|
// the visual hierarchy matches the semantic one.
|
||||||
|
//
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
.h1,
|
||||||
|
.h2,
|
||||||
|
.h3,
|
||||||
|
.h4,
|
||||||
|
.h5,
|
||||||
|
.h6 {
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: .5em;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
scroll-margin-top: 4rem; // anchor-link friendly
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2,
|
||||||
|
.h2 {
|
||||||
|
padding-bottom: .35em;
|
||||||
|
font-size: 1.75rem;
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3,
|
||||||
|
.h3 {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4,
|
||||||
|
.h4 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// h5 is the dominant section heading across docs MDX files. Give it
|
||||||
|
// a visible separator above so sections are easy to scan.
|
||||||
|
h5,
|
||||||
|
.h5 {
|
||||||
|
padding-top: 1.5em;
|
||||||
|
margin-top: 2.5em;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
border-top: 1px solid var(--#{$prefix}border-color);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// h6 is the sub-section / FAQ question style. Smaller than h5 but
|
||||||
|
// still distinctly heading-like, with a touch of accent colour to
|
||||||
|
// separate from body text.
|
||||||
|
h6,
|
||||||
|
.h6 {
|
||||||
|
margin-top: 1.75em;
|
||||||
|
font-size: 1.08rem;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Paragraphs and lists.
|
||||||
|
//
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
dl,
|
||||||
|
blockquote,
|
||||||
|
table {
|
||||||
|
margin-bottom: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: .35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tighter nested lists
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-top: .35rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lead-style first paragraph (just after a heading)
|
||||||
|
h2 + p,
|
||||||
|
h3 + p,
|
||||||
|
h5 + p {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inline code — pill style that complements MDX's syntax-highlighted blocks.
|
||||||
|
//
|
||||||
|
p code,
|
||||||
|
li code,
|
||||||
|
td code,
|
||||||
|
th code,
|
||||||
|
h2 code,
|
||||||
|
h3 code,
|
||||||
|
h4 code,
|
||||||
|
h5 code,
|
||||||
|
h6 code {
|
||||||
|
padding: .15em .4em;
|
||||||
|
font-size: .875em;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Code blocks.
|
||||||
|
//
|
||||||
|
pre.astro-code,
|
||||||
|
pre {
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
font-size: .875rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tables — reference-doc styling with hairline borders.
|
||||||
|
//
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: .95rem;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: .65rem .9rem;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Blockquotes used as info callouts.
|
||||||
|
//
|
||||||
|
blockquote {
|
||||||
|
padding: .85rem 1.1rem;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
background: var(--#{$prefix}info-bg-subtle);
|
||||||
|
border-left: 4px solid var(--#{$prefix}info-border-subtle);
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prose links — stand out more than Bootstrap defaults.
|
||||||
|
//
|
||||||
|
a:not(.btn):not(.nav-link) {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-thickness: 1px;
|
||||||
|
text-underline-offset: 3px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration-thickness: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Horizontal rule — used as additional section separator.
|
||||||
|
//
|
||||||
|
hr {
|
||||||
|
margin: 2.5rem 0;
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid var(--#{$prefix}border-color);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lead paragraph — the first paragraph in any doc is a summary.
|
||||||
|
// Visually heavier so it functions as a deck.
|
||||||
|
//
|
||||||
|
> p:first-child,
|
||||||
|
> p:first-of-type {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAQ / disclosure accordion — uses native <details>/<summary>.
|
||||||
|
// Add `.faq-item` to <details> to opt in.
|
||||||
|
//
|
||||||
|
details.faq-item {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
@include transition(border-color .15s ease, box-shadow .15s ease);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--#{$prefix}primary-border-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] {
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
border-color: var(--#{$prefix}primary-border-subtle);
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
position: relative;
|
||||||
|
padding: .9rem 3rem .9rem 1.1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
@include transition(color .15s ease);
|
||||||
|
|
||||||
|
// Hide the default disclosure triangle in Webkit/Blink
|
||||||
|
&::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the marker in modern Firefox too
|
||||||
|
&::marker {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right-side chevron, rotates on open
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 1.1rem;
|
||||||
|
display: inline-block;
|
||||||
|
width: .55rem;
|
||||||
|
height: .55rem;
|
||||||
|
margin-top: -.4rem;
|
||||||
|
content: "";
|
||||||
|
border-right: 2px solid currentcolor;
|
||||||
|
border-bottom: 2px solid currentcolor;
|
||||||
|
opacity: .55;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
@include transition(transform .2s ease);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] > summary {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
margin-top: -.15rem;
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(-135deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content (everything after <summary>) gets the inner padding
|
||||||
|
> *:not(summary) {
|
||||||
|
padding-right: 1.1rem;
|
||||||
|
padding-left: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> *:not(summary):first-of-type {
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> *:not(summary):last-child {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tighten paragraphs/lists inside an FAQ answer
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-bottom: .65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> *:last-child p:last-child,
|
||||||
|
> p:last-child,
|
||||||
|
> ul:last-child,
|
||||||
|
> ol:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code blocks inside an FAQ answer get a less-distracting bg
|
||||||
|
pre.astro-code,
|
||||||
|
pre {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark-mode tweak: blockquote info bg needs more contrast on dark
|
||||||
|
&[data-bs-theme="dark"],
|
||||||
|
[data-bs-theme="dark"] & {
|
||||||
|
.card > .card-body blockquote code {
|
||||||
|
background: rgba(255, 255, 255, .08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAQ page — custom layout that breaks out of the standard docs card
|
||||||
|
// to give the FAQ a more distinctive visual identity. Opt in via
|
||||||
|
// body.faq-page (set in pages/docs/faq.astro).
|
||||||
|
//
|
||||||
|
|
||||||
|
.faq-page {
|
||||||
|
// The FAQ doesn't use the standard card wrapper used by other docs,
|
||||||
|
// so the container can stretch wider for the chip strip and section
|
||||||
|
// grid.
|
||||||
|
.app-content > .container-fluid {
|
||||||
|
max-width: 64rem;
|
||||||
|
|
||||||
|
@include media-breakpoint-up(xxl) {
|
||||||
|
max-width: 72rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Hero -------------------------------------------------------------
|
||||||
|
.faq-hero {
|
||||||
|
position: relative;
|
||||||
|
padding: 3rem 1.5rem 2.5rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
background: radial-gradient(ellipse at top left, rgba(var(--#{$prefix}primary-rgb), .12), transparent 60%), radial-gradient(ellipse at bottom right, rgba(var(--#{$prefix}info-rgb), .1), transparent 65%), var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-hero-eyebrow {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: .4rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: .35rem .85rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: .75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .08em;
|
||||||
|
background: var(--#{$prefix}primary-bg-subtle);
|
||||||
|
border: 1px solid var(--#{$prefix}primary-border-subtle);
|
||||||
|
@include border-radius(50rem);
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-hero-title {
|
||||||
|
margin: 0 0 .5rem;
|
||||||
|
font-size: 2.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.15;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
font-size: 2.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-hero-lead {
|
||||||
|
max-width: 36rem;
|
||||||
|
margin: 0 auto 1.75rem;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-search {
|
||||||
|
position: relative;
|
||||||
|
max-width: 32rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: 3rem;
|
||||||
|
padding-right: 3rem;
|
||||||
|
padding-left: 3rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
@include border-radius(50rem);
|
||||||
|
@include transition(box-shadow .15s ease, border-color .15s ease);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 .25rem rgba(var(--#{$prefix}primary-rgb), .15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-search-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 1.2rem;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-search-clear {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: .65rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
border: 0;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
@include border-radius(50%);
|
||||||
|
@include transition(background .15s ease, color .15s ease);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
background: var(--#{$prefix}secondary-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-empty-state {
|
||||||
|
max-width: 32rem;
|
||||||
|
padding: 1rem;
|
||||||
|
margin: 1.5rem auto 0;
|
||||||
|
font-size: .95rem;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
margin-right: .35rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Section nav chips ------------------------------------------------
|
||||||
|
.faq-chips {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: .5rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: .45rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: .45rem .85rem;
|
||||||
|
font-size: .875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius(50rem);
|
||||||
|
@include transition(transform .15s ease, border-color .15s ease, background-color .15s ease, color .15s ease);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-chip-count {
|
||||||
|
padding: 0 .45rem;
|
||||||
|
font-size: .7rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
@include border-radius(50rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-section chip accent on hover/active
|
||||||
|
@each $tone in (primary, info, warning, success, danger, secondary) {
|
||||||
|
.faq-chip-#{$tone}:hover {
|
||||||
|
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||||
|
background: var(--#{$prefix}#{$tone}-bg-subtle);
|
||||||
|
border-color: var(--#{$prefix}#{$tone}-border-subtle);
|
||||||
|
|
||||||
|
.faq-chip-count {
|
||||||
|
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||||
|
background: rgba(0, 0, 0, .06);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Sections ---------------------------------------------------------
|
||||||
|
.faq-section {
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
scroll-margin-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section-header {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
border-left: 4px solid var(--#{$prefix}primary);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2.75rem;
|
||||||
|
height: 2.75rem;
|
||||||
|
font-size: 1.35rem;
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
background: var(--#{$prefix}primary-bg-subtle);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section-count {
|
||||||
|
margin: .1rem 0 0;
|
||||||
|
font-size: .8rem;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-section tone accents
|
||||||
|
@each $tone in (primary, info, warning, success, danger, secondary) {
|
||||||
|
.faq-section-#{$tone} {
|
||||||
|
border-left-color: var(--#{$prefix}#{$tone});
|
||||||
|
|
||||||
|
.faq-section-icon {
|
||||||
|
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||||
|
background: var(--#{$prefix}#{$tone}-bg-subtle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FAQ items (override the generic .docs-page details styling) ------
|
||||||
|
.faq-section-items .faq-item {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
@include transition(border-color .15s ease, box-shadow .15s ease, transform .15s ease);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--#{$prefix}primary-border-subtle);
|
||||||
|
transform: translateX(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] {
|
||||||
|
border-color: var(--#{$prefix}primary-border-subtle);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, .04);
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: flex;
|
||||||
|
gap: .85rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::marker {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: none; // disable the generic chevron, we use our own
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-q-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.75rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
font-size: .85rem;
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
background: var(--#{$prefix}primary-bg-subtle);
|
||||||
|
@include border-radius(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-q-text {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-q-chevron {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
@include transition(transform .2s ease, color .2s ease);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] .faq-q-chevron {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] summary {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-answer {
|
||||||
|
padding: 1.1rem 1.25rem 1.1rem 3.85rem; // align with the question text (icon + gap)
|
||||||
|
font-size: .95rem;
|
||||||
|
line-height: 1.65;
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
|
||||||
|
p:last-child,
|
||||||
|
ul:last-child,
|
||||||
|
ol:last-child,
|
||||||
|
pre:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration-thickness: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: .12em .35em;
|
||||||
|
font-size: .875em;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
background: var(--#{$prefix}tertiary-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.astro-code,
|
||||||
|
pre {
|
||||||
|
padding: .85rem 1rem;
|
||||||
|
margin-top: .75rem;
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
font-size: .85rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- CTA footer -------------------------------------------------------
|
||||||
|
.faq-cta {
|
||||||
|
padding: 2.5rem 1.5rem;
|
||||||
|
text-align: center;
|
||||||
|
background: radial-gradient(ellipse at top, rgba(var(--#{$prefix}primary-rgb), .08), transparent 60%), var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
@include border-radius($border-radius-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-cta-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 3.5rem;
|
||||||
|
height: 3.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
color: var(--#{$prefix}primary);
|
||||||
|
background: var(--#{$prefix}primary-bg-subtle);
|
||||||
|
@include border-radius(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-cta h2 {
|
||||||
|
margin: 0 0 .5rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-cta p {
|
||||||
|
max-width: 32rem;
|
||||||
|
margin: 0 auto 1.5rem;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-cta-actions {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: .5rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
//
|
||||||
|
// Component: Dropdown
|
||||||
|
//
|
||||||
|
|
||||||
|
// General Dropdown Rules
|
||||||
|
|
||||||
|
// Ensure children cannot overflow and break the dropdown border radius
|
||||||
|
.dropdown-menu {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs-7 {
|
||||||
|
.dropdown-menu {
|
||||||
|
font-size: $font-size-sm !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
vertical-align: .2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: $font-size-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-icon {
|
||||||
|
&::after {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown Sizes
|
||||||
|
.dropdown-menu-lg {
|
||||||
|
min-width: 280px;
|
||||||
|
max-width: 300px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.dropdown-divider {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
padding: $dropdown-padding-y $dropdown-item-padding-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown Submenu
|
||||||
|
.dropdown-submenu {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> a::after {
|
||||||
|
@include caret-end();
|
||||||
|
float: right;
|
||||||
|
margin-top: .5rem;
|
||||||
|
margin-left: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .dropdown-menu {
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown Hover
|
||||||
|
.dropdown-hover {
|
||||||
|
&:hover,
|
||||||
|
&.nav-item.dropdown:hover,
|
||||||
|
.dropdown-submenu:hover,
|
||||||
|
&.dropdown-submenu:hover {
|
||||||
|
> .dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Dropdown Sizes
|
||||||
|
.dropdown-menu-xl {
|
||||||
|
min-width: 360px;
|
||||||
|
max-width: 420px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.dropdown-divider {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
padding: $dropdown-padding-y $dropdown-item-padding-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown header and footer
|
||||||
|
.dropdown-footer,
|
||||||
|
.dropdown-header {
|
||||||
|
display: block;
|
||||||
|
padding: .5rem $dropdown-item-padding-x;
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add fade animation to dropdown menus by appending
|
||||||
|
// the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)
|
||||||
|
.open:not(.dropup) > .animated-dropdown-menu {
|
||||||
|
animation: flipInX .7s both;
|
||||||
|
backface-visibility: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix dropdown menu in navbars
|
||||||
|
.navbar-custom-menu > .navbar-nav {
|
||||||
|
> li {
|
||||||
|
position: relative;
|
||||||
|
> .dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-down(sm) {
|
||||||
|
.navbar-custom-menu > .navbar-nav {
|
||||||
|
float: right;
|
||||||
|
> li {
|
||||||
|
position: static;
|
||||||
|
> .dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 5%;
|
||||||
|
left: auto;
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User Menu
|
||||||
|
.navbar-nav > .user-menu {
|
||||||
|
> .nav-link::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .dropdown-menu {
|
||||||
|
width: 280px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
// Header menu
|
||||||
|
> li.user-header {
|
||||||
|
min-height: 175px;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
// User image
|
||||||
|
> img {
|
||||||
|
z-index: 5;
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
border: 3px solid;
|
||||||
|
border-color: transparent;
|
||||||
|
border-color: var(--#{$prefix}border-color-translucent);
|
||||||
|
}
|
||||||
|
|
||||||
|
> p {
|
||||||
|
z-index: 5;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 17px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
> small {
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menu Body
|
||||||
|
> .user-body {
|
||||||
|
@include clearfix();
|
||||||
|
padding: 15px;
|
||||||
|
border-top: 1px solid var(--#{$prefix}border-color);
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color-translucent);
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menu Footer
|
||||||
|
> .user-footer {
|
||||||
|
@include clearfix();
|
||||||
|
padding: 10px;
|
||||||
|
background-color: var(--#{$prefix}light-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-image {
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
float: none;
|
||||||
|
margin-top: -8px;
|
||||||
|
margin-right: .4rem;
|
||||||
|
line-height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
float: left;
|
||||||
|
width: $lte-sidebar-user-image-width;
|
||||||
|
height: $lte-sidebar-user-image-width;
|
||||||
|
margin-top: -2px;
|
||||||
|
// margin-right: 10px;
|
||||||
|
@include border-radius(50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
//
|
||||||
|
// Component: Info Box
|
||||||
|
//
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
@include box-shadow($lte-card-shadow);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 80px;
|
||||||
|
padding: .5rem;
|
||||||
|
margin-bottom: map-get($spacers, 3);
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
height: 2px;
|
||||||
|
margin: 5px 0;
|
||||||
|
background-color: rgba(var(--#{$lte-prefix}card-variant-color-rgb), .125);
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
background-color: var(--#{$lte-prefix}card-variant-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 70px;
|
||||||
|
font-size: 1.875rem;
|
||||||
|
text-align: center;
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
|
||||||
|
> img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-number {
|
||||||
|
display: block;
|
||||||
|
margin-top: .25rem;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-description,
|
||||||
|
.info-box-text {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-more {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-description {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
.col-xl-2 &,
|
||||||
|
.col-lg-2 &,
|
||||||
|
.col-md-2 & {
|
||||||
|
.progress-description {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-xl-3 &,
|
||||||
|
.col-lg-3 &,
|
||||||
|
.col-md-3 & {
|
||||||
|
.progress-description {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(lg) {
|
||||||
|
.col-xl-2 &,
|
||||||
|
.col-lg-2 &,
|
||||||
|
.col-md-2 & {
|
||||||
|
.progress-description {
|
||||||
|
@include font-size(.75rem);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-xl-3 &,
|
||||||
|
.col-lg-3 &,
|
||||||
|
.col-md-3 & {
|
||||||
|
.progress-description {
|
||||||
|
@include font-size(.75rem);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(xl) {
|
||||||
|
.col-xl-2 &,
|
||||||
|
.col-lg-2 &,
|
||||||
|
.col-md-2 & {
|
||||||
|
.progress-description {
|
||||||
|
@include font-size(1rem);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-xl-3 &,
|
||||||
|
.col-lg-3 &,
|
||||||
|
.col-md-3 & {
|
||||||
|
.progress-description {
|
||||||
|
@include font-size(1rem);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
//
|
||||||
|
// Misc: Miscellaneous
|
||||||
|
//
|
||||||
|
|
||||||
|
// Image sizes
|
||||||
|
.img-size-64,
|
||||||
|
.img-size-50,
|
||||||
|
.img-size-32 {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-size-64 {
|
||||||
|
width: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-size-50 {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-size-32 {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
//
|
||||||
|
// General: Mixins
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "mixins/animations";
|
||||||
|
@import "mixins/scrollbar";
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
//
|
||||||
|
// Component: Progress Bar
|
||||||
|
//
|
||||||
|
|
||||||
|
//General CSS
|
||||||
|
.progress {
|
||||||
|
@include box-shadow(null);
|
||||||
|
@include border-radius($lte-progress-bar-border-radius);
|
||||||
|
|
||||||
|
// Vertical bars
|
||||||
|
&.vertical {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 30px;
|
||||||
|
height: 200px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
> .progress-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sizes
|
||||||
|
&.sm,
|
||||||
|
&.progress-sm {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.xs,
|
||||||
|
&.progress-xs {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.xxs,
|
||||||
|
&.progress-xxs {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-group {
|
||||||
|
margin-bottom: map-get($spacers, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// size variation
|
||||||
|
.progress-sm {
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-xs {
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-xxs {
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove margins from progress bars when put in a table
|
||||||
|
.table {
|
||||||
|
tr > td {
|
||||||
|
.progress {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
:root,
|
||||||
|
[data-bs-theme="light"] {
|
||||||
|
// Sidebar
|
||||||
|
--#{$lte-prefix}sidebar-width: #{$lte-sidebar-width};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
//
|
||||||
|
// Component: Small Box
|
||||||
|
//
|
||||||
|
|
||||||
|
.small-box {
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
@include box-shadow($lte-card-shadow);
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
--bs-link-color-rgb: none;
|
||||||
|
--bs-link-hover-color-rgb: none;
|
||||||
|
--bs-heading-color: none;
|
||||||
|
|
||||||
|
// content wrapper
|
||||||
|
> .inner {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .small-box-footer {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
display: block;
|
||||||
|
padding: 3px 0;
|
||||||
|
text-align: center;
|
||||||
|
background-color: rgba($black, .07);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba($black, .1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@include font-size(2.2rem);
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(lg) {
|
||||||
|
.col-xl-2 &,
|
||||||
|
.col-lg-2 &,
|
||||||
|
.col-md-2 & {
|
||||||
|
h3 {
|
||||||
|
@include font-size(1.6rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-xl-3 &,
|
||||||
|
.col-lg-3 &,
|
||||||
|
.col-md-3 & {
|
||||||
|
h3 {
|
||||||
|
@include font-size(1.6rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(xl) {
|
||||||
|
.col-xl-2 &,
|
||||||
|
.col-lg-2 &,
|
||||||
|
.col-md-2 & {
|
||||||
|
h3 {
|
||||||
|
@include font-size(2.2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-xl-3 &,
|
||||||
|
.col-lg-3 &,
|
||||||
|
.col-md-3 & {
|
||||||
|
h3 {
|
||||||
|
@include font-size(2.2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
> small {
|
||||||
|
display: block;
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: .9rem;
|
||||||
|
color: $gray-100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3,
|
||||||
|
p {
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the icon
|
||||||
|
.small-box-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 15px;
|
||||||
|
z-index: 0;
|
||||||
|
height: 70px;
|
||||||
|
font-size: 70px;
|
||||||
|
color: rgba($black, .15);
|
||||||
|
@include transition(transform $lte-transition-speed linear);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small box hover state
|
||||||
|
&:hover {
|
||||||
|
// Animate icons on small box hover
|
||||||
|
.small-box-icon {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-down(sm) {
|
||||||
|
// No need for icons on very small devices
|
||||||
|
.small-box {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.small-box-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
//
|
||||||
|
// Component: Table
|
||||||
|
//
|
||||||
|
|
||||||
|
.table {
|
||||||
|
&:not(.table-dark) {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixed table head
|
||||||
|
// Uses Bootstrap CSS variables so the sticky header follows light/dark mode
|
||||||
|
// automatically. Fixes #6026.
|
||||||
|
&.table-head-fixed {
|
||||||
|
thead tr:nth-child(1) th {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: var(--bs-body-bg, #{$white});
|
||||||
|
border-bottom: 0;
|
||||||
|
box-shadow: inset 0 1px 0 var(--bs-border-color, #{$table-border-color}), inset 0 -1px 0 var(--bs-border-color, #{$table-border-color});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no border
|
||||||
|
&.no-border {
|
||||||
|
&,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .text-center in tables
|
||||||
|
&.text-center {
|
||||||
|
&,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-valign-middle {
|
||||||
|
thead > tr > th,
|
||||||
|
thead > tr > td,
|
||||||
|
tbody > tr > th,
|
||||||
|
tbody > tr > td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body.p-0 & {
|
||||||
|
thead > tr > th,
|
||||||
|
thead > tr > td,
|
||||||
|
tfoot > tr > th,
|
||||||
|
tfoot > tr > td,
|
||||||
|
tbody > tr > th,
|
||||||
|
tbody > tr > td {
|
||||||
|
&:first-of-type {
|
||||||
|
padding-left: map-get($spacers, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
padding-right: map-get($spacers, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
//
|
||||||
|
// Component: Timeline
|
||||||
|
//
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 45px;
|
||||||
|
// The line
|
||||||
|
&::before {
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 31px;
|
||||||
|
width: 4px;
|
||||||
|
margin: 0;
|
||||||
|
content: "";
|
||||||
|
background-color: var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
// Element
|
||||||
|
> div {
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
// The content
|
||||||
|
> .timeline-item {
|
||||||
|
@include box-shadow($lte-card-shadow);
|
||||||
|
@include border-radius($border-radius);
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
margin-left: 60px;
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
// The time and header
|
||||||
|
> .time {
|
||||||
|
float: right;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
}
|
||||||
|
// Header
|
||||||
|
> .timeline-header {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.1;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||||
|
// Link in header
|
||||||
|
> a {
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Item body and footer
|
||||||
|
> .timeline-body,
|
||||||
|
> .timeline-footer {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .timeline-body {
|
||||||
|
> img {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
> dl,
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 18px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: var(--#{$prefix}secondary-bg);
|
||||||
|
border-radius: 50%; // stylelint-disable-line property-disallowed-list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Time label
|
||||||
|
> .time-label {
|
||||||
|
> span {
|
||||||
|
@include border-radius(4px);
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-inverse {
|
||||||
|
> div {
|
||||||
|
> .timeline-item {
|
||||||
|
@include box-shadow(none);
|
||||||
|
background-color: var(--#{$prefix}tertiary-bg);
|
||||||
|
border: 1px solid var(--#{$prefix}border-color);
|
||||||
|
|
||||||
|
> .timeline-header {
|
||||||
|
border-bottom-color: var(--#{$prefix}border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
//
|
||||||
|
// Toast
|
||||||
|
//
|
||||||
|
|
||||||
|
@each $name, $color in $theme-colors {
|
||||||
|
.toast-#{$name} {
|
||||||
|
--#{$prefix}toast-header-color: #{color-contrast($color)};
|
||||||
|
--#{$prefix}toast-header-bg: #{$color};
|
||||||
|
--#{$prefix}toast-header-border-color: #{$color};
|
||||||
|
--#{$prefix}toast-border-color: #{$color};
|
||||||
|
--#{$prefix}toast-bg: var(--#{$prefix}#{$name}-bg-subtle);
|
||||||
|
|
||||||
|
@if color-contrast($color) == $color-contrast-light {
|
||||||
|
.btn-close {
|
||||||
|
@include btn-close-white();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $enable-dark-mode {
|
||||||
|
@include color-mode(dark) {
|
||||||
|
@each $name, $color in $theme-colors {
|
||||||
|
.toast-#{$name} {
|
||||||
|
@if color-contrast($color) == $color-contrast-dark {
|
||||||
|
.btn-close {
|
||||||
|
--#{$prefix}btn-close-white-filter: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// SIDEBAR SKINS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
$lte-sidebar-hover-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||||
|
$lte-sidebar-color-dark: #c2c7d0 !default;
|
||||||
|
$lte-sidebar-hover-color-dark: $white !default;
|
||||||
|
$lte-sidebar-active-color-dark: $white !default;
|
||||||
|
$lte-sidebar-menu-active-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||||
|
$lte-sidebar-menu-active-color-dark: $white !default;
|
||||||
|
$lte-sidebar-submenu-bg-dark: transparent !default;
|
||||||
|
$lte-sidebar-submenu-color-dark: #c2c7d0 !default;
|
||||||
|
$lte-sidebar-submenu-hover-color-dark: $white !default;
|
||||||
|
$lte-sidebar-submenu-hover-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||||
|
$lte-sidebar-submenu-active-color-dark: $white !default;
|
||||||
|
$lte-sidebar-submenu-active-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||||
|
$lte-sidebar-header-color-dark: tint-color(#c2c7d0, 5%) !default;
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
//
|
||||||
|
// Custom AdminLTE Variables
|
||||||
|
//
|
||||||
|
|
||||||
|
// Prefix for :root CSS variables and others.
|
||||||
|
$lte-prefix: lte- !default;
|
||||||
|
|
||||||
|
// TRANSITIONS SETTINGS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// Transition global options
|
||||||
|
$lte-transition-speed: .3s !default;
|
||||||
|
$lte-transition-fn: ease-in-out !default;
|
||||||
|
|
||||||
|
// SIDEBAR
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-sidebar-width: 250px !default;
|
||||||
|
$lte-sidebar-breakpoint: lg !default;
|
||||||
|
$lte-sidebar-padding-x: .5rem !default;
|
||||||
|
$lte-sidebar-padding-x-compact: .5rem !default;
|
||||||
|
$lte-sidebar-padding-y: .5rem !default;
|
||||||
|
$lte-sidebar-padding-y-compact: .25rem !default;
|
||||||
|
$lte-sidebar-transition: min-width $lte-transition-speed $lte-transition-fn,
|
||||||
|
max-width $lte-transition-speed $lte-transition-fn,
|
||||||
|
margin-left $lte-transition-speed $lte-transition-fn,
|
||||||
|
margin-right $lte-transition-speed $lte-transition-fn !default;
|
||||||
|
|
||||||
|
// SIDEBAR SKINS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
$lte-sidebar-hover-bg: rgba($black, .1) !default;
|
||||||
|
$lte-sidebar-color: $gray-800 !default;
|
||||||
|
$lte-sidebar-hover-color: $gray-900 !default;
|
||||||
|
$lte-sidebar-active-color: $black !default;
|
||||||
|
$lte-sidebar-menu-active-bg: rgba($black, .1) !default;
|
||||||
|
$lte-sidebar-menu-active-color: $black !default;
|
||||||
|
$lte-sidebar-submenu-bg: transparent !default;
|
||||||
|
$lte-sidebar-submenu-color: #777 !default;
|
||||||
|
$lte-sidebar-submenu-hover-color: $black !default;
|
||||||
|
$lte-sidebar-submenu-hover-bg: rgba($black, .1) !default;
|
||||||
|
$lte-sidebar-submenu-active-color: $gray-900 !default;
|
||||||
|
$lte-sidebar-submenu-active-bg: rgba($black, .1) !default;
|
||||||
|
$lte-sidebar-header-color: shade-color($gray-800, 5%) !default;
|
||||||
|
|
||||||
|
// SIDEBAR MINI
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$nav-link-padding-x-compact: .25rem !default;
|
||||||
|
$lte-sidebar-mini-width: ($nav-link-padding-x + $lte-sidebar-padding-x + .8rem) * 2 !default;
|
||||||
|
$lte-sidebar-mini-width-compact: ($nav-link-padding-x-compact + $lte-sidebar-padding-x-compact + .8rem) * 2 !default;
|
||||||
|
$lte-sidebar-nav-icon-width: $lte-sidebar-mini-width - (($lte-sidebar-padding-x + $nav-link-padding-x) * 2) !default;
|
||||||
|
$lte-sidebar-user-image-width: $lte-sidebar-nav-icon-width + ($nav-link-padding-x * .4) !default;
|
||||||
|
|
||||||
|
// MAIN HEADER
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$nav-link-height-compact: 1.75rem !default;
|
||||||
|
$lte-app-header-bottom-border-width: $border-width !default;
|
||||||
|
$lte-app-header-bottom-border-color: var(--#{$prefix}border-color) !default;
|
||||||
|
$lte-app-header-bottom-border: $lte-app-header-bottom-border-width solid $lte-app-header-bottom-border-color !default;
|
||||||
|
$lte-app-header-link-padding-y: $navbar-padding-y !default;
|
||||||
|
$lte-app-header-height: ($nav-link-height + ($lte-app-header-link-padding-y * 2)) !default;
|
||||||
|
$lte-app-header-height-compact: ($nav-link-height-compact + ($lte-app-header-link-padding-y * 2)) !default;
|
||||||
|
$lte-zindex-fixed-header: $zindex-fixed !default;
|
||||||
|
|
||||||
|
// APP MAIN
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-app-main-padding-bottom: $grid-gutter-width * .5 !default;
|
||||||
|
|
||||||
|
// CONTENT PADDING
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-content-padding-y: 0 !default;
|
||||||
|
$lte-content-padding-x: .5rem !default;
|
||||||
|
|
||||||
|
// MAIN FOOTER
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-app-footer-padding: 1rem !default;
|
||||||
|
$lte-app-footer-padding-compact: .5rem !default;
|
||||||
|
$lte-app-footer-border-top-width: 1px !default;
|
||||||
|
$lte-app-footer-border-top-color: var(--#{$prefix}border-color) !default;
|
||||||
|
$lte-app-footer-border-top: $lte-app-footer-border-top-width solid $lte-app-footer-border-top-color !default;
|
||||||
|
$lte-app-footer-bg: var(--#{$prefix}body-bg) !default;
|
||||||
|
$lte-app-footer-color: var(--#{$prefix}secondary-color) !default;
|
||||||
|
$lte-zindex-fixed-footer: $zindex-fixed !default;
|
||||||
|
// CONTENT BOTTOM AREA
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-app-content-bottom-area-margin-bottom: -$lte-app-main-padding-bottom !default;
|
||||||
|
$lte-app-content-bottom-area-color: $lte-app-footer-color !default;
|
||||||
|
$lte-app-content-bottom-area-bg: $lte-app-footer-bg !default;
|
||||||
|
$lte-app-content-bottom-area-top-border: $lte-app-footer-border-top !default;
|
||||||
|
$lte-app-content-bottom-area-padding-y: $lte-app-footer-padding !default;
|
||||||
|
$lte-app-content-bottom-area-padding-x: 0 !default;
|
||||||
|
|
||||||
|
// CONTENT TOP AREA
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-app-content-top-area-top-border: $lte-app-footer-border-top !default;
|
||||||
|
$lte-app-content-top-area-padding-y: $lte-app-footer-padding !default;
|
||||||
|
$lte-app-content-top-area-padding-x: 0 !default;
|
||||||
|
|
||||||
|
// BRAND LINK
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$navbar-brand-padding-y-compact: $navbar-brand-padding-y * .75 !default;
|
||||||
|
$navbar-padding-y-compact: $navbar-padding-y * .5 !default;
|
||||||
|
$lte-brand-link-padding-y: $navbar-brand-padding-y + $navbar-padding-y !default;
|
||||||
|
$lte-brand-link-padding-y-compact: $navbar-brand-padding-y-compact + $navbar-padding-y-compact !default;
|
||||||
|
$lte-brand-link-padding-x: $lte-sidebar-padding-x !default;
|
||||||
|
$lte-brand-link-padding-x-compact: $lte-sidebar-padding-x-compact !default;
|
||||||
|
$lte-brand-link-border-buttom: 1px !default;
|
||||||
|
|
||||||
|
// CARDS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-card-shadow: 0 0 1px rgba(var(--#{$prefix}body-color-rgb), .125), 0 1px 3px rgba(var(--#{$prefix}body-color-rgb), .2) !default;
|
||||||
|
$lte-card-title-font-size: 1.1rem !default;
|
||||||
|
$lte-card-title-font-weight: $font-weight-normal !default;
|
||||||
|
|
||||||
|
// PROGRESS BARS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-progress-bar-border-radius: 1px !default;
|
||||||
|
|
||||||
|
// CALLOUTS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-callout-link-font-weight: $alert-link-font-weight !default;
|
||||||
|
|
||||||
|
// DIRECT CHAT
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-direct-chat-default-msg-bg: var(--#{$prefix}secondary-bg) !default;
|
||||||
|
$lte-direct-chat-default-font-color: var(--#{$prefix}emphasis-color) !default;
|
||||||
|
$lte-direct-chat-default-msg-border-color: var(--#{$prefix}border-color) !default;
|
||||||
|
|
||||||
|
// Z-INDEX
|
||||||
|
// --------------------------------------------------------
|
||||||
|
$lte-zindex-app-header: $zindex-fixed + 4 !default;
|
||||||
|
$lte-zindex-sidebar: $zindex-fixed + 8 !default;
|
||||||
|
$lte-zindex-sidebar-overlay: $lte-zindex-sidebar - 1 !default;
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*!
|
||||||
|
* AdminLTE v4.0.0
|
||||||
|
* Author: Colorlib
|
||||||
|
* Website: AdminLTE.io <https://adminlte.io>
|
||||||
|
* License: Open source - MIT <https://opensource.org/licenses/MIT>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Bootstrap Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootstrap/scss/functions";
|
||||||
|
|
||||||
|
// AdminLTE Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootstrap-variables"; // little modified are here
|
||||||
|
|
||||||
|
// Bootstrap Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootstrap/scss/variables";
|
||||||
|
@import "bootstrap/scss/variables-dark";
|
||||||
|
@import "bootstrap/scss/maps";
|
||||||
|
@import "bootstrap/scss/mixins";
|
||||||
|
@import "bootstrap/scss/utilities";
|
||||||
|
|
||||||
|
// Bootstrap Layout & components
|
||||||
|
@import "bootstrap/scss/root";
|
||||||
|
@import "bootstrap/scss/reboot";
|
||||||
|
@import "bootstrap/scss/type";
|
||||||
|
@import "bootstrap/scss/images";
|
||||||
|
@import "bootstrap/scss/containers";
|
||||||
|
@import "bootstrap/scss/grid";
|
||||||
|
@import "bootstrap/scss/tables";
|
||||||
|
@import "bootstrap/scss/forms";
|
||||||
|
@import "bootstrap/scss/buttons";
|
||||||
|
@import "bootstrap/scss/transitions";
|
||||||
|
@import "bootstrap/scss/dropdown";
|
||||||
|
@import "bootstrap/scss/button-group";
|
||||||
|
@import "bootstrap/scss/nav";
|
||||||
|
@import "bootstrap/scss/navbar";
|
||||||
|
@import "bootstrap/scss/card";
|
||||||
|
@import "bootstrap/scss/accordion";
|
||||||
|
@import "bootstrap/scss/breadcrumb";
|
||||||
|
@import "bootstrap/scss/pagination";
|
||||||
|
@import "bootstrap/scss/badge";
|
||||||
|
@import "bootstrap/scss/alert";
|
||||||
|
@import "bootstrap/scss/progress";
|
||||||
|
@import "bootstrap/scss/list-group";
|
||||||
|
@import "bootstrap/scss/close";
|
||||||
|
@import "bootstrap/scss/toasts";
|
||||||
|
@import "bootstrap/scss/modal";
|
||||||
|
@import "bootstrap/scss/tooltip";
|
||||||
|
@import "bootstrap/scss/popover";
|
||||||
|
@import "bootstrap/scss/carousel";
|
||||||
|
@import "bootstrap/scss/spinners";
|
||||||
|
@import "bootstrap/scss/offcanvas";
|
||||||
|
@import "bootstrap/scss/placeholders";
|
||||||
|
|
||||||
|
// Bootstrap Helpers
|
||||||
|
@import "bootstrap/scss/helpers";
|
||||||
|
|
||||||
|
// Bootstrap Utilities
|
||||||
|
@import "bootstrap/scss/utilities/api";
|
||||||
|
|
||||||
|
// AdminLTE Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "variables";
|
||||||
|
@import "variables-dark";
|
||||||
|
@import "mixins";
|
||||||
|
|
||||||
|
// AdiminLTE Parts
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "parts/core";
|
||||||
|
@import "parts/components";
|
||||||
|
@import "parts/extra-components";
|
||||||
|
@import "parts/pages";
|
||||||
|
@import "parts/miscellaneous";
|
||||||
|
|
||||||
|
// AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||||
|
@import "accessibility";
|
||||||
|
|
||||||
|
// AdminLTE Documentation Styles (only applies to pages with body.docs-page)
|
||||||
|
@import "docs";
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
//
|
||||||
|
// Mixins: Animation
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes flipInX {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transition-timing-function: ease-in;
|
||||||
|
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
transition-timing-function: ease-in;
|
||||||
|
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
80% {
|
||||||
|
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: perspective(400px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shake {
|
||||||
|
0% {
|
||||||
|
transform: translate(2px, 1px) rotate(0deg);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: translate(-1px, -2px) rotate(-2deg);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: translate(-3px, 0) rotate(3deg);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: translate(0, 2px) rotate(0deg);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: translate(1px, -1px) rotate(1deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-1px, 2px) rotate(-1deg);
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: translate(-3px, 1px) rotate(0deg);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: translate(2px, 1px) rotate(-2deg);
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: translate(-1px, -1px) rotate(4deg);
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
transform: translate(2px, 2px) rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate(1px, -2px) rotate(-1deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes wobble {
|
||||||
|
0% {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
15% {
|
||||||
|
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
45% {
|
||||||
|
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// Mixins: Scrollbar
|
||||||
|
//
|
||||||
|
|
||||||
|
@mixin scrollbar-color-gray() {
|
||||||
|
scrollbar-color: var(--#{$prefix}secondary-bg) transparent;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: var(--#{$prefix}secondary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-corner {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-width-thin() {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: .5rem;
|
||||||
|
height: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-width-none() {
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
//
|
||||||
|
// Pages: Lock Screen
|
||||||
|
//
|
||||||
|
|
||||||
|
// ADD THIS CLASS TO THE <BODY> TAG
|
||||||
|
.lockscreen {
|
||||||
|
// User name [optional]
|
||||||
|
.lockscreen-name {
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lockscreen-logo {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--#{$prefix}emphasis-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lockscreen-wrapper {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will contain the image and the sign in form
|
||||||
|
.lockscreen-item {
|
||||||
|
position: relative;
|
||||||
|
width: 290px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 10px auto 30px;
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
@include border-radius(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
// User image
|
||||||
|
.lockscreen-image {
|
||||||
|
position: absolute;
|
||||||
|
top: -25px;
|
||||||
|
left: -10px;
|
||||||
|
z-index: 10;
|
||||||
|
padding: 5px;
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
@include border-radius(50%);
|
||||||
|
|
||||||
|
> img {
|
||||||
|
@include border-radius(50%);
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains the password input and the login button
|
||||||
|
.lockscreen-credentials {
|
||||||
|
margin-left: 70px;
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lockscreen-footer {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
// Pages: Login & Register
|
||||||
|
//
|
||||||
|
|
||||||
|
.login-logo,
|
||||||
|
.register-logo {
|
||||||
|
margin-bottom: .9rem;
|
||||||
|
font-size: 2.1rem;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-page,
|
||||||
|
.register-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-box,
|
||||||
|
.register-box {
|
||||||
|
width: 400px;
|
||||||
|
|
||||||
|
@media (max-width: map-get($grid-breakpoints, sm)) {
|
||||||
|
width: 90%;
|
||||||
|
margin-top: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card-body,
|
||||||
|
.register-card-body {
|
||||||
|
padding: 20px;
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
background-color: var(--#{$prefix}body-bg);
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
.form-control {
|
||||||
|
&:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
~ .input-group-prepend .input-group-text,
|
||||||
|
~ .input-group-append .input-group-text {
|
||||||
|
border-color: $input-focus-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-valid {
|
||||||
|
&:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ .input-group-prepend .input-group-text,
|
||||||
|
~ .input-group-append .input-group-text {
|
||||||
|
border-color: $success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-invalid {
|
||||||
|
&:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ .input-group-append .input-group-text {
|
||||||
|
border-color: $danger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
color: var(--#{$prefix}secondary-color);
|
||||||
|
background-color: transparent;
|
||||||
|
@include border-top-end-radius($border-radius);
|
||||||
|
@include border-bottom-end-radius($border-radius);
|
||||||
|
@include transition($input-transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-box-msg,
|
||||||
|
.register-box-msg {
|
||||||
|
padding: 0 20px 20px;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-auth-links {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
//
|
||||||
|
// Part: Components
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "../progress-bars";
|
||||||
|
@import "../cards";
|
||||||
|
@import "../table";
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// Part: Core
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "../root";
|
||||||
|
@import "../app-wrapper";
|
||||||
|
@import "../app-content";
|
||||||
|
@import "../app-header";
|
||||||
|
@import "../app-sidebar";
|
||||||
|
@import "../app-main";
|
||||||
|
@import "../app-footer";
|
||||||
|
@import "../dropdown";
|
||||||
|
@import "../callouts";
|
||||||
|
@import "../compact-mode";
|
||||||
|
@import "../docs";
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
//
|
||||||
|
// Part: Extra Components
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "../small-box";
|
||||||
|
@import "../info-box";
|
||||||
|
@import "../timeline";
|
||||||
|
@import "../direct-chat";
|
||||||
|
@import "../toasts";
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
//
|
||||||
|
// Part: Miscellaneous
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "../miscellaneous";
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
//
|
||||||
|
// Part: Pages
|
||||||
|
//
|
||||||
|
|
||||||
|
@import "../pages/login_and_register";
|
||||||
|
@import "../pages/lockscreen";
|
||||||
91
extensions/pagetop-bootsier/assets/bootsier.scss
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
// AdminLTE v4.0.0 + Bootstrap 5.3.8 - PageTop Bootsier Styles.
|
||||||
|
|
||||||
|
// Bootstrap Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootstrap-5.3.8/scss/functions";
|
||||||
|
|
||||||
|
// AdminLTE Configuration (little modified are here)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "adminlte-4.0.0/scss/bootstrap-variables";
|
||||||
|
|
||||||
|
// Bootsier Bootstrap variable overrides
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootsier-variables";
|
||||||
|
|
||||||
|
// Bootstrap Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootstrap-5.3.8/scss/variables";
|
||||||
|
@import "bootstrap-5.3.8/scss/variables-dark";
|
||||||
|
@import "bootstrap-5.3.8/scss/maps";
|
||||||
|
@import "bootstrap-5.3.8/scss/mixins";
|
||||||
|
@import "bootstrap-5.3.8/scss/utilities";
|
||||||
|
|
||||||
|
// Bootstrap Layout & components
|
||||||
|
@import "bootstrap-5.3.8/scss/root";
|
||||||
|
@import "bootstrap-5.3.8/scss/reboot";
|
||||||
|
@import "bootstrap-5.3.8/scss/type";
|
||||||
|
@import "bootstrap-5.3.8/scss/images";
|
||||||
|
@import "bootstrap-5.3.8/scss/containers";
|
||||||
|
@import "bootstrap-5.3.8/scss/grid";
|
||||||
|
@import "bootstrap-5.3.8/scss/tables";
|
||||||
|
@import "bootstrap-5.3.8/scss/forms";
|
||||||
|
@import "bootstrap-5.3.8/scss/buttons";
|
||||||
|
@import "bootstrap-5.3.8/scss/transitions";
|
||||||
|
@import "bootstrap-5.3.8/scss/dropdown";
|
||||||
|
@import "bootstrap-5.3.8/scss/button-group";
|
||||||
|
@import "bootstrap-5.3.8/scss/nav";
|
||||||
|
@import "bootstrap-5.3.8/scss/navbar";
|
||||||
|
@import "bootstrap-5.3.8/scss/card";
|
||||||
|
@import "bootstrap-5.3.8/scss/accordion";
|
||||||
|
@import "bootstrap-5.3.8/scss/breadcrumb";
|
||||||
|
@import "bootstrap-5.3.8/scss/pagination";
|
||||||
|
@import "bootstrap-5.3.8/scss/badge";
|
||||||
|
@import "bootstrap-5.3.8/scss/alert";
|
||||||
|
@import "bootstrap-5.3.8/scss/progress";
|
||||||
|
@import "bootstrap-5.3.8/scss/list-group";
|
||||||
|
@import "bootstrap-5.3.8/scss/close";
|
||||||
|
@import "bootstrap-5.3.8/scss/toasts";
|
||||||
|
@import "bootstrap-5.3.8/scss/modal";
|
||||||
|
@import "bootstrap-5.3.8/scss/tooltip";
|
||||||
|
@import "bootstrap-5.3.8/scss/popover";
|
||||||
|
@import "bootstrap-5.3.8/scss/carousel";
|
||||||
|
@import "bootstrap-5.3.8/scss/spinners";
|
||||||
|
@import "bootstrap-5.3.8/scss/offcanvas";
|
||||||
|
@import "bootstrap-5.3.8/scss/placeholders";
|
||||||
|
|
||||||
|
// Bootstrap Helpers
|
||||||
|
@import "bootstrap-5.3.8/scss/helpers";
|
||||||
|
|
||||||
|
// Bootsier Utilities (must precede utilities/api to extend $utilities)
|
||||||
|
@import "bootsier-utilities";
|
||||||
|
|
||||||
|
// Bootstrap Utilities
|
||||||
|
@import "bootstrap-5.3.8/scss/utilities/api";
|
||||||
|
|
||||||
|
// AdminLTE Configuration
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "adminlte-4.0.0/scss/variables";
|
||||||
|
@import "adminlte-4.0.0/scss/variables-dark";
|
||||||
|
@import "adminlte-4.0.0/scss/mixins";
|
||||||
|
|
||||||
|
// AdminLTE Parts
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "adminlte-4.0.0/scss/parts/core";
|
||||||
|
@import "adminlte-4.0.0/scss/parts/components";
|
||||||
|
@import "adminlte-4.0.0/scss/parts/extra-components";
|
||||||
|
@import "adminlte-4.0.0/scss/parts/pages";
|
||||||
|
@import "adminlte-4.0.0/scss/parts/miscellaneous";
|
||||||
|
|
||||||
|
// AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||||
|
@import "adminlte-4.0.0/scss/accessibility";
|
||||||
|
|
||||||
|
// AdminLTE Documentation Styles (only applies to pages with body.docs-page)
|
||||||
|
@import "adminlte-4.0.0/scss/docs";
|
||||||
|
|
||||||
|
// Bootstrap Icons 1.13.1
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootsier-icons";
|
||||||
|
|
||||||
|
// Bootsier customizations
|
||||||
|
// ---------------------------------------------------
|
||||||
|
@import "bootsier-custom";
|
||||||
65
extensions/pagetop-bootsier/assets/bootsier.shell.js
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Fullscreen: keeps maximize/minimize icons in sync with the actual fullscreen state.
|
||||||
|
document.addEventListener('fullscreenchange', function () {
|
||||||
|
var isFs = !!document.fullscreenElement;
|
||||||
|
document.querySelectorAll('[data-lte-icon="maximize"]').forEach(function (el) {
|
||||||
|
el.classList.toggle('d-none', isFs);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-lte-icon="minimize"]').forEach(function (el) {
|
||||||
|
el.classList.toggle('d-none', !isFs);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Color mode selector (light / dark / auto).
|
||||||
|
var STORAGE_KEY = 'lte-theme';
|
||||||
|
var getStored = function () { return localStorage.getItem(STORAGE_KEY); };
|
||||||
|
var setStored = function (theme) { localStorage.setItem(STORAGE_KEY, theme); };
|
||||||
|
var prefersDark = function () {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
};
|
||||||
|
|
||||||
|
var setTheme = function (theme) {
|
||||||
|
var resolved = (theme === 'auto') ? (prefersDark() ? 'dark' : 'light') : theme;
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', resolved);
|
||||||
|
};
|
||||||
|
|
||||||
|
var showActiveTheme = function (theme) {
|
||||||
|
document.querySelectorAll('[data-bs-theme-value]').forEach(function (el) {
|
||||||
|
el.classList.remove('active');
|
||||||
|
el.setAttribute('aria-pressed', 'false');
|
||||||
|
var check = el.querySelector('.bi-check-lg');
|
||||||
|
if (check) { check.classList.add('d-none'); }
|
||||||
|
});
|
||||||
|
var active = document.querySelector('[data-bs-theme-value="' + theme + '"]');
|
||||||
|
if (active) {
|
||||||
|
active.classList.add('active');
|
||||||
|
active.setAttribute('aria-pressed', 'true');
|
||||||
|
var check = active.querySelector('.bi-check-lg');
|
||||||
|
if (check) { check.classList.remove('d-none'); }
|
||||||
|
}
|
||||||
|
document.querySelectorAll('[data-lte-theme-icon]').forEach(function (icon) {
|
||||||
|
icon.classList.toggle('d-none', icon.dataset.lteThemeIcon !== theme);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
|
||||||
|
var stored = getStored();
|
||||||
|
if (!stored || stored === 'auto') { setTheme('auto'); }
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var theme = getStored() || 'auto';
|
||||||
|
setTheme(theme);
|
||||||
|
showActiveTheme(theme);
|
||||||
|
document.querySelectorAll('[data-bs-theme-value]').forEach(function (toggle) {
|
||||||
|
toggle.addEventListener('click', function () {
|
||||||
|
var t = toggle.getAttribute('data-bs-theme-value');
|
||||||
|
setStored(t);
|
||||||
|
setTheme(t);
|
||||||
|
showActiveTheme(t);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}());
|
||||||