`s.
+
+.nav {
+ // scss-docs-start nav-css-vars
+ --#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
+ --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
+ @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
+ --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
+ --#{$prefix}nav-link-color: #{$nav-link-color};
+ --#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
+ --#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
+ // scss-docs-end nav-css-vars
+
+ display: flex;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav-link {
+ display: block;
+ padding: var(--#{$prefix}nav-link-padding-y) var(--#{$prefix}nav-link-padding-x);
+ @include font-size(var(--#{$prefix}nav-link-font-size));
+ font-weight: var(--#{$prefix}nav-link-font-weight);
+ color: var(--#{$prefix}nav-link-color);
+ text-decoration: if($link-decoration == none, null, none);
+ background: none;
+ border: 0;
+ @include transition($nav-link-transition);
+
+ &:hover,
+ &:focus {
+ color: var(--#{$prefix}nav-link-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ }
+
+ &:focus-visible {
+ outline: 0;
+ box-shadow: $nav-link-focus-box-shadow;
+ }
+
+ // Disabled state lightens text
+ &.disabled,
+ &:disabled {
+ color: var(--#{$prefix}nav-link-disabled-color);
+ pointer-events: none;
+ cursor: default;
+ }
+}
+
+//
+// Tabs
+//
+
+.nav-tabs {
+ // scss-docs-start nav-tabs-css-vars
+ --#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
+ --#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
+ --#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
+ --#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
+ --#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
+ --#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
+ --#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};
+ // scss-docs-end nav-tabs-css-vars
+
+ border-bottom: var(--#{$prefix}nav-tabs-border-width) solid var(--#{$prefix}nav-tabs-border-color);
+
+ .nav-link {
+ margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
+ border: var(--#{$prefix}nav-tabs-border-width) solid transparent;
+ @include border-top-radius(var(--#{$prefix}nav-tabs-border-radius));
+
+ &:hover,
+ &:focus {
+ // Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link
+ isolation: isolate;
+ border-color: var(--#{$prefix}nav-tabs-link-hover-border-color);
+ }
+ }
+
+ .nav-link.active,
+ .nav-item.show .nav-link {
+ color: var(--#{$prefix}nav-tabs-link-active-color);
+ background-color: var(--#{$prefix}nav-tabs-link-active-bg);
+ border-color: var(--#{$prefix}nav-tabs-link-active-border-color);
+ }
+
+ .dropdown-menu {
+ // Make dropdown border overlap tab border
+ margin-top: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
+ // Remove the top rounded corners here since there is a hard edge above the menu
+ @include border-top-radius(0);
+ }
+}
+
+
+//
+// Pills
+//
+
+.nav-pills {
+ // scss-docs-start nav-pills-css-vars
+ --#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
+ --#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
+ --#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};
+ // scss-docs-end nav-pills-css-vars
+
+ .nav-link {
+ @include border-radius(var(--#{$prefix}nav-pills-border-radius));
+ }
+
+ .nav-link.active,
+ .show > .nav-link {
+ color: var(--#{$prefix}nav-pills-link-active-color);
+ @include gradient-bg(var(--#{$prefix}nav-pills-link-active-bg));
+ }
+}
+
+
+//
+// Underline
+//
+
+.nav-underline {
+ // scss-docs-start nav-underline-css-vars
+ --#{$prefix}nav-underline-gap: #{$nav-underline-gap};
+ --#{$prefix}nav-underline-border-width: #{$nav-underline-border-width};
+ --#{$prefix}nav-underline-link-active-color: #{$nav-underline-link-active-color};
+ // scss-docs-end nav-underline-css-vars
+
+ gap: var(--#{$prefix}nav-underline-gap);
+
+ .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+ border-bottom: var(--#{$prefix}nav-underline-border-width) solid transparent;
+
+ &:hover,
+ &:focus {
+ border-bottom-color: currentcolor;
+ }
+ }
+
+ .nav-link.active,
+ .show > .nav-link {
+ font-weight: $font-weight-bold;
+ color: var(--#{$prefix}nav-underline-link-active-color);
+ border-bottom-color: currentcolor;
+ }
+}
+
+
+//
+// Justified variants
+//
+
+.nav-fill {
+ > .nav-link,
+ .nav-item {
+ flex: 1 1 auto;
+ text-align: center;
+ }
+}
+
+.nav-justified {
+ > .nav-link,
+ .nav-item {
+ flex-basis: 0;
+ flex-grow: 1;
+ text-align: center;
+ }
+}
+
+.nav-fill,
+.nav-justified {
+ .nav-item .nav-link {
+ width: 100%; // Make sure button will grow
+ }
+}
+
+
+// Tabbable tabs
+//
+// Hide tabbable panes to start, show them when `.active`
+
+.tab-content {
+ > .tab-pane {
+ display: none;
+ }
+ > .active {
+ display: block;
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_navbar.scss b/Moonlight/Styles/bootstrap/scss/_navbar.scss
new file mode 100644
index 00000000..71619382
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_navbar.scss
@@ -0,0 +1,289 @@
+// Navbar
+//
+// Provide a static navbar from which we expand to create full-width, fixed, and
+// other navbar variations.
+
+.navbar {
+ // scss-docs-start navbar-css-vars
+ --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)};
+ --#{$prefix}navbar-padding-y: #{$navbar-padding-y};
+ --#{$prefix}navbar-color: #{$navbar-light-color};
+ --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
+ --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
+ --#{$prefix}navbar-active-color: #{$navbar-light-active-color};
+ --#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y};
+ --#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end};
+ --#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size};
+ --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
+ --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
+ --#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x};
+ --#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y};
+ --#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x};
+ --#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size};
+ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)};
+ --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
+ --#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius};
+ --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width};
+ --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition};
+ // scss-docs-end navbar-css-vars
+
+ position: relative;
+ display: flex;
+ flex-wrap: wrap; // allow us to do the line break for collapsing content
+ align-items: center;
+ justify-content: space-between; // space out brand from logo
+ padding: var(--#{$prefix}navbar-padding-y) var(--#{$prefix}navbar-padding-x);
+ @include gradient-bg();
+
+ // Because flex properties aren't inherited, we need to redeclare these first
+ // few properties so that content nested within behave properly.
+ // The `flex-wrap` property is inherited to simplify the expanded navbars
+ %container-flex-properties {
+ display: flex;
+ flex-wrap: inherit;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ > .container,
+ > .container-fluid {
+ @extend %container-flex-properties;
+ }
+
+ @each $breakpoint, $container-max-width in $container-max-widths {
+ > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
+ @extend %container-flex-properties;
+ }
+ }
+}
+
+
+// Navbar brand
+//
+// Used for brand, project, or site names.
+
+.navbar-brand {
+ padding-top: var(--#{$prefix}navbar-brand-padding-y);
+ padding-bottom: var(--#{$prefix}navbar-brand-padding-y);
+ margin-right: var(--#{$prefix}navbar-brand-margin-end);
+ @include font-size(var(--#{$prefix}navbar-brand-font-size));
+ color: var(--#{$prefix}navbar-brand-color);
+ text-decoration: if($link-decoration == none, null, none);
+ white-space: nowrap;
+
+ &:hover,
+ &:focus {
+ color: var(--#{$prefix}navbar-brand-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ }
+}
+
+
+// Navbar nav
+//
+// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
+
+.navbar-nav {
+ // scss-docs-start navbar-nav-css-vars
+ --#{$prefix}nav-link-padding-x: 0;
+ --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
+ @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
+ --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
+ --#{$prefix}nav-link-color: var(--#{$prefix}navbar-color);
+ --#{$prefix}nav-link-hover-color: var(--#{$prefix}navbar-hover-color);
+ --#{$prefix}nav-link-disabled-color: var(--#{$prefix}navbar-disabled-color);
+ // scss-docs-end navbar-nav-css-vars
+
+ display: flex;
+ flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+
+ .nav-link {
+ &.active,
+ &.show {
+ color: var(--#{$prefix}navbar-active-color);
+ }
+ }
+
+ .dropdown-menu {
+ position: static;
+ }
+}
+
+
+// Navbar text
+//
+//
+
+.navbar-text {
+ padding-top: $nav-link-padding-y;
+ padding-bottom: $nav-link-padding-y;
+ color: var(--#{$prefix}navbar-color);
+
+ a,
+ a:hover,
+ a:focus {
+ color: var(--#{$prefix}navbar-active-color);
+ }
+}
+
+
+// Responsive navbar
+//
+// Custom styles for responsive collapsing and toggling of navbar contents.
+// Powered by the collapse Bootstrap JavaScript plugin.
+
+// When collapsed, prevent the toggleable navbar contents from appearing in
+// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
+// on the `.navbar` parent.
+.navbar-collapse {
+ flex-basis: 100%;
+ flex-grow: 1;
+ // For always expanded or extra full navbars, ensure content aligns itself
+ // properly vertically. Can be easily overridden with flex utilities.
+ align-items: center;
+}
+
+// Button for toggling the navbar when in its collapsed state
+.navbar-toggler {
+ padding: var(--#{$prefix}navbar-toggler-padding-y) var(--#{$prefix}navbar-toggler-padding-x);
+ @include font-size(var(--#{$prefix}navbar-toggler-font-size));
+ line-height: 1;
+ color: var(--#{$prefix}navbar-color);
+ background-color: transparent; // remove default button style
+ border: var(--#{$prefix}border-width) solid var(--#{$prefix}navbar-toggler-border-color); // remove default button style
+ @include border-radius(var(--#{$prefix}navbar-toggler-border-radius));
+ @include transition(var(--#{$prefix}navbar-toggler-transition));
+
+ &:hover {
+ text-decoration: none;
+ }
+
+ &:focus {
+ text-decoration: none;
+ outline: 0;
+ box-shadow: 0 0 0 var(--#{$prefix}navbar-toggler-focus-width);
+ }
+}
+
+// Keep as a separate element so folks can easily override it with another icon
+// or image file as needed.
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ background-image: var(--#{$prefix}navbar-toggler-icon-bg);
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100%;
+}
+
+.navbar-nav-scroll {
+ max-height: var(--#{$prefix}scroll-height, 75vh);
+ overflow-y: auto;
+}
+
+// scss-docs-start navbar-expand-loop
+// Generate series of `.navbar-expand-*` responsive classes for configuring
+// where your navbar collapses.
+.navbar-expand {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ // stylelint-disable-next-line scss/selector-no-union-class-name
+ {$infix} {
+ @include media-breakpoint-up($next) {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+
+ .navbar-nav {
+ flex-direction: row;
+
+ .dropdown-menu {
+ position: absolute;
+ }
+
+ .nav-link {
+ padding-right: var(--#{$prefix}navbar-nav-link-padding-x);
+ padding-left: var(--#{$prefix}navbar-nav-link-padding-x);
+ }
+ }
+
+ .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-collapse {
+ display: flex !important; // stylelint-disable-line declaration-no-important
+ flex-basis: auto;
+ }
+
+ .navbar-toggler {
+ display: none;
+ }
+
+ .offcanvas {
+ // stylelint-disable declaration-no-important
+ position: static;
+ z-index: auto;
+ flex-grow: 1;
+ width: auto !important;
+ height: auto !important;
+ visibility: visible !important;
+ background-color: transparent !important;
+ border: 0 !important;
+ transform: none !important;
+ @include box-shadow(none);
+ @include transition(none);
+ // stylelint-enable declaration-no-important
+
+ .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+ }
+ }
+ }
+ }
+}
+// scss-docs-end navbar-expand-loop
+
+// Navbar themes
+//
+// Styles for switching between navbars with light or dark background.
+
+.navbar-light {
+ @include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true);
+}
+
+.navbar-dark,
+.navbar[data-bs-theme="dark"] {
+ // scss-docs-start navbar-dark-css-vars
+ --#{$prefix}navbar-color: #{$navbar-dark-color};
+ --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
+ --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
+ --#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
+ --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
+ --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
+ --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
+ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
+ // scss-docs-end navbar-dark-css-vars
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .navbar-toggler-icon {
+ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_offcanvas.scss b/Moonlight/Styles/bootstrap/scss/_offcanvas.scss
new file mode 100644
index 00000000..04e3ce64
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_offcanvas.scss
@@ -0,0 +1,146 @@
+// stylelint-disable function-disallowed-list
+
+%offcanvas-css-vars {
+ // scss-docs-start offcanvas-css-vars
+ --#{$prefix}offcanvas-zindex: #{$zindex-offcanvas};
+ --#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width};
+ --#{$prefix}offcanvas-height: #{$offcanvas-vertical-height};
+ --#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x};
+ --#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y};
+ --#{$prefix}offcanvas-color: #{$offcanvas-color};
+ --#{$prefix}offcanvas-bg: #{$offcanvas-bg-color};
+ --#{$prefix}offcanvas-border-width: #{$offcanvas-border-width};
+ --#{$prefix}offcanvas-border-color: #{$offcanvas-border-color};
+ --#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow};
+ --#{$prefix}offcanvas-transition: #{transform $offcanvas-transition-duration ease-in-out};
+ --#{$prefix}offcanvas-title-line-height: #{$offcanvas-title-line-height};
+ // scss-docs-end offcanvas-css-vars
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @extend %offcanvas-css-vars;
+ }
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @include media-breakpoint-down($next) {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--#{$prefix}offcanvas-zindex);
+ display: flex;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--#{$prefix}offcanvas-color);
+ visibility: hidden;
+ background-color: var(--#{$prefix}offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ @include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
+ @include transition(var(--#{$prefix}offcanvas-transition));
+
+ &.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(-100%);
+ }
+
+ &.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(100%);
+ }
+
+ &.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(-100%);
+ }
+
+ &.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(100%);
+ }
+
+ &.showing,
+ &.show:not(.hiding) {
+ transform: none;
+ }
+
+ &.showing,
+ &.hiding,
+ &.show {
+ visibility: visible;
+ }
+ }
+
+ @if not ($infix == "") {
+ @include media-breakpoint-up($next) {
+ --#{$prefix}offcanvas-height: auto;
+ --#{$prefix}offcanvas-border-width: 0;
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+
+ .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ // Reset `background-color` in case `.bg-*` classes are used in offcanvas
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+ }
+ }
+ }
+ }
+}
+
+.offcanvas-backdrop {
+ @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
+}
+
+.offcanvas-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
+
+ .btn-close {
+ padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5);
+ margin-top: calc(-.5 * var(--#{$prefix}offcanvas-padding-y));
+ margin-right: calc(-.5 * var(--#{$prefix}offcanvas-padding-x));
+ margin-bottom: calc(-.5 * var(--#{$prefix}offcanvas-padding-y));
+ }
+}
+
+.offcanvas-title {
+ margin-bottom: 0;
+ line-height: var(--#{$prefix}offcanvas-title-line-height);
+}
+
+.offcanvas-body {
+ flex-grow: 1;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
+ overflow-y: auto;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_pagination.scss b/Moonlight/Styles/bootstrap/scss/_pagination.scss
new file mode 100644
index 00000000..f275a62e
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_pagination.scss
@@ -0,0 +1,109 @@
+.pagination {
+ // scss-docs-start pagination-css-vars
+ --#{$prefix}pagination-padding-x: #{$pagination-padding-x};
+ --#{$prefix}pagination-padding-y: #{$pagination-padding-y};
+ @include rfs($pagination-font-size, --#{$prefix}pagination-font-size);
+ --#{$prefix}pagination-color: #{$pagination-color};
+ --#{$prefix}pagination-bg: #{$pagination-bg};
+ --#{$prefix}pagination-border-width: #{$pagination-border-width};
+ --#{$prefix}pagination-border-color: #{$pagination-border-color};
+ --#{$prefix}pagination-border-radius: #{$pagination-border-radius};
+ --#{$prefix}pagination-hover-color: #{$pagination-hover-color};
+ --#{$prefix}pagination-hover-bg: #{$pagination-hover-bg};
+ --#{$prefix}pagination-hover-border-color: #{$pagination-hover-border-color};
+ --#{$prefix}pagination-focus-color: #{$pagination-focus-color};
+ --#{$prefix}pagination-focus-bg: #{$pagination-focus-bg};
+ --#{$prefix}pagination-focus-box-shadow: #{$pagination-focus-box-shadow};
+ --#{$prefix}pagination-active-color: #{$pagination-active-color};
+ --#{$prefix}pagination-active-bg: #{$pagination-active-bg};
+ --#{$prefix}pagination-active-border-color: #{$pagination-active-border-color};
+ --#{$prefix}pagination-disabled-color: #{$pagination-disabled-color};
+ --#{$prefix}pagination-disabled-bg: #{$pagination-disabled-bg};
+ --#{$prefix}pagination-disabled-border-color: #{$pagination-disabled-border-color};
+ // scss-docs-end pagination-css-vars
+
+ display: flex;
+ @include list-unstyled();
+}
+
+.page-link {
+ position: relative;
+ display: block;
+ padding: var(--#{$prefix}pagination-padding-y) var(--#{$prefix}pagination-padding-x);
+ @include font-size(var(--#{$prefix}pagination-font-size));
+ color: var(--#{$prefix}pagination-color);
+ text-decoration: if($link-decoration == none, null, none);
+ background-color: var(--#{$prefix}pagination-bg);
+ border: var(--#{$prefix}pagination-border-width) solid var(--#{$prefix}pagination-border-color);
+ @include transition($pagination-transition);
+
+ &:hover {
+ z-index: 2;
+ color: var(--#{$prefix}pagination-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ background-color: var(--#{$prefix}pagination-hover-bg);
+ border-color: var(--#{$prefix}pagination-hover-border-color);
+ }
+
+ &:focus {
+ z-index: 3;
+ color: var(--#{$prefix}pagination-focus-color);
+ background-color: var(--#{$prefix}pagination-focus-bg);
+ outline: $pagination-focus-outline;
+ box-shadow: var(--#{$prefix}pagination-focus-box-shadow);
+ }
+
+ &.active,
+ .active > & {
+ z-index: 3;
+ color: var(--#{$prefix}pagination-active-color);
+ @include gradient-bg(var(--#{$prefix}pagination-active-bg));
+ border-color: var(--#{$prefix}pagination-active-border-color);
+ }
+
+ &.disabled,
+ .disabled > & {
+ color: var(--#{$prefix}pagination-disabled-color);
+ pointer-events: none;
+ background-color: var(--#{$prefix}pagination-disabled-bg);
+ border-color: var(--#{$prefix}pagination-disabled-border-color);
+ }
+}
+
+.page-item {
+ &:not(:first-child) .page-link {
+ margin-left: $pagination-margin-start;
+ }
+
+ @if $pagination-margin-start == calc(#{$pagination-border-width} * -1) {
+ &:first-child {
+ .page-link {
+ @include border-start-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+
+ &:last-child {
+ .page-link {
+ @include border-end-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+ } @else {
+ // Add border-radius to all pageLinks in case they have left margin
+ .page-link {
+ @include border-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+}
+
+
+//
+// Sizing
+//
+
+.pagination-lg {
+ @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
+}
+
+.pagination-sm {
+ @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_placeholders.scss b/Moonlight/Styles/bootstrap/scss/_placeholders.scss
new file mode 100644
index 00000000..6e32e1cd
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_placeholders.scss
@@ -0,0 +1,51 @@
+.placeholder {
+ display: inline-block;
+ min-height: 1em;
+ vertical-align: middle;
+ cursor: wait;
+ background-color: currentcolor;
+ opacity: $placeholder-opacity-max;
+
+ &.btn::before {
+ display: inline-block;
+ content: "";
+ }
+}
+
+// Sizing
+.placeholder-xs {
+ min-height: .6em;
+}
+
+.placeholder-sm {
+ min-height: .8em;
+}
+
+.placeholder-lg {
+ min-height: 1.2em;
+}
+
+// Animation
+.placeholder-glow {
+ .placeholder {
+ animation: placeholder-glow 2s ease-in-out infinite;
+ }
+}
+
+@keyframes placeholder-glow {
+ 50% {
+ opacity: $placeholder-opacity-min;
+ }
+}
+
+.placeholder-wave {
+ mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%);
+ mask-size: 200% 100%;
+ animation: placeholder-wave 2s linear infinite;
+}
+
+@keyframes placeholder-wave {
+ 100% {
+ mask-position: -200% 0%;
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_popover.scss b/Moonlight/Styles/bootstrap/scss/_popover.scss
new file mode 100644
index 00000000..7b69f623
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_popover.scss
@@ -0,0 +1,196 @@
+.popover {
+ // scss-docs-start popover-css-vars
+ --#{$prefix}popover-zindex: #{$zindex-popover};
+ --#{$prefix}popover-max-width: #{$popover-max-width};
+ @include rfs($popover-font-size, --#{$prefix}popover-font-size);
+ --#{$prefix}popover-bg: #{$popover-bg};
+ --#{$prefix}popover-border-width: #{$popover-border-width};
+ --#{$prefix}popover-border-color: #{$popover-border-color};
+ --#{$prefix}popover-border-radius: #{$popover-border-radius};
+ --#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
+ --#{$prefix}popover-box-shadow: #{$popover-box-shadow};
+ --#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
+ --#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
+ @include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
+ --#{$prefix}popover-header-color: #{$popover-header-color};
+ --#{$prefix}popover-header-bg: #{$popover-header-bg};
+ --#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
+ --#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
+ --#{$prefix}popover-body-color: #{$popover-body-color};
+ --#{$prefix}popover-arrow-width: #{$popover-arrow-width};
+ --#{$prefix}popover-arrow-height: #{$popover-arrow-height};
+ --#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
+ // scss-docs-end popover-css-vars
+
+ z-index: var(--#{$prefix}popover-zindex);
+ display: block;
+ max-width: var(--#{$prefix}popover-max-width);
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ @include font-size(var(--#{$prefix}popover-font-size));
+ // Allow breaking very long words so they don't overflow the popover's bounds
+ word-wrap: break-word;
+ background-color: var(--#{$prefix}popover-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
+ @include border-radius(var(--#{$prefix}popover-border-radius));
+ @include box-shadow(var(--#{$prefix}popover-box-shadow));
+
+ .popover-arrow {
+ display: block;
+ width: var(--#{$prefix}popover-arrow-width);
+ height: var(--#{$prefix}popover-arrow-height);
+
+ &::before,
+ &::after {
+ position: absolute;
+ display: block;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ border-width: 0;
+ }
+ }
+}
+
+.bs-popover-top {
+ > .popover-arrow {
+ bottom: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+
+ &::before,
+ &::after {
+ border-width: var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ bottom: 0;
+ border-top-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ bottom: var(--#{$prefix}popover-border-width);
+ border-top-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-popover-end {
+ > .popover-arrow {
+ left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}popover-arrow-height);
+ height: var(--#{$prefix}popover-arrow-width);
+
+ &::before,
+ &::after {
+ border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ left: 0;
+ border-right-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ left: var(--#{$prefix}popover-border-width);
+ border-right-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-popover-bottom {
+ > .popover-arrow {
+ top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+
+ &::before,
+ &::after {
+ border-width: 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ top: 0;
+ border-bottom-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ top: var(--#{$prefix}popover-border-width);
+ border-bottom-color: var(--#{$prefix}popover-bg);
+ }
+ }
+
+ // This will remove the popover-header's border just below the arrow
+ .popover-header::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: var(--#{$prefix}popover-arrow-width);
+ margin-left: calc(-.5 * var(--#{$prefix}popover-arrow-width)); // stylelint-disable-line function-disallowed-list
+ content: "";
+ border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-header-bg);
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-popover-start {
+ > .popover-arrow {
+ right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}popover-arrow-height);
+ height: var(--#{$prefix}popover-arrow-width);
+
+ &::before,
+ &::after {
+ border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ right: 0;
+ border-left-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ right: var(--#{$prefix}popover-border-width);
+ border-left-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-popover-auto {
+ &[data-popper-placement^="top"] {
+ @extend .bs-popover-top;
+ }
+ &[data-popper-placement^="right"] {
+ @extend .bs-popover-end;
+ }
+ &[data-popper-placement^="bottom"] {
+ @extend .bs-popover-bottom;
+ }
+ &[data-popper-placement^="left"] {
+ @extend .bs-popover-start;
+ }
+}
+
+// Offset the popover to account for the popover arrow
+.popover-header {
+ padding: var(--#{$prefix}popover-header-padding-y) var(--#{$prefix}popover-header-padding-x);
+ margin-bottom: 0; // Reset the default from Reboot
+ @include font-size(var(--#{$prefix}popover-header-font-size));
+ color: var(--#{$prefix}popover-header-color);
+ background-color: var(--#{$prefix}popover-header-bg);
+ border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
+ @include border-top-radius(var(--#{$prefix}popover-inner-border-radius));
+
+ &:empty {
+ display: none;
+ }
+}
+
+.popover-body {
+ padding: var(--#{$prefix}popover-body-padding-y) var(--#{$prefix}popover-body-padding-x);
+ color: var(--#{$prefix}popover-body-color);
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_progress.scss b/Moonlight/Styles/bootstrap/scss/_progress.scss
new file mode 100644
index 00000000..148c3815
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_progress.scss
@@ -0,0 +1,68 @@
+// Disable animation if transitions are disabled
+
+// scss-docs-start progress-keyframes
+@if $enable-transitions {
+ @keyframes progress-bar-stripes {
+ 0% { background-position-x: $progress-height; }
+ }
+}
+// scss-docs-end progress-keyframes
+
+.progress,
+.progress-stacked {
+ // scss-docs-start progress-css-vars
+ --#{$prefix}progress-height: #{$progress-height};
+ @include rfs($progress-font-size, --#{$prefix}progress-font-size);
+ --#{$prefix}progress-bg: #{$progress-bg};
+ --#{$prefix}progress-border-radius: #{$progress-border-radius};
+ --#{$prefix}progress-box-shadow: #{$progress-box-shadow};
+ --#{$prefix}progress-bar-color: #{$progress-bar-color};
+ --#{$prefix}progress-bar-bg: #{$progress-bar-bg};
+ --#{$prefix}progress-bar-transition: #{$progress-bar-transition};
+ // scss-docs-end progress-css-vars
+
+ display: flex;
+ height: var(--#{$prefix}progress-height);
+ overflow: hidden; // force rounded corners by cropping it
+ @include font-size(var(--#{$prefix}progress-font-size));
+ background-color: var(--#{$prefix}progress-bg);
+ @include border-radius(var(--#{$prefix}progress-border-radius));
+ @include box-shadow(var(--#{$prefix}progress-box-shadow));
+}
+
+.progress-bar {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ overflow: hidden;
+ color: var(--#{$prefix}progress-bar-color);
+ text-align: center;
+ white-space: nowrap;
+ background-color: var(--#{$prefix}progress-bar-bg);
+ @include transition(var(--#{$prefix}progress-bar-transition));
+}
+
+.progress-bar-striped {
+ @include gradient-striped();
+ background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height);
+}
+
+.progress-stacked > .progress {
+ overflow: visible;
+}
+
+.progress-stacked > .progress > .progress-bar {
+ width: 100%;
+}
+
+@if $enable-transitions {
+ .progress-bar-animated {
+ animation: $progress-bar-animation-timing progress-bar-stripes;
+
+ @if $enable-reduced-motion {
+ @media (prefers-reduced-motion: reduce) {
+ animation: none;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_reboot.scss b/Moonlight/Styles/bootstrap/scss/_reboot.scss
new file mode 100644
index 00000000..18791753
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_reboot.scss
@@ -0,0 +1,611 @@
+// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
+
+
+// Reboot
+//
+// Normalization of HTML elements, manually forked from Normalize.css to remove
+// styles targeting irrelevant browsers while applying new styles.
+//
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
+
+
+// Document
+//
+// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+
+// Root
+//
+// Ability to the value of the root font sizes, affecting the value of `rem`.
+// null by default, thus nothing is generated.
+
+:root {
+ @if $font-size-root != null {
+ @include font-size(var(--#{$prefix}root-font-size));
+ }
+
+ @if $enable-smooth-scroll {
+ @media (prefers-reduced-motion: no-preference) {
+ scroll-behavior: smooth;
+ }
+ }
+}
+
+
+// Body
+//
+// 1. Remove the margin in all browsers.
+// 2. As a best practice, apply a default `background-color`.
+// 3. Prevent adjustments of font size after orientation changes in iOS.
+// 4. Change the default tap highlight to be completely transparent in iOS.
+
+// scss-docs-start reboot-body-rules
+body {
+ margin: 0; // 1
+ font-family: var(--#{$prefix}body-font-family);
+ @include font-size(var(--#{$prefix}body-font-size));
+ font-weight: var(--#{$prefix}body-font-weight);
+ line-height: var(--#{$prefix}body-line-height);
+ color: var(--#{$prefix}body-color);
+ text-align: var(--#{$prefix}body-text-align);
+ background-color: var(--#{$prefix}body-bg); // 2
+ -webkit-text-size-adjust: 100%; // 3
+ -webkit-tap-highlight-color: rgba($black, 0); // 4
+}
+// scss-docs-end reboot-body-rules
+
+
+// Content grouping
+//
+// 1. Reset Firefox's gray color
+
+hr {
+ margin: $hr-margin-y 0;
+ color: $hr-color; // 1
+ border: 0;
+ border-top: $hr-border-width solid $hr-border-color;
+ opacity: $hr-opacity;
+}
+
+
+// Typography
+//
+// 1. Remove top margins from headings
+// By default, ``-`` all receive top and bottom margins. We nuke the top
+// margin for easier control within type scales as it avoids margin collapsing.
+
+%heading {
+ margin-top: 0; // 1
+ margin-bottom: $headings-margin-bottom;
+ font-family: $headings-font-family;
+ font-style: $headings-font-style;
+ font-weight: $headings-font-weight;
+ line-height: $headings-line-height;
+ color: var(--#{$prefix}heading-color);
+}
+
+h1 {
+ @extend %heading;
+ @include font-size($h1-font-size);
+}
+
+h2 {
+ @extend %heading;
+ @include font-size($h2-font-size);
+}
+
+h3 {
+ @extend %heading;
+ @include font-size($h3-font-size);
+}
+
+h4 {
+ @extend %heading;
+ @include font-size($h4-font-size);
+}
+
+h5 {
+ @extend %heading;
+ @include font-size($h5-font-size);
+}
+
+h6 {
+ @extend %heading;
+ @include font-size($h6-font-size);
+}
+
+
+// Reset margins on paragraphs
+//
+// Similarly, the top margin on ` `s get reset. However, we also reset the
+// bottom margin to use `rem` units instead of `em`.
+
+p {
+ margin-top: 0;
+ margin-bottom: $paragraph-margin-bottom;
+}
+
+
+// Abbreviations
+//
+// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
+// 2. Add explicit cursor to indicate changed behavior.
+// 3. Prevent the text-decoration to be skipped.
+
+abbr[title] {
+ text-decoration: underline dotted; // 1
+ cursor: help; // 2
+ text-decoration-skip-ink: none; // 3
+}
+
+
+// Address
+
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+
+
+// Lists
+
+ol,
+ul {
+ padding-left: 2rem;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: $dt-font-weight;
+}
+
+// 1. Undo browser default
+
+dd {
+ margin-bottom: .5rem;
+ margin-left: 0; // 1
+}
+
+
+// Blockquote
+
+blockquote {
+ margin: 0 0 1rem;
+}
+
+
+// Strong
+//
+// Add the correct font weight in Chrome, Edge, and Safari
+
+b,
+strong {
+ font-weight: $font-weight-bolder;
+}
+
+
+// Small
+//
+// Add the correct font size in all browsers
+
+small {
+ @include font-size($small-font-size);
+}
+
+
+// Mark
+
+mark {
+ padding: $mark-padding;
+ color: var(--#{$prefix}highlight-color);
+ background-color: var(--#{$prefix}highlight-bg);
+}
+
+
+// Sub and Sup
+//
+// Prevent `sub` and `sup` elements from affecting the line height in
+// all browsers.
+
+sub,
+sup {
+ position: relative;
+ @include font-size($sub-sup-font-size);
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub { bottom: -.25em; }
+sup { top: -.5em; }
+
+
+// Links
+
+a {
+ color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));
+ text-decoration: $link-decoration;
+
+ &:hover {
+ --#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);
+ text-decoration: $link-hover-decoration;
+ }
+}
+
+// And undo these styles for placeholder links/named anchors (without href).
+// It would be more straightforward to just use a[href] in previous block, but that
+// causes specificity issues in many other styles that are too complex to fix.
+// See https://github.com/twbs/bootstrap/issues/19402
+
+a:not([href]):not([class]) {
+ &,
+ &:hover {
+ color: inherit;
+ text-decoration: none;
+ }
+}
+
+
+// Code
+
+pre,
+code,
+kbd,
+samp {
+ font-family: $font-family-code;
+ @include font-size(1em); // Correct the odd `em` font sizing in all browsers.
+}
+
+// 1. Remove browser default top margin
+// 2. Reset browser default of `1em` to use `rem`s
+// 3. Don't allow content to break outside
+
+pre {
+ display: block;
+ margin-top: 0; // 1
+ margin-bottom: 1rem; // 2
+ overflow: auto; // 3
+ @include font-size($code-font-size);
+ color: $pre-color;
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ @include font-size(inherit);
+ color: inherit;
+ word-break: normal;
+ }
+}
+
+code {
+ @include font-size($code-font-size);
+ color: var(--#{$prefix}code-color);
+ word-wrap: break-word;
+
+ // Streamline the style when inside anchors to avoid broken underline and more
+ a > & {
+ color: inherit;
+ }
+}
+
+kbd {
+ padding: $kbd-padding-y $kbd-padding-x;
+ @include font-size($kbd-font-size);
+ color: $kbd-color;
+ background-color: $kbd-bg;
+ @include border-radius($border-radius-sm);
+
+ kbd {
+ padding: 0;
+ @include font-size(1em);
+ font-weight: $nested-kbd-font-weight;
+ }
+}
+
+
+// Figures
+//
+// Apply a consistent margin strategy (matches our type styles).
+
+figure {
+ margin: 0 0 1rem;
+}
+
+
+// Images and content
+
+img,
+svg {
+ vertical-align: middle;
+}
+
+
+// Tables
+//
+// Prevent double borders
+
+table {
+ caption-side: bottom;
+ border-collapse: collapse;
+}
+
+caption {
+ padding-top: $table-cell-padding-y;
+ padding-bottom: $table-cell-padding-y;
+ color: $table-caption-color;
+ text-align: left;
+}
+
+// 1. Removes font-weight bold by inheriting
+// 2. Matches default `
` alignment by inheriting `text-align`.
+// 3. Fix alignment for Safari
+
+th {
+ font-weight: $table-th-font-weight; // 1
+ text-align: inherit; // 2
+ text-align: -webkit-match-parent; // 3
+}
+
+thead,
+tbody,
+tfoot,
+tr,
+td,
+th {
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+}
+
+
+// Forms
+//
+// 1. Allow labels to use `margin` for spacing.
+
+label {
+ display: inline-block; // 1
+}
+
+// Remove the default `border-radius` that macOS Chrome adds.
+// See https://github.com/twbs/bootstrap/issues/24093
+
+button {
+ // stylelint-disable-next-line property-disallowed-list
+ border-radius: 0;
+}
+
+// Explicitly remove focus outline in Chromium when it shouldn't be
+// visible (e.g. as result of mouse click or touch tap). It already
+// should be doing this automatically, but seems to currently be
+// confused and applies its very visible two-tone outline anyway.
+
+button:focus:not(:focus-visible) {
+ outline: 0;
+}
+
+// 1. Remove the margin in Firefox and Safari
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0; // 1
+ font-family: inherit;
+ @include font-size(inherit);
+ line-height: inherit;
+}
+
+// Remove the inheritance of text transform in Firefox
+button,
+select {
+ text-transform: none;
+}
+// Set the cursor for non-`` buttons
+//
+// Details at https://github.com/twbs/bootstrap/pull/30562
+[role="button"] {
+ cursor: pointer;
+}
+
+select {
+ // Remove the inheritance of word-wrap in Safari.
+ // See https://github.com/twbs/bootstrap/issues/24990
+ word-wrap: normal;
+
+ // Undo the opacity change from Chrome
+ &:disabled {
+ opacity: 1;
+ }
+}
+
+// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.
+// See https://stackoverflow.com/a/54997118
+
+[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator {
+ display: none !important;
+}
+
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+// controls in Android 4.
+// 2. Correct the inability to style clickable types in iOS and Safari.
+// 3. Opinionated: add "hand" cursor to non-disabled button elements.
+
+button,
+[type="button"], // 1
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; // 2
+
+ @if $enable-button-pointers {
+ &:not(:disabled) {
+ cursor: pointer; // 3
+ }
+ }
+}
+
+// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
+
+::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
+
+textarea {
+ resize: vertical; // 1
+}
+
+// 1. Browsers set a default `min-width: min-content;` on fieldsets,
+// unlike e.g. ``s, which have `min-width: 0;` by default.
+// So we reset that to ensure fieldsets behave more like a standard block element.
+// See https://github.com/twbs/bootstrap/issues/12359
+// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
+// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.
+
+fieldset {
+ min-width: 0; // 1
+ padding: 0; // 2
+ margin: 0; // 2
+ border: 0; // 2
+}
+
+// 1. By using `float: left`, the legend will behave like a block element.
+// This way the border of a fieldset wraps around the legend if present.
+// 2. Fix wrapping bug.
+// See https://github.com/twbs/bootstrap/issues/29712
+
+legend {
+ float: left; // 1
+ width: 100%;
+ padding: 0;
+ margin-bottom: $legend-margin-bottom;
+ @include font-size($legend-font-size);
+ font-weight: $legend-font-weight;
+ line-height: inherit;
+
+ + * {
+ clear: left; // 2
+ }
+}
+
+// Fix height of inputs with a type of datetime-local, date, month, week, or time
+// See https://github.com/twbs/bootstrap/issues/18842
+
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-year-field {
+ padding: 0;
+}
+
+::-webkit-inner-spin-button {
+ height: auto;
+}
+
+// 1. This overrides the extra rounded corners on search inputs in iOS so that our
+// `.form-control` class can properly style them. Note that this cannot simply
+// be added to `.form-control` as it's not specific enough. For details, see
+// https://github.com/twbs/bootstrap/issues/11586.
+// 2. Correct the outline style in Safari.
+
+[type="search"] {
+ -webkit-appearance: textfield; // 1
+ outline-offset: -2px; // 2
+}
+
+// 1. A few input types should stay LTR
+// See https://rtlstyling.com/posts/rtl-styling#form-inputs
+// 2. RTL only output
+// See https://rtlcss.com/learn/usage-guide/control-directives/#raw
+
+/* rtl:raw:
+[type="tel"],
+[type="url"],
+[type="email"],
+[type="number"] {
+ direction: ltr;
+}
+*/
+
+// Remove the inner padding in Chrome and Safari on macOS.
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+// Remove padding around color pickers in webkit browsers
+
+::-webkit-color-swatch-wrapper {
+ padding: 0;
+}
+
+
+// 1. Inherit font family and line height for file input buttons
+// 2. Correct the inability to style clickable types in iOS and Safari.
+
+::file-selector-button {
+ font: inherit; // 1
+ -webkit-appearance: button; // 2
+}
+
+// Correct element displays
+
+output {
+ display: inline-block;
+}
+
+// Remove border from iframe
+
+iframe {
+ border: 0;
+}
+
+// Summary
+//
+// 1. Add the correct display in all browsers
+
+summary {
+ display: list-item; // 1
+ cursor: pointer;
+}
+
+
+// Progress
+//
+// Add the correct vertical alignment in Chrome, Firefox, and Opera.
+
+progress {
+ vertical-align: baseline;
+}
+
+
+// Hidden attribute
+//
+// Always hide an element with the `hidden` HTML attribute.
+
+[hidden] {
+ display: none !important;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_root.scss b/Moonlight/Styles/bootstrap/scss/_root.scss
new file mode 100644
index 00000000..becddf14
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_root.scss
@@ -0,0 +1,187 @@
+:root,
+[data-bs-theme="light"] {
+ // Note: Custom variable values only support SassScript inside `#{}`.
+
+ // Colors
+ //
+ // Generate palettes for full colors, grays, and theme colors.
+
+ @each $color, $value in $colors {
+ --#{$prefix}#{$color}: #{$value};
+ }
+
+ @each $color, $value in $grays {
+ --#{$prefix}gray-#{$color}: #{$value};
+ }
+
+ @each $color, $value in $theme-colors {
+ --#{$prefix}#{$color}: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-rgb {
+ --#{$prefix}#{$color}-rgb: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-text {
+ --#{$prefix}#{$color}-text-emphasis: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-bg-subtle {
+ --#{$prefix}#{$color}-bg-subtle: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-border-subtle {
+ --#{$prefix}#{$color}-border-subtle: #{$value};
+ }
+
+ --#{$prefix}white-rgb: #{to-rgb($white)};
+ --#{$prefix}black-rgb: #{to-rgb($black)};
+
+ // Fonts
+
+ // Note: Use `inspect` for lists so that quoted items keep the quotes.
+ // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
+ --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};
+ --#{$prefix}font-monospace: #{inspect($font-family-monospace)};
+ --#{$prefix}gradient: #{$gradient};
+
+ // Root and body
+ // scss-docs-start root-body-variables
+ @if $font-size-root != null {
+ --#{$prefix}root-font-size: #{$font-size-root};
+ }
+ --#{$prefix}body-font-family: #{inspect($font-family-base)};
+ @include rfs($font-size-base, --#{$prefix}body-font-size);
+ --#{$prefix}body-font-weight: #{$font-weight-base};
+ --#{$prefix}body-line-height: #{$line-height-base};
+ @if $body-text-align != null {
+ --#{$prefix}body-text-align: #{$body-text-align};
+ }
+
+ --#{$prefix}body-color: #{$body-color};
+ --#{$prefix}body-color-rgb: #{to-rgb($body-color)};
+ --#{$prefix}body-bg: #{$body-bg};
+ --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};
+
+ --#{$prefix}emphasis-color: #{$body-emphasis-color};
+ --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};
+
+ --#{$prefix}secondary-color: #{$body-secondary-color};
+ --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};
+ --#{$prefix}secondary-bg: #{$body-secondary-bg};
+ --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};
+
+ --#{$prefix}tertiary-color: #{$body-tertiary-color};
+ --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};
+ --#{$prefix}tertiary-bg: #{$body-tertiary-bg};
+ --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};
+ // scss-docs-end root-body-variables
+
+ --#{$prefix}heading-color: #{$headings-color};
+
+ --#{$prefix}link-color: #{$link-color};
+ --#{$prefix}link-color-rgb: #{to-rgb($link-color)};
+ --#{$prefix}link-decoration: #{$link-decoration};
+
+ --#{$prefix}link-hover-color: #{$link-hover-color};
+ --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color)};
+
+ @if $link-hover-decoration != null {
+ --#{$prefix}link-hover-decoration: #{$link-hover-decoration};
+ }
+
+ --#{$prefix}code-color: #{$code-color};
+ --#{$prefix}highlight-color: #{$mark-color};
+ --#{$prefix}highlight-bg: #{$mark-bg};
+
+ // scss-docs-start root-border-var
+ --#{$prefix}border-width: #{$border-width};
+ --#{$prefix}border-style: #{$border-style};
+ --#{$prefix}border-color: #{$border-color};
+ --#{$prefix}border-color-translucent: #{$border-color-translucent};
+
+ --#{$prefix}border-radius: #{$border-radius};
+ --#{$prefix}border-radius-sm: #{$border-radius-sm};
+ --#{$prefix}border-radius-lg: #{$border-radius-lg};
+ --#{$prefix}border-radius-xl: #{$border-radius-xl};
+ --#{$prefix}border-radius-xxl: #{$border-radius-xxl};
+ --#{$prefix}border-radius-2xl: var(--#{$prefix}border-radius-xxl); // Deprecated in v5.3.0 for consistency
+ --#{$prefix}border-radius-pill: #{$border-radius-pill};
+ // scss-docs-end root-border-var
+
+ --#{$prefix}box-shadow: #{$box-shadow};
+ --#{$prefix}box-shadow-sm: #{$box-shadow-sm};
+ --#{$prefix}box-shadow-lg: #{$box-shadow-lg};
+ --#{$prefix}box-shadow-inset: #{$box-shadow-inset};
+
+ // Focus styles
+ // scss-docs-start root-focus-variables
+ --#{$prefix}focus-ring-width: #{$focus-ring-width};
+ --#{$prefix}focus-ring-opacity: #{$focus-ring-opacity};
+ --#{$prefix}focus-ring-color: #{$focus-ring-color};
+ // scss-docs-end root-focus-variables
+
+ // scss-docs-start root-form-validation-variables
+ --#{$prefix}form-valid-color: #{$form-valid-color};
+ --#{$prefix}form-valid-border-color: #{$form-valid-border-color};
+ --#{$prefix}form-invalid-color: #{$form-invalid-color};
+ --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color};
+ // scss-docs-end root-form-validation-variables
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark, true) {
+ color-scheme: dark;
+
+ // scss-docs-start root-dark-mode-vars
+ --#{$prefix}body-color: #{$body-color-dark};
+ --#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};
+ --#{$prefix}body-bg: #{$body-bg-dark};
+ --#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};
+
+ --#{$prefix}emphasis-color: #{$body-emphasis-color-dark};
+ --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};
+
+ --#{$prefix}secondary-color: #{$body-secondary-color-dark};
+ --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
+ --#{$prefix}secondary-bg: #{$body-secondary-bg-dark};
+ --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};
+
+ --#{$prefix}tertiary-color: #{$body-tertiary-color-dark};
+ --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
+ --#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};
+ --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};
+
+ @each $color, $value in $theme-colors-text-dark {
+ --#{$prefix}#{$color}-text-emphasis: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-bg-subtle-dark {
+ --#{$prefix}#{$color}-bg-subtle: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-border-subtle-dark {
+ --#{$prefix}#{$color}-border-subtle: #{$value};
+ }
+
+ --#{$prefix}heading-color: #{$headings-color-dark};
+
+ --#{$prefix}link-color: #{$link-color-dark};
+ --#{$prefix}link-hover-color: #{$link-hover-color-dark};
+ --#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};
+ --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};
+
+ --#{$prefix}code-color: #{$code-color-dark};
+ --#{$prefix}highlight-color: #{$mark-color-dark};
+ --#{$prefix}highlight-bg: #{$mark-bg-dark};
+
+ --#{$prefix}border-color: #{$border-color-dark};
+ --#{$prefix}border-color-translucent: #{$border-color-translucent-dark};
+
+ --#{$prefix}form-valid-color: #{$form-valid-color-dark};
+ --#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};
+ --#{$prefix}form-invalid-color: #{$form-invalid-color-dark};
+ --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};
+ // scss-docs-end root-dark-mode-vars
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_spinners.scss b/Moonlight/Styles/bootstrap/scss/_spinners.scss
new file mode 100644
index 00000000..ec847320
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_spinners.scss
@@ -0,0 +1,85 @@
+//
+// Rotating border
+//
+
+.spinner-grow,
+.spinner-border {
+ display: inline-block;
+ width: var(--#{$prefix}spinner-width);
+ height: var(--#{$prefix}spinner-height);
+ vertical-align: var(--#{$prefix}spinner-vertical-align);
+ // stylelint-disable-next-line property-disallowed-list
+ border-radius: 50%;
+ animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name);
+}
+
+// scss-docs-start spinner-border-keyframes
+@keyframes spinner-border {
+ to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
+}
+// scss-docs-end spinner-border-keyframes
+
+.spinner-border {
+ // scss-docs-start spinner-border-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width};
+ --#{$prefix}spinner-height: #{$spinner-height};
+ --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+ --#{$prefix}spinner-border-width: #{$spinner-border-width};
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+ --#{$prefix}spinner-animation-name: spinner-border;
+ // scss-docs-end spinner-border-css-vars
+
+ border: var(--#{$prefix}spinner-border-width) solid currentcolor;
+ border-right-color: transparent;
+}
+
+.spinner-border-sm {
+ // scss-docs-start spinner-border-sm-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width-sm};
+ --#{$prefix}spinner-height: #{$spinner-height-sm};
+ --#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
+ // scss-docs-end spinner-border-sm-css-vars
+}
+
+//
+// Growing circle
+//
+
+// scss-docs-start spinner-grow-keyframes
+@keyframes spinner-grow {
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ opacity: 1;
+ transform: none;
+ }
+}
+// scss-docs-end spinner-grow-keyframes
+
+.spinner-grow {
+ // scss-docs-start spinner-grow-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width};
+ --#{$prefix}spinner-height: #{$spinner-height};
+ --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+ --#{$prefix}spinner-animation-name: spinner-grow;
+ // scss-docs-end spinner-grow-css-vars
+
+ background-color: currentcolor;
+ opacity: 0;
+}
+
+.spinner-grow-sm {
+ --#{$prefix}spinner-width: #{$spinner-width-sm};
+ --#{$prefix}spinner-height: #{$spinner-height-sm};
+}
+
+@if $enable-reduced-motion {
+ @media (prefers-reduced-motion: reduce) {
+ .spinner-border,
+ .spinner-grow {
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2};
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_tables.scss b/Moonlight/Styles/bootstrap/scss/_tables.scss
new file mode 100644
index 00000000..ebfc00a5
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_tables.scss
@@ -0,0 +1,171 @@
+//
+// Basic Bootstrap table
+//
+
+.table {
+ // Reset needed for nesting tables
+ --#{$prefix}table-color-type: initial;
+ --#{$prefix}table-bg-type: initial;
+ --#{$prefix}table-color-state: initial;
+ --#{$prefix}table-bg-state: initial;
+ // End of reset
+ --#{$prefix}table-color: #{$table-color};
+ --#{$prefix}table-bg: #{$table-bg};
+ --#{$prefix}table-border-color: #{$table-border-color};
+ --#{$prefix}table-accent-bg: #{$table-accent-bg};
+ --#{$prefix}table-striped-color: #{$table-striped-color};
+ --#{$prefix}table-striped-bg: #{$table-striped-bg};
+ --#{$prefix}table-active-color: #{$table-active-color};
+ --#{$prefix}table-active-bg: #{$table-active-bg};
+ --#{$prefix}table-hover-color: #{$table-hover-color};
+ --#{$prefix}table-hover-bg: #{$table-hover-bg};
+
+ width: 100%;
+ margin-bottom: $spacer;
+ vertical-align: $table-cell-vertical-align;
+ border-color: var(--#{$prefix}table-border-color);
+
+ // Target th & td
+ // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.
+ // We use the universal selectors here to simplify the selector (else we would need 6 different selectors).
+ // Another advantage is that this generates less code and makes the selector less specific making it easier to override.
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ padding: $table-cell-padding-y $table-cell-padding-x;
+ // Following the precept of cascades: https://codepen.io/miriamsuzanne/full/vYNgodb
+ color: var(--#{$prefix}table-color-state, var(--#{$prefix}table-color-type, var(--#{$prefix}table-color)));
+ background-color: var(--#{$prefix}table-bg);
+ border-bottom-width: $table-border-width;
+ box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-bg-state, var(--#{$prefix}table-bg-type, var(--#{$prefix}table-accent-bg)));
+ }
+
+ > tbody {
+ vertical-align: inherit;
+ }
+
+ > thead {
+ vertical-align: bottom;
+ }
+}
+
+.table-group-divider {
+ border-top: calc(#{$table-border-width} * 2) solid $table-group-separator-color; // stylelint-disable-line function-disallowed-list
+}
+
+//
+// Change placement of captions with a class
+//
+
+.caption-top {
+ caption-side: top;
+}
+
+
+//
+// Condensed table w/ half padding
+//
+
+.table-sm {
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;
+ }
+}
+
+
+// Border versions
+//
+// Add or remove borders all around the table and between all the columns.
+//
+// When borders are added on all sides of the cells, the corners can render odd when
+// these borders do not have the same color or if they are semi-transparent.
+// Therefor we add top and border bottoms to the `tr`s and left and right borders
+// to the `td`s or `th`s
+
+.table-bordered {
+ > :not(caption) > * {
+ border-width: $table-border-width 0;
+
+ // stylelint-disable-next-line selector-max-universal
+ > * {
+ border-width: 0 $table-border-width;
+ }
+ }
+}
+
+.table-borderless {
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ border-bottom-width: 0;
+ }
+
+ > :not(:first-child) {
+ border-top-width: 0;
+ }
+}
+
+// Zebra-striping
+//
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+
+// For rows
+.table-striped {
+ > tbody > tr:nth-of-type(#{$table-striped-order}) > * {
+ --#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
+ --#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
+ }
+}
+
+// For columns
+.table-striped-columns {
+ > :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {
+ --#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
+ --#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
+ }
+}
+
+// Active table
+//
+// The `.table-active` class can be added to highlight rows or cells
+
+.table-active {
+ --#{$prefix}table-color-state: var(--#{$prefix}table-active-color);
+ --#{$prefix}table-bg-state: var(--#{$prefix}table-active-bg);
+}
+
+// Hover effect
+//
+// Placed here since it has to come after the potential zebra striping
+
+.table-hover {
+ > tbody > tr:hover > * {
+ --#{$prefix}table-color-state: var(--#{$prefix}table-hover-color);
+ --#{$prefix}table-bg-state: var(--#{$prefix}table-hover-bg);
+ }
+}
+
+
+// Table variants
+//
+// Table variants set the table cell backgrounds, border colors
+// and the colors of the striped, hovered & active tables
+
+@each $color, $value in $table-variants {
+ @include table-variant($color, $value);
+}
+
+// Responsive tables
+//
+// Generate series of `.table-responsive-*` classes for configuring the screen
+// size of where your table will overflow.
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @include media-breakpoint-down($breakpoint) {
+ .table-responsive#{$infix} {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_toasts.scss b/Moonlight/Styles/bootstrap/scss/_toasts.scss
new file mode 100644
index 00000000..2ce378d5
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_toasts.scss
@@ -0,0 +1,73 @@
+.toast {
+ // scss-docs-start toast-css-vars
+ --#{$prefix}toast-zindex: #{$zindex-toast};
+ --#{$prefix}toast-padding-x: #{$toast-padding-x};
+ --#{$prefix}toast-padding-y: #{$toast-padding-y};
+ --#{$prefix}toast-spacing: #{$toast-spacing};
+ --#{$prefix}toast-max-width: #{$toast-max-width};
+ @include rfs($toast-font-size, --#{$prefix}toast-font-size);
+ --#{$prefix}toast-color: #{$toast-color};
+ --#{$prefix}toast-bg: #{$toast-background-color};
+ --#{$prefix}toast-border-width: #{$toast-border-width};
+ --#{$prefix}toast-border-color: #{$toast-border-color};
+ --#{$prefix}toast-border-radius: #{$toast-border-radius};
+ --#{$prefix}toast-box-shadow: #{$toast-box-shadow};
+ --#{$prefix}toast-header-color: #{$toast-header-color};
+ --#{$prefix}toast-header-bg: #{$toast-header-background-color};
+ --#{$prefix}toast-header-border-color: #{$toast-header-border-color};
+ // scss-docs-end toast-css-vars
+
+ width: var(--#{$prefix}toast-max-width);
+ max-width: 100%;
+ @include font-size(var(--#{$prefix}toast-font-size));
+ color: var(--#{$prefix}toast-color);
+ pointer-events: auto;
+ background-color: var(--#{$prefix}toast-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color);
+ box-shadow: var(--#{$prefix}toast-box-shadow);
+ @include border-radius(var(--#{$prefix}toast-border-radius));
+
+ &.showing {
+ opacity: 0;
+ }
+
+ &:not(.show) {
+ display: none;
+ }
+}
+
+.toast-container {
+ --#{$prefix}toast-zindex: #{$zindex-toast};
+
+ position: absolute;
+ z-index: var(--#{$prefix}toast-zindex);
+ width: max-content;
+ max-width: 100%;
+ pointer-events: none;
+
+ > :not(:last-child) {
+ margin-bottom: var(--#{$prefix}toast-spacing);
+ }
+}
+
+.toast-header {
+ display: flex;
+ align-items: center;
+ padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x);
+ color: var(--#{$prefix}toast-header-color);
+ background-color: var(--#{$prefix}toast-header-bg);
+ background-clip: padding-box;
+ border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color);
+ @include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width)));
+
+ .btn-close {
+ margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list
+ margin-left: var(--#{$prefix}toast-padding-x);
+ }
+}
+
+.toast-body {
+ padding: var(--#{$prefix}toast-padding-x);
+ word-wrap: break-word;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_tooltip.scss b/Moonlight/Styles/bootstrap/scss/_tooltip.scss
new file mode 100644
index 00000000..85de90f5
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_tooltip.scss
@@ -0,0 +1,119 @@
+// Base class
+.tooltip {
+ // scss-docs-start tooltip-css-vars
+ --#{$prefix}tooltip-zindex: #{$zindex-tooltip};
+ --#{$prefix}tooltip-max-width: #{$tooltip-max-width};
+ --#{$prefix}tooltip-padding-x: #{$tooltip-padding-x};
+ --#{$prefix}tooltip-padding-y: #{$tooltip-padding-y};
+ --#{$prefix}tooltip-margin: #{$tooltip-margin};
+ @include rfs($tooltip-font-size, --#{$prefix}tooltip-font-size);
+ --#{$prefix}tooltip-color: #{$tooltip-color};
+ --#{$prefix}tooltip-bg: #{$tooltip-bg};
+ --#{$prefix}tooltip-border-radius: #{$tooltip-border-radius};
+ --#{$prefix}tooltip-opacity: #{$tooltip-opacity};
+ --#{$prefix}tooltip-arrow-width: #{$tooltip-arrow-width};
+ --#{$prefix}tooltip-arrow-height: #{$tooltip-arrow-height};
+ // scss-docs-end tooltip-css-vars
+
+ z-index: var(--#{$prefix}tooltip-zindex);
+ display: block;
+ margin: var(--#{$prefix}tooltip-margin);
+ @include deprecate("`$tooltip-margin`", "v5", "v5.x", true);
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ @include font-size(var(--#{$prefix}tooltip-font-size));
+ // Allow breaking very long words so they don't overflow the tooltip's bounds
+ word-wrap: break-word;
+ opacity: 0;
+
+ &.show { opacity: var(--#{$prefix}tooltip-opacity); }
+
+ .tooltip-arrow {
+ display: block;
+ width: var(--#{$prefix}tooltip-arrow-width);
+ height: var(--#{$prefix}tooltip-arrow-height);
+
+ &::before {
+ position: absolute;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ }
+ }
+}
+
+.bs-tooltip-top .tooltip-arrow {
+ bottom: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
+
+ &::before {
+ top: -1px;
+ border-width: var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ border-top-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-end .tooltip-arrow {
+ left: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}tooltip-arrow-height);
+ height: var(--#{$prefix}tooltip-arrow-width);
+
+ &::before {
+ right: -1px;
+ border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ border-right-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-tooltip-bottom .tooltip-arrow {
+ top: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
+
+ &::before {
+ bottom: -1px;
+ border-width: 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
+ border-bottom-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-start .tooltip-arrow {
+ right: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}tooltip-arrow-height);
+ height: var(--#{$prefix}tooltip-arrow-width);
+
+ &::before {
+ left: -1px;
+ border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
+ border-left-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-tooltip-auto {
+ &[data-popper-placement^="top"] {
+ @extend .bs-tooltip-top;
+ }
+ &[data-popper-placement^="right"] {
+ @extend .bs-tooltip-end;
+ }
+ &[data-popper-placement^="bottom"] {
+ @extend .bs-tooltip-bottom;
+ }
+ &[data-popper-placement^="left"] {
+ @extend .bs-tooltip-start;
+ }
+}
+
+// Wrapper for the tooltip content
+.tooltip-inner {
+ max-width: var(--#{$prefix}tooltip-max-width);
+ padding: var(--#{$prefix}tooltip-padding-y) var(--#{$prefix}tooltip-padding-x);
+ color: var(--#{$prefix}tooltip-color);
+ text-align: center;
+ background-color: var(--#{$prefix}tooltip-bg);
+ @include border-radius(var(--#{$prefix}tooltip-border-radius));
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_transitions.scss b/Moonlight/Styles/bootstrap/scss/_transitions.scss
new file mode 100644
index 00000000..bfb26aa8
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_transitions.scss
@@ -0,0 +1,27 @@
+.fade {
+ @include transition($transition-fade);
+
+ &:not(.show) {
+ opacity: 0;
+ }
+}
+
+// scss-docs-start collapse-classes
+.collapse {
+ &:not(.show) {
+ display: none;
+ }
+}
+
+.collapsing {
+ height: 0;
+ overflow: hidden;
+ @include transition($transition-collapse);
+
+ &.collapse-horizontal {
+ width: 0;
+ height: auto;
+ @include transition($transition-collapse-width);
+ }
+}
+// scss-docs-end collapse-classes
diff --git a/Moonlight/Styles/bootstrap/scss/_type.scss b/Moonlight/Styles/bootstrap/scss/_type.scss
new file mode 100644
index 00000000..37d64bf8
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_type.scss
@@ -0,0 +1,106 @@
+//
+// Headings
+//
+.h1 {
+ @extend h1;
+}
+
+.h2 {
+ @extend h2;
+}
+
+.h3 {
+ @extend h3;
+}
+
+.h4 {
+ @extend h4;
+}
+
+.h5 {
+ @extend h5;
+}
+
+.h6 {
+ @extend h6;
+}
+
+
+.lead {
+ @include font-size($lead-font-size);
+ font-weight: $lead-font-weight;
+}
+
+// Type display classes
+@each $display, $font-size in $display-font-sizes {
+ .display-#{$display} {
+ @include font-size($font-size);
+ font-family: $display-font-family;
+ font-style: $display-font-style;
+ font-weight: $display-font-weight;
+ line-height: $display-line-height;
+ }
+}
+
+//
+// Emphasis
+//
+.small {
+ @extend small;
+}
+
+.mark {
+ @extend mark;
+}
+
+//
+// Lists
+//
+
+.list-unstyled {
+ @include list-unstyled();
+}
+
+// Inline turns list items into inline-block
+.list-inline {
+ @include list-unstyled();
+}
+.list-inline-item {
+ display: inline-block;
+
+ &:not(:last-child) {
+ margin-right: $list-inline-padding;
+ }
+}
+
+
+//
+// Misc
+//
+
+// Builds on `abbr`
+.initialism {
+ @include font-size($initialism-font-size);
+ text-transform: uppercase;
+}
+
+// Blockquotes
+.blockquote {
+ margin-bottom: $blockquote-margin-y;
+ @include font-size($blockquote-font-size);
+
+ > :last-child {
+ margin-bottom: 0;
+ }
+}
+
+.blockquote-footer {
+ margin-top: -$blockquote-margin-y;
+ margin-bottom: $blockquote-margin-y;
+ @include font-size($blockquote-footer-font-size);
+ color: $blockquote-footer-color;
+
+ &::before {
+ content: "\2014\00A0"; // em dash, nbsp
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/_utilities.scss b/Moonlight/Styles/bootstrap/scss/_utilities.scss
new file mode 100644
index 00000000..696f906e
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_utilities.scss
@@ -0,0 +1,806 @@
+// Utilities
+
+$utilities: () !default;
+// stylelint-disable-next-line scss/dollar-variable-default
+$utilities: map-merge(
+ (
+ // scss-docs-start utils-vertical-align
+ "align": (
+ property: vertical-align,
+ class: align,
+ values: baseline top middle bottom text-bottom text-top
+ ),
+ // scss-docs-end utils-vertical-align
+ // scss-docs-start utils-float
+ "float": (
+ responsive: true,
+ property: float,
+ values: (
+ start: left,
+ end: right,
+ none: none,
+ )
+ ),
+ // scss-docs-end utils-float
+ // Object Fit utilities
+ // scss-docs-start utils-object-fit
+ "object-fit": (
+ responsive: true,
+ property: object-fit,
+ values: (
+ contain: contain,
+ cover: cover,
+ fill: fill,
+ scale: scale-down,
+ none: none,
+ )
+ ),
+ // scss-docs-end utils-object-fit
+ // Opacity utilities
+ // scss-docs-start utils-opacity
+ "opacity": (
+ property: opacity,
+ values: (
+ 0: 0,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1,
+ )
+ ),
+ // scss-docs-end utils-opacity
+ // scss-docs-start utils-overflow
+ "overflow": (
+ property: overflow,
+ values: auto hidden visible scroll,
+ ),
+ "overflow-x": (
+ property: overflow-x,
+ values: auto hidden visible scroll,
+ ),
+ "overflow-y": (
+ property: overflow-y,
+ values: auto hidden visible scroll,
+ ),
+ // scss-docs-end utils-overflow
+ // scss-docs-start utils-display
+ "display": (
+ responsive: true,
+ print: true,
+ property: display,
+ class: d,
+ values: inline inline-block block grid inline-grid table table-row table-cell flex inline-flex none
+ ),
+ // scss-docs-end utils-display
+ // scss-docs-start utils-shadow
+ "shadow": (
+ property: box-shadow,
+ class: shadow,
+ values: (
+ null: var(--#{$prefix}box-shadow),
+ sm: var(--#{$prefix}box-shadow-sm),
+ lg: var(--#{$prefix}box-shadow-lg),
+ none: none,
+ )
+ ),
+ // scss-docs-end utils-shadow
+ // scss-docs-start utils-focus-ring
+ "focus-ring": (
+ css-var: true,
+ css-variable-name: focus-ring-color,
+ class: focus-ring,
+ values: map-loop($theme-colors-rgb, rgba-css-var, "$key", "focus-ring")
+ ),
+ // scss-docs-end utils-focus-ring
+ // scss-docs-start utils-position
+ "position": (
+ property: position,
+ values: static relative absolute fixed sticky
+ ),
+ "top": (
+ property: top,
+ values: $position-values
+ ),
+ "bottom": (
+ property: bottom,
+ values: $position-values
+ ),
+ "start": (
+ property: left,
+ class: start,
+ values: $position-values
+ ),
+ "end": (
+ property: right,
+ class: end,
+ values: $position-values
+ ),
+ "translate-middle": (
+ property: transform,
+ class: translate-middle,
+ values: (
+ null: translate(-50%, -50%),
+ x: translateX(-50%),
+ y: translateY(-50%),
+ )
+ ),
+ // scss-docs-end utils-position
+ // scss-docs-start utils-borders
+ "border": (
+ property: border,
+ values: (
+ null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
+ 0: 0,
+ )
+ ),
+ "border-top": (
+ property: border-top,
+ values: (
+ null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
+ 0: 0,
+ )
+ ),
+ "border-end": (
+ property: border-right,
+ class: border-end,
+ values: (
+ null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
+ 0: 0,
+ )
+ ),
+ "border-bottom": (
+ property: border-bottom,
+ values: (
+ null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
+ 0: 0,
+ )
+ ),
+ "border-start": (
+ property: border-left,
+ class: border-start,
+ values: (
+ null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
+ 0: 0,
+ )
+ ),
+ "border-color": (
+ property: border-color,
+ class: border,
+ local-vars: (
+ "border-opacity": 1
+ ),
+ values: $utilities-border-colors
+ ),
+ "subtle-border-color": (
+ property: border-color,
+ class: border,
+ values: $utilities-border-subtle
+ ),
+ "border-width": (
+ property: border-width,
+ class: border,
+ values: $border-widths
+ ),
+ "border-opacity": (
+ css-var: true,
+ class: border-opacity,
+ values: (
+ 10: .1,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1
+ )
+ ),
+ // scss-docs-end utils-borders
+ // Sizing utilities
+ // scss-docs-start utils-sizing
+ "width": (
+ property: width,
+ class: w,
+ values: (
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%,
+ auto: auto
+ )
+ ),
+ "max-width": (
+ property: max-width,
+ class: mw,
+ values: (100: 100%)
+ ),
+ "viewport-width": (
+ property: width,
+ class: vw,
+ values: (100: 100vw)
+ ),
+ "min-viewport-width": (
+ property: min-width,
+ class: min-vw,
+ values: (100: 100vw)
+ ),
+ "height": (
+ property: height,
+ class: h,
+ values: (
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%,
+ auto: auto
+ )
+ ),
+ "max-height": (
+ property: max-height,
+ class: mh,
+ values: (100: 100%)
+ ),
+ "viewport-height": (
+ property: height,
+ class: vh,
+ values: (100: 100vh)
+ ),
+ "min-viewport-height": (
+ property: min-height,
+ class: min-vh,
+ values: (100: 100vh)
+ ),
+ // scss-docs-end utils-sizing
+ // Flex utilities
+ // scss-docs-start utils-flex
+ "flex": (
+ responsive: true,
+ property: flex,
+ values: (fill: 1 1 auto)
+ ),
+ "flex-direction": (
+ responsive: true,
+ property: flex-direction,
+ class: flex,
+ values: row column row-reverse column-reverse
+ ),
+ "flex-grow": (
+ responsive: true,
+ property: flex-grow,
+ class: flex,
+ values: (
+ grow-0: 0,
+ grow-1: 1,
+ )
+ ),
+ "flex-shrink": (
+ responsive: true,
+ property: flex-shrink,
+ class: flex,
+ values: (
+ shrink-0: 0,
+ shrink-1: 1,
+ )
+ ),
+ "flex-wrap": (
+ responsive: true,
+ property: flex-wrap,
+ class: flex,
+ values: wrap nowrap wrap-reverse
+ ),
+ "justify-content": (
+ responsive: true,
+ property: justify-content,
+ values: (
+ start: flex-start,
+ end: flex-end,
+ center: center,
+ between: space-between,
+ around: space-around,
+ evenly: space-evenly,
+ )
+ ),
+ "align-items": (
+ responsive: true,
+ property: align-items,
+ values: (
+ start: flex-start,
+ end: flex-end,
+ center: center,
+ baseline: baseline,
+ stretch: stretch,
+ )
+ ),
+ "align-content": (
+ responsive: true,
+ property: align-content,
+ values: (
+ start: flex-start,
+ end: flex-end,
+ center: center,
+ between: space-between,
+ around: space-around,
+ stretch: stretch,
+ )
+ ),
+ "align-self": (
+ responsive: true,
+ property: align-self,
+ values: (
+ auto: auto,
+ start: flex-start,
+ end: flex-end,
+ center: center,
+ baseline: baseline,
+ stretch: stretch,
+ )
+ ),
+ "order": (
+ responsive: true,
+ property: order,
+ values: (
+ first: -1,
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ 3: 3,
+ 4: 4,
+ 5: 5,
+ last: 6,
+ ),
+ ),
+ // scss-docs-end utils-flex
+ // Margin utilities
+ // scss-docs-start utils-spacing
+ "margin": (
+ responsive: true,
+ property: margin,
+ class: m,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-x": (
+ responsive: true,
+ property: margin-right margin-left,
+ class: mx,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-y": (
+ responsive: true,
+ property: margin-top margin-bottom,
+ class: my,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-top": (
+ responsive: true,
+ property: margin-top,
+ class: mt,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-end": (
+ responsive: true,
+ property: margin-right,
+ class: me,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-bottom": (
+ responsive: true,
+ property: margin-bottom,
+ class: mb,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ "margin-start": (
+ responsive: true,
+ property: margin-left,
+ class: ms,
+ values: map-merge($spacers, (auto: auto))
+ ),
+ // Negative margin utilities
+ "negative-margin": (
+ responsive: true,
+ property: margin,
+ class: m,
+ values: $negative-spacers
+ ),
+ "negative-margin-x": (
+ responsive: true,
+ property: margin-right margin-left,
+ class: mx,
+ values: $negative-spacers
+ ),
+ "negative-margin-y": (
+ responsive: true,
+ property: margin-top margin-bottom,
+ class: my,
+ values: $negative-spacers
+ ),
+ "negative-margin-top": (
+ responsive: true,
+ property: margin-top,
+ class: mt,
+ values: $negative-spacers
+ ),
+ "negative-margin-end": (
+ responsive: true,
+ property: margin-right,
+ class: me,
+ values: $negative-spacers
+ ),
+ "negative-margin-bottom": (
+ responsive: true,
+ property: margin-bottom,
+ class: mb,
+ values: $negative-spacers
+ ),
+ "negative-margin-start": (
+ responsive: true,
+ property: margin-left,
+ class: ms,
+ values: $negative-spacers
+ ),
+ // Padding utilities
+ "padding": (
+ responsive: true,
+ property: padding,
+ class: p,
+ values: $spacers
+ ),
+ "padding-x": (
+ responsive: true,
+ property: padding-right padding-left,
+ class: px,
+ values: $spacers
+ ),
+ "padding-y": (
+ responsive: true,
+ property: padding-top padding-bottom,
+ class: py,
+ values: $spacers
+ ),
+ "padding-top": (
+ responsive: true,
+ property: padding-top,
+ class: pt,
+ values: $spacers
+ ),
+ "padding-end": (
+ responsive: true,
+ property: padding-right,
+ class: pe,
+ values: $spacers
+ ),
+ "padding-bottom": (
+ responsive: true,
+ property: padding-bottom,
+ class: pb,
+ values: $spacers
+ ),
+ "padding-start": (
+ responsive: true,
+ property: padding-left,
+ class: ps,
+ values: $spacers
+ ),
+ // Gap utility
+ "gap": (
+ responsive: true,
+ property: gap,
+ class: gap,
+ values: $spacers
+ ),
+ "row-gap": (
+ responsive: true,
+ property: row-gap,
+ class: row-gap,
+ values: $spacers
+ ),
+ "column-gap": (
+ responsive: true,
+ property: column-gap,
+ class: column-gap,
+ values: $spacers
+ ),
+ // scss-docs-end utils-spacing
+ // Text
+ // scss-docs-start utils-text
+ "font-family": (
+ property: font-family,
+ class: font,
+ values: (monospace: var(--#{$prefix}font-monospace))
+ ),
+ "font-size": (
+ rfs: true,
+ property: font-size,
+ class: fs,
+ values: $font-sizes
+ ),
+ "font-style": (
+ property: font-style,
+ class: fst,
+ values: italic normal
+ ),
+ "font-weight": (
+ property: font-weight,
+ class: fw,
+ values: (
+ lighter: $font-weight-lighter,
+ light: $font-weight-light,
+ normal: $font-weight-normal,
+ medium: $font-weight-medium,
+ semibold: $font-weight-semibold,
+ bold: $font-weight-bold,
+ bolder: $font-weight-bolder
+ )
+ ),
+ "line-height": (
+ property: line-height,
+ class: lh,
+ values: (
+ 1: 1,
+ sm: $line-height-sm,
+ base: $line-height-base,
+ lg: $line-height-lg,
+ )
+ ),
+ "text-align": (
+ responsive: true,
+ property: text-align,
+ class: text,
+ values: (
+ start: left,
+ end: right,
+ center: center,
+ )
+ ),
+ "text-decoration": (
+ property: text-decoration,
+ values: none underline line-through
+ ),
+ "text-transform": (
+ property: text-transform,
+ class: text,
+ values: lowercase uppercase capitalize
+ ),
+ "white-space": (
+ property: white-space,
+ class: text,
+ values: (
+ wrap: normal,
+ nowrap: nowrap,
+ )
+ ),
+ "word-wrap": (
+ property: word-wrap word-break,
+ class: text,
+ values: (break: break-word),
+ rtl: false
+ ),
+ // scss-docs-end utils-text
+ // scss-docs-start utils-color
+ "color": (
+ property: color,
+ class: text,
+ local-vars: (
+ "text-opacity": 1
+ ),
+ values: map-merge(
+ $utilities-text-colors,
+ (
+ "muted": var(--#{$prefix}secondary-color), // deprecated
+ "black-50": rgba($black, .5), // deprecated
+ "white-50": rgba($white, .5), // deprecated
+ "body-secondary": var(--#{$prefix}secondary-color),
+ "body-tertiary": var(--#{$prefix}tertiary-color),
+ "body-emphasis": var(--#{$prefix}emphasis-color),
+ "reset": inherit,
+ )
+ )
+ ),
+ "text-opacity": (
+ css-var: true,
+ class: text-opacity,
+ values: (
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1
+ )
+ ),
+ "text-color": (
+ property: color,
+ class: text,
+ values: $utilities-text-emphasis-colors
+ ),
+ // scss-docs-end utils-color
+ // scss-docs-start utils-links
+ "link-opacity": (
+ css-var: true,
+ class: link-opacity,
+ state: hover,
+ values: (
+ 10: .1,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1
+ )
+ ),
+ "link-offset": (
+ property: text-underline-offset,
+ class: link-offset,
+ state: hover,
+ values: (
+ 1: .125em,
+ 2: .25em,
+ 3: .375em,
+ )
+ ),
+ "link-underline": (
+ property: text-decoration-color,
+ class: link-underline,
+ local-vars: (
+ "link-underline-opacity": 1
+ ),
+ values: map-merge(
+ $utilities-links-underline,
+ (
+ null: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-underline-opacity, 1)),
+ )
+ )
+ ),
+ "link-underline-opacity": (
+ css-var: true,
+ class: link-underline-opacity,
+ state: hover,
+ values: (
+ 0: 0,
+ 10: .1,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1
+ ),
+ ),
+ // scss-docs-end utils-links
+ // scss-docs-start utils-bg-color
+ "background-color": (
+ property: background-color,
+ class: bg,
+ local-vars: (
+ "bg-opacity": 1
+ ),
+ values: map-merge(
+ $utilities-bg-colors,
+ (
+ "transparent": transparent,
+ "body-secondary": rgba(var(--#{$prefix}secondary-bg-rgb), var(--#{$prefix}bg-opacity)),
+ "body-tertiary": rgba(var(--#{$prefix}tertiary-bg-rgb), var(--#{$prefix}bg-opacity)),
+ )
+ )
+ ),
+ "bg-opacity": (
+ css-var: true,
+ class: bg-opacity,
+ values: (
+ 10: .1,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1
+ )
+ ),
+ "subtle-background-color": (
+ property: background-color,
+ class: bg,
+ values: $utilities-bg-subtle
+ ),
+ // scss-docs-end utils-bg-color
+ "gradient": (
+ property: background-image,
+ class: bg,
+ values: (gradient: var(--#{$prefix}gradient))
+ ),
+ // scss-docs-start utils-interaction
+ "user-select": (
+ property: user-select,
+ values: all auto none
+ ),
+ "pointer-events": (
+ property: pointer-events,
+ class: pe,
+ values: none auto,
+ ),
+ // scss-docs-end utils-interaction
+ // scss-docs-start utils-border-radius
+ "rounded": (
+ property: border-radius,
+ class: rounded,
+ values: (
+ null: var(--#{$prefix}border-radius),
+ 0: 0,
+ 1: var(--#{$prefix}border-radius-sm),
+ 2: var(--#{$prefix}border-radius),
+ 3: var(--#{$prefix}border-radius-lg),
+ 4: var(--#{$prefix}border-radius-xl),
+ 5: var(--#{$prefix}border-radius-xxl),
+ circle: 50%,
+ pill: var(--#{$prefix}border-radius-pill)
+ )
+ ),
+ "rounded-top": (
+ property: border-top-left-radius border-top-right-radius,
+ class: rounded-top,
+ values: (
+ null: var(--#{$prefix}border-radius),
+ 0: 0,
+ 1: var(--#{$prefix}border-radius-sm),
+ 2: var(--#{$prefix}border-radius),
+ 3: var(--#{$prefix}border-radius-lg),
+ 4: var(--#{$prefix}border-radius-xl),
+ 5: var(--#{$prefix}border-radius-xxl),
+ circle: 50%,
+ pill: var(--#{$prefix}border-radius-pill)
+ )
+ ),
+ "rounded-end": (
+ property: border-top-right-radius border-bottom-right-radius,
+ class: rounded-end,
+ values: (
+ null: var(--#{$prefix}border-radius),
+ 0: 0,
+ 1: var(--#{$prefix}border-radius-sm),
+ 2: var(--#{$prefix}border-radius),
+ 3: var(--#{$prefix}border-radius-lg),
+ 4: var(--#{$prefix}border-radius-xl),
+ 5: var(--#{$prefix}border-radius-xxl),
+ circle: 50%,
+ pill: var(--#{$prefix}border-radius-pill)
+ )
+ ),
+ "rounded-bottom": (
+ property: border-bottom-right-radius border-bottom-left-radius,
+ class: rounded-bottom,
+ values: (
+ null: var(--#{$prefix}border-radius),
+ 0: 0,
+ 1: var(--#{$prefix}border-radius-sm),
+ 2: var(--#{$prefix}border-radius),
+ 3: var(--#{$prefix}border-radius-lg),
+ 4: var(--#{$prefix}border-radius-xl),
+ 5: var(--#{$prefix}border-radius-xxl),
+ circle: 50%,
+ pill: var(--#{$prefix}border-radius-pill)
+ )
+ ),
+ "rounded-start": (
+ property: border-bottom-left-radius border-top-left-radius,
+ class: rounded-start,
+ values: (
+ null: var(--#{$prefix}border-radius),
+ 0: 0,
+ 1: var(--#{$prefix}border-radius-sm),
+ 2: var(--#{$prefix}border-radius),
+ 3: var(--#{$prefix}border-radius-lg),
+ 4: var(--#{$prefix}border-radius-xl),
+ 5: var(--#{$prefix}border-radius-xxl),
+ circle: 50%,
+ pill: var(--#{$prefix}border-radius-pill)
+ )
+ ),
+ // scss-docs-end utils-border-radius
+ // scss-docs-start utils-visibility
+ "visibility": (
+ property: visibility,
+ class: null,
+ values: (
+ visible: visible,
+ invisible: hidden,
+ )
+ ),
+ // scss-docs-end utils-visibility
+ // scss-docs-start utils-zindex
+ "z-index": (
+ property: z-index,
+ class: z,
+ values: $zindex-levels,
+ )
+ // scss-docs-end utils-zindex
+ ),
+ $utilities
+);
diff --git a/Moonlight/Styles/bootstrap/scss/_variables-dark.scss b/Moonlight/Styles/bootstrap/scss/_variables-dark.scss
new file mode 100644
index 00000000..6422b387
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_variables-dark.scss
@@ -0,0 +1,87 @@
+// Dark color mode variables
+//
+// Custom variables for the `[data-bs-theme="dark"]` theme. Use this as a starting point for your own custom color modes by creating a new theme-specific file like `_variables-dark.scss` and adding the variables you need.
+
+//
+// Global colors
+//
+
+// scss-docs-start sass-dark-mode-vars
+// scss-docs-start theme-text-dark-variables
+$primary-text-emphasis-dark: tint-color($primary, 40%) !default;
+$secondary-text-emphasis-dark: tint-color($secondary, 40%) !default;
+$success-text-emphasis-dark: tint-color($success, 40%) !default;
+$info-text-emphasis-dark: tint-color($info, 40%) !default;
+$warning-text-emphasis-dark: tint-color($warning, 40%) !default;
+$danger-text-emphasis-dark: tint-color($danger, 40%) !default;
+$light-text-emphasis-dark: $gray-100 !default;
+$dark-text-emphasis-dark: $gray-300 !default;
+// scss-docs-end theme-text-dark-variables
+
+// scss-docs-start theme-bg-subtle-dark-variables
+$primary-bg-subtle-dark: shade-color($primary, 80%) !default;
+$secondary-bg-subtle-dark: shade-color($secondary, 80%) !default;
+$success-bg-subtle-dark: shade-color($success, 80%) !default;
+$info-bg-subtle-dark: shade-color($info, 80%) !default;
+$warning-bg-subtle-dark: shade-color($warning, 80%) !default;
+$danger-bg-subtle-dark: shade-color($danger, 80%) !default;
+$light-bg-subtle-dark: $gray-800 !default;
+$dark-bg-subtle-dark: mix($gray-800, $black) !default;
+// scss-docs-end theme-bg-subtle-dark-variables
+
+// scss-docs-start theme-border-subtle-dark-variables
+$primary-border-subtle-dark: shade-color($primary, 40%) !default;
+$secondary-border-subtle-dark: shade-color($secondary, 40%) !default;
+$success-border-subtle-dark: shade-color($success, 40%) !default;
+$info-border-subtle-dark: shade-color($info, 40%) !default;
+$warning-border-subtle-dark: shade-color($warning, 40%) !default;
+$danger-border-subtle-dark: shade-color($danger, 40%) !default;
+$light-border-subtle-dark: $gray-700 !default;
+$dark-border-subtle-dark: $gray-800 !default;
+// scss-docs-end theme-border-subtle-dark-variables
+
+$body-color-dark: $gray-300 !default;
+$body-bg-dark: $gray-900 !default;
+$body-secondary-color-dark: rgba($body-color-dark, .75) !default;
+$body-secondary-bg-dark: $gray-800 !default;
+$body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
+$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%) !default;
+$body-emphasis-color-dark: $white !default;
+$border-color-dark: $gray-700 !default;
+$border-color-translucent-dark: rgba($white, .15) !default;
+$headings-color-dark: inherit !default;
+$link-color-dark: tint-color($primary, 40%) !default;
+$link-hover-color-dark: shift-color($link-color-dark, -$link-shade-percentage) !default;
+$code-color-dark: tint-color($code-color, 40%) !default;
+$mark-color-dark: $body-color-dark !default;
+$mark-bg-dark: $yellow-800 !default;
+
+
+//
+// Forms
+//
+
+$form-select-indicator-color-dark: $body-color-dark !default;
+$form-select-indicator-dark: url("data:image/svg+xml,
") !default;
+
+$form-switch-color-dark: rgba($white, .25) !default;
+$form-switch-bg-image-dark: url("data:image/svg+xml,
") !default;
+
+// scss-docs-start form-validation-colors-dark
+$form-valid-color-dark: $green-300 !default;
+$form-valid-border-color-dark: $green-300 !default;
+$form-invalid-color-dark: $red-300 !default;
+$form-invalid-border-color-dark: $red-300 !default;
+// scss-docs-end form-validation-colors-dark
+
+
+//
+// Accordion
+//
+
+$accordion-icon-color-dark: $primary-text-emphasis-dark !default;
+$accordion-icon-active-color-dark: $primary-text-emphasis-dark !default;
+
+$accordion-button-icon-dark: url("data:image/svg+xml,
") !default;
+$accordion-button-active-icon-dark: url("data:image/svg+xml,
") !default;
+// scss-docs-end sass-dark-mode-vars
diff --git a/Moonlight/Styles/bootstrap/scss/_variables.scss b/Moonlight/Styles/bootstrap/scss/_variables.scss
new file mode 100644
index 00000000..5429c017
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/_variables.scss
@@ -0,0 +1,1747 @@
+// Variables
+//
+// Variables should follow the `$component-state-property-size` formula for
+// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
+
+// Color system
+
+// scss-docs-start gray-color-variables
+$white: #fff !default;
+$gray-100: #f8f9fa !default;
+$gray-200: #e9ecef !default;
+$gray-300: #dee2e6 !default;
+$gray-400: #ced4da !default;
+$gray-500: #adb5bd !default;
+$gray-600: #6c757d !default;
+$gray-700: #495057 !default;
+$gray-800: #343a40 !default;
+$gray-900: #212529 !default;
+$black: #000 !default;
+// scss-docs-end gray-color-variables
+
+// fusv-disable
+// scss-docs-start gray-colors-map
+$grays: (
+ "100": $gray-100,
+ "200": $gray-200,
+ "300": $gray-300,
+ "400": $gray-400,
+ "500": $gray-500,
+ "600": $gray-600,
+ "700": $gray-700,
+ "800": $gray-800,
+ "900": $gray-900
+) !default;
+// scss-docs-end gray-colors-map
+// fusv-enable
+
+// scss-docs-start color-variables
+$blue: #0d6efd !default;
+$indigo: #6610f2 !default;
+$purple: #6f42c1 !default;
+$pink: #d63384 !default;
+$red: #dc3545 !default;
+$orange: #fd7e14 !default;
+$yellow: #ffc107 !default;
+$green: #198754 !default;
+$teal: #20c997 !default;
+$cyan: #0dcaf0 !default;
+// scss-docs-end color-variables
+
+// scss-docs-start colors-map
+$colors: (
+ "blue": $blue,
+ "indigo": $indigo,
+ "purple": $purple,
+ "pink": $pink,
+ "red": $red,
+ "orange": $orange,
+ "yellow": $yellow,
+ "green": $green,
+ "teal": $teal,
+ "cyan": $cyan,
+ "black": $black,
+ "white": $white,
+ "gray": $gray-600,
+ "gray-dark": $gray-800
+) !default;
+// scss-docs-end colors-map
+
+// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.
+// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
+$min-contrast-ratio: 4.5 !default;
+
+// Customize the light and dark text colors for use in our color contrast function.
+$color-contrast-dark: $black !default;
+$color-contrast-light: $white !default;
+
+// fusv-disable
+$blue-100: tint-color($blue, 80%) !default;
+$blue-200: tint-color($blue, 60%) !default;
+$blue-300: tint-color($blue, 40%) !default;
+$blue-400: tint-color($blue, 20%) !default;
+$blue-500: $blue !default;
+$blue-600: shade-color($blue, 20%) !default;
+$blue-700: shade-color($blue, 40%) !default;
+$blue-800: shade-color($blue, 60%) !default;
+$blue-900: shade-color($blue, 80%) !default;
+
+$indigo-100: tint-color($indigo, 80%) !default;
+$indigo-200: tint-color($indigo, 60%) !default;
+$indigo-300: tint-color($indigo, 40%) !default;
+$indigo-400: tint-color($indigo, 20%) !default;
+$indigo-500: $indigo !default;
+$indigo-600: shade-color($indigo, 20%) !default;
+$indigo-700: shade-color($indigo, 40%) !default;
+$indigo-800: shade-color($indigo, 60%) !default;
+$indigo-900: shade-color($indigo, 80%) !default;
+
+$purple-100: tint-color($purple, 80%) !default;
+$purple-200: tint-color($purple, 60%) !default;
+$purple-300: tint-color($purple, 40%) !default;
+$purple-400: tint-color($purple, 20%) !default;
+$purple-500: $purple !default;
+$purple-600: shade-color($purple, 20%) !default;
+$purple-700: shade-color($purple, 40%) !default;
+$purple-800: shade-color($purple, 60%) !default;
+$purple-900: shade-color($purple, 80%) !default;
+
+$pink-100: tint-color($pink, 80%) !default;
+$pink-200: tint-color($pink, 60%) !default;
+$pink-300: tint-color($pink, 40%) !default;
+$pink-400: tint-color($pink, 20%) !default;
+$pink-500: $pink !default;
+$pink-600: shade-color($pink, 20%) !default;
+$pink-700: shade-color($pink, 40%) !default;
+$pink-800: shade-color($pink, 60%) !default;
+$pink-900: shade-color($pink, 80%) !default;
+
+$red-100: tint-color($red, 80%) !default;
+$red-200: tint-color($red, 60%) !default;
+$red-300: tint-color($red, 40%) !default;
+$red-400: tint-color($red, 20%) !default;
+$red-500: $red !default;
+$red-600: shade-color($red, 20%) !default;
+$red-700: shade-color($red, 40%) !default;
+$red-800: shade-color($red, 60%) !default;
+$red-900: shade-color($red, 80%) !default;
+
+$orange-100: tint-color($orange, 80%) !default;
+$orange-200: tint-color($orange, 60%) !default;
+$orange-300: tint-color($orange, 40%) !default;
+$orange-400: tint-color($orange, 20%) !default;
+$orange-500: $orange !default;
+$orange-600: shade-color($orange, 20%) !default;
+$orange-700: shade-color($orange, 40%) !default;
+$orange-800: shade-color($orange, 60%) !default;
+$orange-900: shade-color($orange, 80%) !default;
+
+$yellow-100: tint-color($yellow, 80%) !default;
+$yellow-200: tint-color($yellow, 60%) !default;
+$yellow-300: tint-color($yellow, 40%) !default;
+$yellow-400: tint-color($yellow, 20%) !default;
+$yellow-500: $yellow !default;
+$yellow-600: shade-color($yellow, 20%) !default;
+$yellow-700: shade-color($yellow, 40%) !default;
+$yellow-800: shade-color($yellow, 60%) !default;
+$yellow-900: shade-color($yellow, 80%) !default;
+
+$green-100: tint-color($green, 80%) !default;
+$green-200: tint-color($green, 60%) !default;
+$green-300: tint-color($green, 40%) !default;
+$green-400: tint-color($green, 20%) !default;
+$green-500: $green !default;
+$green-600: shade-color($green, 20%) !default;
+$green-700: shade-color($green, 40%) !default;
+$green-800: shade-color($green, 60%) !default;
+$green-900: shade-color($green, 80%) !default;
+
+$teal-100: tint-color($teal, 80%) !default;
+$teal-200: tint-color($teal, 60%) !default;
+$teal-300: tint-color($teal, 40%) !default;
+$teal-400: tint-color($teal, 20%) !default;
+$teal-500: $teal !default;
+$teal-600: shade-color($teal, 20%) !default;
+$teal-700: shade-color($teal, 40%) !default;
+$teal-800: shade-color($teal, 60%) !default;
+$teal-900: shade-color($teal, 80%) !default;
+
+$cyan-100: tint-color($cyan, 80%) !default;
+$cyan-200: tint-color($cyan, 60%) !default;
+$cyan-300: tint-color($cyan, 40%) !default;
+$cyan-400: tint-color($cyan, 20%) !default;
+$cyan-500: $cyan !default;
+$cyan-600: shade-color($cyan, 20%) !default;
+$cyan-700: shade-color($cyan, 40%) !default;
+$cyan-800: shade-color($cyan, 60%) !default;
+$cyan-900: shade-color($cyan, 80%) !default;
+
+$blues: (
+ "blue-100": $blue-100,
+ "blue-200": $blue-200,
+ "blue-300": $blue-300,
+ "blue-400": $blue-400,
+ "blue-500": $blue-500,
+ "blue-600": $blue-600,
+ "blue-700": $blue-700,
+ "blue-800": $blue-800,
+ "blue-900": $blue-900
+) !default;
+
+$indigos: (
+ "indigo-100": $indigo-100,
+ "indigo-200": $indigo-200,
+ "indigo-300": $indigo-300,
+ "indigo-400": $indigo-400,
+ "indigo-500": $indigo-500,
+ "indigo-600": $indigo-600,
+ "indigo-700": $indigo-700,
+ "indigo-800": $indigo-800,
+ "indigo-900": $indigo-900
+) !default;
+
+$purples: (
+ "purple-100": $purple-100,
+ "purple-200": $purple-200,
+ "purple-300": $purple-300,
+ "purple-400": $purple-400,
+ "purple-500": $purple-500,
+ "purple-600": $purple-600,
+ "purple-700": $purple-700,
+ "purple-800": $purple-800,
+ "purple-900": $purple-900
+) !default;
+
+$pinks: (
+ "pink-100": $pink-100,
+ "pink-200": $pink-200,
+ "pink-300": $pink-300,
+ "pink-400": $pink-400,
+ "pink-500": $pink-500,
+ "pink-600": $pink-600,
+ "pink-700": $pink-700,
+ "pink-800": $pink-800,
+ "pink-900": $pink-900
+) !default;
+
+$reds: (
+ "red-100": $red-100,
+ "red-200": $red-200,
+ "red-300": $red-300,
+ "red-400": $red-400,
+ "red-500": $red-500,
+ "red-600": $red-600,
+ "red-700": $red-700,
+ "red-800": $red-800,
+ "red-900": $red-900
+) !default;
+
+$oranges: (
+ "orange-100": $orange-100,
+ "orange-200": $orange-200,
+ "orange-300": $orange-300,
+ "orange-400": $orange-400,
+ "orange-500": $orange-500,
+ "orange-600": $orange-600,
+ "orange-700": $orange-700,
+ "orange-800": $orange-800,
+ "orange-900": $orange-900
+) !default;
+
+$yellows: (
+ "yellow-100": $yellow-100,
+ "yellow-200": $yellow-200,
+ "yellow-300": $yellow-300,
+ "yellow-400": $yellow-400,
+ "yellow-500": $yellow-500,
+ "yellow-600": $yellow-600,
+ "yellow-700": $yellow-700,
+ "yellow-800": $yellow-800,
+ "yellow-900": $yellow-900
+) !default;
+
+$greens: (
+ "green-100": $green-100,
+ "green-200": $green-200,
+ "green-300": $green-300,
+ "green-400": $green-400,
+ "green-500": $green-500,
+ "green-600": $green-600,
+ "green-700": $green-700,
+ "green-800": $green-800,
+ "green-900": $green-900
+) !default;
+
+$teals: (
+ "teal-100": $teal-100,
+ "teal-200": $teal-200,
+ "teal-300": $teal-300,
+ "teal-400": $teal-400,
+ "teal-500": $teal-500,
+ "teal-600": $teal-600,
+ "teal-700": $teal-700,
+ "teal-800": $teal-800,
+ "teal-900": $teal-900
+) !default;
+
+$cyans: (
+ "cyan-100": $cyan-100,
+ "cyan-200": $cyan-200,
+ "cyan-300": $cyan-300,
+ "cyan-400": $cyan-400,
+ "cyan-500": $cyan-500,
+ "cyan-600": $cyan-600,
+ "cyan-700": $cyan-700,
+ "cyan-800": $cyan-800,
+ "cyan-900": $cyan-900
+) !default;
+// fusv-enable
+
+// scss-docs-start theme-color-variables
+$primary: $blue !default;
+$secondary: $gray-600 !default;
+$success: $green !default;
+$info: $cyan !default;
+$warning: $yellow !default;
+$danger: $red !default;
+$light: $gray-100 !default;
+$dark: $gray-900 !default;
+// scss-docs-end theme-color-variables
+
+// scss-docs-start theme-colors-map
+$theme-colors: (
+ "primary": $primary,
+ "secondary": $secondary,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "light": $light,
+ "dark": $dark
+) !default;
+// scss-docs-end theme-colors-map
+
+// scss-docs-start theme-text-variables
+$primary-text-emphasis: shade-color($primary, 60%) !default;
+$secondary-text-emphasis: shade-color($secondary, 60%) !default;
+$success-text-emphasis: shade-color($success, 60%) !default;
+$info-text-emphasis: shade-color($info, 60%) !default;
+$warning-text-emphasis: shade-color($warning, 60%) !default;
+$danger-text-emphasis: shade-color($danger, 60%) !default;
+$light-text-emphasis: $gray-700 !default;
+$dark-text-emphasis: $gray-700 !default;
+// scss-docs-end theme-text-variables
+
+// scss-docs-start theme-bg-subtle-variables
+$primary-bg-subtle: tint-color($primary, 80%) !default;
+$secondary-bg-subtle: tint-color($secondary, 80%) !default;
+$success-bg-subtle: tint-color($success, 80%) !default;
+$info-bg-subtle: tint-color($info, 80%) !default;
+$warning-bg-subtle: tint-color($warning, 80%) !default;
+$danger-bg-subtle: tint-color($danger, 80%) !default;
+$light-bg-subtle: mix($gray-100, $white) !default;
+$dark-bg-subtle: $gray-400 !default;
+// scss-docs-end theme-bg-subtle-variables
+
+// scss-docs-start theme-border-subtle-variables
+$primary-border-subtle: tint-color($primary, 60%) !default;
+$secondary-border-subtle: tint-color($secondary, 60%) !default;
+$success-border-subtle: tint-color($success, 60%) !default;
+$info-border-subtle: tint-color($info, 60%) !default;
+$warning-border-subtle: tint-color($warning, 60%) !default;
+$danger-border-subtle: tint-color($danger, 60%) !default;
+$light-border-subtle: $gray-200 !default;
+$dark-border-subtle: $gray-500 !default;
+// scss-docs-end theme-border-subtle-variables
+
+// Characters which are escaped by the escape-svg function
+$escaped-characters: (
+ ("<", "%3c"),
+ (">", "%3e"),
+ ("#", "%23"),
+ ("(", "%28"),
+ (")", "%29"),
+) !default;
+
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
+
+$enable-caret: true !default;
+$enable-rounded: true !default;
+$enable-shadows: false !default;
+$enable-gradients: false !default;
+$enable-transitions: true !default;
+$enable-reduced-motion: true !default;
+$enable-smooth-scroll: true !default;
+$enable-grid-classes: true !default;
+$enable-container-classes: true !default;
+$enable-cssgrid: false !default;
+$enable-button-pointers: true !default;
+$enable-rfs: true !default;
+$enable-validation-icons: true !default;
+$enable-negative-margins: false !default;
+$enable-deprecation-messages: true !default;
+$enable-important-utilities: true !default;
+
+$enable-dark-mode: true !default;
+$color-mode-type: data !default; // `data` or `media-query`
+
+// Prefix for :root CSS variables
+
+$variable-prefix: bs- !default; // Deprecated in v5.2.0 for the shorter `$prefix`
+$prefix: $variable-prefix !default;
+
+// Gradient
+//
+// The gradient which is added to components if `$enable-gradients` is `true`
+// This gradient is also added to elements with `.bg-gradient`
+// scss-docs-start variable-gradient
+$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;
+// scss-docs-end variable-gradient
+
+// Spacing
+//
+// Control the default styling of most Bootstrap elements by modifying these
+// variables. Mostly focused on spacing.
+// You can add more entries to the $spacers map, should you need more variation.
+
+// scss-docs-start spacer-variables-maps
+$spacer: 1rem !default;
+$spacers: (
+ 0: 0,
+ 1: $spacer * .25,
+ 2: $spacer * .5,
+ 3: $spacer,
+ 4: $spacer * 1.5,
+ 5: $spacer * 3,
+) !default;
+// scss-docs-end spacer-variables-maps
+
+// Position
+//
+// Define the edge positioning anchors of the position utilities.
+
+// scss-docs-start position-map
+$position-values: (
+ 0: 0,
+ 50: 50%,
+ 100: 100%
+) !default;
+// scss-docs-end position-map
+
+// Body
+//
+// Settings for the `` element.
+
+$body-text-align: null !default;
+$body-color: $gray-900 !default;
+$body-bg: $white !default;
+
+$body-secondary-color: rgba($body-color, .75) !default;
+$body-secondary-bg: $gray-200 !default;
+
+$body-tertiary-color: rgba($body-color, .5) !default;
+$body-tertiary-bg: $gray-100 !default;
+
+$body-emphasis-color: $black !default;
+
+// Links
+//
+// Style anchor elements.
+
+$link-color: $primary !default;
+$link-decoration: underline !default;
+$link-shade-percentage: 20% !default;
+$link-hover-color: shift-color($link-color, $link-shade-percentage) !default;
+$link-hover-decoration: null !default;
+
+$stretched-link-pseudo-element: after !default;
+$stretched-link-z-index: 1 !default;
+
+// Icon links
+// scss-docs-start icon-link-variables
+$icon-link-gap: .375rem !default;
+$icon-link-underline-offset: .25em !default;
+$icon-link-icon-size: 1em !default;
+$icon-link-icon-transition: .2s ease-in-out transform !default;
+$icon-link-icon-transform: translate3d(.25em, 0, 0) !default;
+// scss-docs-end icon-link-variables
+
+// Paragraphs
+//
+// Style p element.
+
+$paragraph-margin-bottom: 1rem !default;
+
+
+// Grid breakpoints
+//
+// Define the minimum dimensions at which your layout will change,
+// adapting to different screen sizes, for use in media queries.
+
+// scss-docs-start grid-breakpoints
+$grid-breakpoints: (
+ xs: 0,
+ sm: 576px,
+ md: 768px,
+ lg: 992px,
+ xl: 1200px,
+ xxl: 1400px
+) !default;
+// scss-docs-end grid-breakpoints
+
+@include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
+@include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints");
+
+
+// Grid containers
+//
+// Define the maximum width of `.container` for different screen sizes.
+
+// scss-docs-start container-max-widths
+$container-max-widths: (
+ sm: 540px,
+ md: 720px,
+ lg: 960px,
+ xl: 1140px,
+ xxl: 1320px
+) !default;
+// scss-docs-end container-max-widths
+
+@include _assert-ascending($container-max-widths, "$container-max-widths");
+
+
+// Grid columns
+//
+// Set the number of columns and specify the width of the gutters.
+
+$grid-columns: 12 !default;
+$grid-gutter-width: 1.5rem !default;
+$grid-row-columns: 6 !default;
+
+// Container padding
+
+$container-padding-x: $grid-gutter-width !default;
+
+
+// Components
+//
+// Define common padding and border radius sizes and more.
+
+// scss-docs-start border-variables
+$border-width: 1px !default;
+$border-widths: (
+ 1: 1px,
+ 2: 2px,
+ 3: 3px,
+ 4: 4px,
+ 5: 5px
+) !default;
+$border-style: solid !default;
+$border-color: $gray-300 !default;
+$border-color-translucent: rgba($black, .175) !default;
+// scss-docs-end border-variables
+
+// scss-docs-start border-radius-variables
+$border-radius: .375rem !default;
+$border-radius-sm: .25rem !default;
+$border-radius-lg: .5rem !default;
+$border-radius-xl: 1rem !default;
+$border-radius-xxl: 2rem !default;
+$border-radius-pill: 50rem !default;
+// scss-docs-end border-radius-variables
+// fusv-disable
+$border-radius-2xl: $border-radius-xxl !default; // Deprecated in v5.3.0
+// fusv-enable
+
+// scss-docs-start box-shadow-variables
+$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;
+$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;
+$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;
+$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default;
+// scss-docs-end box-shadow-variables
+
+$component-active-color: $white !default;
+$component-active-bg: $primary !default;
+
+// scss-docs-start focus-ring-variables
+$focus-ring-width: .25rem !default;
+$focus-ring-opacity: .25 !default;
+$focus-ring-color: rgba($primary, $focus-ring-opacity) !default;
+$focus-ring-blur: 0 !default;
+$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;
+// scss-docs-end focus-ring-variables
+
+// scss-docs-start caret-variables
+$caret-width: .3em !default;
+$caret-vertical-align: $caret-width * .85 !default;
+$caret-spacing: $caret-width * .85 !default;
+// scss-docs-end caret-variables
+
+$transition-base: all .2s ease-in-out !default;
+$transition-fade: opacity .15s linear !default;
+// scss-docs-start collapse-transition
+$transition-collapse: height .35s ease !default;
+$transition-collapse-width: width .35s ease !default;
+// scss-docs-end collapse-transition
+
+// stylelint-disable function-disallowed-list
+// scss-docs-start aspect-ratios
+$aspect-ratios: (
+ "1x1": 100%,
+ "4x3": calc(3 / 4 * 100%),
+ "16x9": calc(9 / 16 * 100%),
+ "21x9": calc(9 / 21 * 100%)
+) !default;
+// scss-docs-end aspect-ratios
+// stylelint-enable function-disallowed-list
+
+// Typography
+//
+// Font, line-height, and color for body text, headings, and more.
+
+// scss-docs-start font-variables
+// stylelint-disable value-keyword-case
+$font-family-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
+$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
+// stylelint-enable value-keyword-case
+$font-family-base: var(--#{$prefix}font-sans-serif) !default;
+$font-family-code: var(--#{$prefix}font-monospace) !default;
+
+// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins
+// $font-size-base affects the font size of the body text
+$font-size-root: null !default;
+$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`
+$font-size-sm: $font-size-base * .875 !default;
+$font-size-lg: $font-size-base * 1.25 !default;
+
+$font-weight-lighter: lighter !default;
+$font-weight-light: 300 !default;
+$font-weight-normal: 400 !default;
+$font-weight-medium: 500 !default;
+$font-weight-semibold: 600 !default;
+$font-weight-bold: 700 !default;
+$font-weight-bolder: bolder !default;
+
+$font-weight-base: $font-weight-normal !default;
+
+$line-height-base: 1.5 !default;
+$line-height-sm: 1.25 !default;
+$line-height-lg: 2 !default;
+
+$h1-font-size: $font-size-base * 2.5 !default;
+$h2-font-size: $font-size-base * 2 !default;
+$h3-font-size: $font-size-base * 1.75 !default;
+$h4-font-size: $font-size-base * 1.5 !default;
+$h5-font-size: $font-size-base * 1.25 !default;
+$h6-font-size: $font-size-base !default;
+// scss-docs-end font-variables
+
+// scss-docs-start font-sizes
+$font-sizes: (
+ 1: $h1-font-size,
+ 2: $h2-font-size,
+ 3: $h3-font-size,
+ 4: $h4-font-size,
+ 5: $h5-font-size,
+ 6: $h6-font-size
+) !default;
+// scss-docs-end font-sizes
+
+// scss-docs-start headings-variables
+$headings-margin-bottom: $spacer * .5 !default;
+$headings-font-family: null !default;
+$headings-font-style: null !default;
+$headings-font-weight: 500 !default;
+$headings-line-height: 1.2 !default;
+$headings-color: inherit !default;
+// scss-docs-end headings-variables
+
+// scss-docs-start display-headings
+$display-font-sizes: (
+ 1: 5rem,
+ 2: 4.5rem,
+ 3: 4rem,
+ 4: 3.5rem,
+ 5: 3rem,
+ 6: 2.5rem
+) !default;
+
+$display-font-family: null !default;
+$display-font-style: null !default;
+$display-font-weight: 300 !default;
+$display-line-height: $headings-line-height !default;
+// scss-docs-end display-headings
+
+// scss-docs-start type-variables
+$lead-font-size: $font-size-base * 1.25 !default;
+$lead-font-weight: 300 !default;
+
+$small-font-size: .875em !default;
+
+$sub-sup-font-size: .75em !default;
+
+// fusv-disable
+$text-muted: var(--#{$prefix}secondary-color) !default; // Deprecated in 5.3.0
+// fusv-enable
+
+$initialism-font-size: $small-font-size !default;
+
+$blockquote-margin-y: $spacer !default;
+$blockquote-font-size: $font-size-base * 1.25 !default;
+$blockquote-footer-color: $gray-600 !default;
+$blockquote-footer-font-size: $small-font-size !default;
+
+$hr-margin-y: $spacer !default;
+$hr-color: inherit !default;
+
+// fusv-disable
+$hr-bg-color: null !default; // Deprecated in v5.2.0
+$hr-height: null !default; // Deprecated in v5.2.0
+// fusv-enable
+
+$hr-border-color: null !default; // Allows for inherited colors
+$hr-border-width: var(--#{$prefix}border-width) !default;
+$hr-opacity: .25 !default;
+
+// scss-docs-start vr-variables
+$vr-border-width: var(--#{$prefix}border-width) !default;
+// scss-docs-end vr-variables
+
+$legend-margin-bottom: .5rem !default;
+$legend-font-size: 1.5rem !default;
+$legend-font-weight: null !default;
+
+$dt-font-weight: $font-weight-bold !default;
+
+$list-inline-padding: .5rem !default;
+
+$mark-padding: .1875em !default;
+$mark-color: $body-color !default;
+$mark-bg: $yellow-100 !default;
+// scss-docs-end type-variables
+
+
+// Tables
+//
+// Customizes the `.table` component with basic values, each used across all table variations.
+
+// scss-docs-start table-variables
+$table-cell-padding-y: .5rem !default;
+$table-cell-padding-x: .5rem !default;
+$table-cell-padding-y-sm: .25rem !default;
+$table-cell-padding-x-sm: .25rem !default;
+
+$table-cell-vertical-align: top !default;
+
+$table-color: var(--#{$prefix}emphasis-color) !default;
+$table-bg: var(--#{$prefix}body-bg) !default;
+$table-accent-bg: transparent !default;
+
+$table-th-font-weight: null !default;
+
+$table-striped-color: $table-color !default;
+$table-striped-bg-factor: .05 !default;
+$table-striped-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-striped-bg-factor) !default;
+
+$table-active-color: $table-color !default;
+$table-active-bg-factor: .1 !default;
+$table-active-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-active-bg-factor) !default;
+
+$table-hover-color: $table-color !default;
+$table-hover-bg-factor: .075 !default;
+$table-hover-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-hover-bg-factor) !default;
+
+$table-border-factor: .2 !default;
+$table-border-width: var(--#{$prefix}border-width) !default;
+$table-border-color: var(--#{$prefix}border-color) !default;
+
+$table-striped-order: odd !default;
+$table-striped-columns-order: even !default;
+
+$table-group-separator-color: currentcolor !default;
+
+$table-caption-color: var(--#{$prefix}secondary-color) !default;
+
+$table-bg-scale: -80% !default;
+// scss-docs-end table-variables
+
+// scss-docs-start table-loop
+$table-variants: (
+ "primary": shift-color($primary, $table-bg-scale),
+ "secondary": shift-color($secondary, $table-bg-scale),
+ "success": shift-color($success, $table-bg-scale),
+ "info": shift-color($info, $table-bg-scale),
+ "warning": shift-color($warning, $table-bg-scale),
+ "danger": shift-color($danger, $table-bg-scale),
+ "light": $light,
+ "dark": $dark,
+) !default;
+// scss-docs-end table-loop
+
+
+// Buttons + Forms
+//
+// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.
+
+// scss-docs-start input-btn-variables
+$input-btn-padding-y: .375rem !default;
+$input-btn-padding-x: .75rem !default;
+$input-btn-font-family: null !default;
+$input-btn-font-size: $font-size-base !default;
+$input-btn-line-height: $line-height-base !default;
+
+$input-btn-focus-width: $focus-ring-width !default;
+$input-btn-focus-color-opacity: $focus-ring-opacity !default;
+$input-btn-focus-color: $focus-ring-color !default;
+$input-btn-focus-blur: $focus-ring-blur !default;
+$input-btn-focus-box-shadow: $focus-ring-box-shadow !default;
+
+$input-btn-padding-y-sm: .25rem !default;
+$input-btn-padding-x-sm: .5rem !default;
+$input-btn-font-size-sm: $font-size-sm !default;
+
+$input-btn-padding-y-lg: .5rem !default;
+$input-btn-padding-x-lg: 1rem !default;
+$input-btn-font-size-lg: $font-size-lg !default;
+
+$input-btn-border-width: var(--#{$prefix}border-width) !default;
+// scss-docs-end input-btn-variables
+
+
+// Buttons
+//
+// For each of Bootstrap's buttons, define text, background, and border color.
+
+// scss-docs-start btn-variables
+$btn-color: var(--#{$prefix}body-color) !default;
+$btn-padding-y: $input-btn-padding-y !default;
+$btn-padding-x: $input-btn-padding-x !default;
+$btn-font-family: $input-btn-font-family !default;
+$btn-font-size: $input-btn-font-size !default;
+$btn-line-height: $input-btn-line-height !default;
+$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping
+
+$btn-padding-y-sm: $input-btn-padding-y-sm !default;
+$btn-padding-x-sm: $input-btn-padding-x-sm !default;
+$btn-font-size-sm: $input-btn-font-size-sm !default;
+
+$btn-padding-y-lg: $input-btn-padding-y-lg !default;
+$btn-padding-x-lg: $input-btn-padding-x-lg !default;
+$btn-font-size-lg: $input-btn-font-size-lg !default;
+
+$btn-border-width: $input-btn-border-width !default;
+
+$btn-font-weight: $font-weight-normal !default;
+$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;
+$btn-focus-width: $input-btn-focus-width !default;
+$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;
+$btn-disabled-opacity: .65 !default;
+$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;
+
+$btn-link-color: var(--#{$prefix}link-color) !default;
+$btn-link-hover-color: var(--#{$prefix}link-hover-color) !default;
+$btn-link-disabled-color: $gray-600 !default;
+$btn-link-focus-shadow-rgb: to-rgb(mix(color-contrast($link-color), $link-color, 15%)) !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius: var(--#{$prefix}border-radius) !default;
+$btn-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;
+$btn-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;
+
+$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+
+$btn-hover-bg-shade-amount: 15% !default;
+$btn-hover-bg-tint-amount: 15% !default;
+$btn-hover-border-shade-amount: 20% !default;
+$btn-hover-border-tint-amount: 10% !default;
+$btn-active-bg-shade-amount: 20% !default;
+$btn-active-bg-tint-amount: 20% !default;
+$btn-active-border-shade-amount: 25% !default;
+$btn-active-border-tint-amount: 10% !default;
+// scss-docs-end btn-variables
+
+
+// Forms
+
+// scss-docs-start form-text-variables
+$form-text-margin-top: .25rem !default;
+$form-text-font-size: $small-font-size !default;
+$form-text-font-style: null !default;
+$form-text-font-weight: null !default;
+$form-text-color: var(--#{$prefix}secondary-color) !default;
+// scss-docs-end form-text-variables
+
+// scss-docs-start form-label-variables
+$form-label-margin-bottom: .5rem !default;
+$form-label-font-size: null !default;
+$form-label-font-style: null !default;
+$form-label-font-weight: null !default;
+$form-label-color: null !default;
+// scss-docs-end form-label-variables
+
+// scss-docs-start form-input-variables
+$input-padding-y: $input-btn-padding-y !default;
+$input-padding-x: $input-btn-padding-x !default;
+$input-font-family: $input-btn-font-family !default;
+$input-font-size: $input-btn-font-size !default;
+$input-font-weight: $font-weight-base !default;
+$input-line-height: $input-btn-line-height !default;
+
+$input-padding-y-sm: $input-btn-padding-y-sm !default;
+$input-padding-x-sm: $input-btn-padding-x-sm !default;
+$input-font-size-sm: $input-btn-font-size-sm !default;
+
+$input-padding-y-lg: $input-btn-padding-y-lg !default;
+$input-padding-x-lg: $input-btn-padding-x-lg !default;
+$input-font-size-lg: $input-btn-font-size-lg !default;
+
+$input-bg: var(--#{$prefix}body-bg) !default;
+$input-disabled-color: null !default;
+$input-disabled-bg: var(--#{$prefix}secondary-bg) !default;
+$input-disabled-border-color: null !default;
+
+$input-color: var(--#{$prefix}body-color) !default;
+$input-border-color: var(--#{$prefix}border-color) !default;
+$input-border-width: $input-btn-border-width !default;
+$input-box-shadow: var(--#{$prefix}box-shadow-inset) !default;
+
+$input-border-radius: var(--#{$prefix}border-radius) !default;
+$input-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;
+$input-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;
+
+$input-focus-bg: $input-bg !default;
+$input-focus-border-color: tint-color($component-active-bg, 50%) !default;
+$input-focus-color: $input-color !default;
+$input-focus-width: $input-btn-focus-width !default;
+$input-focus-box-shadow: $input-btn-focus-box-shadow !default;
+
+$input-placeholder-color: var(--#{$prefix}secondary-color) !default;
+$input-plaintext-color: var(--#{$prefix}body-color) !default;
+
+$input-height-border: calc(#{$input-border-width} * 2) !default; // stylelint-disable-line function-disallowed-list
+
+$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;
+$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;
+$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default;
+
+$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;
+$input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;
+$input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;
+
+$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+
+$form-color-width: 3rem !default;
+// scss-docs-end form-input-variables
+
+// scss-docs-start form-check-variables
+$form-check-input-width: 1em !default;
+$form-check-min-height: $font-size-base * $line-height-base !default;
+$form-check-padding-start: $form-check-input-width + .5em !default;
+$form-check-margin-bottom: .125rem !default;
+$form-check-label-color: null !default;
+$form-check-label-cursor: null !default;
+$form-check-transition: null !default;
+
+$form-check-input-active-filter: brightness(90%) !default;
+
+$form-check-input-bg: $input-bg !default;
+$form-check-input-border: var(--#{$prefix}border-width) solid var(--#{$prefix}border-color) !default;
+$form-check-input-border-radius: .25em !default;
+$form-check-radio-border-radius: 50% !default;
+$form-check-input-focus-border: $input-focus-border-color !default;
+$form-check-input-focus-box-shadow: $focus-ring-box-shadow !default;
+
+$form-check-input-checked-color: $component-active-color !default;
+$form-check-input-checked-bg-color: $component-active-bg !default;
+$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default;
+$form-check-input-checked-bg-image: url("data:image/svg+xml,
") !default;
+$form-check-radio-checked-bg-image: url("data:image/svg+xml,
") !default;
+
+$form-check-input-indeterminate-color: $component-active-color !default;
+$form-check-input-indeterminate-bg-color: $component-active-bg !default;
+$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default;
+$form-check-input-indeterminate-bg-image: url("data:image/svg+xml,
") !default;
+
+$form-check-input-disabled-opacity: .5 !default;
+$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default;
+$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default;
+
+$form-check-inline-margin-end: 1rem !default;
+// scss-docs-end form-check-variables
+
+// scss-docs-start form-switch-variables
+$form-switch-color: rgba($black, .25) !default;
+$form-switch-width: 2em !default;
+$form-switch-padding-start: $form-switch-width + .5em !default;
+$form-switch-bg-image: url("data:image/svg+xml,
") !default;
+$form-switch-border-radius: $form-switch-width !default;
+$form-switch-transition: background-position .15s ease-in-out !default;
+
+$form-switch-focus-color: $input-focus-border-color !default;
+$form-switch-focus-bg-image: url("data:image/svg+xml,
") !default;
+
+$form-switch-checked-color: $component-active-color !default;
+$form-switch-checked-bg-image: url("data:image/svg+xml,
") !default;
+$form-switch-checked-bg-position: right center !default;
+// scss-docs-end form-switch-variables
+
+// scss-docs-start input-group-variables
+$input-group-addon-padding-y: $input-padding-y !default;
+$input-group-addon-padding-x: $input-padding-x !default;
+$input-group-addon-font-weight: $input-font-weight !default;
+$input-group-addon-color: $input-color !default;
+$input-group-addon-bg: var(--#{$prefix}tertiary-bg) !default;
+$input-group-addon-border-color: $input-border-color !default;
+// scss-docs-end input-group-variables
+
+// scss-docs-start form-select-variables
+$form-select-padding-y: $input-padding-y !default;
+$form-select-padding-x: $input-padding-x !default;
+$form-select-font-family: $input-font-family !default;
+$form-select-font-size: $input-font-size !default;
+$form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image
+$form-select-font-weight: $input-font-weight !default;
+$form-select-line-height: $input-line-height !default;
+$form-select-color: $input-color !default;
+$form-select-bg: $input-bg !default;
+$form-select-disabled-color: null !default;
+$form-select-disabled-bg: $input-disabled-bg !default;
+$form-select-disabled-border-color: $input-disabled-border-color !default;
+$form-select-bg-position: right $form-select-padding-x center !default;
+$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions
+$form-select-indicator-color: $gray-800 !default;
+$form-select-indicator: url("data:image/svg+xml,
") !default;
+
+$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;
+$form-select-feedback-icon-position: center right $form-select-indicator-padding !default;
+$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;
+
+$form-select-border-width: $input-border-width !default;
+$form-select-border-color: $input-border-color !default;
+$form-select-border-radius: $input-border-radius !default;
+$form-select-box-shadow: var(--#{$prefix}box-shadow-inset) !default;
+
+$form-select-focus-border-color: $input-focus-border-color !default;
+$form-select-focus-width: $input-focus-width !default;
+$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;
+
+$form-select-padding-y-sm: $input-padding-y-sm !default;
+$form-select-padding-x-sm: $input-padding-x-sm !default;
+$form-select-font-size-sm: $input-font-size-sm !default;
+$form-select-border-radius-sm: $input-border-radius-sm !default;
+
+$form-select-padding-y-lg: $input-padding-y-lg !default;
+$form-select-padding-x-lg: $input-padding-x-lg !default;
+$form-select-font-size-lg: $input-font-size-lg !default;
+$form-select-border-radius-lg: $input-border-radius-lg !default;
+
+$form-select-transition: $input-transition !default;
+// scss-docs-end form-select-variables
+
+// scss-docs-start form-range-variables
+$form-range-track-width: 100% !default;
+$form-range-track-height: .5rem !default;
+$form-range-track-cursor: pointer !default;
+$form-range-track-bg: var(--#{$prefix}secondary-bg) !default;
+$form-range-track-border-radius: 1rem !default;
+$form-range-track-box-shadow: var(--#{$prefix}box-shadow-inset) !default;
+
+$form-range-thumb-width: 1rem !default;
+$form-range-thumb-height: $form-range-thumb-width !default;
+$form-range-thumb-bg: $component-active-bg !default;
+$form-range-thumb-border: 0 !default;
+$form-range-thumb-border-radius: 1rem !default;
+$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;
+$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;
+$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge
+$form-range-thumb-active-bg: tint-color($component-active-bg, 70%) !default;
+$form-range-thumb-disabled-bg: var(--#{$prefix}secondary-color) !default;
+$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+// scss-docs-end form-range-variables
+
+// scss-docs-start form-file-variables
+$form-file-button-color: $input-color !default;
+$form-file-button-bg: var(--#{$prefix}tertiary-bg) !default;
+$form-file-button-hover-bg: var(--#{$prefix}secondary-bg) !default;
+// scss-docs-end form-file-variables
+
+// scss-docs-start form-floating-variables
+$form-floating-height: add(3.5rem, $input-height-border) !default;
+$form-floating-line-height: 1.25 !default;
+$form-floating-padding-x: $input-padding-x !default;
+$form-floating-padding-y: 1rem !default;
+$form-floating-input-padding-t: 1.625rem !default;
+$form-floating-input-padding-b: .625rem !default;
+$form-floating-label-height: 1.5em !default;
+$form-floating-label-opacity: .65 !default;
+$form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default;
+$form-floating-label-disabled-color: $gray-600 !default;
+$form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default;
+// scss-docs-end form-floating-variables
+
+// Form validation
+
+// scss-docs-start form-feedback-variables
+$form-feedback-margin-top: $form-text-margin-top !default;
+$form-feedback-font-size: $form-text-font-size !default;
+$form-feedback-font-style: $form-text-font-style !default;
+$form-feedback-valid-color: $success !default;
+$form-feedback-invalid-color: $danger !default;
+
+$form-feedback-icon-valid-color: $form-feedback-valid-color !default;
+$form-feedback-icon-valid: url("data:image/svg+xml,
") !default;
+$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;
+$form-feedback-icon-invalid: url("data:image/svg+xml,
") !default;
+// scss-docs-end form-feedback-variables
+
+// scss-docs-start form-validation-colors
+$form-valid-color: $form-feedback-valid-color !default;
+$form-valid-border-color: $form-feedback-valid-color !default;
+$form-invalid-color: $form-feedback-invalid-color !default;
+$form-invalid-border-color: $form-feedback-invalid-color !default;
+// scss-docs-end form-validation-colors
+
+// scss-docs-start form-validation-states
+$form-validation-states: (
+ "valid": (
+ "color": var(--#{$prefix}form-valid-color),
+ "icon": $form-feedback-icon-valid,
+ "tooltip-color": #fff,
+ "tooltip-bg-color": var(--#{$prefix}success),
+ "focus-box-shadow": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}success-rgb), $input-btn-focus-color-opacity),
+ "border-color": var(--#{$prefix}form-valid-border-color),
+ ),
+ "invalid": (
+ "color": var(--#{$prefix}form-invalid-color),
+ "icon": $form-feedback-icon-invalid,
+ "tooltip-color": #fff,
+ "tooltip-bg-color": var(--#{$prefix}danger),
+ "focus-box-shadow": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}danger-rgb), $input-btn-focus-color-opacity),
+ "border-color": var(--#{$prefix}form-invalid-border-color),
+ )
+) !default;
+// scss-docs-end form-validation-states
+
+// Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+
+// scss-docs-start zindex-stack
+$zindex-dropdown: 1000 !default;
+$zindex-sticky: 1020 !default;
+$zindex-fixed: 1030 !default;
+$zindex-offcanvas-backdrop: 1040 !default;
+$zindex-offcanvas: 1045 !default;
+$zindex-modal-backdrop: 1050 !default;
+$zindex-modal: 1055 !default;
+$zindex-popover: 1070 !default;
+$zindex-tooltip: 1080 !default;
+$zindex-toast: 1090 !default;
+// scss-docs-end zindex-stack
+
+// scss-docs-start zindex-levels-map
+$zindex-levels: (
+ n1: -1,
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ 3: 3
+) !default;
+// scss-docs-end zindex-levels-map
+
+
+// Navs
+
+// scss-docs-start nav-variables
+$nav-link-padding-y: .5rem !default;
+$nav-link-padding-x: 1rem !default;
+$nav-link-font-size: null !default;
+$nav-link-font-weight: null !default;
+$nav-link-color: var(--#{$prefix}link-color) !default;
+$nav-link-hover-color: var(--#{$prefix}link-hover-color) !default;
+$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;
+$nav-link-disabled-color: var(--#{$prefix}secondary-color) !default;
+$nav-link-focus-box-shadow: $focus-ring-box-shadow !default;
+
+$nav-tabs-border-color: var(--#{$prefix}border-color) !default;
+$nav-tabs-border-width: var(--#{$prefix}border-width) !default;
+$nav-tabs-border-radius: var(--#{$prefix}border-radius) !default;
+$nav-tabs-link-hover-border-color: var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color !default;
+$nav-tabs-link-active-color: var(--#{$prefix}emphasis-color) !default;
+$nav-tabs-link-active-bg: var(--#{$prefix}body-bg) !default;
+$nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg !default;
+
+$nav-pills-border-radius: var(--#{$prefix}border-radius) !default;
+$nav-pills-link-active-color: $component-active-color !default;
+$nav-pills-link-active-bg: $component-active-bg !default;
+
+$nav-underline-gap: 1rem !default;
+$nav-underline-border-width: .125rem !default;
+$nav-underline-link-active-color: var(--#{$prefix}emphasis-color) !default;
+// scss-docs-end nav-variables
+
+
+// Navbar
+
+// scss-docs-start navbar-variables
+$navbar-padding-y: $spacer * .5 !default;
+$navbar-padding-x: null !default;
+
+$navbar-nav-link-padding-x: .5rem !default;
+
+$navbar-brand-font-size: $font-size-lg !default;
+// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link
+$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;
+$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;
+$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default;
+$navbar-brand-margin-end: 1rem !default;
+
+$navbar-toggler-padding-y: .25rem !default;
+$navbar-toggler-padding-x: .75rem !default;
+$navbar-toggler-font-size: $font-size-lg !default;
+$navbar-toggler-border-radius: $btn-border-radius !default;
+$navbar-toggler-focus-width: $btn-focus-width !default;
+$navbar-toggler-transition: box-shadow .15s ease-in-out !default;
+
+$navbar-light-color: rgba(var(--#{$prefix}emphasis-color-rgb), .65) !default;
+$navbar-light-hover-color: rgba(var(--#{$prefix}emphasis-color-rgb), .8) !default;
+$navbar-light-active-color: rgba(var(--#{$prefix}emphasis-color-rgb), 1) !default;
+$navbar-light-disabled-color: rgba(var(--#{$prefix}emphasis-color-rgb), .3) !default;
+$navbar-light-icon-color: rgba($body-color, .75) !default;
+$navbar-light-toggler-icon-bg: url("data:image/svg+xml,
") !default;
+$navbar-light-toggler-border-color: rgba(var(--#{$prefix}emphasis-color-rgb), .15) !default;
+$navbar-light-brand-color: $navbar-light-active-color !default;
+$navbar-light-brand-hover-color: $navbar-light-active-color !default;
+// scss-docs-end navbar-variables
+
+// scss-docs-start navbar-dark-variables
+$navbar-dark-color: rgba($white, .55) !default;
+$navbar-dark-hover-color: rgba($white, .75) !default;
+$navbar-dark-active-color: $white !default;
+$navbar-dark-disabled-color: rgba($white, .25) !default;
+$navbar-dark-icon-color: $navbar-dark-color !default;
+$navbar-dark-toggler-icon-bg: url("data:image/svg+xml,
") !default;
+$navbar-dark-toggler-border-color: rgba($white, .1) !default;
+$navbar-dark-brand-color: $navbar-dark-active-color !default;
+$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;
+// scss-docs-end navbar-dark-variables
+
+
+// Dropdowns
+//
+// Dropdown menu container and contents.
+
+// scss-docs-start dropdown-variables
+$dropdown-min-width: 10rem !default;
+$dropdown-padding-x: 0 !default;
+$dropdown-padding-y: .5rem !default;
+$dropdown-spacer: .125rem !default;
+$dropdown-font-size: $font-size-base !default;
+$dropdown-color: var(--#{$prefix}body-color) !default;
+$dropdown-bg: var(--#{$prefix}body-bg) !default;
+$dropdown-border-color: var(--#{$prefix}border-color-translucent) !default;
+$dropdown-border-radius: var(--#{$prefix}border-radius) !default;
+$dropdown-border-width: var(--#{$prefix}border-width) !default;
+$dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default; // stylelint-disable-line function-disallowed-list
+$dropdown-divider-bg: $dropdown-border-color !default;
+$dropdown-divider-margin-y: $spacer * .5 !default;
+$dropdown-box-shadow: var(--#{$prefix}box-shadow) !default;
+
+$dropdown-link-color: var(--#{$prefix}body-color) !default;
+$dropdown-link-hover-color: $dropdown-link-color !default;
+$dropdown-link-hover-bg: var(--#{$prefix}tertiary-bg) !default;
+
+$dropdown-link-active-color: $component-active-color !default;
+$dropdown-link-active-bg: $component-active-bg !default;
+
+$dropdown-link-disabled-color: var(--#{$prefix}tertiary-color) !default;
+
+$dropdown-item-padding-y: $spacer * .25 !default;
+$dropdown-item-padding-x: $spacer !default;
+
+$dropdown-header-color: $gray-600 !default;
+$dropdown-header-padding-x: $dropdown-item-padding-x !default;
+$dropdown-header-padding-y: $dropdown-padding-y !default;
+// fusv-disable
+$dropdown-header-padding: $dropdown-header-padding-y $dropdown-header-padding-x !default; // Deprecated in v5.2.0
+// fusv-enable
+// scss-docs-end dropdown-variables
+
+// scss-docs-start dropdown-dark-variables
+$dropdown-dark-color: $gray-300 !default;
+$dropdown-dark-bg: $gray-800 !default;
+$dropdown-dark-border-color: $dropdown-border-color !default;
+$dropdown-dark-divider-bg: $dropdown-divider-bg !default;
+$dropdown-dark-box-shadow: null !default;
+$dropdown-dark-link-color: $dropdown-dark-color !default;
+$dropdown-dark-link-hover-color: $white !default;
+$dropdown-dark-link-hover-bg: rgba($white, .15) !default;
+$dropdown-dark-link-active-color: $dropdown-link-active-color !default;
+$dropdown-dark-link-active-bg: $dropdown-link-active-bg !default;
+$dropdown-dark-link-disabled-color: $gray-500 !default;
+$dropdown-dark-header-color: $gray-500 !default;
+// scss-docs-end dropdown-dark-variables
+
+
+// Pagination
+
+// scss-docs-start pagination-variables
+$pagination-padding-y: .375rem !default;
+$pagination-padding-x: .75rem !default;
+$pagination-padding-y-sm: .25rem !default;
+$pagination-padding-x-sm: .5rem !default;
+$pagination-padding-y-lg: .75rem !default;
+$pagination-padding-x-lg: 1.5rem !default;
+
+$pagination-font-size: $font-size-base !default;
+
+$pagination-color: var(--#{$prefix}link-color) !default;
+$pagination-bg: var(--#{$prefix}body-bg) !default;
+$pagination-border-radius: var(--#{$prefix}border-radius) !default;
+$pagination-border-width: var(--#{$prefix}border-width) !default;
+$pagination-margin-start: calc(#{$pagination-border-width} * -1) !default; // stylelint-disable-line function-disallowed-list
+$pagination-border-color: var(--#{$prefix}border-color) !default;
+
+$pagination-focus-color: var(--#{$prefix}link-hover-color) !default;
+$pagination-focus-bg: var(--#{$prefix}secondary-bg) !default;
+$pagination-focus-box-shadow: $focus-ring-box-shadow !default;
+$pagination-focus-outline: 0 !default;
+
+$pagination-hover-color: var(--#{$prefix}link-hover-color) !default;
+$pagination-hover-bg: var(--#{$prefix}tertiary-bg) !default;
+$pagination-hover-border-color: var(--#{$prefix}border-color) !default; // Todo in v6: remove this?
+
+$pagination-active-color: $component-active-color !default;
+$pagination-active-bg: $component-active-bg !default;
+$pagination-active-border-color: $component-active-bg !default;
+
+$pagination-disabled-color: var(--#{$prefix}secondary-color) !default;
+$pagination-disabled-bg: var(--#{$prefix}secondary-bg) !default;
+$pagination-disabled-border-color: var(--#{$prefix}border-color) !default;
+
+$pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+
+$pagination-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;
+$pagination-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;
+// scss-docs-end pagination-variables
+
+
+// Placeholders
+
+// scss-docs-start placeholders
+$placeholder-opacity-max: .5 !default;
+$placeholder-opacity-min: .2 !default;
+// scss-docs-end placeholders
+
+// Cards
+
+// scss-docs-start card-variables
+$card-spacer-y: $spacer !default;
+$card-spacer-x: $spacer !default;
+$card-title-spacer-y: $spacer * .5 !default;
+$card-title-color: null !default;
+$card-subtitle-color: null !default;
+$card-border-width: var(--#{$prefix}border-width) !default;
+$card-border-color: var(--#{$prefix}border-color-translucent) !default;
+$card-border-radius: var(--#{$prefix}border-radius) !default;
+$card-box-shadow: null !default;
+$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;
+$card-cap-padding-y: $card-spacer-y * .5 !default;
+$card-cap-padding-x: $card-spacer-x !default;
+$card-cap-bg: rgba(var(--#{$prefix}body-color-rgb), .03) !default;
+$card-cap-color: null !default;
+$card-height: null !default;
+$card-color: null !default;
+$card-bg: var(--#{$prefix}body-bg) !default;
+$card-img-overlay-padding: $spacer !default;
+$card-group-margin: $grid-gutter-width * .5 !default;
+// scss-docs-end card-variables
+
+// Accordion
+
+// scss-docs-start accordion-variables
+$accordion-padding-y: 1rem !default;
+$accordion-padding-x: 1.25rem !default;
+$accordion-color: var(--#{$prefix}body-color) !default;
+$accordion-bg: var(--#{$prefix}body-bg) !default;
+$accordion-border-width: var(--#{$prefix}border-width) !default;
+$accordion-border-color: var(--#{$prefix}border-color) !default;
+$accordion-border-radius: var(--#{$prefix}border-radius) !default;
+$accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default;
+
+$accordion-body-padding-y: $accordion-padding-y !default;
+$accordion-body-padding-x: $accordion-padding-x !default;
+
+$accordion-button-padding-y: $accordion-padding-y !default;
+$accordion-button-padding-x: $accordion-padding-x !default;
+$accordion-button-color: var(--#{$prefix}body-color) !default;
+$accordion-button-bg: var(--#{$prefix}accordion-bg) !default;
+$accordion-transition: $btn-transition, border-radius .15s ease !default;
+$accordion-button-active-bg: var(--#{$prefix}primary-bg-subtle) !default;
+$accordion-button-active-color: var(--#{$prefix}primary-text-emphasis) !default;
+
+$accordion-button-focus-border-color: $input-focus-border-color !default;
+$accordion-button-focus-box-shadow: $btn-focus-box-shadow !default;
+
+$accordion-icon-width: 1.25rem !default;
+$accordion-icon-color: $body-color !default;
+$accordion-icon-active-color: $primary-text-emphasis !default;
+$accordion-icon-transition: transform .2s ease-in-out !default;
+$accordion-icon-transform: rotate(-180deg) !default;
+
+$accordion-button-icon: url("data:image/svg+xml,
") !default;
+$accordion-button-active-icon: url("data:image/svg+xml,
") !default;
+// scss-docs-end accordion-variables
+
+// Tooltips
+
+// scss-docs-start tooltip-variables
+$tooltip-font-size: $font-size-sm !default;
+$tooltip-max-width: 200px !default;
+$tooltip-color: var(--#{$prefix}body-bg) !default;
+$tooltip-bg: var(--#{$prefix}emphasis-color) !default;
+$tooltip-border-radius: var(--#{$prefix}border-radius) !default;
+$tooltip-opacity: .9 !default;
+$tooltip-padding-y: $spacer * .25 !default;
+$tooltip-padding-x: $spacer * .5 !default;
+$tooltip-margin: null !default; // TODO: remove this in v6
+
+$tooltip-arrow-width: .8rem !default;
+$tooltip-arrow-height: .4rem !default;
+// fusv-disable
+$tooltip-arrow-color: null !default; // Deprecated in Bootstrap 5.2.0 for CSS variables
+// fusv-enable
+// scss-docs-end tooltip-variables
+
+// Form tooltips must come after regular tooltips
+// scss-docs-start tooltip-feedback-variables
+$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;
+$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;
+$form-feedback-tooltip-font-size: $tooltip-font-size !default;
+$form-feedback-tooltip-line-height: null !default;
+$form-feedback-tooltip-opacity: $tooltip-opacity !default;
+$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
+// scss-docs-end tooltip-feedback-variables
+
+
+// Popovers
+
+// scss-docs-start popover-variables
+$popover-font-size: $font-size-sm !default;
+$popover-bg: var(--#{$prefix}body-bg) !default;
+$popover-max-width: 276px !default;
+$popover-border-width: var(--#{$prefix}border-width) !default;
+$popover-border-color: var(--#{$prefix}border-color-translucent) !default;
+$popover-border-radius: var(--#{$prefix}border-radius-lg) !default;
+$popover-inner-border-radius: calc(#{$popover-border-radius} - #{$popover-border-width}) !default; // stylelint-disable-line function-disallowed-list
+$popover-box-shadow: var(--#{$prefix}box-shadow) !default;
+
+$popover-header-font-size: $font-size-base !default;
+$popover-header-bg: var(--#{$prefix}secondary-bg) !default;
+$popover-header-color: $headings-color !default;
+$popover-header-padding-y: .5rem !default;
+$popover-header-padding-x: $spacer !default;
+
+$popover-body-color: var(--#{$prefix}body-color) !default;
+$popover-body-padding-y: $spacer !default;
+$popover-body-padding-x: $spacer !default;
+
+$popover-arrow-width: 1rem !default;
+$popover-arrow-height: .5rem !default;
+// scss-docs-end popover-variables
+
+// fusv-disable
+// Deprecated in Bootstrap 5.2.0 for CSS variables
+$popover-arrow-color: $popover-bg !default;
+$popover-arrow-outer-color: var(--#{$prefix}border-color-translucent) !default;
+// fusv-enable
+
+
+// Toasts
+
+// scss-docs-start toast-variables
+$toast-max-width: 350px !default;
+$toast-padding-x: .75rem !default;
+$toast-padding-y: .5rem !default;
+$toast-font-size: .875rem !default;
+$toast-color: null !default;
+$toast-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;
+$toast-border-width: var(--#{$prefix}border-width) !default;
+$toast-border-color: var(--#{$prefix}border-color-translucent) !default;
+$toast-border-radius: var(--#{$prefix}border-radius) !default;
+$toast-box-shadow: var(--#{$prefix}box-shadow) !default;
+$toast-spacing: $container-padding-x !default;
+
+$toast-header-color: var(--#{$prefix}secondary-color) !default;
+$toast-header-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;
+$toast-header-border-color: $toast-border-color !default;
+// scss-docs-end toast-variables
+
+
+// Badges
+
+// scss-docs-start badge-variables
+$badge-font-size: .75em !default;
+$badge-font-weight: $font-weight-bold !default;
+$badge-color: $white !default;
+$badge-padding-y: .35em !default;
+$badge-padding-x: .65em !default;
+$badge-border-radius: var(--#{$prefix}border-radius) !default;
+// scss-docs-end badge-variables
+
+
+// Modals
+
+// scss-docs-start modal-variables
+$modal-inner-padding: $spacer !default;
+
+$modal-footer-margin-between: .5rem !default;
+
+$modal-dialog-margin: .5rem !default;
+$modal-dialog-margin-y-sm-up: 1.75rem !default;
+
+$modal-title-line-height: $line-height-base !default;
+
+$modal-content-color: null !default;
+$modal-content-bg: var(--#{$prefix}body-bg) !default;
+$modal-content-border-color: var(--#{$prefix}border-color-translucent) !default;
+$modal-content-border-width: var(--#{$prefix}border-width) !default;
+$modal-content-border-radius: var(--#{$prefix}border-radius-lg) !default;
+$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;
+$modal-content-box-shadow-xs: var(--#{$prefix}box-shadow-sm) !default;
+$modal-content-box-shadow-sm-up: var(--#{$prefix}box-shadow) !default;
+
+$modal-backdrop-bg: $black !default;
+$modal-backdrop-opacity: .5 !default;
+
+$modal-header-border-color: var(--#{$prefix}border-color) !default;
+$modal-header-border-width: $modal-content-border-width !default;
+$modal-header-padding-y: $modal-inner-padding !default;
+$modal-header-padding-x: $modal-inner-padding !default;
+$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility
+
+$modal-footer-bg: null !default;
+$modal-footer-border-color: $modal-header-border-color !default;
+$modal-footer-border-width: $modal-header-border-width !default;
+
+$modal-sm: 300px !default;
+$modal-md: 500px !default;
+$modal-lg: 800px !default;
+$modal-xl: 1140px !default;
+
+$modal-fade-transform: translate(0, -50px) !default;
+$modal-show-transform: none !default;
+$modal-transition: transform .3s ease-out !default;
+$modal-scale-transform: scale(1.02) !default;
+// scss-docs-end modal-variables
+
+
+// Alerts
+//
+// Define alert colors, border radius, and padding.
+
+// scss-docs-start alert-variables
+$alert-padding-y: $spacer !default;
+$alert-padding-x: $spacer !default;
+$alert-margin-bottom: 1rem !default;
+$alert-border-radius: var(--#{$prefix}border-radius) !default;
+$alert-link-font-weight: $font-weight-bold !default;
+$alert-border-width: var(--#{$prefix}border-width) !default;
+$alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side
+// scss-docs-end alert-variables
+
+// fusv-disable
+$alert-bg-scale: -80% !default; // Deprecated in v5.2.0, to be removed in v6
+$alert-border-scale: -70% !default; // Deprecated in v5.2.0, to be removed in v6
+$alert-color-scale: 40% !default; // Deprecated in v5.2.0, to be removed in v6
+// fusv-enable
+
+// Progress bars
+
+// scss-docs-start progress-variables
+$progress-height: 1rem !default;
+$progress-font-size: $font-size-base * .75 !default;
+$progress-bg: var(--#{$prefix}secondary-bg) !default;
+$progress-border-radius: var(--#{$prefix}border-radius) !default;
+$progress-box-shadow: var(--#{$prefix}box-shadow-inset) !default;
+$progress-bar-color: $white !default;
+$progress-bar-bg: $primary !default;
+$progress-bar-animation-timing: 1s linear infinite !default;
+$progress-bar-transition: width .6s ease !default;
+// scss-docs-end progress-variables
+
+
+// List group
+
+// scss-docs-start list-group-variables
+$list-group-color: var(--#{$prefix}body-color) !default;
+$list-group-bg: var(--#{$prefix}body-bg) !default;
+$list-group-border-color: var(--#{$prefix}border-color) !default;
+$list-group-border-width: var(--#{$prefix}border-width) !default;
+$list-group-border-radius: var(--#{$prefix}border-radius) !default;
+
+$list-group-item-padding-y: $spacer * .5 !default;
+$list-group-item-padding-x: $spacer !default;
+// fusv-disable
+$list-group-item-bg-scale: -80% !default; // Deprecated in v5.3.0
+$list-group-item-color-scale: 40% !default; // Deprecated in v5.3.0
+// fusv-enable
+
+$list-group-hover-bg: var(--#{$prefix}tertiary-bg) !default;
+$list-group-active-color: $component-active-color !default;
+$list-group-active-bg: $component-active-bg !default;
+$list-group-active-border-color: $list-group-active-bg !default;
+
+$list-group-disabled-color: var(--#{$prefix}secondary-color) !default;
+$list-group-disabled-bg: $list-group-bg !default;
+
+$list-group-action-color: var(--#{$prefix}secondary-color) !default;
+$list-group-action-hover-color: var(--#{$prefix}emphasis-color) !default;
+
+$list-group-action-active-color: var(--#{$prefix}body-color) !default;
+$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;
+// scss-docs-end list-group-variables
+
+
+// Image thumbnails
+
+// scss-docs-start thumbnail-variables
+$thumbnail-padding: .25rem !default;
+$thumbnail-bg: var(--#{$prefix}body-bg) !default;
+$thumbnail-border-width: var(--#{$prefix}border-width) !default;
+$thumbnail-border-color: var(--#{$prefix}border-color) !default;
+$thumbnail-border-radius: var(--#{$prefix}border-radius) !default;
+$thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default;
+// scss-docs-end thumbnail-variables
+
+
+// Figures
+
+// scss-docs-start figure-variables
+$figure-caption-font-size: $small-font-size !default;
+$figure-caption-color: var(--#{$prefix}secondary-color) !default;
+// scss-docs-end figure-variables
+
+
+// Breadcrumbs
+
+// scss-docs-start breadcrumb-variables
+$breadcrumb-font-size: null !default;
+$breadcrumb-padding-y: 0 !default;
+$breadcrumb-padding-x: 0 !default;
+$breadcrumb-item-padding-x: .5rem !default;
+$breadcrumb-margin-bottom: 1rem !default;
+$breadcrumb-bg: null !default;
+$breadcrumb-divider-color: var(--#{$prefix}secondary-color) !default;
+$breadcrumb-active-color: var(--#{$prefix}secondary-color) !default;
+$breadcrumb-divider: quote("/") !default;
+$breadcrumb-divider-flipped: $breadcrumb-divider !default;
+$breadcrumb-border-radius: null !default;
+// scss-docs-end breadcrumb-variables
+
+// Carousel
+
+// scss-docs-start carousel-variables
+$carousel-control-color: $white !default;
+$carousel-control-width: 15% !default;
+$carousel-control-opacity: .5 !default;
+$carousel-control-hover-opacity: .9 !default;
+$carousel-control-transition: opacity .15s ease !default;
+
+$carousel-indicator-width: 30px !default;
+$carousel-indicator-height: 3px !default;
+$carousel-indicator-hit-area-height: 10px !default;
+$carousel-indicator-spacer: 3px !default;
+$carousel-indicator-opacity: .5 !default;
+$carousel-indicator-active-bg: $white !default;
+$carousel-indicator-active-opacity: 1 !default;
+$carousel-indicator-transition: opacity .6s ease !default;
+
+$carousel-caption-width: 70% !default;
+$carousel-caption-color: $white !default;
+$carousel-caption-padding-y: 1.25rem !default;
+$carousel-caption-spacer: 1.25rem !default;
+
+$carousel-control-icon-width: 2rem !default;
+
+$carousel-control-prev-icon-bg: url("data:image/svg+xml,
") !default;
+$carousel-control-next-icon-bg: url("data:image/svg+xml,
") !default;
+
+$carousel-transition-duration: .6s !default;
+$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)
+// scss-docs-end carousel-variables
+
+// scss-docs-start carousel-dark-variables
+$carousel-dark-indicator-active-bg: $black !default;
+$carousel-dark-caption-color: $black !default;
+$carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;
+// scss-docs-end carousel-dark-variables
+
+
+// Spinners
+
+// scss-docs-start spinner-variables
+$spinner-width: 2rem !default;
+$spinner-height: $spinner-width !default;
+$spinner-vertical-align: -.125em !default;
+$spinner-border-width: .25em !default;
+$spinner-animation-speed: .75s !default;
+
+$spinner-width-sm: 1rem !default;
+$spinner-height-sm: $spinner-width-sm !default;
+$spinner-border-width-sm: .2em !default;
+// scss-docs-end spinner-variables
+
+
+// Close
+
+// scss-docs-start close-variables
+$btn-close-width: 1em !default;
+$btn-close-height: $btn-close-width !default;
+$btn-close-padding-x: .25em !default;
+$btn-close-padding-y: $btn-close-padding-x !default;
+$btn-close-color: $black !default;
+$btn-close-bg: url("data:image/svg+xml,
") !default;
+$btn-close-focus-shadow: $focus-ring-box-shadow !default;
+$btn-close-opacity: .5 !default;
+$btn-close-hover-opacity: .75 !default;
+$btn-close-focus-opacity: 1 !default;
+$btn-close-disabled-opacity: .25 !default;
+$btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default;
+// scss-docs-end close-variables
+
+
+// Offcanvas
+
+// scss-docs-start offcanvas-variables
+$offcanvas-padding-y: $modal-inner-padding !default;
+$offcanvas-padding-x: $modal-inner-padding !default;
+$offcanvas-horizontal-width: 400px !default;
+$offcanvas-vertical-height: 30vh !default;
+$offcanvas-transition-duration: .3s !default;
+$offcanvas-border-color: $modal-content-border-color !default;
+$offcanvas-border-width: $modal-content-border-width !default;
+$offcanvas-title-line-height: $modal-title-line-height !default;
+$offcanvas-bg-color: var(--#{$prefix}body-bg) !default;
+$offcanvas-color: var(--#{$prefix}body-color) !default;
+$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
+$offcanvas-backdrop-bg: $modal-backdrop-bg !default;
+$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;
+// scss-docs-end offcanvas-variables
+
+// Code
+
+$code-font-size: $small-font-size !default;
+$code-color: $pink !default;
+
+$kbd-padding-y: .1875rem !default;
+$kbd-padding-x: .375rem !default;
+$kbd-font-size: $code-font-size !default;
+$kbd-color: var(--#{$prefix}body-bg) !default;
+$kbd-bg: var(--#{$prefix}body-color) !default;
+$nested-kbd-font-weight: null !default; // Deprecated in v5.2.0, removing in v6
+
+$pre-color: null !default;
diff --git a/Moonlight/Styles/bootstrap/scss/bootstrap-grid.scss b/Moonlight/Styles/bootstrap/scss/bootstrap-grid.scss
new file mode 100644
index 00000000..52bd577e
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/bootstrap-grid.scss
@@ -0,0 +1,62 @@
+@import "mixins/banner";
+@include bsBanner(Grid);
+
+$include-column-box-sizing: true !default;
+
+@import "functions";
+@import "variables";
+@import "variables-dark";
+@import "maps";
+
+@import "mixins/breakpoints";
+@import "mixins/container";
+@import "mixins/grid";
+@import "mixins/utilities";
+
+@import "vendor/rfs";
+
+@import "containers";
+@import "grid";
+
+@import "utilities";
+// Only use the utilities we need
+// stylelint-disable-next-line scss/dollar-variable-default
+$utilities: map-get-multiple(
+ $utilities,
+ (
+ "display",
+ "order",
+ "flex",
+ "flex-direction",
+ "flex-grow",
+ "flex-shrink",
+ "flex-wrap",
+ "justify-content",
+ "align-items",
+ "align-content",
+ "align-self",
+ "margin",
+ "margin-x",
+ "margin-y",
+ "margin-top",
+ "margin-end",
+ "margin-bottom",
+ "margin-start",
+ "negative-margin",
+ "negative-margin-x",
+ "negative-margin-y",
+ "negative-margin-top",
+ "negative-margin-end",
+ "negative-margin-bottom",
+ "negative-margin-start",
+ "padding",
+ "padding-x",
+ "padding-y",
+ "padding-top",
+ "padding-end",
+ "padding-bottom",
+ "padding-start",
+ )
+);
+
+@import "utilities/api";
diff --git a/Moonlight/Styles/bootstrap/scss/bootstrap-reboot.scss b/Moonlight/Styles/bootstrap/scss/bootstrap-reboot.scss
new file mode 100644
index 00000000..5b69b955
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/bootstrap-reboot.scss
@@ -0,0 +1,10 @@
+@import "mixins/banner";
+@include bsBanner(Reboot);
+
+@import "functions";
+@import "variables";
+@import "variables-dark";
+@import "maps";
+@import "mixins";
+@import "root";
+@import "reboot";
diff --git a/Moonlight/Styles/bootstrap/scss/bootstrap-utilities.scss b/Moonlight/Styles/bootstrap/scss/bootstrap-utilities.scss
new file mode 100644
index 00000000..99c4a359
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/bootstrap-utilities.scss
@@ -0,0 +1,19 @@
+@import "mixins/banner";
+@include bsBanner(Utilities);
+
+// Configuration
+@import "functions";
+@import "variables";
+@import "variables-dark";
+@import "maps";
+@import "mixins";
+@import "utilities";
+
+// Layout & components
+@import "root";
+
+// Helpers
+@import "helpers";
+
+// Utilities
+@import "utilities/api";
diff --git a/Moonlight/Styles/bootstrap/scss/bootstrap.scss b/Moonlight/Styles/bootstrap/scss/bootstrap.scss
new file mode 100644
index 00000000..449d7048
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/bootstrap.scss
@@ -0,0 +1,52 @@
+@import "mixins/banner";
+@include bsBanner("");
+
+
+// scss-docs-start import-stack
+// Configuration
+@import "functions";
+@import "variables";
+@import "variables-dark";
+@import "maps";
+@import "mixins";
+@import "utilities";
+
+// Layout & components
+@import "root";
+@import "reboot";
+@import "type";
+@import "images";
+@import "containers";
+@import "grid";
+@import "tables";
+@import "forms";
+@import "buttons";
+@import "transitions";
+@import "dropdown";
+@import "button-group";
+@import "nav";
+@import "navbar";
+@import "card";
+@import "accordion";
+@import "breadcrumb";
+@import "pagination";
+@import "badge";
+@import "alert";
+@import "progress";
+@import "list-group";
+@import "close";
+@import "toasts";
+@import "modal";
+@import "tooltip";
+@import "popover";
+@import "carousel";
+@import "spinners";
+@import "offcanvas";
+@import "placeholders";
+
+// Helpers
+@import "helpers";
+
+// Utilities
+@import "utilities/api";
+// scss-docs-end import-stack
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_floating-labels.scss b/Moonlight/Styles/bootstrap/scss/forms/_floating-labels.scss
new file mode 100644
index 00000000..2cf04704
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_floating-labels.scss
@@ -0,0 +1,95 @@
+.form-floating {
+ position: relative;
+
+ > .form-control,
+ > .form-control-plaintext,
+ > .form-select {
+ height: $form-floating-height;
+ min-height: $form-floating-height;
+ line-height: $form-floating-line-height;
+ }
+
+ > label {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ height: 100%; // allow textareas
+ padding: $form-floating-padding-y $form-floating-padding-x;
+ overflow: hidden;
+ text-align: start;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ pointer-events: none;
+ border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
+ transform-origin: 0 0;
+ @include transition($form-floating-transition);
+ }
+
+ > .form-control,
+ > .form-control-plaintext {
+ padding: $form-floating-padding-y $form-floating-padding-x;
+
+ &::placeholder {
+ color: transparent;
+ }
+
+ &:focus,
+ &:not(:placeholder-shown) {
+ padding-top: $form-floating-input-padding-t;
+ padding-bottom: $form-floating-input-padding-b;
+ }
+ // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
+ &:-webkit-autofill {
+ padding-top: $form-floating-input-padding-t;
+ padding-bottom: $form-floating-input-padding-b;
+ }
+ }
+
+ > .form-select {
+ padding-top: $form-floating-input-padding-t;
+ padding-bottom: $form-floating-input-padding-b;
+ }
+
+ > .form-control:focus,
+ > .form-control:not(:placeholder-shown),
+ > .form-control-plaintext,
+ > .form-select {
+ ~ label {
+ color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
+ transform: $form-floating-label-transform;
+
+ &::after {
+ position: absolute;
+ inset: $form-floating-padding-y ($form-floating-padding-x * .5);
+ z-index: -1;
+ height: $form-floating-label-height;
+ content: "";
+ background-color: $input-bg;
+ @include border-radius($input-border-radius);
+ }
+ }
+ }
+ // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
+ > .form-control:-webkit-autofill {
+ ~ label {
+ color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
+ transform: $form-floating-label-transform;
+ }
+ }
+
+ > .form-control-plaintext {
+ ~ label {
+ border-width: $input-border-width 0; // Required to properly position label text - as explained above
+ }
+ }
+
+ > :disabled ~ label,
+ > .form-control:disabled ~ label { // Required for `.form-control`s because of specificity
+ color: $form-floating-label-disabled-color;
+
+ &::after {
+ background-color: $input-disabled-bg;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_form-check.scss b/Moonlight/Styles/bootstrap/scss/forms/_form-check.scss
new file mode 100644
index 00000000..d3a8fe60
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_form-check.scss
@@ -0,0 +1,189 @@
+//
+// Check/radio
+//
+
+.form-check {
+ display: block;
+ min-height: $form-check-min-height;
+ padding-left: $form-check-padding-start;
+ margin-bottom: $form-check-margin-bottom;
+
+ .form-check-input {
+ float: left;
+ margin-left: $form-check-padding-start * -1;
+ }
+}
+
+.form-check-reverse {
+ padding-right: $form-check-padding-start;
+ padding-left: 0;
+ text-align: right;
+
+ .form-check-input {
+ float: right;
+ margin-right: $form-check-padding-start * -1;
+ margin-left: 0;
+ }
+}
+
+.form-check-input {
+ --#{$prefix}form-check-bg: #{$form-check-input-bg};
+
+ flex-shrink: 0;
+ width: $form-check-input-width;
+ height: $form-check-input-width;
+ margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height
+ vertical-align: top;
+ appearance: none;
+ background-color: var(--#{$prefix}form-check-bg);
+ background-image: var(--#{$prefix}form-check-bg-image);
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ border: $form-check-input-border;
+ print-color-adjust: exact; // Keep themed appearance for print
+ @include transition($form-check-transition);
+
+ &[type="checkbox"] {
+ @include border-radius($form-check-input-border-radius);
+ }
+
+ &[type="radio"] {
+ // stylelint-disable-next-line property-disallowed-list
+ border-radius: $form-check-radio-border-radius;
+ }
+
+ &:active {
+ filter: $form-check-input-active-filter;
+ }
+
+ &:focus {
+ border-color: $form-check-input-focus-border;
+ outline: 0;
+ box-shadow: $form-check-input-focus-box-shadow;
+ }
+
+ &:checked {
+ background-color: $form-check-input-checked-bg-color;
+ border-color: $form-check-input-checked-border-color;
+
+ &[type="checkbox"] {
+ @if $enable-gradients {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}, var(--#{$prefix}gradient);
+ } @else {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)};
+ }
+ }
+
+ &[type="radio"] {
+ @if $enable-gradients {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}, var(--#{$prefix}gradient);
+ } @else {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)};
+ }
+ }
+ }
+
+ &[type="checkbox"]:indeterminate {
+ background-color: $form-check-input-indeterminate-bg-color;
+ border-color: $form-check-input-indeterminate-border-color;
+
+ @if $enable-gradients {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}, var(--#{$prefix}gradient);
+ } @else {
+ --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)};
+ }
+ }
+
+ &:disabled {
+ pointer-events: none;
+ filter: none;
+ opacity: $form-check-input-disabled-opacity;
+ }
+
+ // Use disabled attribute in addition of :disabled pseudo-class
+ // See: https://github.com/twbs/bootstrap/issues/28247
+ &[disabled],
+ &:disabled {
+ ~ .form-check-label {
+ cursor: default;
+ opacity: $form-check-label-disabled-opacity;
+ }
+ }
+}
+
+.form-check-label {
+ color: $form-check-label-color;
+ cursor: $form-check-label-cursor;
+}
+
+//
+// Switch
+//
+
+.form-switch {
+ padding-left: $form-switch-padding-start;
+
+ .form-check-input {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
+
+ width: $form-switch-width;
+ margin-left: $form-switch-padding-start * -1;
+ background-image: var(--#{$prefix}form-switch-bg);
+ background-position: left center;
+ @include border-radius($form-switch-border-radius);
+ @include transition($form-switch-transition);
+
+ &:focus {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)};
+ }
+
+ &:checked {
+ background-position: $form-switch-checked-bg-position;
+
+ @if $enable-gradients {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient);
+ } @else {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
+ }
+ }
+ }
+
+ &.form-check-reverse {
+ padding-right: $form-switch-padding-start;
+ padding-left: 0;
+
+ .form-check-input {
+ margin-right: $form-switch-padding-start * -1;
+ margin-left: 0;
+ }
+ }
+}
+
+.form-check-inline {
+ display: inline-block;
+ margin-right: $form-check-inline-margin-end;
+}
+
+.btn-check {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+
+ &[disabled],
+ &:disabled {
+ + .btn {
+ pointer-events: none;
+ filter: none;
+ opacity: $form-check-btn-check-disabled-opacity;
+ }
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .form-switch .form-check-input:not(:checked):not(:focus) {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_form-control.scss b/Moonlight/Styles/bootstrap/scss/forms/_form-control.scss
new file mode 100644
index 00000000..67ae5f4f
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_form-control.scss
@@ -0,0 +1,214 @@
+//
+// General form controls (plus a few specific high-level interventions)
+//
+
+.form-control {
+ display: block;
+ width: 100%;
+ padding: $input-padding-y $input-padding-x;
+ font-family: $input-font-family;
+ @include font-size($input-font-size);
+ font-weight: $input-font-weight;
+ line-height: $input-line-height;
+ color: $input-color;
+ appearance: none; // Fix appearance for date inputs in Safari
+ background-color: $input-bg;
+ background-clip: padding-box;
+ border: $input-border-width solid $input-border-color;
+
+ // Note: This has no effect on
s in some browsers, due to the limited stylability of ``s in CSS.
+ @include border-radius($input-border-radius, 0);
+
+ @include box-shadow($input-box-shadow);
+ @include transition($input-transition);
+
+ &[type="file"] {
+ overflow: hidden; // prevent pseudo element button overlap
+
+ &:not(:disabled):not([readonly]) {
+ cursor: pointer;
+ }
+ }
+
+ // Customize the `:focus` state to imitate native WebKit styles.
+ &:focus {
+ color: $input-focus-color;
+ background-color: $input-focus-bg;
+ border-color: $input-focus-border-color;
+ outline: 0;
+ @if $enable-shadows {
+ @include box-shadow($input-box-shadow, $input-focus-box-shadow);
+ } @else {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ box-shadow: $input-focus-box-shadow;
+ }
+ }
+
+ &::-webkit-date-and-time-value {
+ // On Android Chrome, form-control's "width: 100%" makes the input width too small
+ // Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
+ //
+ // On iOS Safari, form-control's "appearance: none" + "width: 100%" makes the input width too small
+ // Tested under iOS 16.2 / Safari 16.2
+ min-width: 85px; // Seems to be a good minimum safe width
+
+ // Add some height to date inputs on iOS
+ // https://github.com/twbs/bootstrap/issues/23307
+ // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
+ // Multiply line-height by 1em if it has no unit
+ height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
+
+ // Android Chrome type="date" is taller than the other inputs
+ // because of "margin: 1px 24px 1px 4px" inside the shadow DOM
+ // Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
+ margin: 0;
+ }
+
+ // Prevent excessive date input height in Webkit
+ // https://github.com/twbs/bootstrap/issues/34433
+ &::-webkit-datetime-edit {
+ display: block;
+ padding: 0;
+ }
+
+ // Placeholder
+ &::placeholder {
+ color: $input-placeholder-color;
+ // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
+ opacity: 1;
+ }
+
+ // Disabled inputs
+ //
+ // HTML5 says that controls under a fieldset > legend:first-child won't be
+ // disabled if the fieldset is disabled. Due to implementation difficulty, we
+ // don't honor that edge case; we style them as disabled anyway.
+ &:disabled {
+ color: $input-disabled-color;
+ background-color: $input-disabled-bg;
+ border-color: $input-disabled-border-color;
+ // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
+ opacity: 1;
+ }
+
+ // File input buttons theming
+ &::file-selector-button {
+ padding: $input-padding-y $input-padding-x;
+ margin: (-$input-padding-y) (-$input-padding-x);
+ margin-inline-end: $input-padding-x;
+ color: $form-file-button-color;
+ @include gradient-bg($form-file-button-bg);
+ pointer-events: none;
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+ border-inline-end-width: $input-border-width;
+ border-radius: 0; // stylelint-disable-line property-disallowed-list
+ @include transition($btn-transition);
+ }
+
+ &:hover:not(:disabled):not([readonly])::file-selector-button {
+ background-color: $form-file-button-hover-bg;
+ }
+}
+
+// Readonly controls as plain text
+//
+// Apply class to a readonly input to make it appear like regular plain
+// text (without any border, background color, focus indicator)
+
+.form-control-plaintext {
+ display: block;
+ width: 100%;
+ padding: $input-padding-y 0;
+ margin-bottom: 0; // match inputs if this class comes on inputs with default margins
+ line-height: $input-line-height;
+ color: $input-plaintext-color;
+ background-color: transparent;
+ border: solid transparent;
+ border-width: $input-border-width 0;
+
+ &:focus {
+ outline: 0;
+ }
+
+ &.form-control-sm,
+ &.form-control-lg {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+// Form control sizing
+//
+// Build on `.form-control` with modifier classes to decrease or increase the
+// height and font-size of form controls.
+//
+// Repeated in `_input_group.scss` to avoid Sass extend issues.
+
+.form-control-sm {
+ min-height: $input-height-sm;
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ @include font-size($input-font-size-sm);
+ @include border-radius($input-border-radius-sm);
+
+ &::file-selector-button {
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
+ margin-inline-end: $input-padding-x-sm;
+ }
+}
+
+.form-control-lg {
+ min-height: $input-height-lg;
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ @include font-size($input-font-size-lg);
+ @include border-radius($input-border-radius-lg);
+
+ &::file-selector-button {
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
+ margin-inline-end: $input-padding-x-lg;
+ }
+}
+
+// Make sure textareas don't shrink too much when resized
+// https://github.com/twbs/bootstrap/pull/29124
+// stylelint-disable selector-no-qualifying-type
+textarea {
+ &.form-control {
+ min-height: $input-height;
+ }
+
+ &.form-control-sm {
+ min-height: $input-height-sm;
+ }
+
+ &.form-control-lg {
+ min-height: $input-height-lg;
+ }
+}
+// stylelint-enable selector-no-qualifying-type
+
+.form-control-color {
+ width: $form-color-width;
+ height: $input-height;
+ padding: $input-padding-y;
+
+ &:not(:disabled):not([readonly]) {
+ cursor: pointer;
+ }
+
+ &::-moz-color-swatch {
+ border: 0 !important; // stylelint-disable-line declaration-no-important
+ @include border-radius($input-border-radius);
+ }
+
+ &::-webkit-color-swatch {
+ border: 0 !important; // stylelint-disable-line declaration-no-important
+ @include border-radius($input-border-radius);
+ }
+
+ &.form-control-sm { height: $input-height-sm; }
+ &.form-control-lg { height: $input-height-lg; }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_form-range.scss b/Moonlight/Styles/bootstrap/scss/forms/_form-range.scss
new file mode 100644
index 00000000..4732213e
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_form-range.scss
@@ -0,0 +1,91 @@
+// Range
+//
+// Style range inputs the same across browsers. Vendor-specific rules for pseudo
+// elements cannot be mixed. As such, there are no shared styles for focus or
+// active states on prefixed selectors.
+
+.form-range {
+ width: 100%;
+ height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);
+ padding: 0; // Need to reset padding
+ appearance: none;
+ background-color: transparent;
+
+ &:focus {
+ outline: 0;
+
+ // Pseudo-elements must be split across multiple rulesets to have an effect.
+ // No box-shadow() mixin for focus accessibility.
+ &::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
+ &::-moz-range-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
+ }
+
+ &::-moz-focus-outer {
+ border: 0;
+ }
+
+ &::-webkit-slider-thumb {
+ width: $form-range-thumb-width;
+ height: $form-range-thumb-height;
+ margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific
+ appearance: none;
+ @include gradient-bg($form-range-thumb-bg);
+ border: $form-range-thumb-border;
+ @include border-radius($form-range-thumb-border-radius);
+ @include box-shadow($form-range-thumb-box-shadow);
+ @include transition($form-range-thumb-transition);
+
+ &:active {
+ @include gradient-bg($form-range-thumb-active-bg);
+ }
+ }
+
+ &::-webkit-slider-runnable-track {
+ width: $form-range-track-width;
+ height: $form-range-track-height;
+ color: transparent; // Why?
+ cursor: $form-range-track-cursor;
+ background-color: $form-range-track-bg;
+ border-color: transparent;
+ @include border-radius($form-range-track-border-radius);
+ @include box-shadow($form-range-track-box-shadow);
+ }
+
+ &::-moz-range-thumb {
+ width: $form-range-thumb-width;
+ height: $form-range-thumb-height;
+ appearance: none;
+ @include gradient-bg($form-range-thumb-bg);
+ border: $form-range-thumb-border;
+ @include border-radius($form-range-thumb-border-radius);
+ @include box-shadow($form-range-thumb-box-shadow);
+ @include transition($form-range-thumb-transition);
+
+ &:active {
+ @include gradient-bg($form-range-thumb-active-bg);
+ }
+ }
+
+ &::-moz-range-track {
+ width: $form-range-track-width;
+ height: $form-range-track-height;
+ color: transparent;
+ cursor: $form-range-track-cursor;
+ background-color: $form-range-track-bg;
+ border-color: transparent; // Firefox specific?
+ @include border-radius($form-range-track-border-radius);
+ @include box-shadow($form-range-track-box-shadow);
+ }
+
+ &:disabled {
+ pointer-events: none;
+
+ &::-webkit-slider-thumb {
+ background-color: $form-range-thumb-disabled-bg;
+ }
+
+ &::-moz-range-thumb {
+ background-color: $form-range-thumb-disabled-bg;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_form-select.scss b/Moonlight/Styles/bootstrap/scss/forms/_form-select.scss
new file mode 100644
index 00000000..69ace529
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_form-select.scss
@@ -0,0 +1,80 @@
+// Select
+//
+// Replaces the browser default select with a custom one, mostly pulled from
+// https://primer.github.io/.
+
+.form-select {
+ --#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator)};
+
+ display: block;
+ width: 100%;
+ padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
+ font-family: $form-select-font-family;
+ @include font-size($form-select-font-size);
+ font-weight: $form-select-font-weight;
+ line-height: $form-select-line-height;
+ color: $form-select-color;
+ appearance: none;
+ background-color: $form-select-bg;
+ background-image: var(--#{$prefix}form-select-bg-img), var(--#{$prefix}form-select-bg-icon, none);
+ background-repeat: no-repeat;
+ background-position: $form-select-bg-position;
+ background-size: $form-select-bg-size;
+ border: $form-select-border-width solid $form-select-border-color;
+ @include border-radius($form-select-border-radius, 0);
+ @include box-shadow($form-select-box-shadow);
+ @include transition($form-select-transition);
+
+ &:focus {
+ border-color: $form-select-focus-border-color;
+ outline: 0;
+ @if $enable-shadows {
+ @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);
+ } @else {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ box-shadow: $form-select-focus-box-shadow;
+ }
+ }
+
+ &[multiple],
+ &[size]:not([size="1"]) {
+ padding-right: $form-select-padding-x;
+ background-image: none;
+ }
+
+ &:disabled {
+ color: $form-select-disabled-color;
+ background-color: $form-select-disabled-bg;
+ border-color: $form-select-disabled-border-color;
+ }
+
+ // Remove outline from select box in FF
+ &:-moz-focusring {
+ color: transparent;
+ text-shadow: 0 0 0 $form-select-color;
+ }
+}
+
+.form-select-sm {
+ padding-top: $form-select-padding-y-sm;
+ padding-bottom: $form-select-padding-y-sm;
+ padding-left: $form-select-padding-x-sm;
+ @include font-size($form-select-font-size-sm);
+ @include border-radius($form-select-border-radius-sm);
+}
+
+.form-select-lg {
+ padding-top: $form-select-padding-y-lg;
+ padding-bottom: $form-select-padding-y-lg;
+ padding-left: $form-select-padding-x-lg;
+ @include font-size($form-select-font-size-lg);
+ @include border-radius($form-select-border-radius-lg);
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .form-select {
+ --#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_form-text.scss b/Moonlight/Styles/bootstrap/scss/forms/_form-text.scss
new file mode 100644
index 00000000..f080d1a2
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_form-text.scss
@@ -0,0 +1,11 @@
+//
+// Form text
+//
+
+.form-text {
+ margin-top: $form-text-margin-top;
+ @include font-size($form-text-font-size);
+ font-style: $form-text-font-style;
+ font-weight: $form-text-font-weight;
+ color: $form-text-color;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_input-group.scss b/Moonlight/Styles/bootstrap/scss/forms/_input-group.scss
new file mode 100644
index 00000000..58e4d409
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_input-group.scss
@@ -0,0 +1,132 @@
+//
+// Base styles
+//
+
+.input-group {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap; // For form validation feedback
+ align-items: stretch;
+ width: 100%;
+
+ > .form-control,
+ > .form-select,
+ > .form-floating {
+ position: relative; // For focus state's z-index
+ flex: 1 1 auto;
+ width: 1%;
+ min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
+ }
+
+ // Bring the "active" form control to the top of surrounding elements
+ > .form-control:focus,
+ > .form-select:focus,
+ > .form-floating:focus-within {
+ z-index: 5;
+ }
+
+ // Ensure buttons are always above inputs for more visually pleasing borders.
+ // This isn't needed for `.input-group-text` since it shares the same border-color
+ // as our inputs.
+ .btn {
+ position: relative;
+ z-index: 2;
+
+ &:focus {
+ z-index: 5;
+ }
+ }
+}
+
+
+// Textual addons
+//
+// Serves as a catch-all element for any text or radio/checkbox input you wish
+// to prepend or append to an input.
+
+.input-group-text {
+ display: flex;
+ align-items: center;
+ padding: $input-group-addon-padding-y $input-group-addon-padding-x;
+ @include font-size($input-font-size); // Match inputs
+ font-weight: $input-group-addon-font-weight;
+ line-height: $input-line-height;
+ color: $input-group-addon-color;
+ text-align: center;
+ white-space: nowrap;
+ background-color: $input-group-addon-bg;
+ border: $input-border-width solid $input-group-addon-border-color;
+ @include border-radius($input-border-radius);
+}
+
+
+// Sizing
+//
+// Remix the default form control sizing classes into new ones for easier
+// manipulation.
+
+.input-group-lg > .form-control,
+.input-group-lg > .form-select,
+.input-group-lg > .input-group-text,
+.input-group-lg > .btn {
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ @include font-size($input-font-size-lg);
+ @include border-radius($input-border-radius-lg);
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .form-select,
+.input-group-sm > .input-group-text,
+.input-group-sm > .btn {
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ @include font-size($input-font-size-sm);
+ @include border-radius($input-border-radius-sm);
+}
+
+.input-group-lg > .form-select,
+.input-group-sm > .form-select {
+ padding-right: $form-select-padding-x + $form-select-indicator-padding;
+}
+
+
+// Rounded corners
+//
+// These rulesets must come after the sizing ones to properly override sm and lg
+// border-radius values when extending. They're more specific than we'd like
+// with the `.input-group >` part, but without it, we cannot override the sizing.
+
+// stylelint-disable-next-line no-duplicate-selectors
+.input-group {
+ &:not(.has-validation) {
+ > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+ > .dropdown-toggle:nth-last-child(n + 3),
+ > .form-floating:not(:last-child) > .form-control,
+ > .form-floating:not(:last-child) > .form-select {
+ @include border-end-radius(0);
+ }
+ }
+
+ &.has-validation {
+ > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+ > .dropdown-toggle:nth-last-child(n + 4),
+ > .form-floating:nth-last-child(n + 3) > .form-control,
+ > .form-floating:nth-last-child(n + 3) > .form-select {
+ @include border-end-radius(0);
+ }
+ }
+
+ $validation-messages: "";
+ @each $state in map-keys($form-validation-states) {
+ $validation-messages: $validation-messages + ":not(." + unquote($state) + "-tooltip)" + ":not(." + unquote($state) + "-feedback)";
+ }
+
+ > :not(:first-child):not(.dropdown-menu)#{$validation-messages} {
+ margin-left: calc(#{$input-border-width} * -1); // stylelint-disable-line function-disallowed-list
+ @include border-start-radius(0);
+ }
+
+ > .form-floating:not(:first-child) > .form-control,
+ > .form-floating:not(:first-child) > .form-select {
+ @include border-start-radius(0);
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_labels.scss b/Moonlight/Styles/bootstrap/scss/forms/_labels.scss
new file mode 100644
index 00000000..39ecafcd
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_labels.scss
@@ -0,0 +1,36 @@
+//
+// Labels
+//
+
+.form-label {
+ margin-bottom: $form-label-margin-bottom;
+ @include font-size($form-label-font-size);
+ font-style: $form-label-font-style;
+ font-weight: $form-label-font-weight;
+ color: $form-label-color;
+}
+
+// For use with horizontal and inline forms, when you need the label (or legend)
+// text to align with the form controls.
+.col-form-label {
+ padding-top: add($input-padding-y, $input-border-width);
+ padding-bottom: add($input-padding-y, $input-border-width);
+ margin-bottom: 0; // Override the `` default
+ @include font-size(inherit); // Override the `` default
+ font-style: $form-label-font-style;
+ font-weight: $form-label-font-weight;
+ line-height: $input-line-height;
+ color: $form-label-color;
+}
+
+.col-form-label-lg {
+ padding-top: add($input-padding-y-lg, $input-border-width);
+ padding-bottom: add($input-padding-y-lg, $input-border-width);
+ @include font-size($input-font-size-lg);
+}
+
+.col-form-label-sm {
+ padding-top: add($input-padding-y-sm, $input-border-width);
+ padding-bottom: add($input-padding-y-sm, $input-border-width);
+ @include font-size($input-font-size-sm);
+}
diff --git a/Moonlight/Styles/bootstrap/scss/forms/_validation.scss b/Moonlight/Styles/bootstrap/scss/forms/_validation.scss
new file mode 100644
index 00000000..c48123a7
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/forms/_validation.scss
@@ -0,0 +1,12 @@
+// Form validation
+//
+// Provide feedback to users when form field values are valid or invalid. Works
+// primarily for client-side validation via scoped `:invalid` and `:valid`
+// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
+// server-side validation.
+
+// scss-docs-start form-validation-states-loop
+@each $state, $data in $form-validation-states {
+ @include form-validation-state($state, $data...);
+}
+// scss-docs-end form-validation-states-loop
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_clearfix.scss b/Moonlight/Styles/bootstrap/scss/helpers/_clearfix.scss
new file mode 100644
index 00000000..e92522a9
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_clearfix.scss
@@ -0,0 +1,3 @@
+.clearfix {
+ @include clearfix();
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_color-bg.scss b/Moonlight/Styles/bootstrap/scss/helpers/_color-bg.scss
new file mode 100644
index 00000000..1a3a4cff
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_color-bg.scss
@@ -0,0 +1,7 @@
+// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
+@each $color, $value in $theme-colors {
+ .text-bg-#{$color} {
+ color: color-contrast($value) if($enable-important-utilities, !important, null);
+ background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null);
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_colored-links.scss b/Moonlight/Styles/bootstrap/scss/helpers/_colored-links.scss
new file mode 100644
index 00000000..5f868578
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_colored-links.scss
@@ -0,0 +1,30 @@
+// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
+@each $color, $value in $theme-colors {
+ .link-#{$color} {
+ color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
+ text-decoration-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
+
+ @if $link-shade-percentage != 0 {
+ &:hover,
+ &:focus {
+ $hover-color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));
+ color: RGBA(#{to-rgb($hover-color)}, var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
+ text-decoration-color: RGBA(to-rgb($hover-color), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
+ }
+ }
+ }
+}
+
+// One-off special link helper as a bridge until v6
+.link-body-emphasis {
+ color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
+ text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
+
+ @if $link-shade-percentage != 0 {
+ &:hover,
+ &:focus {
+ color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, .75)) if($enable-important-utilities, !important, null);
+ text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, .75)) if($enable-important-utilities, !important, null);
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_focus-ring.scss b/Moonlight/Styles/bootstrap/scss/helpers/_focus-ring.scss
new file mode 100644
index 00000000..26508a8d
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_focus-ring.scss
@@ -0,0 +1,5 @@
+.focus-ring:focus {
+ outline: 0;
+ // By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values
+ box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color);
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_icon-link.scss b/Moonlight/Styles/bootstrap/scss/helpers/_icon-link.scss
new file mode 100644
index 00000000..3f8bcb33
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_icon-link.scss
@@ -0,0 +1,25 @@
+.icon-link {
+ display: inline-flex;
+ gap: $icon-link-gap;
+ align-items: center;
+ text-decoration-color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, .5));
+ text-underline-offset: $icon-link-underline-offset;
+ backface-visibility: hidden;
+
+ > .bi {
+ flex-shrink: 0;
+ width: $icon-link-icon-size;
+ height: $icon-link-icon-size;
+ fill: currentcolor;
+ @include transition($icon-link-icon-transition);
+ }
+}
+
+.icon-link-hover {
+ &:hover,
+ &:focus-visible {
+ > .bi {
+ transform: var(--#{$prefix}icon-link-transform, $icon-link-icon-transform);
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_position.scss b/Moonlight/Styles/bootstrap/scss/helpers/_position.scss
new file mode 100644
index 00000000..59103d94
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_position.scss
@@ -0,0 +1,36 @@
+// Shorthand
+
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+// Responsive sticky top and bottom
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .sticky#{$infix}-top {
+ position: sticky;
+ top: 0;
+ z-index: $zindex-sticky;
+ }
+
+ .sticky#{$infix}-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: $zindex-sticky;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_ratio.scss b/Moonlight/Styles/bootstrap/scss/helpers/_ratio.scss
new file mode 100644
index 00000000..b6a7654c
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_ratio.scss
@@ -0,0 +1,26 @@
+// Credit: Nicolas Gallagher and SUIT CSS.
+
+.ratio {
+ position: relative;
+ width: 100%;
+
+ &::before {
+ display: block;
+ padding-top: var(--#{$prefix}aspect-ratio);
+ content: "";
+ }
+
+ > * {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+}
+
+@each $key, $ratio in $aspect-ratios {
+ .ratio-#{$key} {
+ --#{$prefix}aspect-ratio: #{$ratio};
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_stacks.scss b/Moonlight/Styles/bootstrap/scss/helpers/_stacks.scss
new file mode 100644
index 00000000..6cd237ae
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_stacks.scss
@@ -0,0 +1,15 @@
+// scss-docs-start stacks
+.hstack {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ align-self: stretch;
+}
+
+.vstack {
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+ align-self: stretch;
+}
+// scss-docs-end stacks
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_stretched-link.scss b/Moonlight/Styles/bootstrap/scss/helpers/_stretched-link.scss
new file mode 100644
index 00000000..71a1c755
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_stretched-link.scss
@@ -0,0 +1,15 @@
+//
+// Stretched link
+//
+
+.stretched-link {
+ &::#{$stretched-link-pseudo-element} {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $stretched-link-z-index;
+ content: "";
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_text-truncation.scss b/Moonlight/Styles/bootstrap/scss/helpers/_text-truncation.scss
new file mode 100644
index 00000000..6421dac9
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_text-truncation.scss
@@ -0,0 +1,7 @@
+//
+// Text truncation
+//
+
+.text-truncate {
+ @include text-truncate();
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_visually-hidden.scss b/Moonlight/Styles/bootstrap/scss/helpers/_visually-hidden.scss
new file mode 100644
index 00000000..4760ff03
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_visually-hidden.scss
@@ -0,0 +1,8 @@
+//
+// Visually hidden
+//
+
+.visually-hidden,
+.visually-hidden-focusable:not(:focus):not(:focus-within) {
+ @include visually-hidden();
+}
diff --git a/Moonlight/Styles/bootstrap/scss/helpers/_vr.scss b/Moonlight/Styles/bootstrap/scss/helpers/_vr.scss
new file mode 100644
index 00000000..b6f9d42c
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/helpers/_vr.scss
@@ -0,0 +1,8 @@
+.vr {
+ display: inline-block;
+ align-self: stretch;
+ width: $vr-border-width;
+ min-height: 1em;
+ background-color: currentcolor;
+ opacity: $hr-opacity;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_alert.scss b/Moonlight/Styles/bootstrap/scss/mixins/_alert.scss
new file mode 100644
index 00000000..fb524af1
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_alert.scss
@@ -0,0 +1,18 @@
+@include deprecate("`alert-variant()`", "v5.3.0", "v6.0.0");
+
+// scss-docs-start alert-variant-mixin
+@mixin alert-variant($background, $border, $color) {
+ --#{$prefix}alert-color: #{$color};
+ --#{$prefix}alert-bg: #{$background};
+ --#{$prefix}alert-border-color: #{$border};
+ --#{$prefix}alert-link-color: #{shade-color($color, 20%)};
+
+ @if $enable-gradients {
+ background-image: var(--#{$prefix}gradient);
+ }
+
+ .alert-link {
+ color: var(--#{$prefix}alert-link-color);
+ }
+}
+// scss-docs-end alert-variant-mixin
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_backdrop.scss b/Moonlight/Styles/bootstrap/scss/mixins/_backdrop.scss
new file mode 100644
index 00000000..9705ae9e
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_backdrop.scss
@@ -0,0 +1,14 @@
+// Shared between modals and offcanvases
+@mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: $zindex;
+ width: 100vw;
+ height: 100vh;
+ background-color: $backdrop-bg;
+
+ // Fade for backdrop
+ &.fade { opacity: 0; }
+ &.show { opacity: $backdrop-opacity; }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_banner.scss b/Moonlight/Styles/bootstrap/scss/mixins/_banner.scss
new file mode 100644
index 00000000..ee2c5842
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_banner.scss
@@ -0,0 +1,7 @@
+@mixin bsBanner($file) {
+ /*!
+ * Bootstrap #{$file} v5.3.2 (https://getbootstrap.com/)
+ * Copyright 2011-2023 The Bootstrap Authors
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_border-radius.scss b/Moonlight/Styles/bootstrap/scss/mixins/_border-radius.scss
new file mode 100644
index 00000000..616decbc
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_border-radius.scss
@@ -0,0 +1,78 @@
+// stylelint-disable property-disallowed-list
+// Single side border-radius
+
+// Helper function to replace negative values with 0
+@function valid-radius($radius) {
+ $return: ();
+ @each $value in $radius {
+ @if type-of($value) == number {
+ $return: append($return, max($value, 0));
+ } @else {
+ $return: append($return, $value);
+ }
+ }
+ @return $return;
+}
+
+// scss-docs-start border-radius-mixins
+@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
+ @if $enable-rounded {
+ border-radius: valid-radius($radius);
+ }
+ @else if $fallback-border-radius != false {
+ border-radius: $fallback-border-radius;
+ }
+}
+
+@mixin border-top-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-top-left-radius: valid-radius($radius);
+ border-top-right-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-end-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-top-right-radius: valid-radius($radius);
+ border-bottom-right-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-bottom-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-bottom-right-radius: valid-radius($radius);
+ border-bottom-left-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-start-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-top-left-radius: valid-radius($radius);
+ border-bottom-left-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-top-start-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-top-left-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-top-end-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-top-right-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-bottom-end-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-bottom-right-radius: valid-radius($radius);
+ }
+}
+
+@mixin border-bottom-start-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-bottom-left-radius: valid-radius($radius);
+ }
+}
+// scss-docs-end border-radius-mixins
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_box-shadow.scss b/Moonlight/Styles/bootstrap/scss/mixins/_box-shadow.scss
new file mode 100644
index 00000000..4172541f
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_box-shadow.scss
@@ -0,0 +1,18 @@
+@mixin box-shadow($shadow...) {
+ @if $enable-shadows {
+ $result: ();
+
+ @each $value in $shadow {
+ @if $value != null {
+ $result: append($result, $value, "comma");
+ }
+ @if $value == none and length($shadow) > 1 {
+ @warn "The keyword 'none' must be used as a single argument.";
+ }
+ }
+
+ @if (length($result) > 0) {
+ box-shadow: $result;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_breakpoints.scss b/Moonlight/Styles/bootstrap/scss/mixins/_breakpoints.scss
new file mode 100644
index 00000000..286be893
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_breakpoints.scss
@@ -0,0 +1,127 @@
+// Breakpoint viewport sizes and media queries.
+//
+// Breakpoints are defined as a map of (name: minimum width), order from small to large:
+//
+// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)
+//
+// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
+
+// Name of the next breakpoint, or null for the last breakpoint.
+//
+// >> breakpoint-next(sm)
+// md
+// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
+// md
+// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))
+// md
+@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
+ $n: index($breakpoint-names, $name);
+ @if not $n {
+ @error "breakpoint `#{$name}` not found in `#{$breakpoints}`";
+ }
+ @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
+}
+
+// Minimum breakpoint width. Null for the smallest (first) breakpoint.
+//
+// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
+// 576px
+@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
+ $min: map-get($breakpoints, $name);
+ @return if($min != 0, $min, null);
+}
+
+// Maximum breakpoint width.
+// The maximum value is reduced by 0.02px to work around the limitations of
+// `min-` and `max-` prefixes and viewports with fractional widths.
+// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
+// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
+// See https://bugs.webkit.org/show_bug.cgi?id=178261
+//
+// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
+// 767.98px
+@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
+ $max: map-get($breakpoints, $name);
+ @return if($max and $max > 0, $max - .02, null);
+}
+
+// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
+// Useful for making responsive utilities.
+//
+// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
+// "" (Returns a blank string)
+// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
+// "-sm"
+@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
+ @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
+}
+
+// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
+// Makes the @content apply to the given breakpoint and wider.
+@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($name, $breakpoints);
+ @if $min {
+ @media (min-width: $min) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
+// Makes the @content apply to the given breakpoint and narrower.
+@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
+ $max: breakpoint-max($name, $breakpoints);
+ @if $max {
+ @media (max-width: $max) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media that spans multiple breakpoint widths.
+// Makes the @content apply between the min and max breakpoints
+@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($lower, $breakpoints);
+ $max: breakpoint-max($upper, $breakpoints);
+
+ @if $min != null and $max != null {
+ @media (min-width: $min) and (max-width: $max) {
+ @content;
+ }
+ } @else if $max == null {
+ @include media-breakpoint-up($lower, $breakpoints) {
+ @content;
+ }
+ } @else if $min == null {
+ @include media-breakpoint-down($upper, $breakpoints) {
+ @content;
+ }
+ }
+}
+
+// Media between the breakpoint's minimum and maximum widths.
+// No minimum for the smallest breakpoint, and no maximum for the largest one.
+// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
+@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($name, $breakpoints);
+ $next: breakpoint-next($name, $breakpoints);
+ $max: breakpoint-max($next, $breakpoints);
+
+ @if $min != null and $max != null {
+ @media (min-width: $min) and (max-width: $max) {
+ @content;
+ }
+ } @else if $max == null {
+ @include media-breakpoint-up($name, $breakpoints) {
+ @content;
+ }
+ } @else if $min == null {
+ @include media-breakpoint-down($next, $breakpoints) {
+ @content;
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_buttons.scss b/Moonlight/Styles/bootstrap/scss/mixins/_buttons.scss
new file mode 100644
index 00000000..cf087fda
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_buttons.scss
@@ -0,0 +1,70 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+// scss-docs-start btn-variant-mixin
+@mixin button-variant(
+ $background,
+ $border,
+ $color: color-contrast($background),
+ $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),
+ $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),
+ $hover-color: color-contrast($hover-background),
+ $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),
+ $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),
+ $active-color: color-contrast($active-background),
+ $disabled-background: $background,
+ $disabled-border: $border,
+ $disabled-color: color-contrast($disabled-background)
+) {
+ --#{$prefix}btn-color: #{$color};
+ --#{$prefix}btn-bg: #{$background};
+ --#{$prefix}btn-border-color: #{$border};
+ --#{$prefix}btn-hover-color: #{$hover-color};
+ --#{$prefix}btn-hover-bg: #{$hover-background};
+ --#{$prefix}btn-hover-border-color: #{$hover-border};
+ --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))};
+ --#{$prefix}btn-active-color: #{$active-color};
+ --#{$prefix}btn-active-bg: #{$active-background};
+ --#{$prefix}btn-active-border-color: #{$active-border};
+ --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
+ --#{$prefix}btn-disabled-color: #{$disabled-color};
+ --#{$prefix}btn-disabled-bg: #{$disabled-background};
+ --#{$prefix}btn-disabled-border-color: #{$disabled-border};
+}
+// scss-docs-end btn-variant-mixin
+
+// scss-docs-start btn-outline-variant-mixin
+@mixin button-outline-variant(
+ $color,
+ $color-hover: color-contrast($color),
+ $active-background: $color,
+ $active-border: $color,
+ $active-color: color-contrast($active-background)
+) {
+ --#{$prefix}btn-color: #{$color};
+ --#{$prefix}btn-border-color: #{$color};
+ --#{$prefix}btn-hover-color: #{$color-hover};
+ --#{$prefix}btn-hover-bg: #{$active-background};
+ --#{$prefix}btn-hover-border-color: #{$active-border};
+ --#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)};
+ --#{$prefix}btn-active-color: #{$active-color};
+ --#{$prefix}btn-active-bg: #{$active-background};
+ --#{$prefix}btn-active-border-color: #{$active-border};
+ --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
+ --#{$prefix}btn-disabled-color: #{$color};
+ --#{$prefix}btn-disabled-bg: transparent;
+ --#{$prefix}btn-disabled-border-color: #{$color};
+ --#{$prefix}gradient: none;
+}
+// scss-docs-end btn-outline-variant-mixin
+
+// scss-docs-start btn-size-mixin
+@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
+ --#{$prefix}btn-padding-y: #{$padding-y};
+ --#{$prefix}btn-padding-x: #{$padding-x};
+ @include rfs($font-size, --#{$prefix}btn-font-size);
+ --#{$prefix}btn-border-radius: #{$border-radius};
+}
+// scss-docs-end btn-size-mixin
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_caret.scss b/Moonlight/Styles/bootstrap/scss/mixins/_caret.scss
new file mode 100644
index 00000000..be731165
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_caret.scss
@@ -0,0 +1,69 @@
+// scss-docs-start caret-mixins
+@mixin caret-down($width: $caret-width) {
+ border-top: $width solid;
+ border-right: $width solid transparent;
+ border-bottom: 0;
+ border-left: $width solid transparent;
+}
+
+@mixin caret-up($width: $caret-width) {
+ border-top: 0;
+ border-right: $width solid transparent;
+ border-bottom: $width solid;
+ border-left: $width solid transparent;
+}
+
+@mixin caret-end($width: $caret-width) {
+ border-top: $width solid transparent;
+ border-right: 0;
+ border-bottom: $width solid transparent;
+ border-left: $width solid;
+}
+
+@mixin caret-start($width: $caret-width) {
+ border-top: $width solid transparent;
+ border-right: $width solid;
+ border-bottom: $width solid transparent;
+}
+
+@mixin caret(
+ $direction: down,
+ $width: $caret-width,
+ $spacing: $caret-spacing,
+ $vertical-align: $caret-vertical-align
+) {
+ @if $enable-caret {
+ &::after {
+ display: inline-block;
+ margin-left: $spacing;
+ vertical-align: $vertical-align;
+ content: "";
+ @if $direction == down {
+ @include caret-down($width);
+ } @else if $direction == up {
+ @include caret-up($width);
+ } @else if $direction == end {
+ @include caret-end($width);
+ }
+ }
+
+ @if $direction == start {
+ &::after {
+ display: none;
+ }
+
+ &::before {
+ display: inline-block;
+ margin-right: $spacing;
+ vertical-align: $vertical-align;
+ content: "";
+ @include caret-start($width);
+ }
+ }
+
+ &:empty::after {
+ margin-left: 0;
+ }
+ }
+}
+// scss-docs-end caret-mixins
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_clearfix.scss b/Moonlight/Styles/bootstrap/scss/mixins/_clearfix.scss
new file mode 100644
index 00000000..ffc62bb2
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_clearfix.scss
@@ -0,0 +1,9 @@
+// scss-docs-start clearfix
+@mixin clearfix() {
+ &::after {
+ display: block;
+ clear: both;
+ content: "";
+ }
+}
+// scss-docs-end clearfix
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_color-mode.scss b/Moonlight/Styles/bootstrap/scss/mixins/_color-mode.scss
new file mode 100644
index 00000000..03338b02
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_color-mode.scss
@@ -0,0 +1,21 @@
+// scss-docs-start color-mode-mixin
+@mixin color-mode($mode: light, $root: false) {
+ @if $color-mode-type == "media-query" {
+ @if $root == true {
+ @media (prefers-color-scheme: $mode) {
+ :root {
+ @content;
+ }
+ }
+ } @else {
+ @media (prefers-color-scheme: $mode) {
+ @content;
+ }
+ }
+ } @else {
+ [data-bs-theme="#{$mode}"] {
+ @content;
+ }
+ }
+}
+// scss-docs-end color-mode-mixin
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_color-scheme.scss b/Moonlight/Styles/bootstrap/scss/mixins/_color-scheme.scss
new file mode 100644
index 00000000..90497aa0
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_color-scheme.scss
@@ -0,0 +1,7 @@
+// scss-docs-start mixin-color-scheme
+@mixin color-scheme($name) {
+ @media (prefers-color-scheme: #{$name}) {
+ @content;
+ }
+}
+// scss-docs-end mixin-color-scheme
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_container.scss b/Moonlight/Styles/bootstrap/scss/mixins/_container.scss
new file mode 100644
index 00000000..b9f33519
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_container.scss
@@ -0,0 +1,11 @@
+// Container mixins
+
+@mixin make-container($gutter: $container-padding-x) {
+ --#{$prefix}gutter-x: #{$gutter};
+ --#{$prefix}gutter-y: 0;
+ width: 100%;
+ padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
+ padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
+ margin-right: auto;
+ margin-left: auto;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_deprecate.scss b/Moonlight/Styles/bootstrap/scss/mixins/_deprecate.scss
new file mode 100644
index 00000000..df070bc5
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_deprecate.scss
@@ -0,0 +1,10 @@
+// Deprecate mixin
+//
+// This mixin can be used to deprecate mixins or functions.
+// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
+// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
+@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
+ @if ($enable-deprecation-messages != false and $ignore-warning != true) {
+ @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_forms.scss b/Moonlight/Styles/bootstrap/scss/mixins/_forms.scss
new file mode 100644
index 00000000..d47b1e41
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_forms.scss
@@ -0,0 +1,153 @@
+// This mixin uses an `if()` technique to be compatible with Dart Sass
+// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
+
+// scss-docs-start form-validation-mixins
+@mixin form-validation-state-selector($state) {
+ @if ($state == "valid" or $state == "invalid") {
+ .was-validated #{if(&, "&", "")}:#{$state},
+ #{if(&, "&", "")}.is-#{$state} {
+ @content;
+ }
+ } @else {
+ #{if(&, "&", "")}.is-#{$state} {
+ @content;
+ }
+ }
+}
+
+@mixin form-validation-state(
+ $state,
+ $color,
+ $icon,
+ $tooltip-color: color-contrast($color),
+ $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
+ $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity),
+ $border-color: $color
+) {
+ .#{$state}-feedback {
+ display: none;
+ width: 100%;
+ margin-top: $form-feedback-margin-top;
+ @include font-size($form-feedback-font-size);
+ font-style: $form-feedback-font-style;
+ color: $color;
+ }
+
+ .#{$state}-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ max-width: 100%; // Contain to parent when possible
+ padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
+ margin-top: .1rem;
+ @include font-size($form-feedback-tooltip-font-size);
+ line-height: $form-feedback-tooltip-line-height;
+ color: $tooltip-color;
+ background-color: $tooltip-bg-color;
+ @include border-radius($form-feedback-tooltip-border-radius);
+ }
+
+ @include form-validation-state-selector($state) {
+ ~ .#{$state}-feedback,
+ ~ .#{$state}-tooltip {
+ display: block;
+ }
+ }
+
+ .form-control {
+ @include form-validation-state-selector($state) {
+ border-color: $border-color;
+
+ @if $enable-validation-icons {
+ padding-right: $input-height-inner;
+ background-image: escape-svg($icon);
+ background-repeat: no-repeat;
+ background-position: right $input-height-inner-quarter center;
+ background-size: $input-height-inner-half $input-height-inner-half;
+ }
+
+ &:focus {
+ border-color: $border-color;
+ box-shadow: $focus-box-shadow;
+ }
+ }
+ }
+
+ // stylelint-disable-next-line selector-no-qualifying-type
+ textarea.form-control {
+ @include form-validation-state-selector($state) {
+ @if $enable-validation-icons {
+ padding-right: $input-height-inner;
+ background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
+ }
+ }
+ }
+
+ .form-select {
+ @include form-validation-state-selector($state) {
+ border-color: $border-color;
+
+ @if $enable-validation-icons {
+ &:not([multiple]):not([size]),
+ &:not([multiple])[size="1"] {
+ --#{$prefix}form-select-bg-icon: #{escape-svg($icon)};
+ padding-right: $form-select-feedback-icon-padding-end;
+ background-position: $form-select-bg-position, $form-select-feedback-icon-position;
+ background-size: $form-select-bg-size, $form-select-feedback-icon-size;
+ }
+ }
+
+ &:focus {
+ border-color: $border-color;
+ box-shadow: $focus-box-shadow;
+ }
+ }
+ }
+
+ .form-control-color {
+ @include form-validation-state-selector($state) {
+ @if $enable-validation-icons {
+ width: add($form-color-width, $input-height-inner);
+ }
+ }
+ }
+
+ .form-check-input {
+ @include form-validation-state-selector($state) {
+ border-color: $border-color;
+
+ &:checked {
+ background-color: $color;
+ }
+
+ &:focus {
+ box-shadow: $focus-box-shadow;
+ }
+
+ ~ .form-check-label {
+ color: $color;
+ }
+ }
+ }
+ .form-check-inline .form-check-input {
+ ~ .#{$state}-feedback {
+ margin-left: .5em;
+ }
+ }
+
+ .input-group {
+ > .form-control:not(:focus),
+ > .form-select:not(:focus),
+ > .form-floating:not(:focus-within) {
+ @include form-validation-state-selector($state) {
+ @if $state == "valid" {
+ z-index: 3;
+ } @else if $state == "invalid" {
+ z-index: 4;
+ }
+ }
+ }
+ }
+}
+// scss-docs-end form-validation-mixins
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_gradients.scss b/Moonlight/Styles/bootstrap/scss/mixins/_gradients.scss
new file mode 100644
index 00000000..608e18df
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_gradients.scss
@@ -0,0 +1,47 @@
+// Gradients
+
+// scss-docs-start gradient-bg-mixin
+@mixin gradient-bg($color: null) {
+ background-color: $color;
+
+ @if $enable-gradients {
+ background-image: var(--#{$prefix}gradient);
+ }
+}
+// scss-docs-end gradient-bg-mixin
+
+// scss-docs-start gradient-mixins
+// Horizontal gradient, from left to right
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
+}
+
+// Vertical gradient, from top to bottom
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) {
+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
+}
+
+@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {
+ background-image: linear-gradient($deg, $start-color, $end-color);
+}
+
+@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
+ background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
+}
+
+@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
+ background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
+}
+
+@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {
+ background-image: radial-gradient(circle, $inner-color, $outer-color);
+}
+
+@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {
+ background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+}
+// scss-docs-end gradient-mixins
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_grid.scss b/Moonlight/Styles/bootstrap/scss/mixins/_grid.scss
new file mode 100644
index 00000000..99b1e7de
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_grid.scss
@@ -0,0 +1,151 @@
+// Grid system
+//
+// Generate semantic grid columns with these mixins.
+
+@mixin make-row($gutter: $grid-gutter-width) {
+ --#{$prefix}gutter-x: #{$gutter};
+ --#{$prefix}gutter-y: 0;
+ display: flex;
+ flex-wrap: wrap;
+ // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed
+ margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list
+ margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
+ margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
+}
+
+@mixin make-col-ready() {
+ // Add box sizing if only the grid is loaded
+ box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);
+ // Prevent columns from becoming too narrow when at smaller grid tiers by
+ // always setting `width: 100%;`. This works because we set the width
+ // later on to override this initial width.
+ flex-shrink: 0;
+ width: 100%;
+ max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid
+ padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
+ padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
+ margin-top: var(--#{$prefix}gutter-y);
+}
+
+@mixin make-col($size: false, $columns: $grid-columns) {
+ @if $size {
+ flex: 0 0 auto;
+ width: percentage(divide($size, $columns));
+
+ } @else {
+ flex: 1 1 0;
+ max-width: 100%;
+ }
+}
+
+@mixin make-col-auto() {
+ flex: 0 0 auto;
+ width: auto;
+}
+
+@mixin make-col-offset($size, $columns: $grid-columns) {
+ $num: divide($size, $columns);
+ margin-left: if($num == 0, 0, percentage($num));
+}
+
+// Row columns
+//
+// Specify on a parent element(e.g., .row) to force immediate children into NN
+// number of columns. Supports wrapping to new lines, but does not do a Masonry
+// style grid.
+@mixin row-cols($count) {
+ > * {
+ flex: 0 0 auto;
+ width: percentage(divide(1, $count));
+ }
+}
+
+// Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `$grid-columns`.
+
+@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
+ @each $breakpoint in map-keys($breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $breakpoints);
+
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ // Provide basic `.col-{bp}` classes for equal-width flexbox columns
+ .col#{$infix} {
+ flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
+ }
+
+ .row-cols#{$infix}-auto > * {
+ @include make-col-auto();
+ }
+
+ @if $grid-row-columns > 0 {
+ @for $i from 1 through $grid-row-columns {
+ .row-cols#{$infix}-#{$i} {
+ @include row-cols($i);
+ }
+ }
+ }
+
+ .col#{$infix}-auto {
+ @include make-col-auto();
+ }
+
+ @if $columns > 0 {
+ @for $i from 1 through $columns {
+ .col#{$infix}-#{$i} {
+ @include make-col($i, $columns);
+ }
+ }
+
+ // `$columns - 1` because offsetting by the width of an entire row isn't possible
+ @for $i from 0 through ($columns - 1) {
+ @if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
+ .offset#{$infix}-#{$i} {
+ @include make-col-offset($i, $columns);
+ }
+ }
+ }
+ }
+
+ // Gutters
+ //
+ // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.
+ @each $key, $value in $gutters {
+ .g#{$infix}-#{$key},
+ .gx#{$infix}-#{$key} {
+ --#{$prefix}gutter-x: #{$value};
+ }
+
+ .g#{$infix}-#{$key},
+ .gy#{$infix}-#{$key} {
+ --#{$prefix}gutter-y: #{$value};
+ }
+ }
+ }
+ }
+}
+
+@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {
+ @each $breakpoint in map-keys($breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $breakpoints);
+
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ @if $columns > 0 {
+ @for $i from 1 through $columns {
+ .g-col#{$infix}-#{$i} {
+ grid-column: auto / span $i;
+ }
+ }
+
+ // Start with `1` because `0` is and invalid value.
+ // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.
+ @for $i from 1 through ($columns - 1) {
+ .g-start#{$infix}-#{$i} {
+ grid-column-start: $i;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_image.scss b/Moonlight/Styles/bootstrap/scss/mixins/_image.scss
new file mode 100644
index 00000000..e1df779f
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_image.scss
@@ -0,0 +1,16 @@
+// Image Mixins
+// - Responsive image
+// - Retina image
+
+
+// Responsive image
+//
+// Keep images from scaling beyond the width of their parents.
+
+@mixin img-fluid {
+ // Part 1: Set a maximum relative to the parent
+ max-width: 100%;
+ // Part 2: Override the height to auto, otherwise images will be stretched
+ // when setting a width and height attribute on the img element.
+ height: auto;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_list-group.scss b/Moonlight/Styles/bootstrap/scss/mixins/_list-group.scss
new file mode 100644
index 00000000..6274f343
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_list-group.scss
@@ -0,0 +1,26 @@
+@include deprecate("`list-group-item-variant()`", "v5.3.0", "v6.0.0");
+
+// List Groups
+
+// scss-docs-start list-group-mixin
+@mixin list-group-item-variant($state, $background, $color) {
+ .list-group-item-#{$state} {
+ color: $color;
+ background-color: $background;
+
+ &.list-group-item-action {
+ &:hover,
+ &:focus {
+ color: $color;
+ background-color: shade-color($background, 10%);
+ }
+
+ &.active {
+ color: $white;
+ background-color: $color;
+ border-color: $color;
+ }
+ }
+ }
+}
+// scss-docs-end list-group-mixin
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_lists.scss b/Moonlight/Styles/bootstrap/scss/mixins/_lists.scss
new file mode 100644
index 00000000..25185626
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_lists.scss
@@ -0,0 +1,7 @@
+// Lists
+
+// Unstyled keeps list items block level, just removes default browser padding and list-style
+@mixin list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_pagination.scss b/Moonlight/Styles/bootstrap/scss/mixins/_pagination.scss
new file mode 100644
index 00000000..0d657964
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_pagination.scss
@@ -0,0 +1,10 @@
+// Pagination
+
+// scss-docs-start pagination-mixin
+@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) {
+ --#{$prefix}pagination-padding-x: #{$padding-x};
+ --#{$prefix}pagination-padding-y: #{$padding-y};
+ @include rfs($font-size, --#{$prefix}pagination-font-size);
+ --#{$prefix}pagination-border-radius: #{$border-radius};
+}
+// scss-docs-end pagination-mixin
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_reset-text.scss b/Moonlight/Styles/bootstrap/scss/mixins/_reset-text.scss
new file mode 100644
index 00000000..f5bd1afe
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_reset-text.scss
@@ -0,0 +1,17 @@
+@mixin reset-text {
+ font-family: $font-family-base;
+ // We deliberately do NOT reset font-size or overflow-wrap / word-wrap.
+ font-style: normal;
+ font-weight: $font-weight-normal;
+ line-height: $line-height-base;
+ text-align: left; // Fallback for where `start` is not supported
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ white-space: normal;
+ word-spacing: normal;
+ line-break: auto;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_resize.scss b/Moonlight/Styles/bootstrap/scss/mixins/_resize.scss
new file mode 100644
index 00000000..66f233a6
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_resize.scss
@@ -0,0 +1,6 @@
+// Resize anything
+
+@mixin resizable($direction) {
+ overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
+ resize: $direction; // Options: horizontal, vertical, both
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_table-variants.scss b/Moonlight/Styles/bootstrap/scss/mixins/_table-variants.scss
new file mode 100644
index 00000000..5fe1b9b2
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_table-variants.scss
@@ -0,0 +1,24 @@
+// scss-docs-start table-variant
+@mixin table-variant($state, $background) {
+ .table-#{$state} {
+ $color: color-contrast(opaque($body-bg, $background));
+ $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
+ $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
+ $active-bg: mix($color, $background, percentage($table-active-bg-factor));
+ $table-border-color: mix($color, $background, percentage($table-border-factor));
+
+ --#{$prefix}table-color: #{$color};
+ --#{$prefix}table-bg: #{$background};
+ --#{$prefix}table-border-color: #{$table-border-color};
+ --#{$prefix}table-striped-bg: #{$striped-bg};
+ --#{$prefix}table-striped-color: #{color-contrast($striped-bg)};
+ --#{$prefix}table-active-bg: #{$active-bg};
+ --#{$prefix}table-active-color: #{color-contrast($active-bg)};
+ --#{$prefix}table-hover-bg: #{$hover-bg};
+ --#{$prefix}table-hover-color: #{color-contrast($hover-bg)};
+
+ color: var(--#{$prefix}table-color);
+ border-color: var(--#{$prefix}table-border-color);
+ }
+}
+// scss-docs-end table-variant
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_text-truncate.scss b/Moonlight/Styles/bootstrap/scss/mixins/_text-truncate.scss
new file mode 100644
index 00000000..3504bb1a
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_text-truncate.scss
@@ -0,0 +1,8 @@
+// Text truncate
+// Requires inline-block or block for proper styling
+
+@mixin text-truncate() {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_transition.scss b/Moonlight/Styles/bootstrap/scss/mixins/_transition.scss
new file mode 100644
index 00000000..d437f6d8
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_transition.scss
@@ -0,0 +1,26 @@
+// stylelint-disable property-disallowed-list
+@mixin transition($transition...) {
+ @if length($transition) == 0 {
+ $transition: $transition-base;
+ }
+
+ @if length($transition) > 1 {
+ @each $value in $transition {
+ @if $value == null or $value == none {
+ @warn "The keyword 'none' or 'null' must be used as a single argument.";
+ }
+ }
+ }
+
+ @if $enable-transitions {
+ @if nth($transition, 1) != null {
+ transition: $transition;
+ }
+
+ @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none {
+ @media (prefers-reduced-motion: reduce) {
+ transition: none;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_utilities.scss b/Moonlight/Styles/bootstrap/scss/mixins/_utilities.scss
new file mode 100644
index 00000000..4795e894
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_utilities.scss
@@ -0,0 +1,97 @@
+// Utility generator
+// Used to generate utilities & print utilities
+@mixin generate-utility($utility, $infix: "", $is-rfs-media-query: false) {
+ $values: map-get($utility, values);
+
+ // If the values are a list or string, convert it into a map
+ @if type-of($values) == "string" or type-of(nth($values, 1)) != "list" {
+ $values: zip($values, $values);
+ }
+
+ @each $key, $value in $values {
+ $properties: map-get($utility, property);
+
+ // Multiple properties are possible, for example with vertical or horizontal margins or paddings
+ @if type-of($properties) == "string" {
+ $properties: append((), $properties);
+ }
+
+ // Use custom class if present
+ $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));
+ $property-class: if($property-class == null, "", $property-class);
+
+ // Use custom CSS variable name if present, otherwise default to `class`
+ $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));
+
+ // State params to generate pseudo-classes
+ $state: if(map-has-key($utility, state), map-get($utility, state), ());
+
+ $infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix);
+
+ // Don't prefix if value key is null (e.g. with shadow class)
+ $property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, "");
+
+ @if map-get($utility, rfs) {
+ // Inside the media query
+ @if $is-rfs-media-query {
+ $val: rfs-value($value);
+
+ // Do not render anything if fluid and non fluid values are the same
+ $value: if($val == rfs-fluid-value($value), null, $val);
+ }
+ @else {
+ $value: rfs-fluid-value($value);
+ }
+ }
+
+ $is-css-var: map-get($utility, css-var);
+ $is-local-vars: map-get($utility, local-vars);
+ $is-rtl: map-get($utility, rtl);
+
+ @if $value != null {
+ @if $is-rtl == false {
+ /* rtl:begin:remove */
+ }
+
+ @if $is-css-var {
+ .#{$property-class + $infix + $property-class-modifier} {
+ --#{$prefix}#{$css-variable-name}: #{$value};
+ }
+
+ @each $pseudo in $state {
+ .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
+ --#{$prefix}#{$css-variable-name}: #{$value};
+ }
+ }
+ } @else {
+ .#{$property-class + $infix + $property-class-modifier} {
+ @each $property in $properties {
+ @if $is-local-vars {
+ @each $local-var, $variable in $is-local-vars {
+ --#{$prefix}#{$local-var}: #{$variable};
+ }
+ }
+ #{$property}: $value if($enable-important-utilities, !important, null);
+ }
+ }
+
+ @each $pseudo in $state {
+ .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
+ @each $property in $properties {
+ @if $is-local-vars {
+ @each $local-var, $variable in $is-local-vars {
+ --#{$prefix}#{$local-var}: #{$variable};
+ }
+ }
+ #{$property}: $value if($enable-important-utilities, !important, null);
+ }
+ }
+ }
+ }
+
+ @if $is-rtl == false {
+ /* rtl:end:remove */
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/mixins/_visually-hidden.scss b/Moonlight/Styles/bootstrap/scss/mixins/_visually-hidden.scss
new file mode 100644
index 00000000..082aeec9
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/mixins/_visually-hidden.scss
@@ -0,0 +1,33 @@
+// stylelint-disable declaration-no-important
+
+// Hide content visually while keeping it accessible to assistive technologies
+//
+// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/
+// See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/
+
+@mixin visually-hidden() {
+ width: 1px !important;
+ height: 1px !important;
+ padding: 0 !important;
+ margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686
+ overflow: hidden !important;
+ clip: rect(0, 0, 0, 0) !important;
+ white-space: nowrap !important;
+ border: 0 !important;
+
+ // Fix for positioned table caption that could become anonymous cells
+ &:not(caption) {
+ position: absolute !important;
+ }
+}
+
+// Use to only display content when it's focused, or one of its child elements is focused
+// (i.e. when focus is within the element/container that the class was applied to)
+//
+// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+
+@mixin visually-hidden-focusable() {
+ &:not(:focus):not(:focus-within) {
+ @include visually-hidden();
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/jasmine.js b/Moonlight/Styles/bootstrap/scss/tests/jasmine.js
new file mode 100644
index 00000000..25d838c9
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/jasmine.js
@@ -0,0 +1,16 @@
+/* eslint-disable camelcase */
+
+'use strict'
+
+const path = require('node:path')
+
+module.exports = {
+ spec_dir: 'scss',
+ // Make Jasmine look for `.test.scss` files
+ spec_files: ['**/*.{test,spec}.scss'],
+ // Compile them into JS scripts running `sass-true`
+ requires: [path.join(__dirname, 'sass-true/register')],
+ // Ensure we use `require` so that the require.extensions works
+ // as `import` completely bypasses it
+ jsLoader: 'require'
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/mixins/_color-modes.test.scss b/Moonlight/Styles/bootstrap/scss/tests/mixins/_color-modes.test.scss
new file mode 100644
index 00000000..9ecc628d
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/mixins/_color-modes.test.scss
@@ -0,0 +1,69 @@
+// stylelint-disable selector-attribute-quotes
+
+@import "../../functions";
+@import "../../variables";
+@import "../../variables-dark";
+@import "../../maps";
+@import "../../mixins";
+
+@include describe("global $color-mode-type: data") {
+ @include it("generates data attribute selectors for dark mode") {
+ @include assert() {
+ @include output() {
+ @include color-mode(dark) {
+ .element {
+ color: var(--bs-primary-text-emphasis);
+ background-color: var(--bs-primary-bg-subtle);
+ }
+ }
+ @include color-mode(dark, true) {
+ --custom-color: #{mix($indigo, $blue, 50%)};
+ }
+ }
+ @include expect() {
+ [data-bs-theme=dark] .element {
+ color: var(--bs-primary-text-emphasis);
+ background-color: var(--bs-primary-bg-subtle);
+ }
+ [data-bs-theme=dark] {
+ --custom-color: #3a3ff8;
+ }
+ }
+ }
+ }
+}
+
+@include describe("global $color-mode-type: media-query") {
+ @include it("generates media queries for dark mode") {
+ $color-mode-type: media-query !global;
+
+ @include assert() {
+ @include output() {
+ @include color-mode(dark) {
+ .element {
+ color: var(--bs-primary-text-emphasis);
+ background-color: var(--bs-primary-bg-subtle);
+ }
+ }
+ @include color-mode(dark, true) {
+ --custom-color: #{mix($indigo, $blue, 50%)};
+ }
+ }
+ @include expect() {
+ @media (prefers-color-scheme: dark) {
+ .element {
+ color: var(--bs-primary-text-emphasis);
+ background-color: var(--bs-primary-bg-subtle);
+ }
+ }
+ @media (prefers-color-scheme: dark) {
+ :root {
+ --custom-color: #3a3ff8;
+ }
+ }
+ }
+ }
+
+ $color-mode-type: data !global;
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss b/Moonlight/Styles/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss
new file mode 100644
index 00000000..00ed82d6
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss
@@ -0,0 +1,8 @@
+$color-mode-type: media-query;
+
+@import "../../bootstrap";
+
+@include describe("global $color-mode-type: media-query") {
+ @include it("compiles entirely Bootstrap CSS with media-query color mode") { // stylelint-disable-line block-no-empty
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/mixins/_utilities.test.scss b/Moonlight/Styles/bootstrap/scss/tests/mixins/_utilities.test.scss
new file mode 100644
index 00000000..63fcae3a
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/mixins/_utilities.test.scss
@@ -0,0 +1,393 @@
+$prefix: bs-;
+$enable-important-utilities: false;
+
+// Important: Do not import rfs to check that the mixin just calls the appropriate functions from it
+@import "../../mixins/utilities";
+
+@mixin test-generate-utility($params...) {
+ @include assert() {
+ @include output() {
+ @include generate-utility($params...);
+ }
+
+ @include expect() {
+ @content;
+ }
+ }
+}
+
+@include describe(generate-utility) {
+ @include it("generates a utility class for each value") {
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: (small: .5rem, large: 2rem)
+ )
+ ) {
+ .padding-small {
+ padding: .5rem;
+ }
+
+ .padding-large {
+ padding: 2rem;
+ }
+ }
+ }
+
+ @include describe("global $enable-important-utilities: true") {
+ @include it("sets !important") {
+ $enable-important-utilities: true !global;
+
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: (small: .5rem, large: 2rem)
+ )
+ ) {
+ .padding-small {
+ padding: .5rem !important;
+ }
+
+ .padding-large {
+ padding: 2rem !important;
+ }
+ }
+
+ $enable-important-utilities: false !global;
+ }
+ }
+
+ @include describe("$utility") {
+ @include describe("values") {
+ @include it("supports null keys") {
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: (null: 1rem, small: .5rem, large: 2rem)
+ ),
+ ) {
+ .padding {
+ padding: 1rem;
+ }
+
+ .padding-small {
+ padding: .5rem;
+ }
+
+ .padding-large {
+ padding: 2rem;
+ }
+ }
+ }
+
+ @include it("ignores null values") {
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: (small: null, large: 2rem)
+ )
+ ) {
+ .padding-large {
+ padding: 2rem;
+ }
+ }
+ }
+
+ @include it("supports lists") {
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: 1rem 2rem
+ )
+ ) {
+ .padding-1rem {
+ padding: 1rem;
+ }
+
+ .padding-2rem {
+ padding: 2rem;
+ }
+ }
+ }
+
+ @include it("supports single values") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ values: 1rem
+ )
+ ) {
+ .padding-1rem {
+ padding: 1rem;
+ }
+ }
+ }
+ }
+
+ @include describe("class & property") {
+ @include it("adds each property to the declaration") {
+ @include test-generate-utility(
+ (
+ class: padding-x,
+ property: padding-inline-start padding-inline-end,
+ values: 1rem
+ )
+ ) {
+ .padding-x-1rem {
+ padding-inline-start: 1rem;
+ padding-inline-end: 1rem;
+ }
+ }
+ }
+
+ @include it("uses the first property as class name") {
+ @include test-generate-utility(
+ (
+ property: padding-inline-start padding-inline-end,
+ values: 1rem
+ )
+ ) {
+ .padding-inline-start-1rem {
+ padding-inline-start: 1rem;
+ padding-inline-end: 1rem;
+ }
+ }
+ }
+
+ @include it("supports a null class to create classes straight from the values") {
+ @include test-generate-utility(
+ (
+ property: visibility,
+ class: null,
+ values: (
+ visible: visible,
+ invisible: hidden,
+ )
+ )
+ ) {
+ .visible {
+ visibility: visible;
+ }
+
+ .invisible {
+ visibility: hidden;
+ }
+ }
+ }
+ }
+
+ @include describe("state") {
+ @include it("Generates selectors for each states") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ values: 1rem,
+ state: hover focus,
+ )
+ ) {
+ .padding-1rem {
+ padding: 1rem;
+ }
+
+ .padding-1rem-hover:hover {
+ padding: 1rem;
+ }
+
+ .padding-1rem-focus:focus {
+ padding: 1rem;
+ }
+ }
+ }
+ }
+
+ @include describe("css-var"){
+ @include it("sets a CSS variable instead of the property") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ css-variable-name: padding,
+ css-var: true,
+ values: 1rem 2rem
+ )
+ ) {
+ .padding-1rem {
+ --bs-padding: 1rem;
+ }
+
+ .padding-2rem {
+ --bs-padding: 2rem;
+ }
+ }
+ }
+
+ @include it("defaults to class") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ class: padding,
+ css-var: true,
+ values: 1rem 2rem
+ )
+ ) {
+ .padding-1rem {
+ --bs-padding: 1rem;
+ }
+
+ .padding-2rem {
+ --bs-padding: 2rem;
+ }
+ }
+ }
+ }
+
+ @include describe("local-vars") {
+ @include it("generates the listed variables") {
+ @include test-generate-utility(
+ (
+ property: color,
+ class: desaturated-color,
+ local-vars: (
+ color-opacity: 1,
+ color-saturation: .25
+ ),
+ values: (
+ blue: hsla(192deg, var(--bs-color-saturation), 0, var(--bs-color-opacity))
+ )
+ )
+ ) {
+ .desaturated-color-blue {
+ --bs-color-opacity: 1;
+ // Sass compilation will put a leading zero so we want to keep that one
+ // stylelint-disable-next-line stylistic/number-leading-zero
+ --bs-color-saturation: 0.25;
+ color: hsla(192deg, var(--bs-color-saturation), 0, var(--bs-color-opacity));
+ }
+ }
+ }
+ }
+
+ @include describe("css-var & state") {
+ @include it("Generates a rule with for each state with a CSS variable") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ css-var: true,
+ css-variable-name: padding,
+ values: 1rem,
+ state: hover focus,
+ )
+ ) {
+ .padding-1rem {
+ --bs-padding: 1rem;
+ }
+
+ .padding-1rem-hover:hover {
+ --bs-padding: 1rem;
+ }
+
+ .padding-1rem-focus:focus {
+ --bs-padding: 1rem;
+ }
+ }
+ }
+ }
+
+ @include describe("rtl") {
+ @include it("sets up RTLCSS for removal when false") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ values: 1rem,
+ rtl: false
+ )
+ ) {
+ /* rtl:begin:remove */
+
+ .padding-1rem {
+ padding: 1rem;
+ }
+
+ /* rtl:end:remove */
+
+ }
+ }
+ }
+
+ @include describe("rfs") {
+ @include it("sets the fluid value when not inside media query") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ values: 1rem,
+ rfs: true
+ )
+ ) {
+ .padding-1rem {
+ padding: rfs-fluid-value(1rem);
+ }
+ }
+ }
+
+ @include it("sets the value when inside the media query") {
+ @include test-generate-utility(
+ (
+ property: padding,
+ values: 1rem,
+ rfs: true
+ ),
+ $is-rfs-media-query: true
+ ) {
+ .padding-1rem {
+ padding: rfs-value(1rem);
+ }
+ }
+ }
+ }
+ }
+
+ @include describe("$infix") {
+ @include it("inserts the given infix") {
+ @include test-generate-utility(
+ (
+ property: "padding",
+ values: (null: 1rem, small: .5rem, large: 2rem)
+ ),
+ $infix: -sm
+ ) {
+ .padding-sm {
+ padding: 1rem;
+ }
+
+ .padding-sm-small {
+ padding: .5rem;
+ }
+
+ .padding-sm-large {
+ padding: 2rem;
+ }
+ }
+ }
+
+ @include it("strips leading - if class is null") {
+ @include test-generate-utility(
+ (
+ property: visibility,
+ class: null,
+ values: (
+ visible: visible,
+ invisible: hidden,
+ )
+ ),
+ -sm
+ ) {
+ .sm-visible {
+ visibility: visible;
+ }
+
+ .sm-invisible {
+ visibility: hidden;
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/sass-true/register.js b/Moonlight/Styles/bootstrap/scss/tests/sass-true/register.js
new file mode 100644
index 00000000..d93e414c
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/sass-true/register.js
@@ -0,0 +1,14 @@
+'use strict'
+
+const path = require('node:path')
+
+const runnerPath = path.join(__dirname, 'runner').replace(/\\/g, '/')
+
+require.extensions['.scss'] = (module, filename) => {
+ const normalizedFilename = filename.replace(/\\/g, '/')
+
+ return module._compile(`
+ const runner = require('${runnerPath}')
+ runner('${normalizedFilename}', { describe, it })
+ `, filename)
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/sass-true/runner.js b/Moonlight/Styles/bootstrap/scss/tests/sass-true/runner.js
new file mode 100644
index 00000000..bef870ac
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/sass-true/runner.js
@@ -0,0 +1,17 @@
+'use strict'
+
+const fs = require('node:fs')
+const path = require('node:path')
+const { runSass } = require('sass-true')
+
+module.exports = (filename, { describe, it }) => {
+ const data = fs.readFileSync(filename, 'utf8')
+ const TRUE_SETUP = '$true-terminal-output: false; @import "true";'
+ const sassString = TRUE_SETUP + data
+
+ runSass(
+ { describe, it, sourceType: 'string' },
+ sassString,
+ { loadPaths: [path.dirname(filename)] }
+ )
+}
diff --git a/Moonlight/Styles/bootstrap/scss/tests/utilities/_api.test.scss b/Moonlight/Styles/bootstrap/scss/tests/utilities/_api.test.scss
new file mode 100644
index 00000000..304d8d1c
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/tests/utilities/_api.test.scss
@@ -0,0 +1,75 @@
+@import "../../functions";
+@import "../../variables";
+@import "../../variables-dark";
+@import "../../maps";
+@import "../../mixins";
+
+$utilities: ();
+
+@include describe("utilities/api") {
+ @include it("generates utilities for each breakpoints") {
+ $utilities: (
+ margin: (
+ property: margin,
+ values: auto
+ ),
+ padding: (
+ property: padding,
+ responsive: true,
+ values: 1rem
+ ),
+ font-size: (
+ property: font-size,
+ values: (large: 1.25rem),
+ print: true
+ )
+ ) !global;
+
+ $grid-breakpoints: (
+ xs: 0,
+ sm: 333px,
+ md: 666px
+ ) !global;
+
+ @include assert() {
+ @include output() {
+ @import "../../utilities/api";
+ }
+
+ @include expect() {
+ // margin is not set to responsive
+ .margin-auto {
+ margin: auto !important;
+ }
+
+ // padding is, though
+ .padding-1rem {
+ padding: 1rem !important;
+ }
+
+ .font-size-large {
+ font-size: 1.25rem !important;
+ }
+
+ @media (min-width: 333px) {
+ .padding-sm-1rem {
+ padding: 1rem !important;
+ }
+ }
+
+ @media (min-width: 666px) {
+ .padding-md-1rem {
+ padding: 1rem !important;
+ }
+ }
+
+ @media print {
+ .font-size-print-large {
+ font-size: 1.25rem !important;
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/utilities/_api.scss b/Moonlight/Styles/bootstrap/scss/utilities/_api.scss
new file mode 100644
index 00000000..62e1d398
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/utilities/_api.scss
@@ -0,0 +1,47 @@
+// Loop over each breakpoint
+@each $breakpoint in map-keys($grid-breakpoints) {
+
+ // Generate media query if needed
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ // Loop over each utility property
+ @each $key, $utility in $utilities {
+ // The utility can be disabled with `false`, thus check if the utility is a map first
+ // Only proceed if responsive media queries are enabled or if it's the base media query
+ @if type-of($utility) == "map" and (map-get($utility, responsive) or $infix == "") {
+ @include generate-utility($utility, $infix);
+ }
+ }
+ }
+}
+
+// RFS rescaling
+@media (min-width: $rfs-mq-value) {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {
+ // Loop over each utility property
+ @each $key, $utility in $utilities {
+ // The utility can be disabled with `false`, thus check if the utility is a map first
+ // Only proceed if responsive media queries are enabled or if it's the base media query
+ @if type-of($utility) == "map" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == "") {
+ @include generate-utility($utility, $infix, true);
+ }
+ }
+ }
+ }
+}
+
+
+// Print utilities
+@media print {
+ @each $key, $utility in $utilities {
+ // The utility can be disabled with `false`, thus check if the utility is a map first
+ // Then check if the utility needs print styles
+ @if type-of($utility) == "map" and map-get($utility, print) == true {
+ @include generate-utility($utility, "-print");
+ }
+ }
+}
diff --git a/Moonlight/Styles/bootstrap/scss/vendor/_rfs.scss b/Moonlight/Styles/bootstrap/scss/vendor/_rfs.scss
new file mode 100644
index 00000000..aa1f82b9
--- /dev/null
+++ b/Moonlight/Styles/bootstrap/scss/vendor/_rfs.scss
@@ -0,0 +1,348 @@
+// stylelint-disable scss/dimension-no-non-numeric-values
+
+// SCSS RFS mixin
+//
+// Automated responsive values for font sizes, paddings, margins and much more
+//
+// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)
+
+// Configuration
+
+// Base value
+$rfs-base-value: 1.25rem !default;
+$rfs-unit: rem !default;
+
+@if $rfs-unit != rem and $rfs-unit != px {
+ @error "`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.";
+}
+
+// Breakpoint at where values start decreasing if screen width is smaller
+$rfs-breakpoint: 1200px !default;
+$rfs-breakpoint-unit: px !default;
+
+@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {
+ @error "`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.";
+}
+
+// Resize values based on screen height and width
+$rfs-two-dimensional: false !default;
+
+// Factor of decrease
+$rfs-factor: 10 !default;
+
+@if type-of($rfs-factor) != number or $rfs-factor <= 1 {
+ @error "`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.";
+}
+
+// Mode. Possibilities: "min-media-query", "max-media-query"
+$rfs-mode: min-media-query !default;
+
+// Generate enable or disable classes. Possibilities: false, "enable" or "disable"
+$rfs-class: false !default;
+
+// 1 rem = $rfs-rem-value px
+$rfs-rem-value: 16 !default;
+
+// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14
+$rfs-safari-iframe-resize-bug-fix: false !default;
+
+// Disable RFS by setting $enable-rfs to false
+$enable-rfs: true !default;
+
+// Cache $rfs-base-value unit
+$rfs-base-value-unit: unit($rfs-base-value);
+
+@function divide($dividend, $divisor, $precision: 10) {
+ $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
+ $dividend: abs($dividend);
+ $divisor: abs($divisor);
+ @if $dividend == 0 {
+ @return 0;
+ }
+ @if $divisor == 0 {
+ @error "Cannot divide by 0";
+ }
+ $remainder: $dividend;
+ $result: 0;
+ $factor: 10;
+ @while ($remainder > 0 and $precision >= 0) {
+ $quotient: 0;
+ @while ($remainder >= $divisor) {
+ $remainder: $remainder - $divisor;
+ $quotient: $quotient + 1;
+ }
+ $result: $result * 10 + $quotient;
+ $factor: $factor * .1;
+ $remainder: $remainder * 10;
+ $precision: $precision - 1;
+ @if ($precision < 0 and $remainder >= $divisor * 5) {
+ $result: $result + 1;
+ }
+ }
+ $result: $result * $factor * $sign;
+ $dividend-unit: unit($dividend);
+ $divisor-unit: unit($divisor);
+ $unit-map: (
+ "px": 1px,
+ "rem": 1rem,
+ "em": 1em,
+ "%": 1%
+ );
+ @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {
+ $result: $result * map-get($unit-map, $dividend-unit);
+ }
+ @return $result;
+}
+
+// Remove px-unit from $rfs-base-value for calculations
+@if $rfs-base-value-unit == px {
+ $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);
+}
+@else if $rfs-base-value-unit == rem {
+ $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));
+}
+
+// Cache $rfs-breakpoint unit to prevent multiple calls
+$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);
+
+// Remove unit from $rfs-breakpoint for calculations
+@if $rfs-breakpoint-unit-cache == px {
+ $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);
+}
+@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == "em" {
+ $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));
+}
+
+// Calculate the media query value
+$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});
+$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);
+$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);
+
+// Internal mixin used to determine which media query needs to be used
+@mixin _rfs-media-query {
+ @if $rfs-two-dimensional {
+ @if $rfs-mode == max-media-query {
+ @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {
+ @content;
+ }
+ }
+ @else {
+ @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {
+ @content;
+ }
+ }
+ }
+ @else {
+ @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {
+ @content;
+ }
+ }
+}
+
+// Internal mixin that adds disable classes to the selector if needed.
+@mixin _rfs-rule {
+ @if $rfs-class == disable and $rfs-mode == max-media-query {
+ // Adding an extra class increases specificity, which prevents the media query to override the property
+ &,
+ .disable-rfs &,
+ &.disable-rfs {
+ @content;
+ }
+ }
+ @else if $rfs-class == enable and $rfs-mode == min-media-query {
+ .enable-rfs &,
+ &.enable-rfs {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Internal mixin that adds enable classes to the selector if needed.
+@mixin _rfs-media-query-rule {
+
+ @if $rfs-class == enable {
+ @if $rfs-mode == min-media-query {
+ @content;
+ }
+
+ @include _rfs-media-query () {
+ .enable-rfs &,
+ &.enable-rfs {
+ @content;
+ }
+ }
+ }
+ @else {
+ @if $rfs-class == disable and $rfs-mode == min-media-query {
+ .disable-rfs &,
+ &.disable-rfs {
+ @content;
+ }
+ }
+ @include _rfs-media-query () {
+ @content;
+ }
+ }
+}
+
+// Helper function to get the formatted non-responsive value
+@function rfs-value($values) {
+ // Convert to list
+ $values: if(type-of($values) != list, ($values,), $values);
+
+ $val: "";
+
+ // Loop over each value and calculate value
+ @each $value in $values {
+ @if $value == 0 {
+ $val: $val + " 0";
+ }
+ @else {
+ // Cache $value unit
+ $unit: if(type-of($value) == "number", unit($value), false);
+
+ @if $unit == px {
+ // Convert to rem if needed
+ $val: $val + " " + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);
+ }
+ @else if $unit == rem {
+ // Convert to px if needed
+ $val: $val + " " + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);
+ } @else {
+ // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
+ $val: $val + " " + $value;
+ }
+ }
+ }
+
+ // Remove first space
+ @return unquote(str-slice($val, 2));
+}
+
+// Helper function to get the responsive value calculated by RFS
+@function rfs-fluid-value($values) {
+ // Convert to list
+ $values: if(type-of($values) != list, ($values,), $values);
+
+ $val: "";
+
+ // Loop over each value and calculate value
+ @each $value in $values {
+ @if $value == 0 {
+ $val: $val + " 0";
+ } @else {
+ // Cache $value unit
+ $unit: if(type-of($value) == "number", unit($value), false);
+
+ // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
+ @if not $unit or $unit != px and $unit != rem {
+ $val: $val + " " + $value;
+ } @else {
+ // Remove unit from $value for calculations
+ $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));
+
+ // Only add the media query if the value is greater than the minimum value
+ @if abs($value) <= $rfs-base-value or not $enable-rfs {
+ $val: $val + " " + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);
+ }
+ @else {
+ // Calculate the minimum value
+ $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);
+
+ // Calculate difference between $value and the minimum value
+ $value-diff: abs($value) - $value-min;
+
+ // Base value formatting
+ $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);
+
+ // Use negative value if needed
+ $min-width: if($value < 0, -$min-width, $min-width);
+
+ // Use `vmin` if two-dimensional is enabled
+ $variable-unit: if($rfs-two-dimensional, vmin, vw);
+
+ // Calculate the variable width between 0 and $rfs-breakpoint
+ $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};
+
+ // Return the calculated value
+ $val: $val + " calc(" + $min-width + if($value < 0, " - ", " + ") + $variable-width + ")";
+ }
+ }
+ }
+ }
+
+ // Remove first space
+ @return unquote(str-slice($val, 2));
+}
+
+// RFS mixin
+@mixin rfs($values, $property: font-size) {
+ @if $values != null {
+ $val: rfs-value($values);
+ $fluid-val: rfs-fluid-value($values);
+
+ // Do not print the media query if responsive & non-responsive values are the same
+ @if $val == $fluid-val {
+ #{$property}: $val;
+ }
+ @else {
+ @include _rfs-rule () {
+ #{$property}: if($rfs-mode == max-media-query, $val, $fluid-val);
+
+ // Include safari iframe resize fix if needed
+ min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);
+ }
+
+ @include _rfs-media-query-rule () {
+ #{$property}: if($rfs-mode == max-media-query, $fluid-val, $val);
+ }
+ }
+ }
+}
+
+// Shorthand helper mixins
+@mixin font-size($value) {
+ @include rfs($value);
+}
+
+@mixin padding($value) {
+ @include rfs($value, padding);
+}
+
+@mixin padding-top($value) {
+ @include rfs($value, padding-top);
+}
+
+@mixin padding-right($value) {
+ @include rfs($value, padding-right);
+}
+
+@mixin padding-bottom($value) {
+ @include rfs($value, padding-bottom);
+}
+
+@mixin padding-left($value) {
+ @include rfs($value, padding-left);
+}
+
+@mixin margin($value) {
+ @include rfs($value, margin);
+}
+
+@mixin margin-top($value) {
+ @include rfs($value, margin-top);
+}
+
+@mixin margin-right($value) {
+ @include rfs($value, margin-right);
+}
+
+@mixin margin-bottom($value) {
+ @include rfs($value, margin-bottom);
+}
+
+@mixin margin-left($value) {
+ @include rfs($value, margin-left);
+}
diff --git a/Moonlight/Styles/build.bat b/Moonlight/Styles/build.bat
new file mode 100644
index 00000000..19e34edd
--- /dev/null
+++ b/Moonlight/Styles/build.bat
@@ -0,0 +1,2 @@
+@echo off
+sass style.scss ../wwwroot/css/theme.css
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_accordion.scss b/Moonlight/Styles/components/_accordion.scss
new file mode 100644
index 00000000..41a4a1f5
--- /dev/null
+++ b/Moonlight/Styles/components/_accordion.scss
@@ -0,0 +1,107 @@
+//
+// Accordion
+//
+
+// Base
+.accordion {
+ // According heading
+ .accordion-header {
+ cursor: pointer;
+ }
+
+ // Icon toggle mode
+ &.accordion-icon-toggle {
+ // Accordion icon expaned mode
+ .accordion-icon {
+ display: flex;
+ flex-shrink: 0;
+ transition: $transition-base;
+ transform: rotate(90deg);
+ align-items: center;
+ justify-content: center;
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ // Accordion icon collapsed mode
+ .collapsed {
+ .accordion-icon {
+ transition: $transition-base;
+ transform: rotate(0);
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}text-muted);
+ }
+ }
+ }
+ }
+
+ // Icon collapse mode
+ &.accordion-icon-collapse {
+ // Accordion icon expaned mode
+ .accordion-icon {
+ display: flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+ transition: $transition-base;
+
+ .accordion-icon-on {
+ display: inline-flex;
+ }
+
+ .accordion-icon-off {
+ display: none;
+ }
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ // Accordion icon collapsed mode
+ .collapsed {
+ .accordion-icon {
+ transition: $transition-base;
+
+ .accordion-icon-on {
+ display: none;
+ }
+
+ .accordion-icon-off {
+ display: inline-flex;
+ }
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}text-muted);
+ }
+ }
+ }
+ }
+
+ // Reset accordion item border
+ &.accordion-borderless {
+ // According item
+ .accordion-item {
+ border: 0;
+ }
+ }
+
+ // Reset accordion item border, border radiues and background color
+ &.accordion-flush {
+ // According item
+ .accordion-item {
+ background-color: transparent;
+ border: 0;
+ border-radius: 0;
+ padding-left: 0;
+ padding-right: 0;
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_alert.scss b/Moonlight/Styles/components/_alert.scss
new file mode 100644
index 00000000..94c6c1d0
--- /dev/null
+++ b/Moonlight/Styles/components/_alert.scss
@@ -0,0 +1,15 @@
+//
+// Alert
+//
+
+@each $name, $value in $theme-colors {
+ .alert-#{$name} {
+ color: var(--#{$prefix}#{$name});
+ border-color: var(--#{$prefix}#{$name});
+ background-color: var(--#{$prefix}#{$name}-light);
+
+ .alert-link {
+ color: var(--#{$prefix}#{$name});
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_anchor.scss b/Moonlight/Styles/components/_anchor.scss
new file mode 100644
index 00000000..48996812
--- /dev/null
+++ b/Moonlight/Styles/components/_anchor.scss
@@ -0,0 +1,37 @@
+//
+// Anchor
+//
+
+.anchor {
+ display: flex;
+ align-items: center;
+
+ a {
+ position: relative;
+ display: none;
+ align-items: center;
+ justify-content:flex-start;
+ height: 1em;
+ width: 1.25em;
+ margin-left: -1.25em;
+ font-weight: 500;
+ font-size: 0.8em;
+ color: var(--#{$prefix}text-muted);
+ transition: $transition-base;
+
+ &:before {
+ content: '#';
+ }
+ }
+
+ &:hover {
+ a {
+ display: flex;
+
+ &:hover {
+ color: var(--#{$prefix}primary);
+ transition: $transition-base;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_animation.scss b/Moonlight/Styles/components/_animation.scss
new file mode 100644
index 00000000..c0087820
--- /dev/null
+++ b/Moonlight/Styles/components/_animation.scss
@@ -0,0 +1,81 @@
+//
+// Animation
+//
+
+// Base
+.animation {
+ animation-duration: 1s;
+ animation-fill-mode: both;
+}
+
+// Slide In Down
+@keyframes animationSlideInDown {
+ from {
+ transform: translate3d(0, -100%, 0);
+ visibility: visible;
+ }
+
+ to {
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+.animation-slide-in-down {
+ animation-name: animationSlideInDown;
+}
+
+// Slide In Up
+@keyframes animationSlideInUp {
+ from {
+ transform: translate3d(0, 100%, 0);
+ visibility: visible;
+ }
+
+ to {
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+.animation-slide-in-up {
+ animation-name: animationSlideInUp;
+}
+
+// Fade In
+@keyframes animationFadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+.animation-fade-in {
+ animation-name: animationFadeIn;
+}
+
+// Fade Out
+@keyframes animationFadeOut {
+ from {
+ opacity: 1;
+ }
+
+ to {
+ opacity: 0;
+ }
+}
+.animation-fade-out {
+ animation-name: animationFadeOut;
+}
+
+// Blink
+.animation-blink {
+ animation: animationBlink 1s steps(5, start) infinite;
+}
+
+@keyframes animationBlink {
+ to {
+ visibility: hidden;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_badge.scss b/Moonlight/Styles/components/_badge.scss
new file mode 100644
index 00000000..6886d3c9
--- /dev/null
+++ b/Moonlight/Styles/components/_badge.scss
@@ -0,0 +1,75 @@
+//
+// Badge
+//
+
+.badge {
+ display: inline-flex;
+ align-items: center;
+
+ // Fixed size
+ &.badge-circle,
+ &.badge-square {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ height: $badge-size;
+ min-width: $badge-size;
+ padding: 0 0.1rem;
+ line-height: 0;
+ }
+
+ // Circle
+ &.badge-circle {
+ border-radius: 50%;
+ padding: 0;
+ min-width: unset;
+ width: $badge-size;
+ }
+
+ // Sizes
+ &.badge-sm {
+ min-width: $badge-size-sm;
+ font-size: $badge-font-size-sm;
+
+ &.badge-square {
+ height: $badge-size-sm;
+ }
+
+ &.badge-circle {
+ width: $badge-size-sm;
+ height: $badge-size-sm;
+ }
+ }
+
+ &.badge-lg {
+ min-width: $badge-size-lg;
+ font-size: $badge-font-size-lg;
+
+ &.badge-square {
+ height: $badge-size-lg;
+ }
+
+ &.badge-circle {
+ width: $badge-size-lg;
+ height: $badge-size-lg;
+ }
+ }
+}
+
+@each $name, $value in $theme-colors {
+ .badge-#{$name} {
+ color: var(--#{$prefix}#{$name}-inverse);
+ background-color: var(--#{$prefix}#{$name});
+
+ &.badge-outline {
+ border: 1px solid var(--#{$prefix}#{$name});
+ color: var(--#{$prefix}#{$name});
+ background-color: transparent;
+ }
+ }
+
+ .badge-light-#{$name} {
+ color: var(--#{$prefix}#{$name});
+ background-color: var(--#{$prefix}#{$name}-light);
+ }
+}
diff --git a/Moonlight/Styles/components/_blockui.scss b/Moonlight/Styles/components/_blockui.scss
new file mode 100644
index 00000000..3a0d029e
--- /dev/null
+++ b/Moonlight/Styles/components/_blockui.scss
@@ -0,0 +1,53 @@
+//
+// BlockUI
+//
+
+
+.blockui {
+ position: relative;
+
+ .blockui-overlay {
+ transition: all 0.3s ease;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--#{$prefix}blockui-overlay-bg);
+
+ .spinner-border {
+ height: 1.35rem;
+ width: 1.35rem;
+ }
+ }
+
+ .blockui-message {
+ display: flex;
+ align-items: center;
+ @include border-radius($border-radius);
+ box-shadow: var(--#{$prefix}blockui-message-box-shadow);
+ background-color: var(--#{$prefix}blockui-message-bg);
+ color: var(--#{$prefix}gray-700);
+ font-weight: $font-weight-bold;
+ margin: 0 !important;
+ width: auto;
+ padding: 0.85rem 1.75rem !important;
+
+ .spinner-border {
+ margin-right: 0.65rem;
+ }
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .blockui {
+ --#{$prefix}blockui-overlay-bg: #{$blockui-overlay-bg-dark};
+ --#{$prefix}blockui-message-bg: #{$blockui-message-bg-dark};
+ --#{$prefix}blockui-message-box-shadow: #{$blockui-message-box-shadow-dark};
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_breadcrumb.scss b/Moonlight/Styles/components/_breadcrumb.scss
new file mode 100644
index 00000000..dc532483
--- /dev/null
+++ b/Moonlight/Styles/components/_breadcrumb.scss
@@ -0,0 +1,69 @@
+//
+// Breadcrumb
+//
+
+// Breadcrumb
+.breadcrumb {
+ display: flex;
+ align-items: center;
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+
+ // Item breadcrumb
+ .breadcrumb-item {
+ display: flex;
+ align-items: center;
+ padding-left: $breadcrumb-item-padding-x;
+
+ &:last-child {
+ padding-right: 0;
+ }
+
+ &:after {
+ padding-left: $breadcrumb-item-padding-x;
+ content: "/";
+ }
+
+ &:before {
+ display: none;
+ }
+
+ &:first-child {
+ padding-left: 0;
+ }
+
+ &:last-child {
+ &:after {
+ display: none;
+ }
+ }
+ }
+}
+
+// Breadcrumb line style
+.breadcrumb-line {
+ .breadcrumb-item {
+ &:after {
+ content: "-";
+ }
+ }
+}
+
+// Breadcrumb dot style
+.breadcrumb-dot {
+ .breadcrumb-item {
+ &:after {
+ content: "\2022";
+ }
+ }
+}
+
+// Breadcrumb separatorless style
+.breadcrumb-separatorless {
+ .breadcrumb-item {
+ &:after {
+ display:none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_btn-secondary.scss b/Moonlight/Styles/components/_btn-secondary.scss
new file mode 100644
index 00000000..e7291087
--- /dev/null
+++ b/Moonlight/Styles/components/_btn-secondary.scss
@@ -0,0 +1,36 @@
+//
+// Secondary button
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .btn.btn-secondary {
+ @include button-custom-variant(
+ $color: null,
+ $icon-color: var(--#{$prefix}gray-600),
+ $border-color: null,
+ $bg-color: var(--#{$prefix}gray-200),
+ $color-active: null,
+ $icon-color-active: var(--#{$prefix}primary),
+ $border-color-active: null,
+ $bg-color-active: var(--#{$prefix}gray-300),
+ );
+ }
+}
+
+@include color-mode(dark) {
+ // Secondary button
+ .btn.btn-secondary {
+ @include button-custom-variant(
+ $color: null,
+ $icon-color: #878794,
+ $border-color: null,
+ $bg-color: #1A1A1A,
+ $color-active: null,
+ $icon-color-active: null,
+ $border-color-active: null,
+ $bg-color-active: #1A1A1A,
+ );
+ }
+}
+
diff --git a/Moonlight/Styles/components/_bullet.scss b/Moonlight/Styles/components/_bullet.scss
new file mode 100644
index 00000000..1228b281
--- /dev/null
+++ b/Moonlight/Styles/components/_bullet.scss
@@ -0,0 +1,33 @@
+//
+// Bullet
+//
+
+// Base
+.bullet {
+ display: inline-block;
+ background-color: var(--#{$prefix}bullet-bg-color);
+ @include border-radius($bullet-bar-border-radius);
+ width: $bullet-bar-width;
+ height: $bullet-bar-height;
+ flex-shrink: 0;
+}
+
+// Dot bullet
+.bullet-dot {
+ width: $bullet-dot-size;
+ height: $bullet-dot-size;
+ border-radius: 100% !important;
+}
+
+// Vertical bullet
+.bullet-vertical {
+ width: $bullet-bar-height;
+ height: $bullet-bar-width;
+}
+
+// Vertical line
+.bullet-line {
+ width: $bullet-line-width;
+ height: $bullet-line-height;
+ border-radius: 0;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_buttons.scss b/Moonlight/Styles/components/_buttons.scss
new file mode 100644
index 00000000..9ca32571
--- /dev/null
+++ b/Moonlight/Styles/components/_buttons.scss
@@ -0,0 +1,7 @@
+//
+// Buttons
+//
+
+// Import Dependencies
+@import "buttons/base";
+@import "buttons/theme";
diff --git a/Moonlight/Styles/components/_card.scss b/Moonlight/Styles/components/_card.scss
new file mode 100644
index 00000000..50e31550
--- /dev/null
+++ b/Moonlight/Styles/components/_card.scss
@@ -0,0 +1,314 @@
+//
+// Card
+//
+
+// Base
+.card {
+ @if ($card-border-enabled) {
+ border: $card-border-width $card-border-style var(--#{$prefix}card-border-color);
+ } @else {
+ border: 0;
+ }
+
+ // Header
+ .card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: stretch;
+ flex-wrap: wrap;
+ min-height: $card-header-height;
+ padding: 0 $card-px;
+ color: var(--#{$prefix}card-cap-color);
+ background-color: var(--#{$prefix}card-cap-bg);
+ border-bottom: $card-border-width $card-border-style var(--#{$prefix}card-border-color);
+
+ // Title
+ .card-title {
+ display: flex;
+ align-items: center;
+ margin: $card-header-py;
+ margin-left: 0;
+
+ &.flex-column {
+ align-items: flex-start;
+ justify-content: center;
+ }
+
+ .card-icon {
+ margin-right: 0.75rem;
+ line-height: 0;
+
+ i {
+ font-size: 1.25rem;
+ color: var(--#{$prefix}gray-600);
+ line-height: 0;
+
+ &:after,
+ &:before {
+ line-height: 0;
+ }
+ }
+
+ .svg-icon {
+ color: var(--#{$prefix}gray-600);
+ @include svg-icon-size(24px);
+ }
+ }
+
+ &,
+ .card-label {
+ font-weight: 500;
+ font-size: 1.275rem;
+ color: var(--#{$prefix}text-dark);
+ }
+
+ .card-label {
+ margin: 0 0.75rem 0 0;
+ flex-wrap: wrap;
+ }
+
+ // Description
+ small {
+ color: var(--#{$prefix}text-muted);
+ font-size: 1rem;
+ }
+
+ // Headings
+ h1, h2, h3, h4, h5, h6 {
+ margin-bottom: 0;
+ }
+ }
+
+ // Toolbar
+ .card-toolbar {
+ display: flex;
+ align-items: center;
+ margin: $card-header-py 0;
+ flex-wrap: wrap;
+ }
+ }
+
+ // Body
+ .card-body {
+ padding: $card-py $card-px;
+ color: var(--#{$prefix}card-color);
+ }
+
+ // Footer
+ .card-footer {
+ padding: $card-py $card-px;
+ color: var(--#{$prefix}card-cap-color);
+ background-color: var(--#{$prefix}card-cap-bg);
+ border-top: $card-border-width $card-border-style var(--#{$prefix}card-border-color);
+ }
+
+ // Scroll
+ .card-scroll {
+ position: relative;
+ overflow: auto;
+ }
+
+ // Reset padding x
+ &.card-px-0 {
+ .card-header,
+ .card-body,
+ .card-footer {
+ padding-left: 0;
+ padding-right: 0;
+ }
+ }
+
+ &.card-py-0 {
+ .card-header,
+ .card-body,
+ .card-footer {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+ }
+
+ &.card-p-0 {
+ .card-header,
+ .card-body,
+ .card-footer {
+ padding: 0;
+ }
+ }
+
+ // Dashed style
+ &.card-dashed {
+ box-shadow: none;
+ border: $card-border-width dashed $card-border-dashed-color;
+
+ > .card-header {
+ border-bottom: 1px dashed $card-border-dashed-color;
+ }
+
+ > .card-footer {
+ border-top: 1px dashed $card-border-dashed-color;
+ }
+ }
+
+ // Bordered style
+ &.card-bordered {
+ box-shadow: none;
+ border: $card-border-width $card-border-style $card-border-color;
+ }
+
+ // Flush header and footer borders
+ &.card-flush {
+ > .card-header {
+ border-bottom: 0 !important;
+ }
+
+ > .card-footer {
+ border-top: 0 !important;
+ }
+ }
+
+ // Enable shadow
+ &.card-shadow {
+ box-shadow: var(--#{$prefix}card-box-shadow);
+ border: 0;
+ }
+
+ // Reset styles
+ &.card-reset {
+ border: 0 !important;
+ box-shadow: none !important;
+ background-color: transparent !important;
+
+ > .card-header {
+ border-bottom: 0 !important;
+ }
+
+ > .card-footer {
+ border-top: 0 !important;
+ }
+ }
+
+ // Reset borders
+ &.card-borderless {
+ border: 0 !important;
+
+ > .card-header {
+ border-bottom: 0 !important;
+ }
+
+ > .card-footer {
+ border-top: 0 !important;
+ }
+ }
+
+ // Reset borders
+ &.card-border-0 {
+ border: 0 !important;
+ }
+}
+
+// Responsive stretch heights
+.card {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ // Stretch
+ &.card#{$infix}-stretch {
+ height: calc(100% - var(--#{$prefix}gutter-y));
+ }
+
+ // Stretch 75
+ &.card#{$infix}-stretch-75 {
+ height: calc(75% - var(--#{$prefix}gutter-y));
+ }
+
+ // Stretch 50
+ &.card#{$infix}-stretch-50 {
+ height: calc(50% - var(--#{$prefix}gutter-y));
+ }
+
+ // Stretch 33
+ &.card#{$infix}-stretch-33 {
+ height: calc(33.333% - var(--#{$prefix}gutter-y));
+ }
+
+ // Stretch 25
+ &.card#{$infix}-stretch-25 {
+ height: calc(25% - var(--#{$prefix}gutter-y));
+ }
+
+ // Header stretch
+ .card-header#{$infix}-stretch {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ align-items: stretch;
+
+ .card-toolbar {
+ margin: 0;
+ align-items: stretch;
+ }
+ }
+ }
+ }
+}
+
+// Utilities
+.card-p {
+ padding: $card-py $card-px !important;
+}
+
+.card-px {
+ padding-left: $card-px !important;
+ padding-right: $card-px !important;
+}
+
+.card-shadow {
+ box-shadow: var(--#{$prefix}card-box-shadow);
+}
+
+.card-py {
+ padding-top: $card-py !important;
+ padding-bottom: $card-py !important;
+}
+
+.card-rounded {
+ border-radius: $card-border-radius;
+}
+
+.card-rounded-start {
+ border-top-left-radius: $card-border-radius;
+ border-bottom-left-radius: $card-border-radius;
+}
+
+.card-rounded-end {
+ border-top-right-radius: $card-border-radius;
+ border-bottom-right-radius: $card-border-radius;
+}
+
+.card-rounded-top {
+ border-top-left-radius: $card-border-radius;
+ border-top-right-radius: $card-border-radius;
+}
+
+.card-rounded-bottom {
+ border-bottom-left-radius: $card-border-radius;
+ border-bottom-right-radius: $card-border-radius;
+}
+
+// Mobile mode
+@include media-breakpoint-down(md) {
+ .card {
+ > .card-header:not(.flex-nowrap) {
+ padding-top: $card-header-py;
+ padding-bottom: $card-header-py;
+ }
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .card {
+ --#{$prefix}card-box-shadow: #{$card-box-shadow-dark};
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_carousel.scss b/Moonlight/Styles/components/_carousel.scss
new file mode 100644
index 00000000..4bb117bb
--- /dev/null
+++ b/Moonlight/Styles/components/_carousel.scss
@@ -0,0 +1,130 @@
+//
+// Carousel
+//
+
+
+.carousel-custom {
+ // Indicators
+ .carousel-indicators {
+ align-items: center;
+ position: static;
+ z-index: auto;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+
+ li {
+ transform: none;
+ opacity: 1;
+
+ &.active {
+ transform: none;
+ opacity: 1;
+ }
+ }
+
+ // Dots style
+ &.carousel-indicators-dots {
+ li {
+ border-radius: 0;
+ background-color: transparent !important;
+ height: $carousel-custom-dots-indicator-active-size;
+ width: $carousel-custom-dots-indicator-active-size;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+
+ &:after {
+ display: inline-block;
+ content: " ";
+ @include border-radius(50%);
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ background-color: $carousel-custom-indicator-default-bg-color;
+ height: $carousel-custom-dots-indicator-default-size;
+ width: $carousel-custom-dots-indicator-default-size;
+ }
+
+ &.active {
+ background-color: transparent;
+
+ &:after {
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ height: $carousel-custom-dots-indicator-active-size;
+ width: $carousel-custom-dots-indicator-active-size;
+ background-color: $carousel-custom-indicator-active-bg-color;
+ }
+ }
+ }
+ }
+
+ // Bullet style
+ &.carousel-indicators-bullet {
+ li {
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ background-color: transparent !important;
+ border-radius: $carousel-custom-bullet-indicator-default-size;
+ height: $carousel-custom-bullet-indicator-default-size;
+ width: $carousel-custom-bullet-indicator-default-size;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+
+ &:after {
+ display: inline-block;
+ content: " ";
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ background-color: $carousel-custom-bullet-indicator-default-bg-color;
+ border-radius: $carousel-custom-bullet-indicator-default-size;
+ height: $carousel-custom-bullet-indicator-default-size;
+ width: $carousel-custom-bullet-indicator-default-size;
+ }
+
+ &.active {
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ background-color: transparent;
+ height: $carousel-custom-bullet-indicator-default-size;
+ width: $carousel-custom-bullet-indicator-active-width;
+
+ &:after {
+ transition: all $carousel-custom-indicator-transition-speed ease;
+ height: $carousel-custom-bullet-indicator-default-size;
+ width: $carousel-custom-bullet-indicator-active-width;
+ background-color: $carousel-custom-bullet-indicator-active-bg-color;
+ }
+ }
+ }
+ }
+ }
+
+ // Theme colors
+ @each $name, $value in $theme-colors {
+ .carousel-indicators-active-#{$name} {
+ li.active:after {
+ background-color: var(--#{$prefix}#{$name}) !important;
+ }
+ }
+ }
+
+ // Stretch mode
+ &.carousel-stretch {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ .carousel-inner {
+ flex-grow: 1;
+ }
+
+ .carousel-item {
+ height: 100%;
+ }
+
+ .carousel-wrapper {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_code.scss b/Moonlight/Styles/components/_code.scss
new file mode 100644
index 00000000..3ea1fa9a
--- /dev/null
+++ b/Moonlight/Styles/components/_code.scss
@@ -0,0 +1,15 @@
+//
+// Code
+//
+
+code:not([class*="language-"]) {
+ font-weight: $code-font-weight;
+ color: var(--#{$prefix}code-color);
+ line-height: inherit;
+ font-size: inherit;
+ background-color: var(--#{$prefix}code-bg);
+ padding: $code-padding;
+ margin: $code-margin;
+ box-shadow: var(--#{$prefix}code-box-shadow);
+ @include border-radius($code-border-radius);
+}
diff --git a/Moonlight/Styles/components/_cookiealert.scss b/Moonlight/Styles/components/_cookiealert.scss
new file mode 100644
index 00000000..539756ee
--- /dev/null
+++ b/Moonlight/Styles/components/_cookiealert.scss
@@ -0,0 +1,8 @@
+//
+// Cookie Alert
+//
+
+.cookiealert{
+ background: inherit;
+ color: inherit;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_drawer.scss b/Moonlight/Styles/components/_drawer.scss
new file mode 100644
index 00000000..d88c8260
--- /dev/null
+++ b/Moonlight/Styles/components/_drawer.scss
@@ -0,0 +1,62 @@
+//
+// Drawer
+//
+
+// Drawer
+.drawer {
+ display: flex !important;
+ overflow: auto;
+ z-index: $drawer-z-index;
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ background-color: var(--#{$prefix}drawer-bg-color);
+ transition: transform $drawer-transition-speed ease-in-out !important;
+
+ &.drawer-start {
+ left: 0;
+ transform: translateX(-100%);
+ }
+
+ &.drawer-end {
+ right: 0;
+ transform: translateX(100%);
+ }
+
+ &.drawer-on {
+ transform: none;
+ box-shadow: var(--#{$prefix}drawer-box-shadow);
+ transition: transform $drawer-transition-speed ease-in-out !important;
+ }
+}
+
+// Drawer Overlay
+.drawer-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ overflow: hidden;
+ z-index: $drawer-z-index - 1;
+ background-color: var(--#{$prefix}drawer-overlay-bg-color);
+ animation: animation-drawer-fade-in $drawer-overlay-animation-speed ease-in-out 1;
+}
+
+// Initial state
+[data-kt-drawer="true"] {
+ display: none;
+}
+
+// Animation
+@keyframes animation-drawer-fade-in {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+// Tablet & Mobile Modes
+@include media-breakpoint-down(lg) {
+ body[data-kt-drawer="on"] {
+ overflow: hidden;
+ }
+}
diff --git a/Moonlight/Styles/components/_dropdown.scss b/Moonlight/Styles/components/_dropdown.scss
new file mode 100644
index 00000000..161d11c4
--- /dev/null
+++ b/Moonlight/Styles/components/_dropdown.scss
@@ -0,0 +1,12 @@
+
+//
+// Dropdown
+//
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .dropdown-menu {
+ @include box-shadow($dropdown-box-shadow-dark);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_engage.scss b/Moonlight/Styles/components/_engage.scss
new file mode 100644
index 00000000..e18f7ba8
--- /dev/null
+++ b/Moonlight/Styles/components/_engage.scss
@@ -0,0 +1,118 @@
+//
+// Engage panel(used for demo product demo)
+//
+
+.app-engage {
+ position: fixed;
+ right: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ z-index: $engage-z-index;
+ padding-right: 12px;
+
+ .app-engage-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ box-shadow: var(--#{$prefix}engage-btn-box-shadow);
+ border-width: 1px;
+ border-style: solid;
+ font-size: 12px;
+ font-weight: $font-weight-bold;
+ margin-bottom: 8px;
+ @include border-radius(6px);
+ width: 66px;
+ height: 70px;
+
+ @include button-custom-variant(
+ $color: var(--#{$prefix}engage-btn-color),
+ $icon-color: var(--#{$prefix}engage-btn-icon-color),
+ $border-color: var(--#{$prefix}engage-btn-border-color),
+ $bg-color: var(--#{$prefix}engage-btn-bg),
+ $color-active: null,
+ $icon-color-active: null,
+ $border-color-active: null,
+ $bg-color-active: null
+ );
+
+ &.hover-dark:hover {
+ color: var(--#{$prefix}dark-inverse);
+ border-color: var(--#{$prefix}dark);
+ background-color: var(--#{$prefix}dark);
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}dark-inverse);
+ }
+ }
+
+ &.hover-primary:hover {
+ color: var(--#{$prefix}primary-inverse);
+ border-color: var(--#{$prefix}primary);
+ background-color: var(--#{$prefix}primary);
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}primary-inverse);
+ }
+ }
+
+ &.hover-success:hover {
+ color: var(--#{$prefix}success-inverse);
+ border-color: var(--#{$prefix}success);
+ background-color: var(--#{$prefix}success);
+
+ i,
+ .svg-icon {
+ color: var(--#{$prefix}success-inverse);
+ }
+ }
+
+ &.app-engage-btn-toggle-off {
+ width: 35px;
+ height: 35px;
+ }
+
+ &.app-engage-btn-toggle-on {
+ width: 35px;
+ height: 35px;
+ display: none;
+ }
+ }
+
+ &.app-engage-hide {
+ .app-engage-btn {
+ visibility: hidden;
+
+ &.app-engage-btn-toggle-off {
+ display: none;
+ }
+
+ &.app-engage-btn-toggle-on {
+ visibility: visible;
+ display: flex;
+ }
+ }
+ }
+}
+
+.engage-btn {
+ display: flex;
+ align-items: center;
+ height: 35px !important;
+
+ @include button-custom-variant(
+ $color: var(--#{$prefix}engage-btn-color),
+ $icon-color: var(--#{$prefix}engage-btn-color),
+ $border-color: var(--#{$prefix}engage-btn-bg),
+ $bg-color: var(--#{$prefix}engage-btn-bg),
+ $color-active: var(--#{$prefix}engage-btn-color-active),
+ $icon-color-active: var(--#{$prefix}engage-btn-color-active),
+ $border-color-active: var(--#{$prefix}engage-btn-bg),
+ $bg-color-active: var(--#{$prefix}engage-btn-bg)
+ );
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_explore.scss b/Moonlight/Styles/components/_explore.scss
new file mode 100644
index 00000000..eafad72a
--- /dev/null
+++ b/Moonlight/Styles/components/_explore.scss
@@ -0,0 +1,104 @@
+//
+// Explore(used for demo product demo)
+//
+
+$explore-primary: #00B2FF;
+$explore-primary-light: #F1FAFF;
+$explore-primary-active: #0098DA;
+$explore-primary-inverse: $white;
+
+$explore-success: #50CD89;
+$explore-success-light: #E8FFF3;
+$explore-success-active: #47BE7D;
+$explore-success-inverse: $white;
+
+$explore-warning: #FFC700;
+$explore-warning-inverse: $white;
+
+$explore-danger: #F1416C;
+$explore-warning-inverse: $white;
+
+.explore-btn-toggle {
+ color: var(--#{$prefix}gray-600);
+ background-color: $white;
+
+ &:hover,
+ &:focus,
+ &:active {
+ color: $explore-primary-inverse;
+ background-color: $explore-primary;
+ }
+}
+
+.explore-btn-dismiss {
+ border: 0;
+
+ &:hover {
+ i,
+ .svg-icon {
+ color: $explore-primary;
+ }
+ }
+}
+
+.explore-btn-primary {
+ border: 0;
+ color: $explore-primary-inverse;
+ background-color: $explore-primary;
+
+ &:hover {
+ color: $explore-primary-inverse;
+ background-color: $explore-primary-active;
+ }
+}
+
+.explore-btn-secondary {
+ border: 0;
+ color: var(--#{$prefix}gray-600);
+ background-color: var(--#{$prefix}gray-100);
+
+ &:hover {
+ color: var(--#{$prefix}gray-800);
+ background-color: var(--#{$prefix}gray-200);
+ }
+}
+
+.explore-btn-outline {
+ border: 1px dashed var(--#{$prefix}gray-300) !important;
+
+ &:hover,
+ &.active {
+ border: 1px dashed $explore-success !important;
+ background-color: $explore-success-light;
+ }
+}
+
+.explore-link {
+ color: $explore-primary;
+
+ &:hover {
+ color: $explore-primary-active;
+ }
+}
+
+.explore-link-hover:hover {
+ color: $explore-primary !important;
+}
+
+.explore-icon-success {
+ color: $explore-success;
+}
+
+.explore-icon-danger {
+ color: $explore-danger;
+}
+
+.explore-label-free {
+ color: $explore-warning-inverse;
+ background-color: $explore-warning;
+}
+
+.explore-label-pro {
+ color: $explore-success-inverse;
+ background-color: $explore-success;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_fixed.scss b/Moonlight/Styles/components/_fixed.scss
new file mode 100644
index 00000000..c4935c4d
--- /dev/null
+++ b/Moonlight/Styles/components/_fixed.scss
@@ -0,0 +1,18 @@
+//
+// Fixed
+//
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .fixed-top#{$infix} {
+ position: fixed;
+ z-index: $fixed-z-index;
+ top: 0;
+ left: 0;
+ right: 0;
+ }
+ }
+}
+
diff --git a/Moonlight/Styles/components/_forms.scss b/Moonlight/Styles/components/_forms.scss
new file mode 100644
index 00000000..cd839b93
--- /dev/null
+++ b/Moonlight/Styles/components/_forms.scss
@@ -0,0 +1,13 @@
+//
+// Forms
+//
+
+// Import Dependencies
+@import "forms/labels";
+@import "forms/form-control";
+@import "forms/floating-labels";
+@import "forms/form-select";
+@import "forms/form-check";
+@import "forms/input-group";
+@import "forms/floating-labels";
+@import "forms/required";
diff --git a/Moonlight/Styles/components/_helpers.scss b/Moonlight/Styles/components/_helpers.scss
new file mode 100644
index 00000000..803a272c
--- /dev/null
+++ b/Moonlight/Styles/components/_helpers.scss
@@ -0,0 +1,12 @@
+//
+// Helpers
+//
+
+// Import Dependencies
+@import "helpers/background";
+@import "helpers/borders";
+@import "helpers/flex";
+@import "helpers/shadow";
+@import "helpers/text";
+@import "helpers/opacity";
+@import "helpers/transform";
diff --git a/Moonlight/Styles/components/_hover.scss b/Moonlight/Styles/components/_hover.scss
new file mode 100644
index 00000000..405c86ac
--- /dev/null
+++ b/Moonlight/Styles/components/_hover.scss
@@ -0,0 +1,53 @@
+//
+// Hover effects
+//
+
+.hover-elevate-up {
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: translateY(-2.5%);
+ transition: transform 0.3s ease;
+ will-change: transform;
+ }
+}
+
+.hover-elevate-down {
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: translateY(2.5%);
+ transition: transform 0.3s ease;
+ will-change: transform;
+ }
+}
+
+.hover-scale {
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: scale(1.1);
+ transition: transform 0.3s ease;
+ will-change: transform;
+ }
+}
+
+.hover-rotate-end {
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: rotate(4deg);
+ transition: transform 0.3s ease;
+ will-change: transform;
+ }
+}
+
+.hover-rotate-start {
+ transition: transform 0.3s ease;
+
+ &:hover {
+ transform: rotate(-4deg);
+ transition: transform 0.3s ease;
+ will-change: transform;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_image-input.scss b/Moonlight/Styles/components/_image-input.scss
new file mode 100644
index 00000000..95b0a163
--- /dev/null
+++ b/Moonlight/Styles/components/_image-input.scss
@@ -0,0 +1,111 @@
+//
+// Avatar
+//
+
+
+// Base
+.image-input {
+ position: relative;
+ display: inline-block;
+ @include border-radius($border-radius);
+ background-repeat: no-repeat;
+ background-size: cover;
+
+ // Empty state
+ &:not(.image-input-empty) {
+ background-image: none !important;
+ }
+
+ // Wrapper
+ .image-input-wrapper {
+ width: 120px;
+ height: 120px;
+ @include border-radius($border-radius);
+ background-repeat: no-repeat;
+ background-size: cover;
+ }
+
+ // Actions
+ [data-kt-image-input-action] {
+ cursor: pointer;
+ position: absolute;
+ transform: translate(-50%,-50%);
+ }
+
+ // Change Button
+ [data-kt-image-input-action="change"] {
+ left: 100%;
+ top: 0;
+
+ input {
+ width: 0 !important;
+ height: 0 !important;
+ overflow: hidden;
+ opacity: 0;
+ }
+ }
+
+ // Cancel & Remove Buttons
+ [data-kt-image-input-action="cancel"],
+ [data-kt-image-input-action="remove"] {
+ position: absolute;
+ left: 100%;
+ top: 100%;
+ }
+
+ [data-kt-image-input-action="cancel"] {
+ display: none;
+ }
+
+ // Input Changed State
+ &.image-input-changed {
+ [data-kt-image-input-action="cancel"] {
+ display: flex;
+ }
+
+ [data-kt-image-input-action="remove"] {
+ display: none;
+ }
+ }
+
+ // Input Empty State
+ &.image-input-empty {
+ [data-kt-image-input-action="remove"],
+ [data-kt-image-input-action="cancel"] {
+ display: none;
+ }
+ }
+
+ // Circle style
+ &.image-input-circle {
+ border-radius: 50%;
+
+ // Wrapper
+ .image-input-wrapper {
+ border-radius: 50%;
+ }
+
+ // Change Control
+ [data-kt-image-input-action="change"] {
+ left: 100%;
+ top: 0;
+ transform: translate(-100%, 0%);
+ }
+
+ // Cancel & Remove Buttons
+ [data-kt-image-input-action="cancel"],
+ [data-kt-image-input-action="remove"] {
+ left: 100%;
+ top: 100%;
+ transform: translate(-100%,-100%);
+ }
+ }
+
+ // Bordered style
+ &.image-input-outline {
+ .image-input-wrapper {
+ border: 3px solid var(--#{$prefix}body-bg);
+ box-shadow: var(--#{$prefix}box-shadow);
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_indicator.scss b/Moonlight/Styles/components/_indicator.scss
new file mode 100644
index 00000000..d74a9231
--- /dev/null
+++ b/Moonlight/Styles/components/_indicator.scss
@@ -0,0 +1,17 @@
+//
+// Indicator
+//
+
+.indicator-progress {
+ display: none;
+
+ [data-kt-indicator="on"] > & {
+ display: inline-block;
+ }
+}
+
+.indicator-label {
+ [data-kt-indicator="on"] > & {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_landing.scss b/Moonlight/Styles/components/_landing.scss
new file mode 100644
index 00000000..34f30241
--- /dev/null
+++ b/Moonlight/Styles/components/_landing.scss
@@ -0,0 +1,136 @@
+//
+// Landing elements
+//
+
+// Variables
+$landing-dark-color: #13263C;
+$landing-header-height: 100px;
+$landing-header-height-tablet-and-mobile: 70px;
+$landing-header-sticky-height: 70px;
+$landing-header-sticky-height-tablet-and-mobile: 70px;
+
+// Utility classes
+.landing-dark-bg {
+ background-color: $landing-dark-color;
+}
+
+.landing-dark-color {
+ color: $landing-dark-color;
+}
+
+.landing-dark-border {
+ border:1px dashed #2C3F5B;
+}
+
+.landing-dark-separator {
+ border-top:1px dashed #2C3F5B;
+}
+
+.landing-curve {
+ position: relative;
+
+ svg {
+ position: relative;
+ top: 0;
+ display: block;
+ }
+}
+
+// Landing header
+.landing-header {
+ display: flex;
+ align-items: center;
+ height: $landing-header-height;
+
+ // Logos
+ .logo-default {
+ display: block;
+ }
+
+ .logo-sticky {
+ display: none;
+ }
+
+ // Menu
+ .menu {
+ // Menu link
+ .menu-link {
+ &.active {
+ color: $white;
+ }
+ }
+
+ // Header menu sticky mode
+ [data-kt-sticky-landing-header="on"] & {
+ // Menu link
+ .menu-link {
+ &.active {
+ color: $primary;
+ background-color: rgba(#EFF2F5, 0.4);
+ }
+ }
+ }
+ }
+
+ // Sticky header modes
+ [data-kt-sticky-landing-header="on"] & {
+ padding: 0;
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 100;
+ background-color: $white;
+ box-shadow: 0px 10px 30px 0px rgba(82,63,105,0.05);
+ height: $landing-header-sticky-height;
+
+ // Logos
+ .logo-sticky {
+ display: block;
+ }
+
+ .logo-default {
+ display: none;
+ }
+ }
+}
+
+// Fix body padding top when Landing sticky header is on
+body[data-kt-sticky-landing-header="on"] {
+ padding-top: $landing-header-height;
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Landing header
+ .landing-header {
+ height: $landing-header-height-tablet-and-mobile;
+
+ // Menu wrapper
+ .landing-menu-wrapper {
+ position: relative;
+ overflow: auto;
+ }
+
+ // Sticky header modes
+ [data-kt-sticky-landing-header="on"] & {
+ height: $landing-header-sticky-height-tablet-and-mobile;
+ }
+
+ // Menu
+ .menu {
+ // Menu link
+ .menu-link {
+ &.active {
+ color: $primary;
+ background-color: rgba(#EFF2F5, 0.4);
+ }
+ }
+ }
+ }
+
+ // Fix body padding top when Landing sticky header is on
+ body[data-kt-sticky-landing-header="on"] {
+ padding-top: $landing-header-height-tablet-and-mobile;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_menu.scss b/Moonlight/Styles/components/_menu.scss
new file mode 100644
index 00000000..8564e7cf
--- /dev/null
+++ b/Moonlight/Styles/components/_menu.scss
@@ -0,0 +1,7 @@
+//
+// Menu
+//
+
+// Import Dependencies
+@import "menu/base";
+@import "menu/theme";
diff --git a/Moonlight/Styles/components/_mixins.scss b/Moonlight/Styles/components/_mixins.scss
new file mode 100644
index 00000000..e63d9608
--- /dev/null
+++ b/Moonlight/Styles/components/_mixins.scss
@@ -0,0 +1,13 @@
+//
+// Mixins
+//
+
+// Import Dependencies
+@import "mixins/menu";
+@import "mixins/buttons";
+@import "mixins/ki";
+@import "mixins/symbol";
+@import "mixins/svg-icon";
+@import "mixins/svg-bg-icon";
+@import "mixins/scroll";
+@import "mixins/shape";
diff --git a/Moonlight/Styles/components/_modal.scss b/Moonlight/Styles/components/_modal.scss
new file mode 100644
index 00000000..7dc5fbc8
--- /dev/null
+++ b/Moonlight/Styles/components/_modal.scss
@@ -0,0 +1,7 @@
+//
+// Modal
+//
+
+.modal-rounded {
+ border-radius: $modal-content-border-radius !important;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_nav-line-tabs.scss b/Moonlight/Styles/components/_nav-line-tabs.scss
new file mode 100644
index 00000000..4c1ccbe3
--- /dev/null
+++ b/Moonlight/Styles/components/_nav-line-tabs.scss
@@ -0,0 +1,68 @@
+//
+// Nav
+//
+
+// Line tabs
+.nav-line-tabs {
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-bottom-color: var(--#{$prefix}border-color);
+
+ .nav-item {
+ margin-bottom: -1px;
+
+ // Base link
+ .nav-link {
+ color: var(--#{$prefix}gray-500);
+ border: 0;
+ border-bottom: 1px solid transparent;
+ transition: $transition-link;
+ padding: 0.5rem 0;
+ margin: 0 1rem;
+ }
+
+ // First Item
+ &:first-child {
+ .nav-link {
+ margin-left: 0;
+ }
+ }
+
+ // Last Item
+ &:last-child {
+ .nav-link {
+ margin-right: 0;
+ }
+ }
+ }
+
+ // Active & Hover States
+ .nav-item .nav-link.active,
+ .nav-item.show .nav-link,
+ .nav-item .nav-link:hover:not(.disabled) {
+ background-color: transparent;
+ border: 0;
+ border-bottom: 1px solid var(--#{$prefix}primary);
+ transition: $transition-link;
+ }
+
+ // 2x Line
+ &.nav-line-tabs-2x {
+ border-bottom-width: 2px;
+
+ .nav-item {
+ margin-bottom: -2px;
+
+ .nav-link {
+ border-bottom-width: 2px;
+ }
+ }
+
+ // Active & Hover States
+ .nav-item .nav-link.active,
+ .nav-item.show .nav-link,
+ .nav-item .nav-link:hover:not(.disabled) {
+ border-bottom-width: 2px;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_nav-pills-custom.scss b/Moonlight/Styles/components/_nav-pills-custom.scss
new file mode 100644
index 00000000..9de985a7
--- /dev/null
+++ b/Moonlight/Styles/components/_nav-pills-custom.scss
@@ -0,0 +1,91 @@
+//
+// Custom Nav Pills
+//
+
+.nav.nav-pills.nav-pills-custom {
+ // States
+ .show > .nav-link,
+ .nav-link{
+ border: 1px dashed var(--#{$prefix}border-dashed-color);
+ @include border-radius($border-radius-lg);
+
+ &.nav-link-border-solid {
+ border: 3px solid var(--#{$prefix}border-dashed-color);
+
+ &.active {
+ border: 3px solid var(--#{$prefix}primary);
+ }
+ }
+
+ .nav-icon {
+ img {
+ width: 30px;
+ transition: $transition-link;
+
+ &.default {
+ display: inline-block;
+ }
+
+ &.active {
+ display: none;
+ }
+ }
+ }
+
+ &.active {
+ background-color: transparent;
+ border: 1px solid var(--#{$prefix}border-dashed-color);
+ transition-duration: 1ms;
+ position: relative;
+
+ .nav-text {
+ color: var(--#{$prefix}gray-800) !important;
+ transition: $transition-link;
+ }
+
+ .bullet-custom {
+ display: block;
+ }
+ }
+
+ .bullet-custom {
+ display: none;
+ }
+ }
+
+ &.nav-pills-active-custom {
+ .nav-item {
+ .nav-link {
+ &:not(:active) {
+ span:nth-child(1) {
+ color: #B5B5C3;
+ }
+
+ span:nth-child(2) {
+ color: #3F4254;
+ }
+ }
+
+ &:hover {
+ span:nth-child(1) {
+ color: $white !important;
+ }
+
+ span:nth-child(2) {
+ color: $white !important;
+ }
+ }
+
+ &.active {
+ span:nth-child(1) {
+ color: $white !important;
+ }
+
+ span:nth-child(2) {
+ color: $white !important;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_nav.scss b/Moonlight/Styles/components/_nav.scss
new file mode 100644
index 00000000..87aba9a4
--- /dev/null
+++ b/Moonlight/Styles/components/_nav.scss
@@ -0,0 +1,71 @@
+//
+// Nav
+//
+
+// Nav pills
+.nav-pills {
+ .nav-item {
+ margin-right: 0.5rem;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+}
+
+// Stretch items
+.nav-stretch {
+ align-items: stretch;
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+
+ .nav-item {
+ display: flex;
+ align-items: stretch;
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+
+ .nav-link {
+ display: flex;
+ align-items: center;
+ }
+}
+
+// Nav group
+.nav-group {
+ padding: 0.35rem;
+ @include border-radius($border-radius);
+ background-color: var(--#{$prefix}gray-100);
+
+ // Outline nav group
+ &.nav-group-outline {
+ background-color: transparent;
+ border: 1px solid var(--#{$prefix}border-color);
+ }
+
+ // Fluid option
+ &.nav-group-fluid {
+ display: flex;
+
+ > label,
+ > .btn {
+ position: relative;
+ flex-shrink: 0;
+ flex-grow: 1;
+ flex-basis: 0;
+ }
+
+ > label {
+ margin-right: 0.1rem;
+
+ > .btn {
+ width: 100%;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_offcanvas.scss b/Moonlight/Styles/components/_offcanvas.scss
new file mode 100644
index 00000000..e6425060
--- /dev/null
+++ b/Moonlight/Styles/components/_offcanvas.scss
@@ -0,0 +1,6 @@
+%offcanvas-css-vars {
+ --#{$prefix}offcanvas-color: var(--#{$prefix}offcanvas-color);
+ --#{$prefix}offcanvas-bg: var(--#{$prefix}offcanvas-bg-color);
+ --#{$prefix}offcanvas-border-color: var(--#{$prefix}offcanvas-border-color);
+ --#{$prefix}offcanvas-box-shadow: var(--#{$prefix}offcanvas-box-shadow);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_overlay.scss b/Moonlight/Styles/components/_overlay.scss
new file mode 100644
index 00000000..a3a82a9c
--- /dev/null
+++ b/Moonlight/Styles/components/_overlay.scss
@@ -0,0 +1,35 @@
+//
+// Demo
+//
+
+
+.overlay {
+ position: relative;
+
+ .overlay-layer {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--#{$prefix}overlay-bg);
+ transition: all 0.3s ease;
+ opacity: 0;
+ }
+
+ &.overlay-show,
+ &.overlay-block,
+ &:hover {
+ .overlay-layer {
+ transition: all 0.3s ease;
+ opacity: 1;
+ }
+ }
+
+ &.overlay-block {
+ cursor: wait;
+ }
+}
diff --git a/Moonlight/Styles/components/_page-loader.scss b/Moonlight/Styles/components/_page-loader.scss
new file mode 100644
index 00000000..55ffee63
--- /dev/null
+++ b/Moonlight/Styles/components/_page-loader.scss
@@ -0,0 +1,28 @@
+//
+// Page loader(used by the previous layout system)
+//
+
+// CSS3 Transitions only after page load(.page-loading class added to body tag and remove with JS on page load)
+[data-kt-app-page-loading="on"] *,
+.page-loading * {
+ transition: none !important;
+}
+
+// Base
+.page-loader {
+ background-color: var(--#{$prefix}body-bg);
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 10000;
+ display: none;
+
+ [data-kt-app-page-loading="on"] &,
+ .page-loading & {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+}
diff --git a/Moonlight/Styles/components/_pagination.scss b/Moonlight/Styles/components/_pagination.scss
new file mode 100644
index 00000000..b0d96d0b
--- /dev/null
+++ b/Moonlight/Styles/components/_pagination.scss
@@ -0,0 +1,176 @@
+//
+// Pagination
+//
+
+.pagination {
+ display:flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ margin: 0;
+
+ // Pagination circle
+ &.pagination-circle {
+ .page-link {
+ border-radius: 50%;
+ }
+ }
+
+ // Pagination outline
+ &.pagination-outline {
+ .page-link {
+ border: 1px solid var(--#{$prefix}border-color);
+ }
+
+ .page-item {
+ &:hover:not(.disabled),
+ &.active {
+ .page-link {
+ border-color: var(--#{$prefix}primary-light);
+ }
+ }
+ }
+ }
+}
+
+.page-item {
+ margin-right: $pagination-item-space;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ .page-link {
+ display:flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: $btn-border-radius;
+ height: $pagination-item-height;
+ min-width: $pagination-item-height;
+ font-weight: $pagination-font-weight;
+ font-size: $pagination-font-size;
+
+ i {
+ font-size: $pagination-icon-font-size;
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .previous,
+ .next {
+ display: block;
+ height: $pagination-icon-height;
+ width: $pagination-icon-height;
+
+ /*rtl:raw:transform: rotateZ(-180deg);*/
+ }
+ /*rtl:end:ignore*/
+
+ .previous {
+ @include svg-bg-icon(arrow-start, $pagination-color);
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .next {
+ @include svg-bg-icon(arrow-end, $pagination-color);
+ }
+ }
+
+ &:focus {
+ .page-link {
+ color: var(--#{$prefix}pagination-focus-color);
+
+ .svg-icon,
+ i {
+ color: var(--#{$prefix}pagination-focus-color);
+ }
+
+ .previous {
+ @include svg-bg-icon(arrow-start, var(--#{$prefix}pagination-focus-color));
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .next {
+ @include svg-bg-icon(arrow-end, var(--#{$prefix}pagination-focus-color));
+ }
+ }
+ }
+
+ &:hover:not(.active):not(.offset):not(.disabled) {
+ .page-link {
+ color: var(--#{$prefix}pagination-hover-color);
+
+ &.page-text {
+ background-color: transparent;
+ }
+
+ .svg-icon,
+ i {
+ color: var(--#{$prefix}pagination-hover-color);
+ }
+
+ .previous {
+ @include svg-bg-icon(arrow-start, var(--#{$prefix}pagination-hover-color));
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .next {
+ @include svg-bg-icon(arrow-end, var(--#{$prefix}pagination-hover-color));
+ }
+ }
+ }
+
+ &.active {
+ .page-link {
+ color: var(--#{$prefix}pagination-active-color);
+
+ &.page-text {
+ background-color: transparent;
+ }
+
+ .svg-icon,
+ i {
+ color: var(--#{$prefix}pagination-active-color);;
+ }
+
+ .previous {
+ @include svg-bg-icon(arrow-start, var(--#{$prefix}pagination-active-color));
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .next {
+ @include svg-bg-icon(arrow-end, var(--#{$prefix}pagination-active-color));
+ }
+ }
+ }
+
+ &.disabled {
+ .page-link {
+ color: var(--#{$prefix}pagination-disabled-color);
+
+ .svg-icon,
+ i {
+ color: var(--#{$prefix}pagination-disabled-color);
+ }
+
+ .previous {
+ @include svg-bg-icon(arrow-start, var(--#{$prefix}pagination-disabled-color));
+ }
+
+ /*rtl:options:{"autoRename":false}*/
+ .next {
+ @include svg-bg-icon(arrow-end, var(--#{$prefix}pagination-disabled-color));
+ }
+ }
+ }
+ /*rtl:end:ignore*/
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .page-item {
+ margin-right: $pagination-item-space-tablet-and-mobile;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_popover.scss b/Moonlight/Styles/components/_popover.scss
new file mode 100644
index 00000000..baf9193c
--- /dev/null
+++ b/Moonlight/Styles/components/_popover.scss
@@ -0,0 +1,58 @@
+//
+// Popover
+//
+
+
+// Base
+.popover {
+ --#{$prefix}popover-header-border-color: #{$popover-header-border-color};
+
+ .popover-header {
+ font-size: $popover-header-font-size;
+ font-weight: $popover-header-font-weight;
+ border-bottom: 1px solid var(--#{$prefix}popover-header-border-color);
+ }
+
+ .popover-dismiss {
+ position: absolute;
+ top: $popover-dissmis-btn-top;
+ right: $popover-dissmis-btn-end;
+ height: $popover-dissmis-btn-size;
+ width: $popover-dissmis-btn-size;
+ @include svg-bg-icon(close, var(--#{$prefix}gray-500)); // todo: revise
+ mask-size: 50%;
+ -webkit-mask-size: 50%;
+
+ &:hover {
+ background-color: var(--#{$prefix}primary);
+ }
+
+ & + .popover-header {
+ padding-right: $popover-body-padding-x + $popover-dissmis-btn-size;
+ }
+ }
+}
+
+// Inverse
+.popover-inverse {
+ --#{$prefix}popover-bg: var(--#{$prefix}gray-900);
+ --#{$prefix}popover-border-color: var(--#{$prefix}gray-900);
+ --#{$prefix}popover-box-shadow: #{$popover-box-shadow-dark};
+ --#{$prefix}popover-header-color: var(--#{$prefix}gray-200);
+ --#{$prefix}popover-header-bg: var(--#{$prefix}gray-900);
+ --#{$prefix}popover-body-color: var(--#{$prefix}gray-400);
+ --#{$prefix}popover-arrow-border: transparent;
+ --#{$prefix}popover-header-border-color: var(--#{$prefix}gray-800);
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .popover:not(.popover-inverse) {
+ --#{$prefix}popover-bg: #{$popover-bg-dark};
+ --#{$prefix}popover-border-color: #{$popover-border-color-dark};
+ --#{$prefix}popover-header-bg: #{$popover-bg-dark};
+ --#{$prefix}popover-box-shadow: #{$popover-box-shadow-dark};
+ --#{$prefix}popover-header-border-color: #{$popover-header-border-color-dark};
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_print.scss b/Moonlight/Styles/components/_print.scss
new file mode 100644
index 00000000..ab7854b9
--- /dev/null
+++ b/Moonlight/Styles/components/_print.scss
@@ -0,0 +1,34 @@
+//
+// Print Mode
+//
+
+// Add .print-content-only class to body element in order to allow printing only the content area
+@media print {
+ .print-content-only {
+ padding: 0 !important;
+ background: none !important;
+
+ .wrapper,
+ .page,
+ .page-title
+ .content,
+ .container,
+ .container-xxl,
+ .container-fluid {
+ background: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ .aside,
+ .sidebar,
+ .scrolltop,
+ .header,
+ .footer,
+ .toolbar,
+ .drawer,
+ .btn {
+ display: none !important;
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_progress.scss b/Moonlight/Styles/components/_progress.scss
new file mode 100644
index 00000000..7a3ad84d
--- /dev/null
+++ b/Moonlight/Styles/components/_progress.scss
@@ -0,0 +1,27 @@
+//
+// Progress
+//
+
+// Vertical Position
+.progress-vertical {
+ display: flex;
+ align-items: stretch;
+ justify-content: space-between;
+
+ .progress {
+ height: 100%;
+ @include border-radius($border-radius);
+ display: flex;
+ align-items: flex-end;
+ margin-right: 1rem;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ .progress-bar {
+ width: 8px;
+ @include border-radius($border-radius);
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_pulse.scss b/Moonlight/Styles/components/_pulse.scss
new file mode 100644
index 00000000..43e9b3ab
--- /dev/null
+++ b/Moonlight/Styles/components/_pulse.scss
@@ -0,0 +1,39 @@
+//
+// Pulse
+//
+
+
+// Base
+.pulse {
+ position: relative;
+
+ // Theme Colors
+ @each $name, $color in $theme-colors {
+ &.pulse-#{$name} {
+ .pulse-ring {
+ border-color: var(--#{$prefix}#{$name});
+ }
+ }
+ }
+}
+
+.pulse-ring {
+ display: block;
+ border-radius: 40px;
+ height: 40px;
+ width: 40px;
+ position: absolute;
+ animation: animation-pulse 3.5s ease-out;
+ animation-iteration-count: infinite;
+ opacity: 0;
+ border-width: 3px;
+ border-style: solid;
+ border-color: var(--#{$prefix}gray-500);
+}
+
+@keyframes animation-pulse {
+ 0% {-webkit-transform: scale(0.1, 0.1); opacity: 0.0;}
+ 60% {-webkit-transform: scale(0.1, 0.1); opacity: 0.0;}
+ 65% {opacity: 1;}
+ 100% {-webkit-transform: scale(1.2, 1.2); opacity: 0.0;}
+}
diff --git a/Moonlight/Styles/components/_rating.scss b/Moonlight/Styles/components/_rating.scss
new file mode 100644
index 00000000..547b8da0
--- /dev/null
+++ b/Moonlight/Styles/components/_rating.scss
@@ -0,0 +1,62 @@
+//
+// Rating
+//
+
+.rating {
+ display: flex;
+ align-items: center;
+}
+
+.rating-input {
+ position: absolute !important;
+ left: -9999px !important;
+
+ &[disabled] {
+ display: none;
+ }
+}
+
+.rating-label {
+ padding: 0;
+ margin: 0;
+
+ & > i,
+ & > .svg-icon {
+ line-height: 1;
+ color: var(--#{$prefix}rating-color-default);
+ }
+}
+
+label.rating-label {
+ cursor: pointer;
+}
+
+div.rating-label.checked,
+label.rating-label {
+ & > i,
+ & > .svg-icon {
+ color: var(--#{$prefix}rating-color-active);
+ }
+}
+
+.rating-input:checked ~ .rating-label {
+ & > i,
+ & > .svg-icon {
+ color: var(--#{$prefix}rating-color-default);
+ }
+}
+
+.rating:hover label.rating-label {
+ & > i,
+ & > .svg-icon {
+ color: var(--#{$prefix}rating-color-active);
+ }
+}
+
+label.rating-label:hover ~ .rating-label {
+ & > i,
+ & > .svg-icon {
+ color: var(--#{$prefix}rating-color-default);
+ }
+ color: var(--#{$prefix}rating-color-default);
+}
diff --git a/Moonlight/Styles/components/_reboot.scss b/Moonlight/Styles/components/_reboot.scss
new file mode 100644
index 00000000..722742b1
--- /dev/null
+++ b/Moonlight/Styles/components/_reboot.scss
@@ -0,0 +1,7 @@
+//
+// Reboot
+//
+
+h1, h2, h3, h4, h5, h6 {
+ outline: 0;
+}
diff --git a/Moonlight/Styles/components/_ribbon.scss b/Moonlight/Styles/components/_ribbon.scss
new file mode 100644
index 00000000..071e299f
--- /dev/null
+++ b/Moonlight/Styles/components/_ribbon.scss
@@ -0,0 +1,195 @@
+//
+// Ribbon
+//
+
+// Base
+.ribbon {
+ position: relative;
+
+ // Ribbon target
+ .ribbon-label {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 5px 10px;
+ position: absolute;
+ z-index: 1;
+ background-color: var(--#{$prefix}ribbon-label-bg);
+ box-shadow: var(--#{$prefix}ribbon-label-box-shadow);
+ color: var(--#{$prefix}primary-inverse);
+ top: 50%;
+ right: 0;
+ transform: translateX(5px) translateY(-50%);
+
+ > .ribbon-inner {
+ z-index: -1;
+ position: absolute;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ }
+
+ &:after {
+ border-color: var(--#{$prefix}ribbon-label-border-color);
+ }
+ }
+
+ // Vertical aligment
+ &-vertical {
+ .ribbon-label {
+ padding: 5px 10px;
+ min-width: 36px;
+ min-height: 46px;
+ text-align: center;
+ }
+ }
+
+ &.ribbon-top {
+ .ribbon-label {
+ top: 0;
+ transform: translateX(-15px) translateY(-4px);
+ border-bottom-right-radius: $border-radius;
+ border-bottom-left-radius: $border-radius;
+ }
+ }
+
+ &.ribbon-bottom {
+ .ribbon-label {
+ border-top-right-radius: $border-radius;
+ border-top-left-radius: $border-radius;
+ }
+ }
+
+ &.ribbon-start {
+ .ribbon-label {
+ top: 50%;
+ left: 0;
+ right: auto;
+ transform: translateX(-5px) translateY(-50%);
+ border-top-right-radius: $border-radius;
+ border-bottom-right-radius: $border-radius;
+ }
+ }
+
+ &.ribbon-end {
+ .ribbon-label {
+ border-top-left-radius: $border-radius;
+ border-bottom-left-radius: $border-radius;
+ }
+ }
+}
+
+// Clip style
+.ribbon.ribbon-clip {
+ &.ribbon-start {
+ .ribbon-label {
+ left: -5px;
+
+ .ribbon-inner {
+ border-top-right-radius: $border-radius;
+ border-bottom-right-radius: $border-radius;
+
+ &:before,
+ &:after {
+ content: "";
+ position: absolute;
+ border-style: solid;
+ border-color: transparent !important;
+ bottom: -10px;
+ }
+
+ &:before {
+ border-width: 0 10px 10px 0;
+ border-right-color: var(--#{$prefix}ribbon-clip-bg) !important;
+ left: 0;
+ }
+ }
+ }
+ }
+
+ &.ribbon-end {
+ .ribbon-label {
+ right: -5px;
+
+ .ribbon-inner {
+ border-top-left-radius: $border-radius;
+ border-bottom-left-radius: $border-radius;
+
+ &:before,
+ &:after {
+ content: "";
+ position: absolute;
+ border-style: solid;
+ border-color: transparent !important;
+ bottom: -10px;
+ }
+
+ &:before {
+ border-width: 0 0 10px 10px;
+ border-left-color: var(--#{$prefix}ribbon-clip-bg) !important;
+ right: 0;
+ }
+ }
+ }
+ }
+}
+
+// Triangle style
+.ribbon.ribbon-triangle {
+ position: absolute;
+ z-index: 1;
+ display: flex;
+ align-items: flex-start;
+ justify-content: flex-start;
+
+ // Top start position
+ &.ribbon-top-start {
+ top: 0;
+ left: 0;
+ width: 4rem;
+ height: 4rem;
+ border-bottom: solid 2rem transparent !important;
+ border-left: solid 2rem transparent;
+ border-right: solid 2rem transparent !important;
+ border-top: solid 2rem transparent;
+ }
+
+ // Top end position
+ &.ribbon-top-end {
+ top: 0;
+ right: 0;
+ width: 4rem;
+ height: 4rem;
+ border-bottom: solid 2rem transparent !important;
+ border-left: solid 2rem transparent !important;
+ border-right: solid 2rem transparent;
+ border-top: solid 2rem transparent;
+ }
+
+ // Botton start position
+ &.ribbon-bottom-start {
+ bottom: 0;
+ left: 0;
+ width: 4rem;
+ height: 4rem;
+ border-bottom: solid 2rem transparent;
+ border-left: solid 2rem transparent;
+ border-right: solid 2rem transparent !important;
+ border-top: solid 2rem transparent !important;
+ }
+
+ // Botton end position
+ &.ribbon-bottom-end {
+ bottom: 0;
+ right: 0;
+ width: 4rem;
+ height: 4rem;
+ border-bottom: solid 2rem transparent;
+ border-right: solid 2rem transparent;
+ border-left: solid 2rem transparent !important;
+ border-top: solid 2rem transparent !important;
+ }
+}
+
diff --git a/Moonlight/Styles/components/_root.scss b/Moonlight/Styles/components/_root.scss
new file mode 100644
index 00000000..479a4dda
--- /dev/null
+++ b/Moonlight/Styles/components/_root.scss
@@ -0,0 +1,316 @@
+//
+// CSS Variables
+//
+
+:root {
+ // Breakpoints
+ @each $breakpoint, $value in $grid-breakpoints {
+ --#{$prefix}#{$breakpoint}:#{$value};
+ }
+
+ // Keenthemes scrollbar component
+ --#{$prefix}scrollbar-size: #{$scrollbar-size};
+ --#{$prefix}scrollbar-overlay-size: #{$scrollbar-overlay-size};
+ --#{$prefix}scrollbar-overlay-space: #{$scrollbar-overlay-space};
+
+ // Bootstrap general
+ --#{$prefix}white-bg-rgb: #{to-rgb($white)};
+ --#{$prefix}black-bg-rgb: #{to-rgb($black)};
+}
+
+@include color-mode(light) {
+ // Bootstrap muted color
+ --#{$prefix}text-muted: #{$text-muted};
+
+ // Grey colors
+ @each $name, $value in $grays {
+ --#{$prefix}gray-#{$name}: #{$value};
+ --#{$prefix}gray-#{$name}-rgb: #{to-rgb($value)};
+ }
+
+ // Contextual colors
+ @each $name, $value in $theme-colors {
+ --#{$prefix}#{$name}: #{$value};
+ }
+
+ // Contextual active state colors
+ @each $name, $value in $theme-active-colors {
+ --#{$prefix}#{$name}-active: #{$value};
+ }
+
+ // Contextual light state colors
+ @each $name, $value in $theme-light-colors {
+ --#{$prefix}#{$name}-light: #{$value};
+ }
+
+ // Contextual inverse state colors
+ @each $name, $value in $theme-inverse-colors {
+ --#{$prefix}#{$name}-inverse: #{$value};
+ }
+
+ // Contextual rbg colors
+ @each $name, $value in $theme-colors {
+ --#{$prefix}#{$name}-rgb: #{to-rgb($value)};
+ }
+
+ // Text colors
+ @each $name, $value in $theme-text-colors {
+ --#{$prefix}text-#{$name}: #{$value};
+ }
+
+ // Components
+ --#{$prefix}border-color: #{$border-color};
+ --#{$prefix}border-dashed-color: #{$border-dashed-color};
+
+ --#{$prefix}component-active-color: #{$component-active-color};
+ --#{$prefix}component-active-bg: #{$component-active-bg};
+ --#{$prefix}component-hover-color: #{$component-hover-color};
+ --#{$prefix}component-hover-bg: #{$component-hover-bg};
+ --#{$prefix}component-checked-color: #{$component-checked-color};
+ --#{$prefix}component-checked-bg: #{$component-checked-bg};
+
+ // Box shadow
+ --#{$prefix}box-shadow-xs: #{$box-shadow-xs};
+ --#{$prefix}box-shadow-sm: #{$box-shadow-sm};
+ --#{$prefix}box-shadow: #{$box-shadow};
+ --#{$prefix}box-shadow-lg: #{$box-shadow-lg};
+
+ // Forms
+ --#{$prefix}input-bg: #{$input-bg};
+ --#{$prefix}input-color: #{$input-color};
+ --#{$prefix}input-solid-color: #{$input-solid-color};
+ --#{$prefix}input-solid-bg: #{$input-solid-bg};
+ --#{$prefix}input-solid-bg-focus: #{$input-solid-bg-focus};
+ --#{$prefix}input-solid-placeholder-color: #{$input-solid-placeholder-color};
+
+
+ // Tooltip
+ --#{$prefix}tooltip-box-shadow: #{$tooltip-box-shadow-dark};
+
+ // Table
+ --#{$prefix}table-striped-bg: #{$table-striped-bg};
+ --#{$prefix}table-loading-message-box-shadow: #{$table-loading-message-box-shadow};
+
+ // Dropdowns
+ --#{$prefix}dropdown-bg: #{$dropdown-bg};
+ --#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
+
+ // Code
+ --#{$prefix}code-bg: #{$code-bg};
+ --#{$prefix}code-box-shadow: #{$code-box-shadow};
+ --#{$prefix}code-color: #{$code-color};
+
+ // Symbol
+ --#{$prefix}symbol-label-color: #{$symbol-label-color};
+ --#{$prefix}symbol-label-bg: #{$symbol-label-bg};
+ --#{$prefix}symbol-border-color: #{$symbol-border-color};
+
+ // Bullet
+ --#{$prefix}bullet-bg-color: #{$bullet-bg-color};
+
+ // Scrolltop
+ --#{$prefix}scrolltop-opacity: #{$scrolltop-opacity};
+ --#{$prefix}scrolltop-opacity-on: #{$scrolltop-opacity-on};
+ --#{$prefix}scrolltop-opacity-hover: #{$scrolltop-opacity-hover};
+ --#{$prefix}scrolltop-box-shadow: #{$scrolltop-box-shadow};
+ --#{$prefix}scrolltop-bg-color: #{$scrolltop-bg-color};
+ --#{$prefix}scrolltop-bg-color-hover: #{$scrolltop-bg-color-hover};
+ --#{$prefix}scrolltop-icon-color: #{$scrolltop-icon-color};
+ --#{$prefix}scrolltop-icon-color-hover: #{$scrolltop-icon-color-hover};
+
+ // Keenthemes drawer component
+ --#{$prefix}drawer-box-shadow: #{$drawer-box-shadow};
+ --#{$prefix}drawer-bg-color: #{$drawer-bg-color};
+ --#{$prefix}drawer-overlay-bg-color: #{$drawer-overlay-bg-color};
+
+ // Keenthemes menu component
+ --#{$prefix}menu-dropdown-box-shadow: #{$menu-dropdown-box-shadow};
+ --#{$prefix}menu-dropdown-bg-color: #{$menu-dropdown-bg-color};
+ --#{$prefix}menu-heading-color: #{$menu-heading-color};
+ --#{$prefix}menu-link-color-hover: #{$menu-link-color-hover};
+ --#{$prefix}menu-link-color-show: #{$menu-link-color-show};
+ --#{$prefix}menu-link-color-here: #{$menu-link-color-here};
+ --#{$prefix}menu-link-color-active: #{$menu-link-color-active};
+ --#{$prefix}menu-link-bg-color-hover: #{$menu-link-bg-color-hover};
+ --#{$prefix}menu-link-bg-color-show: #{$menu-link-bg-color-show};
+ --#{$prefix}menu-link-bg-color-here: #{$menu-link-bg-color-here};
+ --#{$prefix}menu-link-bg-color-active: #{$menu-link-bg-color-active};
+
+ // Keenthemes scrollbar component
+ --#{$prefix}scrollbar-color: #{$scrollbar-color};
+ --#{$prefix}scrollbar-hover-color: #{$scrollbar-hover-color};
+
+ // Keenthemes overlay component
+ --#{$prefix}overlay-bg: #{$overlay-bg};
+
+ // Keenthemes blockui component
+ --#{$prefix}blockui-overlay-bg: #{$blockui-overlay-bg};
+
+ // Keenthemes rating component
+ --#{$prefix}rating-color-default: #{$rating-color-default};
+ --#{$prefix}rating-color-active: #{$rating-color-active};
+
+ // Keenthemes ribbon component
+ --#{$prefix}ribbon-label-box-shadow: #{$ribbon-label-box-shadow};
+ --#{$prefix}ribbon-label-bg: #{$ribbon-label-bg};
+ --#{$prefix}ribbon-label-border-color: #{$ribbon-label-border-color};
+ --#{$prefix}ribbon-clip-bg: #{$ribbon-clip-bg};
+
+ // Engage panel
+ --#{$prefix}engage-btn-bg: #{$engage-btn-bg};
+ --#{$prefix}engage-btn-box-shadow: #{$engage-btn-box-shadow};
+ --#{$prefix}engage-btn-border-color: #{$engage-btn-border-color};
+ --#{$prefix}engage-btn-color: #{$engage-btn-color};
+ --#{$prefix}engage-btn-icon-color: #{$engage-btn-icon-color};
+ --#{$prefix}engage-btn-color-active: #{$engage-btn-color-active};
+}
+
+@include color-mode(dark) {
+ // Bootstrap muted color
+ --#{$prefix}text-muted: #{$text-muted-dark};
+
+ // Grey colors
+ @each $name, $value in $grays-dark {
+ --#{$prefix}gray-#{$name}: #{$value};
+ --#{$prefix}gray-#{$name}-rgb: #{to-rgb($value)};
+ }
+
+ // Contextual colors
+ @each $name, $value in $theme-colors-dark {
+ --#{$prefix}#{$name}: #{$value};
+ }
+
+ // Contextual active state colors
+ @each $name, $value in $theme-active-colors-dark {
+ --#{$prefix}#{$name}-active: #{$value};
+ }
+
+ // Contextual light state colors
+ @each $name, $value in $theme-light-colors-dark {
+ --#{$prefix}#{$name}-light: #{$value};
+ }
+
+ // Contextual inverse state colors
+ @each $name, $value in $theme-inverse-colors-dark {
+ --#{$prefix}#{$name}-inverse: #{$value};
+ }
+
+ // Contextual rbg colors
+ @each $name, $value in $theme-colors-dark {
+ --#{$prefix}#{$name}-rgb: #{to-rgb($value)};
+ }
+
+ // Text colors
+ @each $name, $value in $theme-text-colors-dark {
+ --#{$prefix}text-#{$name}: #{$value};
+ }
+
+ // Components
+ --#{$prefix}border-color: #{$border-color-dark};
+ --#{$prefix}border-dashed-color: #{$border-dashed-color-dark};
+
+ --#{$prefix}component-active-color: #{$component-active-color-dark};
+ --#{$prefix}component-active-bg: #{$component-active-bg-dark};
+ --#{$prefix}component-hover-color: #{$component-hover-color-dark};
+ --#{$prefix}component-hover-bg: #{$component-hover-bg-dark};
+ --#{$prefix}component-checked-color: #{$component-checked-color-dark};
+ --#{$prefix}component-checked-bg: #{$component-checked-bg-dark};
+
+ // Box shadow
+ --#{$prefix}box-shadow-xs: #{$box-shadow-xs-dark};
+ --#{$prefix}box-shadow-sm: #{$box-shadow-sm-dark};
+ --#{$prefix}box-shadow: #{$box-shadow-dark};
+ --#{$prefix}box-shadow-lg: #{$box-shadow-lg-dark};
+
+ // Forms
+ --#{$prefix}input-color: #{$input-color};
+ --#{$prefix}input-bg: #{$input-bg};
+ --#{$prefix}input-solid-color: #{$input-solid-color};
+ --#{$prefix}input-solid-bg: #{$input-solid-bg};
+ --#{$prefix}input-solid-bg-focus: #{$input-solid-bg-focus};
+ --#{$prefix}input-solid-placeholder-color: #{$input-solid-placeholder-color};
+
+ // Tooltip
+ --#{$prefix}tooltip-box-shadow: #{$tooltip-box-shadow-dark};
+
+ // Card
+ --#{$prefix}card-box-shadow: #{$card-box-shadow-dark};
+
+ // Table
+ --#{$prefix}table-striped-bg: #{$table-striped-bg-dark};
+ --#{$prefix}table-loading-message-box-shadow: #{$table-loading-message-box-shadow-dark};
+
+ // Dropdowns
+ --#{$prefix}dropdown-bg: #{$dropdown-bg-dark};
+ --#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow-dark};
+
+ // Code
+ --#{$prefix}code-bg: #{$code-bg-dark};
+ --#{$prefix}code-box-shadow: #{$code-box-shadow-dark};
+ --#{$prefix}code-color: #{$code-color-dark};
+
+ // Symbol
+ --#{$prefix}symbol-label-color: #{$symbol-label-color-dark};
+ --#{$prefix}symbol-label-bg: #{$symbol-label-bg-dark};
+ --#{$prefix}symbol-border-color: #{$symbol-border-color-dark};
+
+ // Bullet
+ --#{$prefix}bullet-bg-color: #{$bullet-bg-color-dark};
+
+ // Scrolltop
+ --#{$prefix}scrolltop-opacity: #{$scrolltop-opacity-dark};
+ --#{$prefix}scrolltop-opacity-on: #{$scrolltop-opacity-on-dark};
+ --#{$prefix}scrolltop-opacity-hover: #{$scrolltop-opacity-hover-dark};
+ --#{$prefix}scrolltop-box-shadow: #{$scrolltop-box-shadow-dark};
+ --#{$prefix}scrolltop-bg-color: #{$scrolltop-bg-color-dark};
+ --#{$prefix}scrolltop-bg-color-hover: #{$scrolltop-bg-color-hover-dark};
+ --#{$prefix}scrolltop-icon-color: #{$scrolltop-icon-color-dark};
+ --#{$prefix}scrolltop-icon-color-hover: #{$scrolltop-icon-color-hover-dark};
+
+ // Keenthemes drawer component
+ --#{$prefix}drawer-box-shadow: #{$drawer-box-shadow-dark};
+ --#{$prefix}drawer-bg-color: #{$drawer-bg-color-dark};
+ --#{$prefix}drawer-overlay-bg-color: #{$drawer-overlay-bg-color-dark};
+
+ // Keenthemes menu component
+ --#{$prefix}menu-dropdown-box-shadow: #{$menu-dropdown-box-shadow-dark};
+ --#{$prefix}menu-dropdown-bg-color: #{$menu-dropdown-bg-color-dark};
+ --#{$prefix}menu-heading-color: #{$menu-heading-color-dark};
+
+ --#{$prefix}menu-link-color-hover: #{$menu-link-color-hover-dark};
+ --#{$prefix}menu-link-color-show: #{$menu-link-color-show-dark};
+ --#{$prefix}menu-link-color-here: #{$menu-link-color-here-dark};
+ --#{$prefix}menu-link-color-active: #{$menu-link-color-active-dark};
+ --#{$prefix}menu-link-bg-color-hover: #{$menu-link-bg-color-hover-dark};
+ --#{$prefix}menu-link-bg-color-show: #{$menu-link-bg-color-show-dark};
+ --#{$prefix}menu-link-bg-color-here: #{$menu-link-bg-color-here-dark};
+ --#{$prefix}menu-link-bg-color-active: #{$menu-link-bg-color-active-dark};
+
+ // Keenthemes scrollbar component
+ --#{$prefix}scrollbar-color: #{$scrollbar-color-dark};
+ --#{$prefix}scrollbar-hover-color: #{$scrollbar-hover-color-dark};
+
+ // Keenthemes overlay component
+ --#{$prefix}overlay-bg: #{$overlay-bg-dark};
+
+ // Keenthemes blockui component
+ --#{$prefix}blockui-overlay-bg: #{$blockui-overlay-bg-dark};
+
+ // Keenthemes rating component
+ --#{$prefix}rating-color-default: #{$rating-color-default-dark};
+ --#{$prefix}rating-color-active: #{$rating-color-active-dark};
+
+ // Keenthemes ribbon component
+ --#{$prefix}ribbon-label-box-shadow: #{$ribbon-label-box-shadow-dark};
+ --#{$prefix}ribbon-label-bg: #{$ribbon-label-bg-dark};
+ --#{$prefix}ribbon-label-border-color: #{$ribbon-label-border-color-dark};
+ --#{$prefix}ribbon-clip-bg: #{$ribbon-clip-bg-dark};
+
+ // Engage panel
+ --#{$prefix}engage-btn-bg: #{$engage-btn-bg-dark};
+ --#{$prefix}engage-btn-box-shadow: #{$engage-btn-box-shadow-dark};
+ --#{$prefix}engage-btn-border-color: #{$engage-btn-border-color-dark};
+ --#{$prefix}engage-btn-color: #{$engage-btn-color-dark};
+ --#{$prefix}engage-btn-icon-color: #{$engage-btn-icon-color-dark};
+ --#{$prefix}engage-btn-color-active: #{$engage-btn-color-active-dark};
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_rotate.scss b/Moonlight/Styles/components/_rotate.scss
new file mode 100644
index 00000000..80ece201
--- /dev/null
+++ b/Moonlight/Styles/components/_rotate.scss
@@ -0,0 +1,47 @@
+//
+// Rotate
+//
+
+
+$rotate-transition: transform 0.3s ease;
+
+.rotate {
+ display: inline-flex;
+ align-items: center;
+}
+
+@each $value in (90, 180, 270) {
+ .rotate-#{$value} {
+ transition: $rotate-transition;
+ backface-visibility: hidden;
+ will-change: transform;
+
+ .collapsible:not(.collapsed)> & ,
+ .show > &,
+ .active > & {
+ transform: rotateZ(#{$value}deg);
+ transition: $rotate-transition;
+
+ [direction="rtl"] & {
+ transform: rotateZ(-#{$value}deg);
+ }
+ }
+ }
+
+ .rotate-n#{$value} {
+ transition: $rotate-transition;
+ backface-visibility: hidden;
+ will-change: transform;
+
+ .collapsible:not(.collapsed)> &,
+ .show > &,
+ .active > & {
+ transform: rotateZ(-#{$value}deg);
+ transition: $rotate-transition;
+
+ [direction="rtl"] & {
+ transform: rotateZ(#{$value}deg);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_scroll.scss b/Moonlight/Styles/components/_scroll.scss
new file mode 100644
index 00000000..c4a3de12
--- /dev/null
+++ b/Moonlight/Styles/components/_scroll.scss
@@ -0,0 +1,111 @@
+//
+// Scroll
+//
+
+
+// Customize native scrollbars only for desktop mode
+@include media-breakpoint-up(lg) {
+ main,
+ span,
+ ol,
+ ul,
+ pre,
+ div {
+ // Firefox
+ scrollbar-width: thin;
+
+ // Webkit
+ &::-webkit-scrollbar {
+ width: var(--#{$prefix}scrollbar-size);
+ height: var(--#{$prefix}scrollbar-size);
+ }
+
+ ::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ @include border-radius(var(--#{$prefix}scrollbar-size));
+ }
+
+ // Default color
+ @include scrollbar-color(var(--#{$prefix}scrollbar-color), var(--#{$prefix}scrollbar-hover-color));
+ }
+}
+
+// Scroll
+.scroll,
+.hover-scroll,
+.hover-scroll-overlay {
+ overflow: scroll;
+ position: relative;
+
+ // Tablet & mobile modes
+ @include media-breakpoint-down(lg) {
+ overflow: auto;
+ }
+}
+
+.scroll-x,
+.hover-scroll-x,
+.hover-scroll-overlay-x {
+ overflow-x: scroll;
+ position: relative;
+
+ // Tablet & mobile modes
+ @include media-breakpoint-down(lg) {
+ overflow-x: auto;
+ }
+}
+
+.scroll-y,
+.hover-scroll-y,
+.hover-scroll-overlay-y {
+ overflow-y: scroll;
+ position: relative;
+
+ // Tablet & mobile modes
+ @include media-breakpoint-down(lg) {
+ overflow-y: auto;
+ }
+}
+
+.hover-scroll,
+.hover-scroll-overlay,
+.hover-scroll-x,
+.hover-scroll-overlay-x,
+.hover-scroll-y,
+.hover-scroll-overlay-y {
+ @include scrollbar-color(transparent, var(--#{$prefix}scrollbar-color));
+}
+
+// Utilities
+.scroll-ps {
+ padding-left: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-ms {
+ margin-left: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-mb {
+ margin-bottom: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-pe {
+ padding-right: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-me {
+ margin-right: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-px {
+ padding-left: var(--#{$prefix}scrollbar-size) !important;
+ padding-right: var(--#{$prefix}scrollbar-size) !important;
+}
+
+.scroll-mx {
+ margin-left: var(--#{$prefix}scrollbar-size) !important;
+ margin-right: var(--#{$prefix}scrollbar-size) !important;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_scrolltop.scss b/Moonlight/Styles/components/_scrolltop.scss
new file mode 100644
index 00000000..71518233
--- /dev/null
+++ b/Moonlight/Styles/components/_scrolltop.scss
@@ -0,0 +1,69 @@
+//
+// Scrolltop
+//
+
+.scrolltop {
+ position: fixed;
+ display: none;
+ cursor: pointer;
+ z-index: $scrolltop-z-index;
+ justify-content: center;
+ align-items: center;
+ width: $scrolltop-size;
+ height: $scrolltop-size;
+ bottom: $scrolltop-bottom;
+ right: $scrolltop-end;
+ background-color: var(--#{$prefix}scrolltop-bg-color);
+ box-shadow: var(--#{$prefix}scrolltop-box-shadow);
+ opacity: $scrolltop-opacity;
+ transition: $transition-link;
+ @include border-radius($border-radius);
+
+ .svg-icon {
+ @include svg-icon-size(24px);
+ color: var(--#{$prefix}scrolltop-icon-color);
+ }
+
+ > i {
+ font-size: 1.3rem;
+ color: var(--#{$prefix}scrolltop-icon-color);
+ }
+
+ &:hover {
+ background-color: var(--#{$prefix}scrolltop-bg-color-hover);
+
+ .svg-icon,
+ i {
+ color: var(--#{$prefix}scrolltop-icon-color-hover);
+ }
+ }
+
+ [data-kt-scrolltop="on"] & {
+ opacity: var(--#{$prefix}scrolltop-opacity-on);
+ animation: animation-scrolltop .4s ease-out 1;
+ display: flex;
+
+ &:hover {
+ transition: $transition-link;
+ opacity: var(--#{$prefix}scrolltop-opacity-hover);
+ }
+ }
+
+
+}
+
+// Tablet & Mobile Modess
+@include media-breakpoint-down(lg) {
+ .scrolltop {
+ bottom: $scrolltop-bottom-mobile;
+ right: $scrolltop-end-mobile;
+ width: $scrolltop-size-mobile;
+ height: $scrolltop-size-mobile;
+ }
+}
+
+// Animations
+@keyframes animation-scrolltop {
+ from { margin-bottom: -15px; }
+ to { margin-bottom: 0; }
+}
diff --git a/Moonlight/Styles/components/_separator.scss b/Moonlight/Styles/components/_separator.scss
new file mode 100644
index 00000000..e3e0cac4
--- /dev/null
+++ b/Moonlight/Styles/components/_separator.scss
@@ -0,0 +1,66 @@
+//
+// Separator
+//
+
+.separator {
+ display: block;
+ height: 0;
+ border-bottom: 1px solid var(--#{$prefix}border-color);
+
+ &.separator-dotted {
+ border-bottom-style: dotted;
+ border-bottom-color: var(--#{$prefix}border-dashed-color);
+ }
+
+ &.separator-dashed {
+ border-bottom-style: dashed;
+ border-bottom-color: var(--#{$prefix}border-dashed-color);
+ }
+
+ &.separator-content {
+ display: flex;
+ align-items: center;
+ border-bottom: 0;
+ text-align: center;
+
+ &::before,
+ &::after {
+ content: " ";
+ width: 50%;
+ border-bottom: 1px solid var(--#{$prefix}border-color);
+ }
+
+ &::before{
+ margin-right: 1.25rem;
+ }
+
+ &::after{
+ margin-left: 1.25rem;
+ }
+
+ &.separator-dotted {
+ &::before,
+ &::after {
+ border-bottom-style: dotted;
+ border-bottom-color: var(--#{$prefix}border-dashed-color);
+ }
+ }
+
+ &.separator-dashed {
+ &::before,
+ &::after {
+ border-bottom-style: dashed;
+ border-bottom-color: var(--#{$prefix}border-dashed-color);
+ }
+ }
+
+ @each $color, $value in $theme-colors {
+ &.border-#{$color}{
+ &::before,
+ &::after {
+ border-color: $value !important;
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_shape.scss b/Moonlight/Styles/components/_shape.scss
new file mode 100644
index 00000000..e540908e
--- /dev/null
+++ b/Moonlight/Styles/components/_shape.scss
@@ -0,0 +1,13 @@
+//
+// Shape
+//
+
+.xehagon {
+ //$edges-number: 6, $main-radius: 30%, $rounding-radius: 10%, $rotated: true, $precision: 20
+ @include shape(6);
+}
+
+.octagon {
+ //$edges-number: 6, $main-radius: 30%, $rounding-radius: 10%, $rotated: true, $precision: 20
+ @include shape(8);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_stepper.scss b/Moonlight/Styles/components/_stepper.scss
new file mode 100644
index 00000000..eff128cb
--- /dev/null
+++ b/Moonlight/Styles/components/_stepper.scss
@@ -0,0 +1,8 @@
+//
+// Stepper
+//
+
+// Import Dependencies
+@import "stepper/base";
+@import "stepper/pills";
+@import "stepper/links";
diff --git a/Moonlight/Styles/components/_svg-icon.scss b/Moonlight/Styles/components/_svg-icon.scss
new file mode 100644
index 00000000..6462a797
--- /dev/null
+++ b/Moonlight/Styles/components/_svg-icon.scss
@@ -0,0 +1,30 @@
+//
+// SVG Icon
+//
+
+.svg-icon {
+ line-height: 1;
+ color: var(--#{$prefix}text-muted);
+ @include svg-icon-size(get($font-sizes, 5));
+
+ // Theme colors
+ @each $name, $color in $theme-text-colors {
+ &.svg-icon-#{$name} {
+ color: var(--#{$prefix}text-#{$name});
+ }
+ }
+
+ // Responsive icon sizes
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ // Sizes
+ @each $name, $value in $font-sizes {
+ &.svg-icon#{$infix}-#{$name} {
+ @include svg-icon-size($value, true);
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_symbol.scss b/Moonlight/Styles/components/_symbol.scss
new file mode 100644
index 00000000..d0c0e0f6
--- /dev/null
+++ b/Moonlight/Styles/components/_symbol.scss
@@ -0,0 +1,133 @@
+//
+// symbol
+//
+
+// Base
+.symbol {
+ display: inline-block;;
+ flex-shrink: 0;
+ position: relative;
+ @include border-radius($border-radius);
+
+ // Label
+ .symbol-label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 500;
+ color: var(--#{$prefix}symbol-label-color);
+ background-color: var(--#{$prefix}symbol-label-bg);
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: cover;
+ @include border-radius($border-radius);
+
+ &:after {
+ @include border-radius($border-radius);
+ }
+ }
+
+ // Badge
+ .symbol-badge {
+ position: absolute;
+ border-radius: 100%;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%) translateY(-50%) !important;
+ }
+
+ // Image
+ > img {
+ width: 100%;
+ flex-shrink: 0;
+ display: inline-block;
+ @include border-radius($border-radius);
+ }
+
+ // Square
+ &.symbol-square {
+ &,
+ > img,
+ .symbol-label {
+ border-radius: 0 !important;
+ }
+ }
+
+ // Circle
+ &.symbol-circle {
+ &,
+ > img,
+ .symbol-label {
+ border-radius: 50%;
+
+ &:after {
+ border-radius: 50%;
+ }
+ }
+ }
+
+ // Sizes
+ @include symbol-size(get($symbol-sizes, default));
+
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @each $name, $value in $symbol-sizes {
+ @if ($name != 'default') {
+ &.symbol#{$infix}-#{$name} {
+ @include symbol-size($value);
+ }
+ }
+ }
+ }
+ }
+}
+
+// Group
+.symbol-group {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ margin-left: 10px;
+
+ .symbol {
+ position: relative;
+ z-index: 0;
+ margin-left: -10px;
+ transition: all 0.3s ease;
+
+ &:hover {
+ transition: all 0.3s ease;
+ z-index: 1;
+ }
+ }
+
+ .symbol-badge {
+ border: 2px solid var(--#{$prefix}body-bg);
+ }
+
+ .symbol-label {
+ position: relative;
+
+ &:after {
+ display: block;
+ content: " ";
+ border-radius: inherit;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ border: 2px solid var(--#{$prefix}symbol-border-color);
+ -webkit-background-clip: padding-box; /* for Safari */
+ background-clip: padding-box; /* for IE9+, Firefox 4+, Opera, Chrome */
+ }
+ }
+
+ &.symbol-hover {
+ .symbol {
+ cursor: pointer;
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_tables.scss b/Moonlight/Styles/components/_tables.scss
new file mode 100644
index 00000000..06eb3abb
--- /dev/null
+++ b/Moonlight/Styles/components/_tables.scss
@@ -0,0 +1,232 @@
+//
+// Table
+//
+
+// Table
+.table:not(.table-bordered) {
+ // Fix for BS 5.1.2 update
+ & > :not(:first-child) {
+ border-color: transparent;
+ border-width: 0;
+ border-style: none;
+ }
+
+ >:not(:last-child)>:last-child>* {
+ border-bottom-color: inherit;
+ }
+
+ tr, th, td {
+ border-color: inherit;
+ border-width: inherit;
+ border-style: inherit;
+ text-transform: inherit;
+ font-weight: inherit;
+ font-size: inherit;
+ color: inherit;
+ height: inherit;
+ min-height: inherit;
+
+ &:first-child {
+ padding-left: 0;
+ }
+
+ &:last-child {
+ padding-right: 0;
+ }
+ }
+
+ tfoot,
+ tbody {
+ tr:last-child {
+ border-bottom: 0 !important;
+
+ th, td {
+ border-bottom: 0 !important;
+ }
+ }
+ }
+
+ tfoot {
+ th, td {
+ border-top: inherit;
+ }
+ }
+
+ // Rounded
+ &.table-rounded {
+ border-radius: $border-radius;
+ border-spacing: 0;
+ border-collapse: separate;
+ }
+
+ // Flush
+ &.table-flush {
+ tr, th, td {
+ padding: inherit;
+ }
+ }
+
+ // Row bordered
+ &.table-row-bordered {
+ tr {
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-bottom-color: var(--#{$prefix}border-color);
+ }
+
+ tfoot {
+ th, td {
+ border-top-width: 1px !important;
+ }
+ }
+ }
+
+ // Row dashed
+ &.table-row-dashed {
+ tr {
+ border-bottom-width: 1px;
+ border-bottom-style: dashed;
+ border-bottom-color: var(--#{$prefix}border-color);
+ }
+
+ tfoot {
+ th, td {
+ border-top-width: 1px !important;
+ }
+ }
+ }
+
+ // Row border colors
+ @each $name, $value in $grays {
+ &.table-row-gray-#{$name} {
+ tr {
+ border-bottom-color: var(--#{$prefix}gray-#{$name});
+ }
+ }
+ }
+}
+
+// Layout fixed
+.table-layout-fixed {
+ table-layout: fixed;
+}
+
+// Sorting
+.table-sort {
+ &:after {
+ opacity: 0;
+ }
+}
+
+.table-sort,
+.table-sort-asc,
+.table-sort-desc {
+ vertical-align: middle;
+
+ &:after {
+ position: relative;
+ display: inline-block;
+ width: 0.75rem;
+ height: 0.75rem;
+ content: " ";
+ bottom: auto;
+ right: auto;
+ left: auto;
+ margin-left: 0.5rem;
+ }
+}
+
+.table-sort-asc {
+ &:after {
+ opacity: 1;
+ @include svg-bg-icon(arrow-top, var(--#{$prefix}text-muted));
+ }
+}
+
+.table-sort-desc {
+ &:after {
+ opacity: 1;
+ @include svg-bg-icon(arrow-bottom, var(--#{$prefix}text-muted));
+ }
+}
+
+// Loading
+.table-loading-message {
+ display: none;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ @include border-radius($border-radius);
+ box-shadow: var(--#{$prefix}table-loading-message-box-shadow);
+ background-color: $table-loading-message-bg;
+ color: $table-loading-message-color;
+ font-weight: $font-weight-bold;
+ margin: 0 !important;
+ width: auto;
+ padding: 0.85rem 2rem !important;
+ transform: translateX(-50%) translateY(-50%);
+}
+
+.table-loading {
+ position: relative;
+
+ .table-loading-message {
+ display: block;
+ }
+}
+
+// Cell gutters
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @each $name, $value in $gutters {
+ .table.g#{$infix}-#{$name} {
+ th, td {
+ padding: $value;
+
+ // Datatables responsive mode fix
+ &.dtr-control {
+ padding-left: $value !important;
+ }
+ }
+ }
+
+ .table.gy#{$infix}-#{$name} {
+ th, td {
+ padding-top: $value;
+ padding-bottom: $value;
+ }
+ }
+
+ .table.gx#{$infix}-#{$name} {
+ th, td {
+ padding-left: $value;
+ padding-right: $value;
+
+ // Datatables responsive mode fix
+ &.dtr-control {
+ padding-left: $value !important;
+ }
+ }
+ }
+
+ .table.gs#{$infix}-#{$name} {
+ th, td {
+ &:first-child {
+ padding-left: $value;
+ }
+
+ &:last-child {
+ padding-right: $value;
+ }
+
+ // Datatables responsive mode fix
+ &.dtr-control:first-child {
+ padding-left: $value !important;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_testimonials-slider.scss b/Moonlight/Styles/components/_testimonials-slider.scss
new file mode 100644
index 00000000..d9243325
--- /dev/null
+++ b/Moonlight/Styles/components/_testimonials-slider.scss
@@ -0,0 +1,65 @@
+//
+// Testimonials slider
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .testimonials-slider-highlight {
+ transition: all ease 0.3;
+
+ .testimonials-photo,
+ .testimonials-title,
+ .testimonials-body,
+ .testimonials-author,
+ .testimonials-positon {
+ transition: all ease 0.3s;
+ }
+
+ .tns-item:not(.tns-slide-active) + .tns-item.tns-slide-active {
+ .testimonials-photo {
+ height: 200px;
+ width: 200px;
+ transition: all ease 0.3s;
+ }
+
+ .testimonials-title {
+ color: var(--#{$prefix}gray-900) !important;
+ font-size: 1.54rem !important;
+ transition: all ease 0.3s;
+ margin-bottom: 1.3rem !important;
+ }
+
+ .testimonials-description {
+ color: var(--#{$prefix}gray-700) !important;
+ font-size: 1.38rem !important;
+ transition: all ease 0.3s;
+ margin-bottom: 1.7rem !important;
+ }
+
+ .testimonials-author {
+ color: var(--#{$prefix}primary) !important;
+ font-size: 1.1rem !important;
+ transition: all ease 0.3s;
+ }
+
+ .testimonials-positon {
+ color: var(--#{$prefix}gray-500) !important;
+ font-size: 0.9rem !important;
+ transition: all ease 0.3s;
+ }
+ }
+ }
+}
+
+.testimonials-slider-quote {
+ .testimonials-quote {
+ opacity: 0.2;
+ }
+
+ .tns-item:not(.tns-slide-active) + .tns-slide-active + .tns-slide-active {
+ .testimonials-quote {
+ opacity: 0.5;
+ color: var(--#{$prefix}primary) !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_theme-mode.scss b/Moonlight/Styles/components/_theme-mode.scss
new file mode 100644
index 00000000..46f5c5fb
--- /dev/null
+++ b/Moonlight/Styles/components/_theme-mode.scss
@@ -0,0 +1,38 @@
+//
+// Theme Modes
+//
+
+// Used for theme mode switching via JS
+[data-kt-theme-mode-switching="true"] * {
+ transition: none !important;
+}
+
+// Light mode
+@include color-mode(light) {
+ .theme-dark-show {
+ display: none !important;
+ }
+
+ .theme-light-bg-transparent {
+ background-color: transparent !important;
+ }
+
+ .theme-light-bg-body {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+}
+
+// Dark mode
+@include color-mode(dark) {
+ .theme-light-show {
+ display: none !important;
+ }
+
+ .theme-dark-bg-transparent {
+ background-color: transparent !important;
+ }
+
+ .theme-dark-bg-body {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_timeline-label.scss b/Moonlight/Styles/components/_timeline-label.scss
new file mode 100644
index 00000000..78621172
--- /dev/null
+++ b/Moonlight/Styles/components/_timeline-label.scss
@@ -0,0 +1,59 @@
+//
+// Timeline Label
+//
+
+
+.timeline-label {
+ position: relative;
+
+ $label-width: 50px;
+
+ &:before {
+ content: '';
+ position: absolute;
+ left: $label-width + 1px;
+ width: 3px;
+ top: 0;
+ bottom: 0;
+ background-color: var(--#{$prefix}gray-200);
+ }
+
+ //
+ .timeline-item {
+ display: flex;
+ align-items: flex-start;
+ position: relative;
+ margin-bottom: 1.7rem;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .timeline-label {
+ width: $label-width;
+ flex-shrink: 0;
+ position: relative;
+ color: var(--#{$prefix}gray-800);
+ }
+
+ .timeline-badge {
+ flex-shrink: 0;
+ background-color: var(--#{$prefix}body-bg);
+ width: 1rem;
+ height: 1rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1;
+ position: relative;
+ margin-top: 1px;
+ margin-left: -0.5rem;
+ padding: 3px !important;
+ border: 6px solid var(--#{$prefix}body-bg) !important;
+ }
+
+ .timeline-content {
+ flex-grow: 1;
+ }
+}
diff --git a/Moonlight/Styles/components/_timeline.scss b/Moonlight/Styles/components/_timeline.scss
new file mode 100644
index 00000000..08eca867
--- /dev/null
+++ b/Moonlight/Styles/components/_timeline.scss
@@ -0,0 +1,75 @@
+//
+// Timeline
+//
+
+// Base
+.timeline {
+ // Item
+ .timeline-item {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ align-items: flex-start;
+
+ &:last-child {
+ .timeline-line {
+ bottom: 100%;
+ }
+ }
+ }
+
+ // Line
+ .timeline-line {
+ display: block;
+ content: " ";
+ justify-content: center;
+ position: absolute;
+ z-index: 0;
+ left: 0;
+ top:0;
+ bottom: 0;
+ transform: translate(50%);
+ border-left-width: 1px;
+ border-left-style: dashed;
+ border-left-color: var(--#{$prefix}gray-300);
+ }
+
+ // Line solid
+ .timeline-line-solid {
+ border-left-style: solid !important;
+ }
+
+ // Icon
+ .timeline-icon {
+ z-index: 1;
+ flex-shrink: 0;
+ margin-right: 1rem;
+ }
+
+ // Content
+ .timeline-content {
+ width: 100%;
+ overflow: auto;
+ margin-bottom: 1.5rem;
+ }
+
+ // Vertical center
+ &.timeline-center {
+ .timeline-item {
+ align-items: center;
+
+ &:first-child {
+ .timeline-line {
+ top: 50%;
+ }
+ }
+
+ &:last-child {
+ .timeline-line {
+ bottom: 50%;
+ }
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_toasts.scss b/Moonlight/Styles/components/_toasts.scss
new file mode 100644
index 00000000..7f8b9923
--- /dev/null
+++ b/Moonlight/Styles/components/_toasts.scss
@@ -0,0 +1,17 @@
+.toast {
+ .toast-header {
+ .btn-close {
+ margin-right: 0;
+ }
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .toast {
+ --#{$prefix}toast-bg: #{$toast-background-color-dark};
+ --#{$prefix}toast-header-bg: #{$toast-header-background-color-dark};
+ --#{$prefix}toast-header-border-color: #{$toast-header-border-color-dark};
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_toggle.scss b/Moonlight/Styles/components/_toggle.scss
new file mode 100644
index 00000000..9f97ee20
--- /dev/null
+++ b/Moonlight/Styles/components/_toggle.scss
@@ -0,0 +1,19 @@
+//
+// Toggle
+//
+
+.toggle {
+ &.collapsible:not(.collapsed), // Integration with Bootstrap Collapse
+ &.active {
+ .toggle-off {
+ display: none;
+ }
+ }
+
+ &.collapsible.collapsed, // Integration with Bootstrap Collapse
+ &:not(.collapsible):not(.active) {
+ .toggle-on {
+ display: none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_tooltip.scss b/Moonlight/Styles/components/_tooltip.scss
new file mode 100644
index 00000000..0e1ab87a
--- /dev/null
+++ b/Moonlight/Styles/components/_tooltip.scss
@@ -0,0 +1,32 @@
+//
+// Tooltip
+//
+
+
+// Base
+.tooltip {
+ .tooltip-inner {
+ box-shadow: var(--#{$prefix}tooltip-box-shadow);
+ }
+
+ &.tooltop-auto-width {
+ .tooltip-inner {
+ white-space: nowrap;
+ max-width: none;
+ }
+ }
+
+ &.tooltip-inverse {
+ --#{$prefix}tooltip-color: var(--#{$prefix}dark-inverse);
+ --#{$prefix}tooltip-bg: var(--#{$prefix}dark);
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .tooltip:not(.tooltip-inverse) {
+ --#{$prefix}tooltip-bg: #{$tooltip-bg-dark};
+ --#{$prefix}tooltip-box-shadow: #{$tooltip-box-shadow-dark};
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/_type.scss b/Moonlight/Styles/components/_type.scss
new file mode 100644
index 00000000..41837af9
--- /dev/null
+++ b/Moonlight/Styles/components/_type.scss
@@ -0,0 +1,9 @@
+
+
+.blockquote-footer {
+ color: var(--#{$prefix}blockquote-footer-color);
+}
+
+.list-style-none {
+ list-style: none;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_utilities.scss b/Moonlight/Styles/components/_utilities.scss
new file mode 100644
index 00000000..dfb48f5d
--- /dev/null
+++ b/Moonlight/Styles/components/_utilities.scss
@@ -0,0 +1,130 @@
+//
+// Custom utilities
+//
+
+$utilities: map-merge(
+ $utilities,
+ (
+ "position": (
+ property: position,
+ responsive: true,
+ values: static relative absolute fixed sticky
+ ),
+ "overflow": (
+ property: overflow,
+ responsive: true,
+ values: auto hidden visible scroll,
+ ),
+ "opacity": (
+ property: opacity,
+ class: opacity,
+ values: $opacity-values
+ ),
+ "opacity-hover": (
+ property: opacity,
+ state: hover,
+ class: opacity,
+ values: $opacity-values
+ ),
+ "font-size": (
+ rfs: true,
+ responsive: true,
+ property: font-size,
+ class: fs,
+ values: $font-sizes
+ ),
+ "width": (
+ responsive: true,
+ property: width,
+ class: w,
+ values: $custom-sizes
+ ),
+ "max-width": (
+ responsive: true,
+ property: max-width,
+ class: mw,
+ values: $custom-sizes
+ ),
+ "min-width": (
+ responsive: true,
+ property: min-width,
+ class: min-w,
+ values: $custom-sizes
+ ),
+ "height": (
+ responsive: true,
+ property: height,
+ class: h,
+ values: $custom-sizes
+ ),
+ "max-height": (
+ responsive: true,
+ property: max-height,
+ class: mh,
+ values: $custom-sizes
+ ),
+ "min-height": (
+ responsive: true,
+ property: min-height,
+ class: min-h,
+ values: $custom-sizes
+ ),
+ "z-index": (
+ property: z-index,
+ class: z-index,
+ values: $zindex-values
+ ),
+ "border-top-width": (
+ property: border-top-width,
+ class: border-top,
+ values: $border-widths
+ ),
+ "border-bottom-width": (
+ property: border-bottom-width,
+ class: border-bottom,
+ values: $border-widths
+ ),
+ "border-right-width": (
+ property: border-right-width,
+ class: border-right,
+ values: $border-widths
+ ),
+ "border-left-width": (
+ property: border-left-width,
+ class: border-left,
+ values: $border-widths
+ ),
+ "line-height": (
+ property: line-height,
+ class: lh,
+ values: (
+ 0: 0,
+ 1: 1,
+ sm: $line-height-sm,
+ base: $line-height-base,
+ lg: $line-height-lg,
+ xl: $line-height-xl,
+ xxl: $line-height-xxl
+ )
+ ),
+ "letter-spacing": (
+ property: letter-spacing,
+ class: ls,
+ values: $letter-spacing-values
+ ),
+ "rounded": (
+ property: border-radius,
+ class: rounded,
+ values: (
+ null: $border-radius,
+ 0: 0,
+ 1: $border-radius-sm,
+ 2: $border-radius,
+ 3: $border-radius-lg,
+ 4: $border-radius-xl,
+ circle: 50%,
+ pill: $border-radius-pill
+ )
+ )
+ )
+);
diff --git a/Moonlight/Styles/components/_variables-dark.scss b/Moonlight/Styles/components/_variables-dark.scss
new file mode 100644
index 00000000..68664233
--- /dev/null
+++ b/Moonlight/Styles/components/_variables-dark.scss
@@ -0,0 +1,289 @@
+//
+// Bootstrap & Custom Variables
+// Safely override any variable in _variables.custom.scss
+//
+
+$gray-100-dark: #1b1b29 !default;
+$gray-200-dark: #2B2B40 !default;
+$gray-300-dark: #323248 !default;
+$gray-400-dark: #474761 !default;
+$gray-500-dark: #565674 !default;
+$gray-600-dark: #6D6D80 !default;
+$gray-700-dark: #92929F !default;
+$gray-800-dark: #CDCDDE !default;
+$gray-900-dark: #FFFFFF !default;
+
+$grays-dark: (
+ "100": $gray-100-dark,
+ "200": $gray-200-dark,
+ "300": $gray-300-dark,
+ "400": $gray-400-dark,
+ "500": $gray-500-dark,
+ "600": $gray-600-dark,
+ "700": $gray-700-dark,
+ "800": $gray-800-dark,
+ "900": $gray-900-dark
+) !default;
+
+// Bootstrap muted color
+$text-muted-dark: $gray-500-dark !default;
+
+// Bootstrap contextual colors
+// Primary colors
+$primary-light-dark: #212E48 !default;
+
+// Secondary colors
+$secondary-dark: $gray-300-dark !default;
+$secondary-active-dark: $gray-400-dark !default;
+$secondary-light-dark: $gray-100-dark !default;
+$secondary-inverse-dark: $gray-700-dark !default;
+
+// Light colors
+$light-dark: $gray-200-dark !default;
+$light-active-dark: $gray-300-dark !default;
+$light-inverse-dark: $gray-600-dark !default;
+
+// Success colors
+$success-light-dark: #1C3833 !default;
+
+// Info colors
+$info-light-dark: #2F264F !default;
+
+// Warning colors
+$warning-light-dark: #392F28 !default;
+
+// Danger colors
+$danger-light-dark: #3A2434 !default;
+
+// Dark colors
+$dark-dark: $gray-900-dark !default;
+$dark-active-dark: lighten($gray-900-dark, 3%) !default;
+$dark-light-dark: $gray-200-dark !default;
+$dark-inverse-dark: $gray-100-dark !default;
+
+$theme-colors-dark: (
+ "white": $white, // custom color type
+ "light": $light-dark,
+ "primary": $primary,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "dark": $dark-dark,
+ "secondary": $secondary-dark,
+) !default;
+
+$theme-active-colors-dark: (
+ "primary": $primary-active,
+ "secondary": $secondary-active-dark,
+ "light": $light-active-dark,
+ "success": $success-active,
+ "info": $info-active,
+ "warning": $warning-active,
+ "danger": $danger-active,
+ "dark": $dark-active-dark
+) !default;
+
+$theme-inverse-colors-dark: (
+ "primary": $primary-inverse,
+ "secondary": $secondary-inverse-dark,
+ "light": $light-inverse,
+ "success": $success-inverse,
+ "info": $info-inverse,
+ "warning": $warning-inverse,
+ "danger": $danger-inverse,
+ "dark": $dark-inverse-dark
+) !default;
+
+$theme-light-colors-dark: (
+ "primary": $primary-light-dark,
+ "success": $success-light-dark,
+ "info": $info-light-dark,
+ "warning": $warning-light-dark,
+ "danger": $danger-light-dark,
+ "dark": $dark-light-dark,
+ "secondary": $secondary-light-dark
+) !default;
+
+$theme-text-colors-dark: (
+ "white": $white,
+ "primary": $primary,
+ "secondary": $secondary-dark,
+ "light": $light-dark,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "dark": $dark-dark,
+ "muted": $text-muted-dark,
+ "gray-100": $gray-100-dark,
+ "gray-200": $gray-200-dark,
+ "gray-300": $gray-300-dark,
+ "gray-400": $gray-400-dark,
+ "gray-500": $gray-500-dark,
+ "gray-600": $gray-600-dark,
+ "gray-700": $gray-700-dark,
+ "gray-800": $gray-800-dark,
+ "gray-900": $gray-900-dark
+) !default;
+
+
+// Body
+//
+// Settings for the `` element.
+$body-bg-dark: #1e1e2d !default;
+$body-bg-rgb-dark: to-rgb($body-bg-dark) !default;
+$body-color-dark: $gray-900-dark !default;
+
+
+// Links
+//
+// Style anchor elements.
+$link-color-dark: $primary !default;
+
+
+// Components
+//
+// Define common padding and border radius sizes and more.
+$border-color-dark: $gray-200-dark !default;
+$border-dashed-color-dark: $gray-300-dark !default;
+
+// Keenthemes hover states
+$component-hover-color-dark: $primary !default;
+$component-hover-bg-dark: $gray-100-dark !default;
+
+// Keenthemes active states
+$component-active-color-dark: $primary-inverse !default;
+$component-active-bg-dark: $primary !default;
+
+// Keenthemes checked states
+$component-checked-color-dark: $primary-inverse !default;
+$component-checked-bg-dark: $primary !default;
+
+$headings-color-dark: $gray-900-dark !default;
+$blockquote-footer-color-dark: $gray-600-dark !default;
+
+
+// Box shadow
+$box-shadow-xs-dark: 0 .1rem 0.75rem 0.25rem rgba($black, 0.05) !default;
+$box-shadow-sm-dark: 0 .1rem 1rem 0.25rem rgba($black, .05) !default;
+$box-shadow-dark: 0 .5rem 1.5rem 0.5rem rgba($black, .075) !default;
+$box-shadow-lg-dark: 0 1rem 2rem 1rem rgba($black, .1) !default;
+$box-shadow-inset-dark: inset 0 1px 2px rgba($black, .075) !default;
+
+
+// Card
+$card-box-shadow-dark: null !default;
+
+
+// Tables
+$table-striped-bg-dark: rgba($gray-100-dark, 0.75) !default;
+$table-loading-message-box-shadow-dark: 0px 0px 30px rgba(0, 0, 0, 0.3) !default;
+
+// Forms
+$form-select-indicator-color-dark: $gray-600-dark !default;
+$form-select-indicator-dark: url("data:image/svg+xml, ") !default;
+$form-switch-color-dark: rgba($white, .25) !default;
+$form-switch-color-solid-dark: $gray-500-dark !default;
+$form-switch-bg-image-dark: url("data:image/svg+xml, ") !default;
+$form-switch-bg-image-solid-dark: url("data:image/svg+xml, ") !default;
+
+
+// Accordion
+$accordion-icon-color-dark: $body-color-dark!default;
+$accordion-icon-active-color-dark: $primary !default;
+$accordion-button-icon-dark: url("data:image/svg+xml, ") !default;
+$accordion-button-active-icon-dark: url("data:image/svg+xml, ") !default;
+
+
+// Dropdowns
+$dropdown-bg-dark: $body-bg-dark !default;
+$dropdown-box-shadow-dark: 0px 0px 30px rgba(0, 0, 0, 0.3) !default;
+
+// Popover
+$popover-bg-dark: $gray-200-dark !default;
+$popover-border-color-dark: $gray-200-dark !default;
+$popover-box-shadow-dark: $dropdown-box-shadow-dark !default;
+$popover-header-border-color-dark: $gray-300-dark !default;
+
+// Toasts
+$toast-background-color-dark: $gray-200-dark !default;
+$toast-header-background-color-dark: $gray-200-dark !default;
+$toast-header-border-color-dark: $gray-300-dark !default;
+
+// Tooltip
+$tooltip-bg-dark: $gray-200-dark !default;
+$tooltip-box-shadow-dark: 0px 0px 30px rgba(0, 0, 0, 0.15) !default;
+
+// Code
+$code-bg-dark: $gray-200-dark !default;
+$code-color-dark: #b93993 !default;
+$code-box-shadow-dark: 0px 3px 9px rgba(0, 0, 0, 0.08) !default;
+
+// Symbol
+$symbol-border-color-dark: rgba($body-bg, 0.5);
+$symbol-label-color-dark: $gray-800-dark;
+$symbol-label-bg-dark: $gray-100-dark;
+
+
+// Keenthemes bullet component
+$bullet-bg-color-dark: $gray-400-dark !default;
+
+// Keenthemes scrolltop component
+$scrolltop-opacity-dark: 0 !default;
+$scrolltop-opacity-on-dark: 0.3 !default;
+$scrolltop-opacity-hover-dark: 1 !default;
+$scrolltop-box-shadow-dark: $box-shadow !default;
+$scrolltop-bg-color-dark: $primary !default;
+$scrolltop-bg-color-hover-dark: $primary !default;
+$scrolltop-icon-color-dark: $primary-inverse !default;
+$scrolltop-icon-color-hover-dark: $primary-inverse !default;
+
+
+// Keenthemes drawer component
+$drawer-box-shadow-dark: 0px 0px 30px rgba(0, 0, 0, 0.1) !default;
+$drawer-bg-color-dark: $body-bg-dark !default;
+$drawer-overlay-bg-color-dark: rgba($black, 0.4) !default;
+
+// Keenthemes menu component
+$menu-dropdown-box-shadow-dark: $dropdown-box-shadow-dark !default;
+$menu-dropdown-bg-color-dark: $dropdown-bg-dark !default;
+$menu-link-color-hover-dark: $component-hover-color-dark !default;
+$menu-link-color-show-dark: $component-hover-color-dark !default;
+$menu-link-color-here-dark: $component-hover-color-dark !default;
+$menu-link-color-active-dark: $component-hover-color-dark !default;
+$menu-link-bg-color-hover-dark: $component-hover-bg-dark !default;
+$menu-link-bg-color-show-dark: $component-hover-bg-dark !default;
+$menu-link-bg-color-here-dark: $component-hover-bg-dark !default;
+$menu-link-bg-color-active-dark: $component-hover-bg-dark !default;
+$menu-heading-color-dark: $text-muted-dark !default;
+
+// Keenthemes scrollbar component
+$scrollbar-color-dark: $gray-200-dark !default;
+$scrollbar-hover-color-dark: $gray-300-dark !default;
+
+// Keenthemes overlay component
+$overlay-bg-dark: rgba($white, 0.05) !default;
+
+// Keenthemes blockui component
+$blockui-overlay-bg-dark: rgba($white, 0.05) !default;
+$blockui-message-bg-dark: $tooltip-bg-dark !default;
+$blockui-message-box-shadow-dark: $tooltip-box-shadow-dark !default;
+
+// Keenthemes rating component
+$rating-color-default-dark: $gray-400-dark !default;
+$rating-color-active-dark: #FFAD0F !default;
+
+// Keenthemes ribbon component
+$ribbon-label-box-shadow-dark: 0px -1px 5px 0px rgba($white, 0.1) !default;
+$ribbon-label-bg-dark: $primary !default;
+$ribbon-label-border-color-dark: darken($primary, 20%) !default;
+$ribbon-clip-bg-dark: $light !default;
+
+// Engage panel
+$engage-btn-bg-dark: $gray-200-dark;
+$engage-btn-box-shadow-dark: 0px 0px 30px rgba(0, 0, 0, 0.3);
+$engage-btn-border-color-dark: $border-color-dark;
+$engage-btn-color-dark: $gray-800-dark;
+$engage-btn-icon-color-dark: $gray-600-dark;
+$engage-btn-color-active-dark: $gray-800-dark;
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_variables.custom.scss b/Moonlight/Styles/components/_variables.custom.scss
new file mode 100644
index 00000000..9036ee45
--- /dev/null
+++ b/Moonlight/Styles/components/_variables.custom.scss
@@ -0,0 +1,44 @@
+//
+// To make future updates easier consider overriding the global variables from _variables.bootstrap.scss and _variables.custom.scss for current demo in this file.
+// Note that this file is included first and variables defined in _variables.bootstrap.scss and _variables.custom.scss
+// are not accessible in this file but you can override any global variable as shown below:
+//
+
+// Theme colors
+$success: #50cd89;
+$success-active: #47be7d;
+$success-light: #e8fff3;
+$success-light-dark: #1c3238;
+$success-inverse: #FFFFFF;
+
+// Success
+$primary: #3E97FF;
+$primary-active: #2884Ef;
+$primary-light: #EEF6FF;
+$primary-light-dark: #212E48;
+$primary-inverse: #FFFFFF;
+
+// Info
+$info: #7239ea;
+$info-active: #5014d0;
+$info-light: #f8f5ff;
+$info-light-dark: #2f264f;
+$info-inverse: #FFFFFF;
+
+// Danger
+$danger: #f1416c;
+$danger-active: #d9214e;
+$danger-light: #fff5f8;
+$danger-light-dark: #3a2434;
+$danger-inverse: #FFFFFF;
+
+// Warning
+$warning: #ffc700;
+$warning-active: #f1bc00;
+$warning-light: #fff8dd;
+$warning-light-dark: #392f28;
+$warning-inverse: #FFFFFF;
+
+// Card
+$card-box-shadow: none;
+$card-border-enabled: true;
\ No newline at end of file
diff --git a/Moonlight/Styles/components/_variables.scss b/Moonlight/Styles/components/_variables.scss
new file mode 100644
index 00000000..60f2a609
--- /dev/null
+++ b/Moonlight/Styles/components/_variables.scss
@@ -0,0 +1,1229 @@
+//
+// Bootstrap & Custom Variables
+// Safely override any variable in _variables.custom.scss
+//
+
+// Prefix for :root CSS variables
+$prefix: bs- !default; // Deprecated in v5.2.0 for the shorter `$prefix`
+
+
+// Bootstrap color system
+$white: #ffffff !default;
+$black:#000000 !default;
+
+// Bootstrap grey colors
+$gray-100: #F9F9F9 !default;
+$gray-200: #F1F1F2 !default;
+$gray-300: #DBDFE9 !default;
+$gray-400: #B5B5C3 !default;
+$gray-500: #99A1B7 !default;
+$gray-600: #78829D !default;
+$gray-700: #4B5675 !default;
+$gray-800: #252F4A !default;
+$gray-900: #071437 !default;
+
+// Bootstrap muted color
+$text-muted: $gray-500 !default;
+
+// Bootstrap gray colors map
+$grays: (
+ "100": $gray-100,
+ "200": $gray-200,
+ "300": $gray-300,
+ "400": $gray-400,
+ "500": $gray-500,
+ "600": $gray-600,
+ "700": $gray-700,
+ "800": $gray-800,
+ "900": $gray-900
+) !default;
+
+// Bootstrap contextual colors
+// Primary colors
+$primary: #3699FF !default;
+$primary-active: #187DE4 !default;
+$primary-light: #F1FAFF !default;
+$primary-inverse: $white !default;
+
+// Secondary colors
+$secondary: $gray-300 !default;
+$secondary-active: $gray-400 !default;
+$secondary-light: $gray-100 !default;
+$secondary-inverse: $gray-700 !default;
+
+// Light colors
+$light: $gray-100 !default;
+$light-active: $gray-200 !default;
+$light-light: gba($gray-100, 0.75) !default;
+$light-inverse: $gray-600 !default;
+
+
+// Success colors
+$success: #1BC5BD !default;
+$success-active: #0BB7AF !default;
+$success-light: #C9F7F5 !default;
+$success-inverse: $white !default;
+
+// Info colors
+$info: #8950FC !default;
+$info-active: #7337EE !default;
+$info-light: #EEE5FF !default;
+$info-inverse: $white !default;
+
+// Warning colors
+$warning: #FFA800 !default;
+$warning-active: #EE9D01 !default;
+$warning-light: #FFF4DE !default;
+$warning-inverse: $white !default;
+
+// Danger colors
+$danger: #F64E60 !default;
+$danger-active: #EE2D41 !default;
+$danger-light: #FFE2E5 !default;
+$danger-inverse: $white !default;
+
+// Dark colors
+$dark: $gray-900 !default;
+$dark-active: darken($gray-900, 3%) !default;
+$dark-light: $gray-200 !default;
+$dark-inverse: $white !default;
+
+// Contextual colors
+$theme-colors: (
+ "light": $light,
+ "primary": $primary,
+ "secondary": $secondary,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "dark": $dark
+) !default;
+
+// Contextual active state colors
+$theme-active-colors: (
+ "primary": $primary-active,
+ "secondary": $secondary-active,
+ "light": $light-active,
+ "success": $success-active,
+ "info": $info-active,
+ "warning": $warning-active,
+ "danger": $danger-active,
+ "dark": $dark-active
+) !default;
+
+// Contextual inverse state colors
+$theme-inverse-colors: (
+ "primary": $primary-inverse,
+ "secondary": $secondary-inverse,
+ "light": $light-inverse,
+ "success": $success-inverse,
+ "info": $info-inverse,
+ "warning": $warning-inverse,
+ "danger": $danger-inverse,
+ "dark": $dark-inverse
+) !default;
+
+// Contextual light state colors
+$theme-light-colors: (
+ "primary": $primary-light,
+ "secondary": $secondary-light,
+ "success": $success-light,
+ "info": $info-light,
+ "warning": $warning-light,
+ "danger": $danger-light,
+ "dark": $dark-light
+) !default;
+
+// Text colors
+$theme-text-colors: (
+ "white": $white,
+ "primary": $primary,
+ "secondary": $secondary,
+ "light": $light,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "dark": $dark,
+ "muted": $text-muted,
+ "gray-100": $gray-100,
+ "gray-200": $gray-200,
+ "gray-300": $gray-300,
+ "gray-400": $gray-400,
+ "gray-500": $gray-500,
+ "gray-600": $gray-600,
+ "gray-700": $gray-700,
+ "gray-800": $gray-800,
+ "gray-900": $gray-900
+) !default;
+
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
+$enable-rounded: true !default;
+$enable-shadows: true !default;
+$enable-negative-margins: true !default;
+$enable-smooth-scroll: false !default;
+
+// Spacing
+//
+// Control the default styling of most Bootstrap elements by modifying these
+// variables. Mostly focused on spacing.
+// You can add more entries to the $spacers map, should you need more variation.
+$spacer: 1rem !default;
+
+$spacers: (
+ 0: 0,
+ 1: ($spacer * .25), // 3.5px
+ 2: ($spacer * .5), // 7px;
+ 3: ($spacer * .75), // 10.5px
+ 4: ($spacer * 1), // 14px
+ 5: ($spacer * 1.25), // 17.5px
+ 6: ($spacer * 1.5), // 21px
+ 7: ($spacer * 1.75), // 24.5px
+ 8: ($spacer * 2), // 28px
+ 9: ($spacer * 2.25), // 31.5px
+ 10: ($spacer * 2.5), // 35px
+ 11: ($spacer * 2.75), // 38.5px
+ 12: ($spacer * 3), // 42px
+ 13: ($spacer * 3.25), // 45.5px
+ 14: ($spacer * 3.5), // 49px
+ 15: ($spacer * 3.75), // 52.5px
+ 16: ($spacer * 4), // 55px
+ 17: ($spacer * 4.25), // 58.5px
+ 18: ($spacer * 4.5), // 62px
+ 19: ($spacer * 4.75), // 65.5px
+ 20: ($spacer * 5), // 69px
+);
+
+
+// Position
+//
+// Define the edge positioning anchors of the position utilities.
+$position-values: (
+ 0: 0,
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%
+) !default;
+
+
+// Body
+//
+// Settings for the `` element.
+$body-bg: $white !default;
+$body-bg-rgb: to-rgb($body-bg) !default;
+$body-color: $gray-900 !default;
+$body-text-align: null !default;
+
+
+// Links
+//
+// Style anchor elements.
+$link-color: $primary !default;
+$link-decoration: none !default;
+$link-shade-percentage: 20% !default;
+$link-hover-color: $primary-active !default;
+$link-hover-decoration: none !default;
+
+
+// Paragraphs
+//
+// Style p element.
+$paragraph-margin-bottom: 1rem !default;
+
+
+// Grid breakpoints
+//
+// Define the minimum dimensions at which your layout will change,
+// adapting to different screen sizes, for use in media queries.
+// scss-docs-start grid-breakpoints
+$grid-breakpoints: (
+ xs: 0,
+ sm: 576px,
+ md: 768px,
+ lg: 992px,
+ xl: 1200px,
+ xxl: 1400px
+) !default;
+// scss-docs-end grid-breakpoints
+
+
+// Grid containers
+//
+// Define the maximum width of `.container` for different screen sizes.
+$container-max-widths: (
+ sm: 540px,
+ md: 720px,
+ lg: 960px,
+ xl: 1140px,
+ xxl: 1320px
+) !default;
+
+
+// Components
+//
+// Define common padding and border radius sizes and more.
+$border-width: 1px !default;
+$border-color: $gray-200 !default;
+$border-dashed-color: $gray-300 !default;
+
+$border-widths: (
+ 0: 0,
+ 1: 1px,
+ 2: 2px,
+ 3: 3px,
+ 4: 4px,
+ 5: 5px
+) !default;
+
+// Border Radiues
+$border-radius: .475rem !default;
+$border-radius-sm: .425rem !default;
+$border-radius-lg: .625rem !default;
+$border-radius-xl: 1rem !default;
+$border-radius-2xl: 2rem !default;
+$border-radius-pill: 50rem !default;
+
+// Keenthemes hover states
+$component-hover-color: $primary !default;
+$component-hover-bg: $gray-100 !default;
+
+// Keenthemes active states
+$component-active-color: $primary-inverse !default;
+$component-active-bg: $primary !default;
+
+// Keenthemes checked states
+$component-checked-color: $primary-inverse !default;
+$component-checked-bg: $primary !default;
+
+// Keenthemes custom transition settings
+$transition-link: color .2s ease !default;
+$transition-input: color .2s ease !default;
+
+// Box shadow
+// Shadows
+$box-shadow-xs: 0 .1rem 0.75rem 0.25rem rgba($black, 0.05) !default;
+$box-shadow-sm: 0 .1rem 1rem 0.25rem rgba($black, .05) !default;
+$box-shadow: 0 .5rem 1.5rem 0.5rem rgba($black, .075) !default;
+$box-shadow-lg: 0 1rem 2rem 1rem rgba($black, .1) !default;
+$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default;
+
+// Keenthemes custom gutter sizes
+$gutters: (
+ 0: 0rem,
+ 1: ($spacer * .25), // 3.5px
+ 2: ($spacer * .5), // 7px;
+ 3: ($spacer * .75), // 10.5px
+ 4: ($spacer * 1), // 14px
+ 5: ($spacer * 1.25), // 17.5px
+ 6: ($spacer * 1.5), // 21px
+ 7: ($spacer * 1.75), // 24.5px
+ 8: ($spacer * 2), // 28px
+ 9: ($spacer * 2.25), // 31.5px
+ 10: ($spacer * 2.5), // 35px
+) !default;
+
+
+// Typography
+//
+// Font, line-height, and color for body text, headings, and more.
+// Font family
+$font-family-sans-serif: Inter, Helvetica, "sans-serif" !default;
+
+$font-size-base: 1rem !default; // Assumes the browser default, typically `13px`
+$font-size-lg: $font-size-base * 1.075 !default; // 14.04px
+$font-size-sm: $font-size-base * .95 !default; // 12.025px
+
+$font-weight-lighter: lighter !default;
+$font-weight-light: 300 !default;
+$font-weight-normal: 400 !default;
+$font-weight-semibold: 500 !default;
+$font-weight-bold: 600 !default;
+$font-weight-bolder: 700 !default;
+
+$font-weight-base: $font-weight-normal !default;
+
+// Line heights
+$line-height-base: 1.5 !default;
+$line-height-sm: 1.25 !default;
+$line-height-lg: 1.75 !default;
+
+// Keenthemes custom line heights
+$line-height-xl: 2 !default;
+$line-height-xxl: 2.25 !default;
+
+// Heading sizes
+$h1-font-size: $font-size-base * 1.75 !default; // 22.75px
+$h2-font-size: $font-size-base * 1.5 !default; // 19.50px
+$h3-font-size: $font-size-base * 1.35 !default; // 17.55px
+$h4-font-size: $font-size-base * 1.25 !default; // 16.25px
+$h5-font-size: $font-size-base * 1.15 !default; // 14.95px
+$h6-font-size: $font-size-base * 1.075 !default; // 13.97px
+
+// Font Sizes
+$font-sizes: (
+ 1: $h1-font-size, // 22.75px
+ 2: $h2-font-size, // 19.50px
+ 3: $h3-font-size, // 17.55px
+ 4: $h4-font-size, // 16.25px
+ 5: $h5-font-size, // 14.95px
+ 6: $h6-font-size, // 13.95px
+
+ 7: $font-size-base * 0.95, // 12.35px
+ 8: $font-size-base * 0.85, // 11.05px
+ 9: $font-size-base * 0.75, // 9.75px
+ 10: $font-size-base * 0.5, // 6.50px
+
+ sm: $font-size-sm,
+ base: $font-size-base, // 13px
+ lg: $font-size-lg,
+
+ fluid: 100%, // 100%
+
+ 2x: $font-size-base * 2, // 26px
+ 2qx: $font-size-base * 2.25, // 29.25px
+ 2hx: $font-size-base * 2.5, // 32.5px
+ 2tx: $font-size-base * 2.75, // 35.75px
+
+ 3x: $font-size-base * 3, // 39px
+ 3qx: $font-size-base * 3.25, // 42.25px
+ 3hx: $font-size-base * 3.5, // 45.5px
+ 3tx: $font-size-base * 3.75, // 48.75px
+
+ 4x: $font-size-base * 4, // 52px
+ 4qx: $font-size-base * 4.25, // 55.25px
+ 4hx: $font-size-base * 4.5, // 58.5px
+ 4tx: $font-size-base * 4.75, // 61.75px
+
+ 5x: $font-size-base * 5, // 65px
+ 5qx: $font-size-base * 5.25, // 68.25px
+ 5hx: $font-size-base * 5.5, // 71.5px
+ 5tx: $font-size-base * 5.75, // 74.75px
+
+ 6x: $font-size-base * 6, // 75px
+ 6qx: $font-size-base * 6.25, // 78.25px
+ 6hx: $font-size-base * 6.5, // 81.5px
+ 6tx: $font-size-base * 6.75, // 84.75px
+
+ 7x: $font-size-base * 7, // 85px
+ 7qx: $font-size-base * 7.25, // 88.25px
+ 7hx: $font-size-base * 7.5, // 91.5px
+ 7tx: $font-size-base * 7.75 // 94.75px
+) !default;
+
+$headings-font-weight: 600 !default;
+$headings-color: $gray-900 !default;
+$headings-line-height: 1.2 !default;
+
+$display-font-sizes: (
+ 1: 5rem,
+ 2: 4.5rem,
+ 3: 4rem,
+ 4: 3.5rem,
+ 5: 3rem,
+ 6: 2.5rem
+) !default;
+
+$display-font-weight: $font-weight-bolder !default;
+$display-line-height: $headings-line-height !default;
+
+$blockquote-footer-color: $gray-600 !default;
+
+
+// Tables
+//
+// Customizes the `.table` component with basic values, each used across all table variations.
+$table-cell-padding-y: .75rem !default;
+$table-cell-padding-x: .75rem !default;
+$table-cell-padding-y-sm: .5rem !default;
+$table-cell-padding-x-sm: .5rem !default;
+
+$table-color: var(--#{$prefix}body-color) !default;
+$table-bg: transparent !default;
+$table-accent-bg: transparent !default;
+$table-striped-color: $table-color !default;
+$table-striped-bg: rgba(var(--#{$prefix}gray-100-rgb), 0.75) !default;
+
+$table-active-color: $table-color !default;
+$table-active-bg: var(--#{$prefix}gray-100) !default;
+
+$table-hover-color: $table-color !default;
+$table-hover-bg: var(--#{$prefix}gray-100) !default;
+
+$table-border-factor: .1 !default;
+$table-border-width: $border-width !default;
+$table-border-color: var(--#{$prefix}border-color) !default;
+
+$table-caption-color: $text-muted !default;
+
+$table-loading-message-box-shadow: 0px 0px 50px 0px rgba(82,63,105, 0.15) !default;
+$table-loading-message-bg: var(--#{$prefix}body-bg) !default;
+$table-loading-message-color: var(--#{$prefix}gray-700) !default;
+
+
+// Buttons + Forms
+//
+// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.
+$input-btn-padding-y: .775rem !default;
+$input-btn-padding-x: 1rem !default;
+$input-btn-font-family: null !default;
+$input-btn-font-size: $font-size-base * 1.1 !default;
+$input-btn-line-height: $line-height-base !default;
+
+$input-btn-focus-width: .25rem !default;
+$input-btn-focus-color-opacity: .25 !default;
+$input-btn-focus-color: rgba(var(--#{$prefix}component-active-bg), $input-btn-focus-color-opacity) !default;
+$input-btn-focus-box-shadow: null !default;
+
+
+$input-btn-padding-y-sm: .55rem !default;
+$input-btn-padding-x-sm: .75rem !default;
+$input-btn-font-size-sm: $font-size-sm !default;
+
+$input-btn-padding-y-lg: .825rem !default;
+$input-btn-padding-x-lg: 1.5rem !default;
+$input-btn-font-size-lg: $font-size-base * 1.15 !default;
+
+$input-btn-border-width: $border-width !default;
+
+// Buttons
+//
+// For each of Bootstrap's buttons, define text, background, and border color.
+$btn-padding-y: $input-btn-padding-y !default;
+$btn-padding-x: 1.5rem !default;
+$btn-font-family: $input-btn-font-family !default;
+$btn-font-size: $input-btn-font-size !default;
+$btn-line-height: $input-btn-line-height !default;
+$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping
+
+$btn-padding-y-sm: $input-btn-padding-y-sm !default;
+$btn-padding-x-sm: 1.25rem !default;
+$btn-font-size-sm: $input-btn-font-size-sm !default;
+
+$btn-padding-y-lg: $input-btn-padding-y-lg !default;
+$btn-padding-x-lg: 1.75rem !default;
+$btn-font-size-lg: $input-btn-font-size-lg !default;
+
+$btn-border-width: $input-btn-border-width !default;
+
+$btn-font-weight: $font-weight-semibold !default;
+$btn-box-shadow: null !default;
+$btn-focus-width: $input-btn-focus-width !default;
+$btn-focus-box-shadow: null !default;
+$btn-disabled-opacity: .65 !default;
+$btn-active-box-shadow: null !default;
+
+$btn-link-color: var(--#{$prefix}link-color) !default;
+$btn-link-hover-color: var(--#{$prefix}link-hover-color) !default;
+$btn-link-disabled-color: var(--#{$prefix}gray-600) !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius: $border-radius !default;
+$btn-border-radius-sm: $border-radius-sm !default;
+$btn-border-radius-lg: $border-radius-lg !default;
+
+
+// Forms
+$form-text-margin-top: .5rem !default;
+$form-text-font-size: $font-size-sm !default;
+$form-text-color: var(--#{$prefix}text-muted) !default;
+
+$form-label-margin-bottom: .5rem !default;
+$form-label-font-size: 1.05rem !default;
+$form-label-font-weight: 500 !default;
+$form-label-color: var(--#{$prefix}gray-800) !default;
+
+$input-padding-y: $input-btn-padding-y !default;
+$input-padding-x: $input-btn-padding-x !default;
+$input-font-family: $input-btn-font-family !default;
+$input-font-size: $input-btn-font-size !default;
+$input-font-weight: $font-weight-semibold !default;
+$input-line-height: $input-btn-line-height !default;
+
+$input-bg: var(--#{$prefix}body-bg) !default;
+
+$input-border-width: $input-btn-border-width !default;
+$input-color: var(--#{$prefix}gray-700) !default;
+$input-border-color: var(--#{$prefix}gray-300) !default;
+$input-box-shadow: false !default;
+$input-border-radius: $btn-border-radius !default;
+$input-border-radius-sm: $btn-border-radius-sm !default;
+$input-border-radius-lg: $btn-border-radius-lg !default;
+
+$input-focus-bg: $input-bg !default;
+$input-focus-border-color: var(--#{$prefix}gray-400) !default;
+$input-btn-focus-width: .25rem !default;
+$input-focus-color: $input-color !default;
+$input-focus-width: $input-btn-focus-width !default;
+
+$input-disabled-color: var(--#{$prefix}gray-500) !default;
+$input-disabled-bg: var(--#{$prefix}gray-200) !default;
+$input-disabled-border-color: $input-border-color !default;
+
+$input-placeholder-color: var(--#{$prefix}gray-500) !default;
+$input-plaintext-color: var(--#{$prefix}gray-700) !default;
+
+$inpur-autifill-bg-color: var(--#{$prefix}gray-100) !default;
+
+// Keenthemes solid input style
+$input-solid-color: var(--#{$prefix}gray-700) !default;
+$input-solid-bg: var(--#{$prefix}gray-100) !default;
+$input-solid-bg-focus: var(--#{$prefix}gray-200) !default;
+$input-solid-placeholder-color: var(--#{$prefix}gray-500) !default;
+
+
+// Form checks
+$form-check-input-width: 1.75rem !default;
+$form-check-input-width-sm: 1.55rem !default;
+$form-check-input-width-lg: 2.25rem !default;
+$form-check-input-bg-size: 60% 60% !default;
+$form-check-min-height: $font-size-base * $line-height-base !default;
+$form-check-padding-start: $form-check-input-width + .5rem !default;
+$form-check-padding-left: $form-check-input-width + .5rem !default;
+$form-check-margin-bottom: .125rem !default;
+$form-check-label-color: var(--#{$prefix}gray-500) !default;
+$form-check-label-color-checked: var(--#{$prefix}gray-700) !default;
+$form-check-label-cursor: null !default;
+$form-check-transition: null !default;
+$form-check-inline-margin-right: 1rem !default;
+
+$form-check-input-active-filter: brightness(90%) !default;
+
+$form-check-input-bg: transparent !default;
+$form-check-input-bg-solid: var(--#{$prefix}gray-200) !default;
+$form-check-input-border: 1px solid $input-border-color !default;
+$form-check-input-border-radius: .45em !default;
+$form-check-radio-border-radius: 50% !default;
+$form-check-input-focus-border: $input-focus-border-color !default;
+$form-check-input-focus-box-shadow: none !default;
+
+$form-check-input-checked-color: $component-checked-color !default;
+$form-check-input-checked-bg-color: $component-checked-bg !default;
+$form-check-input-checked-border-color: $component-checked-bg !default;
+$form-check-input-checked-bg-image: url("data:image/svg+xml, ") !default;
+$form-check-radio-checked-bg-image: url("data:image/svg+xml, ") !default;
+
+$form-check-input-checked-bg-color-solid: $component-checked-bg !default;
+$form-check-input-focus-bg-color-solid: $component-checked-bg !default;
+
+$form-check-input-indeterminate-color: $component-checked-color !default;
+$form-check-input-indeterminate-bg-color: $component-checked-bg !default;
+$form-check-input-indeterminate-border-color: $component-checked-bg !default;
+$form-check-input-indeterminate-bg-image: url("data:image/svg+xml, ") !default;
+
+$form-check-input-disabled-opacity: .5 !default;
+$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default;
+$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default;
+
+$form-switch-color: rgba($black, .25) !default;
+$form-switch-color-solid: $white !default;
+$form-switch-width: 3.25rem !default;
+$form-switch-height: 2.25rem !default;
+$form-switch-width-sm: 2.5rem !default;
+$form-switch-height-sm: 1.5rem !default;
+$form-switch-width-lg: 3.75rem !default;
+$form-switch-height-lg: 2.75rem !default;
+
+$form-switch-padding-start: $form-switch-width + .5rem !default;
+$form-switch-padding-left: $form-switch-width + .5rem !default;
+$form-switch-bg-image: url("data:image/svg+xml, ") !default;
+$form-switch-bg-image-solid: url("data:image/svg+xml, ") !default;
+$form-switch-border-radius: $form-switch-width !default;
+
+$form-switch-focus-color: $form-switch-color !default;
+$form-switch-focus-bg-image: url("data:image/svg+xml, ") !default;
+
+$form-switch-checked-color: $component-checked-color !default;
+$form-switch-checked-bg-image: url("data:image/svg+xml, ") !default;
+$form-switch-checked-bg-position: right center !default;
+
+
+// Input groups
+$input-group-addon-bg: var(--#{$prefix}gray-100) !default;
+$input-group-addon-color: var(--#{$prefix}gray-700) !default;
+$input-group-addon-border-color: $input-border-color !default;
+
+
+// Form select
+$form-select-color: $input-color !default;
+$form-select-bg: $input-bg !default;
+$form-select-disabled-color: $input-disabled-color !default;
+$form-select-disabled-bg: var(--#{$prefix}gray-200) !default;
+$form-select-disabled-border-color: $input-disabled-border-color !default;
+$form-select-indicator-color: $gray-600 !default;
+$form-select-indicator: url("data:image/svg+xml, ") !default;
+$form-select-border-color: $input-border-color !default;
+$form-select-box-shadow: false !default;
+$form-select-focus-border-color: $input-focus-border-color !default;
+$form-select-focus-width: $input-focus-width !default;
+$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;
+
+
+// Form range
+$form-range-track-border-radius: $border-radius !default;
+$form-range-track-bg: var(--#{$prefix}gray-300) !default;
+$form-range-thumb-disabled-bg: var(--#{$prefix}gray-500) !default;
+
+
+// Form file button
+$form-file-button-color: $input-color !default;
+$form-file-button-bg: $input-group-addon-bg !default;
+$form-file-button-hover-bg: shade-color($form-file-button-bg, 5%) !default;
+
+
+// Form floating
+$input-height-border: $input-border-width * 2 !default;
+$form-floating-height: calc(3.75rem + #{$input-height-border}) !default;
+$form-floating-input-padding-t: 1.85rem !default;
+
+
+// Navs
+$nav-link-transition: color .15s ease-in-out !default;
+$nav-tabs-border-color: var(--#{$prefix}border-color) !default;
+
+
+// Dropdowns
+// Dropdown menu container and contents.
+$dropdown-color: var(--#{$prefix}body-color) !default;
+$dropdown-bg: var(--#{$prefix}body-bg) !default;
+$dropdown-divider-bg: var(--#{$prefix}gray-100) !default;
+$dropdown-box-shadow: 0px 0px 50px 0px rgba(82,63,105, 0.15) !default;
+$dropdown-border-radius: $border-radius !default;
+$dropdown-border-width: 0rem !default;
+$dropdown-link-color: var(--#{$prefix}gray-900) !default;
+$dropdown-link-active-color: var(--#{$prefix}component-hover-color) !default;
+$dropdown-link-active-bg: var(--#{$prefix}component-hover-bg) !default;
+$dropdown-link-active-color: var(--#{$prefix}component-active-color) !default;
+$dropdown-link-active-bg: var(--#{$prefix}component-active-bg) !default;
+$dropdown-link-disabled-color: var(--#{$prefix}gray-500) !default;
+$dropdown-header-color: var(--#{$prefix}gray-600) !default;
+$dropdown-item-padding-y: 0.65rem !default;
+$dropdown-item-padding-x: 0.85rem !default;
+
+
+// Pagination
+$pagination-item-height: 2.5rem !default;
+$pagination-item-bg: var(--#{$prefix}body-bg) !default;
+$pagination-item-space: 0.5rem !default;
+$pagination-item-space-tablet-and-mobile: 0.25rem !default;
+$pagination-font-weight: $font-weight-semibold !default;
+$pagination-font-size: $font-size-lg !default;
+$pagination-icon-font-size: 0.85rem !default;
+$pagination-icon-height: $pagination-item-height * 0.35 !default;
+
+$pagination-padding-y: .375rem !default;
+$pagination-padding-x: .75rem !default;
+$pagination-padding-y-sm: .25rem !default;
+$pagination-padding-x-sm: .5rem !default;
+$pagination-padding-y-lg: .75rem !default;
+$pagination-padding-x-lg: 1.5rem !default;
+
+$pagination-color: var(--#{$prefix}gray-700) !default;
+$pagination-bg: transparent !default;
+$pagination-border-width: 0 !default;
+$pagination-border-radius: $btn-border-radius !default;
+$pagination-margin-left: 0 !default;
+$pagination-border-color: transparent !default;
+
+$pagination-focus-color: var(--#{$prefix}component-hover-color) !default;
+$pagination-focus-bg: var(--#{$prefix}component-hover-bg) !default;
+$pagination-focus-box-shadow: none !default;
+$pagination-focus-outline: 0 !default;
+
+$pagination-hover-color: var(--#{$prefix}component-hover-color) !default;
+$pagination-hover-bg: var(--#{$prefix}component-hover-bg) !default;
+$pagination-hover-border-color: transparent !default;
+
+$pagination-active-color: var(--#{$prefix}component-active-color) !default;
+$pagination-active-bg: var(--#{$prefix}component-active-bg) !default;
+$pagination-active-border-color: transparent !default;
+
+$pagination-disabled-color: var(--#{$prefix}gray-400) !default;
+$pagination-disabled-bg: transparent !default;
+$pagination-disabled-border-color: transparent !default;
+
+// Card
+$card-box-shadow: 0px 0px 20px 0px rgba(76,87,125,0.02) !default;
+$card-border-color: var(--#{$prefix}border-color) !default;
+$card-border-width: 1px !default;
+$card-border-style: solid !default;
+$card-border-dashed-color: var(--#{$prefix}border-dashed-color) !default;
+$card-color: null !default;
+$card-cap-bg: transparent !default;
+$card-py: 2rem !default;
+$card-px: 2.25rem !default;
+$card-border-radius: $border-radius-lg !default;
+$card-header-py: 0.5rem !default;
+$card-header-height: 70px !default;
+$card-border-enabled: false !default;
+
+
+// Accordion
+$accordion-color: var(--#{$prefix}body-color) !default;
+$accordion-bg: var(--#{$prefix}body-bg) !default;
+$accordion-padding-y: 1.5rem !default;
+$accordion-padding-x: 1.5rem !default;
+$accordion-border-color: var(--#{$prefix}border-color) !default;
+$accordion-border-radius: $border-radius !default;
+$accordion-button-color: $accordion-color !default;
+$accordion-button-bg: $accordion-bg !default;
+$accordion-button-active-bg: var(--#{$prefix}gray-100) !default;
+$accordion-button-active-color: var(--#{$prefix}primary) !default;
+$accordion-button-focus-border-color: var(--#{$prefix}border-color) !default;
+$accordion-button-focus-box-shadow: none !default;
+
+$accordion-icon-width: 1.15rem !default;
+$accordion-icon-color: $body-color !default;
+$accordion-icon-active-color: $primary !default;
+$accordion-button-icon: url("data:image/svg+xml, ") !default;
+$accordion-button-active-icon: url("data:image/svg+xml, ") !default;
+
+
+// Tooltips
+$tooltip-font-size: 1rem !default;
+$tooltip-max-width: 200px !default;
+$tooltip-color: var(--#{$prefix}gray-800) !default;
+$tooltip-bg: var(--#{$prefix}body-bg) !default;
+$tooltip-border-radius: $btn-border-radius !default;
+$tooltip-opacity: 1 !default;
+$tooltip-box-shadow: 0px 0px 50px 0px rgba(82,63,105, 0.075) !default;
+$tooltip-padding-y: .75rem !default;
+$tooltip-padding-x: 1rem !default;
+$tooltip-margin: 0 !default;
+
+
+// Popovers
+$popover-bg: $body-bg !default;
+$popover-font-size: $font-size-base !default;
+$popover-border-color: $popover-bg !default;
+$popover-border-radius: $border-radius !default;
+$popover-inner-border-radius: $border-radius !default;
+$popover-box-shadow: $dropdown-box-shadow !default;
+$popover-header-bg: $popover-bg !default;
+$popover-header-color: var(--#{$prefix}gray-800) !default;
+$popover-header-font-weight: 500 !default;
+$popover-header-font-size: 1rem !default;
+$popover-header-padding-y: 1rem !default;
+$popover-header-padding-x: 1.25rem !default;
+$popover-header-border-color: $border-color !default;
+$popover-body-color: var(--#{$prefix}gray-800) !default;
+$popover-body-padding-y: 1.25rem !default;
+$popover-body-padding-x: 1.25rem !default;
+$popover-dissmis-btn-size: 1.25rem !default;
+$popover-dissmis-btn-top: 0.85rem !default;
+$popover-dissmis-btn-end: 0.85rem !default;
+
+
+// Toasts
+$toast-color: var(--#{$prefix}gray-700) !default;
+$toast-background-color: var(--#{$prefix}body-bg) !default;
+$toast-box-shadow: var(--#{$prefix}box-shadow) !default;
+$toast-header-color: var(--#{$prefix}gray-700) !default;
+$toast-header-background-color: var(--#{$prefix}body-bg) !default;
+$toast-header-border-color: var(--#{$prefix}border-color) !default;
+$toast-border-color: transparent !default;
+
+
+// Badges
+$badge-font-size: 0.85rem !default;
+$badge-font-size-sm: 0.8rem !default;
+$badge-font-size-lg: 1rem !default;
+$badge-font-weight: $font-weight-bold !default;
+$badge-color: var(--#{$prefix}body-color) !default;
+$badge-padding-y: .325rem !default;
+$badge-padding-x: .5rem !default;
+$badge-border-radius: $border-radius-sm !default;
+$badge-size: 1.75rem !default;
+$badge-size-sm: 1.5rem !default;
+$badge-size-lg: 2rem !default;
+
+
+// Modals
+// Padding applied to the modal body
+$modal-inner-padding: 1.75rem !default;
+
+// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding
+$modal-footer-margin-between: .5rem !default;
+
+$modal-dialog-margin: .5rem !default;
+$modal-dialog-margin-y-sm-up: 1.75rem !default;
+
+$modal-content-color: null !default;
+$modal-content-bg: var(--#{$prefix}body-bg) !default;
+$modal-content-border-color: null !default;
+$modal-content-border-width: 0 !default;
+$modal-content-border-radius: $border-radius !default;
+$modal-content-inner-border-radius: $border-radius !default;
+$modal-content-box-shadow: 0 .25rem .5rem rgba($black, .05) !default;
+$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .1) !default;
+$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .1) !default;
+
+$modal-backdrop-bg: $black !default;
+$modal-backdrop-opacity: 0.4 !default;
+
+$modal-header-border-color: var(--#{$prefix}border-color) !default;
+$modal-footer-border-color: $modal-header-border-color !default;
+$modal-header-border-width: 1px !default;
+
+
+// Progress bars
+$progress-height: 1rem !default;
+$progress-font-size: $font-size-base * .75 !default;
+$progress-bg: var(--#{$prefix}gray-100) !default;
+$progress-border-radius: 6px !default;
+$progress-box-shadow: none !default;
+
+
+// List group
+$list-group-color: var(--#{$prefix}gray-900) !default;
+$list-group-bg: $white !default;
+$list-group-border-color: rgba($black, .125) !default;
+
+$list-group-hover-bg: var(--#{$prefix}gray-100) !default;
+$list-group-active-color: var(--#{$prefix}component-active-color) !default;
+$list-group-active-bg: var(--#{$prefix}component-active-bg) !default;
+$list-group-active-border-color: $list-group-active-bg !default;
+
+$list-group-disabled-color: var(--#{$prefix}gray-600) !default;
+$list-group-disabled-bg: $list-group-bg !default;
+
+$list-group-action-color: var(--#{$prefix}gray-700) !default;
+$list-group-action-hover-color: $list-group-action-color !default;
+
+$list-group-action-active-color: var(--#{$prefix}body-color) !default;
+$list-group-action-active-bg: var(--#{$prefix}gray-200) !default;
+
+// Image thumbnails
+$thumbnail-bg: var(--#{$prefix}body-bg) !default;
+$thumbnail-border-color: var(--#{$prefix}border-color) !default;
+$thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default;
+
+
+// Figures
+$figure-caption-color: var(--#{$prefix}gray-600) !default;
+
+
+// Breadcrumbs
+$breadcrumb-bg: null !default;
+$breadcrumb-divider-color: var(--#{$prefix}gray-600) !default;
+$breadcrumb-active-color: var(--#{$prefix}primary) !default;
+$breadcrumb-item-padding-x: .5rem !default;
+
+
+// Carousel
+$carousel-custom-indicator-transition-speed: 0.3s !default;
+$carousel-custom-indicator-default-bg-color: var(--#{$prefix}gray-200) !default;
+$carousel-custom-indicator-active-bg-color: var(--#{$prefix}gray-400) !default;
+
+$carousel-custom-dots-indicator-default-size: 9px !default;
+$carousel-custom-dots-indicator-active-size: 13px !default;
+
+$carousel-custom-bullet-indicator-default-size: 6px !default;
+$carousel-custom-bullet-indicator-active-width: 16px !default;
+$carousel-custom-bullet-indicator-default-bg-color: var(--#{$prefix}gray-400) !default;
+$carousel-custom-bullet-indicator-active-bg-color: var(--#{$prefix}gray-600) !default;
+
+// Spinners
+$spinner-border-width: .185rem !default;
+$spinner-animation-speed: .65s !default;
+$spinner-border-width-sm: .145em !default;
+
+
+// Close
+$btn-close-width: 0.75rem !default;
+$btn-close-height: $btn-close-width !default;
+$btn-close-color: $black !default;
+$btn-close-bg: url("data:image/svg+xml, ") !default;
+$btn-close-focus-shadow: none !default;
+
+// Code
+$code-bg: #F1F3F8 !default;
+$code-box-shadow: 0px 3px 9px rgba(0, 0, 0, 0.08) !default;
+$code-padding: 0.1rem 0.4rem !default;
+$code-margin: 0 0.5rem !default;
+$code-font-weight: 400 !default;
+$code-border-radius: 0.3rem !default;
+$code-color: #b93993 !default;
+$code-space: 0.25rem !default;
+
+// Opacity
+$opacity-values: (
+ 0: 0,
+ 5: .05,
+ 10: .1,
+ 15: .15,
+ 20: .20,
+ 25: .25,
+ 50: .5,
+ 75: .75,
+ 100: 1,
+ ) !default;
+
+// Zindex
+$zindex-values: (
+ n1: -1,
+ n2: -2,
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ 3: 3
+) !default;
+
+// Letter spacing
+$letter-spacing-values: (
+ 1: 0.1rem,
+ 2: 0.115rem,
+ 3: 0.125rem,
+ 4: 0.25rem,
+ 5: 0.5rem,
+ n1: -0.1rem,
+ n2: -0.115rem,
+ n3: -0.125rem,
+ n4: -0.25rem,
+ n5: -0.5rem,
+) !default;
+
+// Keenthemes hight and width sizes
+$custom-sizes: (
+ unset: unset,
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%,
+ auto: auto,
+ 1px: 1px,
+ 2px: 2px,
+ 3px: 3px,
+ 4px: 4px,
+ 5px: 5px,
+ 6px: 6px,
+ 7px: 7px,
+ 8px: 8px,
+ 9px: 9px,
+ 10px: 10px,
+ 15px: 15px,
+ 20px: 20px,
+ 25px: 25px,
+ 30px: 30px,
+ 35px: 35px,
+ 40px: 40px,
+ 45px: 45px,
+ 50px: 50px,
+ 55px: 55px,
+ 60px: 60px,
+ 65px: 65px,
+ 70px: 70px,
+ 75px: 75px,
+ 80px: 80px,
+ 85px: 85px,
+ 90px: 90px,
+ 95px: 95px,
+ 100px: 100px,
+ 125px: 125px,
+ 150px: 150px,
+ 175px: 175px,
+ 200px: 200px,
+ 225px: 225px,
+ 250px: 250px,
+ 275px: 275px,
+ 300px: 300px,
+ 325px: 325px,
+ 350px: 350px,
+ 375px: 375px,
+ 400px: 400px,
+ 425px: 425px,
+ 450px: 450px,
+ 475px: 475px,
+ 500px: 500px,
+ 550px: 550px,
+ 600px: 600px,
+ 650px: 650px,
+ 700px: 700px,
+ 750px: 750px,
+ 800px: 800px,
+ 850px: 850px,
+ 900px: 900px,
+ 950px: 950px,
+ 1000px: 1000px
+) !default;
+
+
+// Keenthemes symbol component
+$symbol-sizes: (
+ 20px: 20px,
+ 25px: 25px,
+ 30px: 30px,
+ 35px: 35px,
+ 40px: 40px,
+ 45px: 45px,
+ default: 50px,
+ 50px: 50px,
+ 55px: 55px,
+ 60px: 60px,
+ 65px: 65px,
+ 70px: 70px,
+ 75px: 75px,
+ 90px: 90px,
+ 100px:100px,
+ 125px:125px,
+ 150px:150px,
+ 160px:160px,
+ 175px:175px,
+ 200px:200px
+) !default;
+
+$symbol-border-color: rgba(var(--#{$prefix}body-bg), 0.5);
+$symbol-label-color: var(--#{$prefix}gray-800);
+$symbol-label-bg: var(--#{$prefix}gray-100);
+
+
+// Keenthemes bullet component
+$bullet-bg-color: var(--#{$prefix}gray-400) !default;
+$bullet-dot-size: 4px !default;
+$bullet-bar-height: 4px !default;
+$bullet-bar-width: 8px !default;
+$bullet-bar-border-radius: 6px !default;
+$bullet-line-height: 1px !default;
+$bullet-line-width: 5px !default;
+
+
+// Keenthemes scrolltop component
+$scrolltop-z-index: 105 !default;
+$scrolltop-opacity: 0 !default;
+$scrolltop-opacity-on: 0.3 !default;
+$scrolltop-opacity-hover: 1 !default;
+$scrolltop-bottom: 40px !default;
+$scrolltop-bottom-mobile: 30px !default;
+$scrolltop-end: 20px !default;
+$scrolltop-end-mobile: 15px !default;
+$scrolltop-size: 36px !default;
+$scrolltop-size-mobile: 30px !default;
+$scrolltop-box-shadow: var(--#{$prefix}box-shadow) !default;
+$scrolltop-bg-color: var(--#{$prefix}primary) !default;
+$scrolltop-bg-color-hover: var(--#{$prefix}primary) !default;
+$scrolltop-icon-color: var(--#{$prefix}primary-inverse) !default;
+$scrolltop-icon-color-hover: var(--#{$prefix}primary-inverse) !default;
+
+// Keenthemes sticky toolbar component
+$sticky-toolbar-z-index: 95 !default;
+
+
+// Keenthemes drawer component
+$drawer-z-index: 110 !default;
+$drawer-box-shadow: 0px 1px 9px -3px rgba(0,0,0, 0.05) !default;
+$drawer-bg-color: $body-bg !default;
+$drawer-transition-speed: 0.3s !default;
+$drawer-overlay-bg-color: rgba($black, 0.2) !default;
+$drawer-overlay-animation-speed: 0.3s !default;
+
+// Keenthemes menu component
+$menu-dropdown-box-shadow: $dropdown-box-shadow !default;
+$menu-dropdown-z-index: 107 !default;
+$menu-dropdown-bg-color: $dropdown-bg !default;
+$menu-dropdown-border-radius: $dropdown-border-radius !default;
+$menu-dropdown-animation: true !default;
+$menu-dropdown-animation-speed: 0.3s !default;
+$menu-dropdown-animation-move-offset: 0.75rem !default;
+$menu-accordion-indention: 1rem !default;
+$menu-accordion-arrow-transition: transform 0.3s ease !default;
+$menu-item-padding-y: 0.15rem !default;
+$menu-item-padding-x: 0 !default;
+$menu-link-padding-y: 0.65rem !default;
+$menu-link-padding-x: 1rem !default;
+$menu-link-border-radius: $border-radius !default;
+$menu-link-color-hover: $component-hover-color !default;
+$menu-link-color-show: $component-hover-color !default;
+$menu-link-color-here: $component-hover-color !default;
+$menu-link-color-active: $component-hover-color !default;
+$menu-link-bg-color-hover: $component-hover-bg !default;
+$menu-link-bg-color-show: $component-hover-bg !default;
+$menu-link-bg-color-here: $component-hover-bg !default;
+$menu-link-bg-color-active: $component-hover-bg !default;
+$menu-icon-size: 2rem !default;
+$menu-icon-space: 0.5rem !default;
+$menu-bullet-size: 1.25rem !default;
+$menu-bullet-space: 0.5rem !default;
+$menu-badge-space: 0.5rem !default;
+$menu-arrow-size: 9px !default;
+$menu-arrow-space: 5px !default;
+$menu-heading-color: $text-muted !default;
+
+// Keenthemes scrollbar component
+$scrollbar-size: 5px !default;
+$scrollbar-overlay-size: 19px !default;
+$scrollbar-overlay-space: 7px !default;
+$scrollbar-color: $gray-200 !default;
+$scrollbar-hover-color: $gray-300 !default;
+
+// Keenthemes overlay component
+$overlay-bg: rgba($black, 0.05) !default;
+
+// Keenthemes blockui component
+$blockui-overlay-bg: rgba($black, 0.05) !default;
+$blockui-message-bg: $tooltip-bg !default;
+$blockui-message-box-shadow: $tooltip-box-shadow !default;
+
+// Keenthemes rating component
+$rating-color-default: $gray-400 !default;
+$rating-color-active: #FFAD0F !default;
+
+// Keenthemes ribbon component
+$ribbon-label-box-shadow: 0px -1px 5px 0px rgba($dark, 0.1) !default;
+$ribbon-label-bg: $primary !default;
+$ribbon-label-border-color: darken($primary, 20%) !default;
+$ribbon-clip-bg: $dark !default;
+
+// Keenthemes fixed component
+$fixed-z-index: 101 !default;
+
+// Engage panel
+$engage-btn-bg: $body-bg;
+$engage-btn-box-shadow: 0px 0px 22px #E0E0E0;
+$engage-btn-border-color: #E8E8E8;
+$engage-btn-color: $gray-800;
+$engage-btn-icon-color: $gray-600;
+$engage-btn-color-active: $gray-800;
+$engage-z-index: 5;
+
+// Social Network Colors Used With Boostrap Buttons(see: https://brandcolors.net)
+$social-colors: (
+ facebook: (
+ base: #3b5998,
+ inverse: #ffffff,
+ light: rgba(#3b5998, 0.1),
+ active: darken(#3b5998, 7.5%)
+ ),
+ google: (
+ base: #dd4b39,
+ inverse: #ffffff,
+ light: rgba(#dd4b39, 0.1),
+ active: darken(#dd4b39, 7.5%)
+ ),
+ twitter: (
+ base: #1da1f2,
+ inverse: #ffffff,
+ light: rgba(#1da1f2, 0.1),
+ active: darken(#1da1f2, 7.5%)
+ ),
+ instagram: (
+ base: #e1306c,
+ inverse: #ffffff,
+ light: rgba(#e1306c, 0.1),
+ active: darken(#e1306c, 7.5%)
+ ),
+ youtube: (
+ base: #ff0000,
+ inverse: #ffffff,
+ light: rgba(#ff0000, 0.1),
+ active: darken(#ff0000, 7.5%)
+ ),
+ linkedin: (
+ base: #0077b5,
+ inverse: #ffffff,
+ light: rgba(#0077b5, 0.1),
+ active: darken(#0077b5, 7.5%)
+ )
+) !default;
\ No newline at end of file
diff --git a/Moonlight/Styles/components/buttons/_base.scss b/Moonlight/Styles/components/buttons/_base.scss
new file mode 100644
index 00000000..117a267e
--- /dev/null
+++ b/Moonlight/Styles/components/buttons/_base.scss
@@ -0,0 +1,129 @@
+//
+// Buttons Base
+//
+
+// Button
+.btn {
+ --#{$prefix}btn-color: var(--#{$prefix}body-color);
+
+ // Reset outline
+ outline: none !important;
+
+ // Reset focus shadow
+ &:not(.btn-shadow):not(.shadow):not(.shadow-sm):not(.shadow-lg):not(.shadow-xs) {
+ box-shadow: none;
+ }
+
+ // Remove border
+ &:not(.btn-outline):not(.btn-dashed):not(.btn-bordered):not(.border-hover):not(.border-active):not(.btn-flush):not(.btn-icon) {
+ border: 0;
+ padding: calc(#{$btn-padding-y} + #{$btn-border-width}) calc(#{$btn-padding-x} + #{$btn-border-width});
+
+ &.btn-lg {
+ padding: calc(#{$btn-padding-y-lg} + #{$btn-border-width}) calc(#{$btn-padding-x-lg} + #{$btn-border-width});
+ }
+
+ &.btn-sm {
+ padding: calc(#{$btn-padding-y-sm} + #{$btn-border-width}) calc(#{$btn-padding-x-sm} + #{$btn-border-width});
+ }
+ }
+
+ // Link
+ &.btn-link {
+ border: 0;
+ border-radius: 0;
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ text-decoration: none;
+ font-weight: $btn-font-weight;
+ }
+
+ // Outline
+ &.btn-outline:not(.btn-outline-dashed) {
+ border: 1px solid $input-border-color;
+ }
+
+ // Outline dashed
+ &.btn-outline-dashed {
+ border: 1px dashed $input-border-color;
+ }
+
+ // Flush
+ &.btn-flush {
+ @include button-reset();
+ }
+
+ // Flex
+ &.btn-flex {
+ display: inline-flex;
+ align-items: center;
+ }
+
+ // Align start
+ &.btn-trim-start {
+ justify-content: flex-start !important;
+ padding-left: 0 !important;
+ }
+
+ // Align start
+ &.btn-trim-end {
+ justify-content: flex-end !important;
+ padding-right: 0 !important;
+ }
+}
+
+// Reset
+.btn-reset {
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ user-select: none;
+ outline: none;
+}
+
+// Icons
+.btn {
+ // Font icon
+ > i {
+ display: inline-flex;
+ font-size: $font-size-base;
+ padding-right: 0.35rem;
+ vertical-align: middle;
+ }
+
+ // Icon only button
+ &.btn-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ height: $input-height;
+ width: $input-height;
+ line-height: 1;
+
+ i {
+ padding-right: 0;
+ }
+
+ // Remove border
+ &:not(.btn-outline):not(.btn-dashed):not(.border-hover):not(.border-active):not(.btn-flush) {
+ border: 0;
+ }
+
+ // Sizes
+ &.btn-sm {
+ height: $input-height-sm;
+ width: $input-height-sm;
+
+ }
+
+ &.btn-lg {
+ height: $input-height-lg;
+ width: $input-height-lg;
+ }
+
+ &.btn-circle {
+ border-radius: 50%;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/buttons/_theme.scss b/Moonlight/Styles/components/buttons/_theme.scss
new file mode 100644
index 00000000..557c8775
--- /dev/null
+++ b/Moonlight/Styles/components/buttons/_theme.scss
@@ -0,0 +1,259 @@
+//
+// Buttons Theme
+//
+
+// Outline dashed basic style
+.btn.btn-outline.btn-outline-dashed {
+ border-width: 1px;
+ border-style: dashed;
+
+ $color: null;
+ $icon-color: null;
+ $border-color: null;
+ $bg-color: null;;
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: var(--#{$prefix}primary);
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+}
+
+// Theme colors
+@each $name, $value in $theme-colors {
+ // Base
+ .btn.btn-#{$name} {
+ $color: var(--#{$prefix}#{$name}-inverse);
+ $icon-color: var(--#{$prefix}#{$name}-inverse);
+ $border-color: var(--#{$prefix}#{$name});
+ $bg-color: var(--#{$prefix}#{$name});
+
+ $color-active: var(--#{$prefix}#{$name}-inverse);
+ $icon-color-active: var(--#{$prefix}#{$name}-inverse);
+ $border-color-active: var(--#{$prefix}#{$name}-active);
+ $bg-color-active: var(--#{$prefix}#{$name}-active);
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Light
+ @if ( theme-light-color($name) ) {
+ .btn.btn-light-#{$name} {
+ $color: var(--#{$prefix}#{$name});
+ $icon-color: var(--#{$prefix}#{$name});
+ $border-color: var(--#{$prefix}#{$name}-light);
+ $bg-color: var(--#{$prefix}#{$name}-light);
+
+ $color-active: var(--#{$prefix}#{$name}-inverse);
+ $icon-color-active: var(--#{$prefix}#{$name}-inverse);
+ $border-color-active: var(--#{$prefix}#{$name});
+ $bg-color-active: var(--#{$prefix}#{$name});
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+ }
+
+ // Background
+ .btn.btn-bg-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $border-color: var(--#{$prefix}#{$name});
+ $bg-color: var(--#{$prefix}#{$name});
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Active
+ .btn.btn-active-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $border-color: null;
+ $bg-color: null;
+
+ $color-active: var(--#{$prefix}#{$name}-inverse);
+ $icon-color-active: var(--#{$prefix}#{$name}-inverse);
+ $border-color-active: var(--#{$prefix}#{$name});
+ $bg-color-active: var(--#{$prefix}#{$name});
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Light
+ @if ( theme-light-color($name) ) {
+ .btn.btn-active-light-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $border-color: null;
+ $bg-color: null;
+
+ $color-active: var(--#{$prefix}#{$name});
+ $icon-color-active: var(--#{$prefix}#{$name});
+ $border-color-active: var(--#{$prefix}#{$name}-light);
+ $bg-color-active: var(--#{$prefix}#{$name}-light);
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+ }
+
+ // Outline
+ .btn.btn-outline.btn-outline-#{$name} {
+ $color: var(--#{$prefix}#{$name});
+ $icon-color: var(--#{$prefix}#{$name});
+ $border-color: var(--#{$prefix}#{$name});
+ $bg-color: transparent;
+
+ $color-active: var(--#{$prefix}#{$name}-active);
+ $icon-color-active: var(--#{$prefix}#{$name}-active);
+ $border-color-active: var(--#{$prefix}#{$name});
+ $bg-color-active: var(--#{$prefix}#{$name}-light);
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+}
+
+// Theme text colors
+@each $name, $value in $theme-text-colors {
+ // Text and icon colors
+ .btn.btn-color-#{$name} {
+ $color: var(--#{$prefix}text-#{$name});
+ $icon-color: var(--#{$prefix}text-#{$name});
+ $bg-color: null;
+ $border-color: null;
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Text and icon colors active state
+ .btn.btn-active-color-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $border-color: null;
+ $bg-color: null;
+
+ $color-active: var(--#{$prefix}text-#{$name});
+ $icon-color-active: var(--#{$prefix}text-#{$name});
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Icon colors
+ .btn.btn-icon-#{$name} {
+ $color: null;
+ $icon-color: var(--#{$prefix}text-#{$name});
+ $bg-color: null;
+ $border-color: null;
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Icon colors active state
+ .btn.btn-active-icon-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $bg-color: null;
+ $border-color: null;
+
+ $color-active: null;
+ $icon-color-active: var(--#{$prefix}text-#{$name});
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Text colors
+ .btn.btn-text-#{$name} {
+ $color: var(--#{$prefix}text-#{$name});
+ $icon-color: null;
+ $bg-color: null;
+ $border-color: null;
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Text colors active state
+ .btn.btn-active-text-#{$name} {
+ $color: null;
+ $icon-color: null;
+ $bg-color: null;
+ $border-color: null;
+
+ $color-active: var(--#{$prefix}text-#{$name});
+ $icon-color-active: null;
+ $border-color-active: null;
+ $bg-color-active: null;
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+}
+
+// Social colors
+@each $name, $value in $social-colors {
+ // Base
+ .btn.btn-#{$name} {
+ $color: get($value, inverse);
+ $icon-color: get($value, inverse);
+ $border-color: get($value, base);
+ $bg-color: get($value, base);
+
+ $color-active: null;
+ $icon-color-active: null;
+ $border-color-active: get($value, active);
+ $bg-color-active: get($value, active);
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+
+ // Light
+ .btn.btn-light-#{$name} {
+ $color: get($value, base);
+ $icon-color: get($value, base);
+ $bg-color: get($value, light);
+ $border-color: get($value, light);
+
+ $color-active: get($value, inverse);
+ $icon-color-active: get($value, inverse);
+ $bg-color-active: get($value, base);
+ $border-color-active: get($value, base);
+
+ @include button-custom-variant($color, $icon-color, $border-color, $bg-color, $color-active, $icon-color-active, $border-color-active, $bg-color-active);
+ }
+}
+
+@include color-mode(dark) {
+ .btn.btn-dark {
+ @include button-custom-variant(
+ $color: $gray-800-dark,
+ $icon-color: $gray-800-dark,
+ $border-color: null,
+ $bg-color: $gray-400-dark,
+ $color-active: lighten($gray-800-dark, 3%),
+ $icon-color-active: lighten($gray-800-dark, 3%),
+ $border-color-active: null,
+ $bg-color-active: lighten($gray-400-dark, 3%),
+ );
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/components.scss b/Moonlight/Styles/components/components.scss
new file mode 100644
index 00000000..8172653f
--- /dev/null
+++ b/Moonlight/Styles/components/components.scss
@@ -0,0 +1,68 @@
+//
+// Components
+//
+
+// Extended bootstrap utilities
+@import "utilities";
+
+// Bootstrap components
+@import "../bootstrap/scss/bootstrap";
+
+// Custom components
+@import "root";
+@import "reboot";
+@import "type";
+@import "theme-mode";
+@import "animation";
+@import "alert";
+@import "dropdown";
+@import "toasts";
+@import "nav";
+@import "nav-line-tabs";
+@import "nav-pills-custom";
+@import "pagination";
+@import "separator";
+@import "carousel";
+@import "menu";
+@import "anchor";
+@import "card";
+@import "breadcrumb";
+@import "buttons";
+@import "modal";
+@import "code";
+@import "forms";
+@import "progress";
+@import "tables";
+@import "popover";
+@import "tooltip";
+@import "accordion";
+@import "image-input";
+@import "symbol";
+@import "pulse";
+@import "page-loader";
+@import "scrolltop";
+@import "svg-icon";
+@import "fixed";
+@import "timeline";
+@import "timeline-label";
+@import "overlay";
+@import "bullet";
+@import "drawer";
+@import "badge";
+@import "indicator";
+@import "hover";
+@import "rotate";
+@import "scroll";
+@import "rating";
+@import "stepper";
+@import "toggle";
+@import "shape";
+@import "ribbon";
+@import "blockui";
+@import "explore";
+@import "engage";
+@import "cookiealert";
+@import "print";
+@import "helpers";
+@import "testimonials-slider";@import "stepper/multistep";
+@import "landing";
diff --git a/Moonlight/Styles/components/forms/_floating-labels.scss b/Moonlight/Styles/components/forms/_floating-labels.scss
new file mode 100644
index 00000000..3c9d5965
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_floating-labels.scss
@@ -0,0 +1,12 @@
+//
+// Floating label
+//
+
+.form-floating {
+ .form-control.form-control-solid {
+ &::placeholder {
+ color: transparent;
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/Moonlight/Styles/components/forms/_form-check.scss b/Moonlight/Styles/components/forms/_form-check.scss
new file mode 100644
index 00000000..eb32a23c
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_form-check.scss
@@ -0,0 +1,193 @@
+//
+// Form Check
+//
+
+// Customization
+.form-check {
+ // Input
+ &:not(.form-switch) {
+ .form-check-input {
+ &[type="checkbox"] {
+ background-size: $form-check-input-bg-size;
+ }
+ }
+ }
+
+ // Sizing
+ &.form-check-sm {
+ .form-check-input {
+ height: $form-check-input-width-sm;
+ width: $form-check-input-width-sm;
+ }
+ }
+
+ &.form-check-lg {
+ .form-check-input {
+ height: $form-check-input-width-lg;
+ width: $form-check-input-width-lg;
+ }
+ }
+
+ // Inline
+ &.form-check-inline {
+ display: inline-block;
+ margin-right: $form-check-inline-margin-end;
+ }
+
+ // Solid
+ &.form-check-solid {
+ .form-check-input {
+ border: 0;
+
+ &:not(:checked) {
+ background-color: $form-check-input-bg-solid;
+ }
+
+ &[type=checkbox]:indeterminate {
+ background-color: $form-check-input-checked-bg-color;
+ }
+ }
+ }
+
+ // States
+ // Success state
+ &.form-check-success {
+ .form-check-input {
+ &:checked {
+ background-color: var(--#{$prefix}success);
+ }
+ }
+ }
+
+ // Danger state
+ &.form-check-danger {
+ .form-check-input {
+ &:checked {
+ background-color: var(--#{$prefix}danger);
+ }
+ }
+ }
+
+ // Warning state
+ &.form-check-warning {
+ .form-check-input {
+ &:checked {
+ background-color: var(--#{$prefix}warning);
+ }
+ }
+ }
+}
+
+// Custom checkbox and radio
+.form-check-custom {
+ display: flex;
+ align-items: center;
+ padding-left: 0;
+ margin: 0;
+
+ // Input
+ .form-check-input {
+ margin: 0;
+ float: none;
+ flex-shrink: 0;
+ }
+
+ // Label
+ .form-check-label {
+ margin-left: 0.55rem;
+ }
+}
+
+// Switch
+.form-switch {
+ &.form-check-custom {
+ .form-check-input {
+ height: $form-switch-height;
+ }
+
+ &.form-switch-sm {
+ .form-check-input {
+ height: $form-switch-height-sm;
+ width: $form-switch-width-sm;
+ }
+ }
+
+ &.form-switch-lg {
+ .form-check-input {
+ height: $form-switch-height-lg;
+ width: $form-switch-width-lg;
+ }
+ }
+ }
+
+ // Solid
+ &.form-check-solid {
+ .form-check-input {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-solid)};
+
+ &:not(:checked) {
+ background-color: $form-check-input-bg-solid;
+ }
+ }
+ }
+}
+
+@if $enable-dark-mode {
+ @include color-mode(dark) {
+ .form-switch .form-check-input {
+ &:focus:not(:checked) {
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
+ }
+ }
+ }
+}
+
+// Image
+.form-check-image {
+ position: relative;
+ overflow: hidden;
+
+ img {
+ max-width: 100%;
+ }
+
+ .form-check-wrapper {
+ @include border-radius($border-radius-lg);
+ border: 2px solid transparent;
+ transition: $transition-base;
+ cursor: pointer;
+ overflow: hidden;
+ margin-bottom: 0.75rem;
+ }
+
+ .form-check-rounded {
+ @include border-radius($border-radius-lg);
+ }
+
+ .form-check-label {
+ font-weight: $font-weight-bold;
+ margin-left: 0.5rem;
+ }
+
+ &.active:not(.form-check-success):not(.form-check-danger) {
+ .form-check-wrapper {
+ border-color: var(--#{$prefix}primary) !important;
+ }
+ }
+
+ &.form-check-success.active {
+ .form-check-wrapper {
+ border-color: var(--#{$prefix}success) !important;
+ }
+ }
+
+ &.form-check-danger.active {
+ .form-check-wrapper {
+ border-color: var(--#{$prefix}danger) !important;
+ }
+ }
+
+ &.disabled {
+ opacity: $form-check-btn-check-disabled-opacity;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/forms/_form-control.scss b/Moonlight/Styles/components/forms/_form-control.scss
new file mode 100644
index 00000000..040eb5ea
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_form-control.scss
@@ -0,0 +1,70 @@
+//
+// Form controls
+//
+
+// Customization
+.form-control {
+ // Transparent style
+ &.form-control-transparent {
+ background-color: transparent;
+ border-color: transparent;
+
+ .dropdown.show > &,
+ &:active,
+ &.active,
+ &:focus,
+ &.focus {
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+
+ // Flush
+ &.form-control-flush {
+ @include input-reset();
+ }
+}
+
+// Solid style
+.form-control.form-control-solid {
+ background-color: $input-solid-bg;
+ border-color: $input-solid-bg;
+ color: $input-solid-color;
+ @include placeholder($input-solid-placeholder-color);
+ transition: $transition-input;
+
+ .dropdown.show > &,
+ &:active,
+ &.active,
+ &:focus,
+ &.focus {
+ background-color: $input-solid-bg-focus;
+ border-color: $input-solid-bg-focus;
+ color: $input-solid-color;
+ transition: $transition-input;
+ }
+}
+
+// Form control solid bg
+.form-control-solid-bg {
+ background-color: $input-solid-bg;
+}
+
+// Readonly controls as plain text
+.form-control-plaintext {
+ color: $input-plaintext-color
+}
+
+// Placeholder colors
+.placeholder-gray-500 {
+ @include placeholder(var(--#{$prefix}gray-500));
+}
+
+.placeholder-white {
+ @include placeholder($white);
+}
+
+// Textarea reset resize
+.resize-none {
+ resize: none;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/forms/_form-select.scss b/Moonlight/Styles/components/forms/_form-select.scss
new file mode 100644
index 00000000..3b277df3
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_form-select.scss
@@ -0,0 +1,68 @@
+// Select
+//
+// Replaces the browser default select with a custom one, mostly pulled from
+// https://primer.github.io/.
+
+.form-select {
+ appearance: none;
+ //box-shadow: none !important;
+
+ &:focus {
+ border-color: $form-select-focus-border-color;
+ @if $enable-shadows {
+ @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);
+ } @else {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ box-shadow: $form-select-focus-box-shadow;
+ }
+ }
+
+ &:disabled {
+ color: $form-select-disabled-color;
+ background-color: $form-select-disabled-bg;
+ border-color: $form-select-disabled-border-color;
+ }
+
+ // Remove outline from select box in FF
+ &:-moz-focusring {
+ text-shadow: 0 0 0 $form-select-color;
+ }
+
+ // Solid style
+ &.form-select-solid {
+ @include placeholder($input-solid-placeholder-color);
+ background-color: $input-solid-bg;
+ border-color: $input-solid-bg;
+ color: $input-solid-color;
+ transition: $transition-input;
+
+ .dropdown.show > &,
+ &:active,
+ &.active,
+ &:focus,
+ &.focus {
+ background-color: $input-solid-bg-focus;
+ border-color: $input-solid-bg-focus !important;
+ color: $input-solid-color;
+ transition: $transition-input;
+ }
+ }
+
+ // Transparent style
+ &.form-select-transparent {
+ @include placeholder($input-placeholder-color);
+ background-color: transparent;
+ border-color: transparent;
+ color: $input-color;
+
+ .dropdown.show > &,
+ &:active,
+ &.active,
+ &:focus,
+ &.focus {
+ background-color: transparent;
+ border-color: transparent !important;
+ color: $input-color;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/forms/_input-group.scss b/Moonlight/Styles/components/forms/_input-group.scss
new file mode 100644
index 00000000..3e9294b0
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_input-group.scss
@@ -0,0 +1,36 @@
+//
+// Input Group
+//
+
+// Form control
+.input-group {
+ &.input-group-solid {
+ @include border-radius($input-border-radius);
+
+ &.input-group-sm {
+ @include border-radius($input-border-radius-sm);
+ }
+
+ &.input-group-lg {
+ @include border-radius($input-border-radius-lg);
+ }
+
+ .input-group-text {
+ background-color: $input-solid-bg;
+ border-color: $input-solid-bg;
+
+ & + .form-control {
+ border-left-color: $input-border-color;
+ }
+ }
+
+ .form-control {
+ background-color: $input-solid-bg;
+ border-color: $input-solid-bg;
+
+ & + .input-group-text {
+ border-left-color: $input-border-color;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/forms/_labels.scss b/Moonlight/Styles/components/forms/_labels.scss
new file mode 100644
index 00000000..3043cda2
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_labels.scss
@@ -0,0 +1,8 @@
+
+//
+// Col form label
+//
+
+.col-form-label {
+ @include font-size($form-label-font-size);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/forms/_required.scss b/Moonlight/Styles/components/forms/_required.scss
new file mode 100644
index 00000000..f170ebca
--- /dev/null
+++ b/Moonlight/Styles/components/forms/_required.scss
@@ -0,0 +1,14 @@
+//
+// Required Label
+//
+
+.required {
+ &:after {
+ content: "*";
+ position: relative;
+ font-size: inherit;
+ color: var(--#{$prefix}danger);
+ padding-left: 0.25rem;
+ font-weight: $font-weight-bold;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/helpers/_background.scss b/Moonlight/Styles/components/helpers/_background.scss
new file mode 100644
index 00000000..17624239
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_background.scss
@@ -0,0 +1,241 @@
+//
+// Custom background helpers
+//
+
+// Background white color
+.bg-white {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}white-bg-rgb);
+ background-color: $white !important;
+}
+
+// Background black color
+.bg-black {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}black-bg-rgb);
+ background-color: $black !important;
+}
+
+// Background body color
+.bg-body {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}body-bg-rgb);
+ background-color: var(--#{$prefix}body-bg) !important;
+}
+
+.bg-hover-body {
+ cursor: pointer;
+
+ &:hover {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+}
+
+.bg-active-body {
+ &.active {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+}
+
+.bg-state-body {
+ cursor: pointer;
+
+ &.active,
+ &:hover {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+}
+
+.bg-hover-white {
+ cursor: pointer;
+
+ &:hover {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}white-bg-rgb);
+ background-color: $white !important;
+ }
+}
+
+.bg-active-white {
+ &.active {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}white-bg-rgb);
+ background-color: $white !important;
+ }
+}
+
+.bg-state-white {
+ cursor: pointer;
+
+ &.active,
+ &:hover {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}white-bg-rgb);
+ background-color: $white !important;
+ }
+}
+
+// Background theme light colors
+@each $name, $value in $theme-colors {
+ @if (theme-light-color($name)) {
+ .bg-light-#{$name} {
+ background-color: var(--#{$prefix}#{$name}-light) !important;
+ }
+ }
+
+ .bg-#{$name} {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}#{$name}-rgb);
+ background-color: var(--#{$prefix}#{$name}) !important;
+ }
+
+ .bg-#{$name}-active {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}#{$name}-active-rgb);
+ background-color: var(--#{$prefix}#{$name}-active) !important;
+ }
+
+ @if (theme-light-color($name)) {
+ .bg-hover-light-#{$name} {
+ cursor: pointer;
+
+ &:hover {
+ background-color: var(--#{$prefix}#{$name}-light) !important;
+ }
+ }
+
+ .bg-state-light-#{$name} {
+ cursor: pointer;
+
+ &.active,
+ &:hover {
+ background-color: var(--#{$prefix}#{$name}-light) !important;
+ }
+ }
+ }
+
+ .bg-hover-#{$name} {
+ cursor: pointer;
+
+ &:hover {
+ background-color: var(--#{$prefix}#{$name}) !important;
+ }
+ }
+
+ .bg-active-#{$name} {
+ &.active {
+ background-color: var(--#{$prefix}#{$name}) !important;
+ }
+ }
+
+ .bg-state-#{$name} {
+ cursor: pointer;
+
+ &.active,
+ &:hover {
+ background-color: var(--#{$prefix}#{$name}) !important;
+ }
+ }
+}
+
+// Background gray colors
+@each $name, $value in $grays {
+ .bg-gray-#{$name} {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}gray-#{$name}-rgb);
+ background-color: var(--#{$prefix}gray-#{$name});
+ }
+
+ .bg-gray-#{$name}i {
+ --#{$prefix}bg-rgb-color: var(--#{$prefix}gray-#{$name}-rgb);
+ background-color: var(--#{$prefix}gray-#{$name}) !important;
+ }
+}
+
+// Opacity
+@each $name, $value in $opacity-values {
+ .bg-opacity-#{$name} {
+ background-color: rgba(var(--#{$prefix}bg-rgb-color), #{$value}) !important;
+ }
+
+ .bg-hover-opacity-#{$name}:hover {
+ background-color: rgba(var(--#{$prefix}bg-rgb-color), #{$value}) !important;
+ }
+
+ .bg-active-opacity-#{$name}.active {
+ background-color: rgba(var(--#{$prefix}bg-rgb-color), #{$value}) !important;
+ }
+
+ .bg-state-opacity-#{$name} {
+ .active,
+ &:hover {
+ background-color: rgba(var(--#{$prefix}bg-rgb-color), #{$value}) !important;
+ }
+ }
+}
+
+// Background image helpers
+// Background repeat
+.bgi-no-repeat {
+ background-repeat: no-repeat;
+}
+
+// Background positions
+.bgi-position-y-top {
+ background-position-y: top;
+}
+
+.bgi-position-y-bottom {
+ background-position-y: bottom;
+}
+
+.bgi-position-y-center {
+ background-position-y: center;
+}
+
+.bgi-position-x-start {
+ background-position-x: left;
+}
+
+.bgi-position-x-end {
+ background-position-x: right;
+}
+
+.bgi-position-x-center {
+ background-position-x: center;
+}
+
+.bgi-position-top {
+ background-position: 0 top;
+}
+
+.bgi-position-bottom {
+ background-position: 0 bottom;
+}
+
+.bgi-position-center {
+ background-position: center;
+}
+
+// Responsive helpers
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ // Background sizes
+ .bgi-size#{$infix}-auto {
+ background-size: auto;
+ }
+
+ .bgi-size#{$infix}-cover {
+ background-size: cover;
+ }
+
+ .bgi-size#{$infix}-contain {
+ background-size: contain;
+ }
+
+ // Background attachment
+ .bgi-attachment#{$infix}-fixed {
+ background-attachment: fixed;
+ }
+
+ .bgi-attachment#{$infix}-scroll {
+ background-attachment: scroll;
+ }
+ }
+}
+
+
+
diff --git a/Moonlight/Styles/components/helpers/_borders.scss b/Moonlight/Styles/components/helpers/_borders.scss
new file mode 100644
index 00000000..21e7dbe1
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_borders.scss
@@ -0,0 +1,114 @@
+//
+// Border
+//
+
+.border-active:not(.active):not(:active):not(:hover):not(:focus) {
+ border-color: transparent !important;
+}
+
+.border-hover:not(:hover):not(:focus):not(.active):not(:active) {
+ cursor: pointer;
+ border-color: transparent !important;
+}
+
+// Gray border colors
+@each $name, $value in $grays {
+ // Initial
+ .border-gray-#{$name} {
+ border-color: var(--#{$prefix}gray-#{$name}) !important;
+ }
+}
+
+// Hover border colors
+@each $name, $value in $theme-colors {
+ .border-hover-#{$name}:hover {
+ border-color: var(--#{$prefix}#{$name}) !important;
+ }
+
+ .border-active-#{$name}.active {
+ border-color: var(--#{$prefix}#{$name}) !important;
+ }
+}
+
+// Hover transparent
+.border-hover-transparent:hover {
+ border-color: transparent !important;
+}
+
+// Dashed style
+.border-dashed {
+ border-style: dashed !important;
+ border-color: var(--#{$prefix}border-dashed-color);
+}
+
+.border-top-dashed {
+ border-top-style: dashed !important;
+}
+
+.border-bottom-dashed {
+ border-bottom-style: dashed !important;
+}
+
+.border-start-dashed {
+ border-left-style: dashed !important;
+}
+
+.border-end-dashed {
+ border-right-style: dashed !important;
+}
+
+// Dotted style
+.border-dotted {
+ border-style: dotted !important;
+}
+
+.border-top-dotted {
+ border-top-style: dotted !important;
+}
+
+.border-bottom-dotted {
+ border-bottom-style: dotted !important;
+}
+
+.border-start-dotted {
+ border-left-style: dotted !important;
+}
+
+.border-end-dotted {
+ border-right-style: dotted !important;
+}
+
+// Border transparent
+.border-transparent {
+ border-color: transparent !important;
+}
+
+// Border body
+.border-body {
+ border-color: var(--#{$prefix}body-bg) !important;
+}
+
+// Border radiuses
+.rounded-top-0 {
+ border-top-left-radius: 0 !important;
+ border-top-right-radius: 0 !important;
+}
+
+.rounded-bottom-0 {
+ border-bottom-left-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+}
+
+.rounded-start-0 {
+ border-top-left-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
+}
+
+.rounded-end-0 {
+ border-top-right-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+}
+
+.rounded-circle {
+ border-radius: 50% !important;
+}
diff --git a/Moonlight/Styles/components/helpers/_flex.scss b/Moonlight/Styles/components/helpers/_flex.scss
new file mode 100644
index 00000000..87faaf9a
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_flex.scss
@@ -0,0 +1,57 @@
+//
+// Flex Utilities
+//
+
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .flex#{$infix}-root {
+ flex: 1;
+ }
+
+ .flex#{$infix}-column-auto {
+ flex: none;
+ }
+
+ .flex#{$infix}-column-fluid {
+ flex: 1 0 auto;
+ }
+
+ .flex#{$infix}-row-auto {
+ flex: 0 0 auto;
+ }
+
+ .flex#{$infix}-row-fluid {
+ flex: 1 auto;
+ min-width: 0;
+ }
+
+ .flex#{$infix}-center {
+ justify-content: center;
+ align-items: center;
+ }
+
+ .flex#{$infix}-start {
+ justify-content: start;
+ align-items: start;
+ }
+
+ .flex#{$infix}-end {
+ justify-content: flex-end;
+ align-items: flex-end;
+ }
+
+ .flex#{$infix}-stack {
+ justify-content: space-between;
+ align-items: center;
+ }
+ }
+}
+
+.flex-equal {
+ flex-grow: 1;
+ flex-basis: 0;
+ flex-shrink: 0;
+}
diff --git a/Moonlight/Styles/components/helpers/_opacity.scss b/Moonlight/Styles/components/helpers/_opacity.scss
new file mode 100644
index 00000000..80e26c8a
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_opacity.scss
@@ -0,0 +1,18 @@
+//
+// Opacity
+//
+
+@each $name, $value in $opacity-values {
+ // Active state
+ .opacity-active-#{$name}.active {
+ opacity: #{$value} !important;
+ }
+
+ // Active and hover states
+ .opacity-state-#{$name} {
+ &:hover,
+ &.active {
+ opacity: #{$value} !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/helpers/_shadow.scss b/Moonlight/Styles/components/helpers/_shadow.scss
new file mode 100644
index 00000000..74618af2
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_shadow.scss
@@ -0,0 +1,19 @@
+//
+// Shadow
+//
+
+.shadow-xs {
+ box-shadow: var(--#{$prefix}box-shadow-xs);
+}
+
+.shadow-sm {
+ box-shadow: var(--#{$prefix}box-shadow-sm);
+}
+
+.shadow {
+ box-shadow: var(--#{$prefix}box-shadow);
+}
+
+.shadow-lg {
+ box-shadow: var(--#{$prefix}box-shadow-lg);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/helpers/_text.scss b/Moonlight/Styles/components/helpers/_text.scss
new file mode 100644
index 00000000..8e77cdee
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_text.scss
@@ -0,0 +1,146 @@
+//
+// Text
+//
+
+// Text colors
+@each $name, $color in $theme-text-colors {
+ // Base color
+ .text-#{$name} {
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+
+ // Inverse color
+ @if (theme-inverse-color($name)) {
+ .text-inverse-#{$name} {
+ color: var(--#{$prefix}#{$name}-inverse) !important;
+ }
+ }
+
+ @if (theme-light-color($name)) {
+ // Light colors
+ .text-light-#{$name} {
+ color: var(--#{$prefix}#{$name}-light) !important;
+ }
+ }
+
+ // Hover
+ .text-hover-#{$name} {
+ transition: $transition-link;
+
+ i {
+ transition: $transition-link;
+ }
+
+ &:hover {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+
+ i {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+
+ .svg-icon {
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+ }
+ }
+
+ // Active
+ .text-active-#{$name} {
+ transition: $transition-link;
+
+ i {
+ transition: $transition-link;
+ }
+
+ &.active {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+
+ i {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+
+ .svg-icon {
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+ }
+ }
+}
+
+// Parent hover
+.parent-hover {
+ @each $name, $color in $theme-text-colors {
+ .parent-hover-#{$name} {
+ transition: $transition-link;
+ }
+
+ &:hover {
+ .parent-hover-#{$name} {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+ }
+ }
+}
+
+// Parent active
+.parent-active {
+ @each $name, $color in $theme-text-colors {
+ .parent-active-#{$name} {
+ transition: $transition-link;
+ }
+
+ &.active {
+ .parent-active-#{$name} {
+ transition: $transition-link;
+ color: var(--#{$prefix}text-#{$name}) !important;
+ }
+ }
+ }
+}
+
+// Text transparent
+.text-transparent {
+ color: transparent;
+}
+
+// Cursor pointer
+.cursor-pointer {
+ cursor: pointer;
+}
+
+// Cursor default
+.cursor-default {
+ cursor: default;
+}
+// Cursor move
+.cursor-move {
+ cursor: move;
+}
+
+// Icons
+i {
+ &.bi,
+ &[class^="fonticon-"],
+ &[class*=" fonticon-"],
+ &[class^="fa-"],
+ &[class*=" fa-"],
+ &[class^="la-"],
+ &[class*=" la-"] {
+ line-height: 1;
+ font-size: 1rem;
+ color: var(--#{$prefix}text-muted);
+ }
+}
+
+// Link transition
+a {
+ transition: $transition-link;
+
+ &:hover {
+ transition:$transition-link;
+ }
+}
diff --git a/Moonlight/Styles/components/helpers/_transform.scss b/Moonlight/Styles/components/helpers/_transform.scss
new file mode 100644
index 00000000..0c8616ff
--- /dev/null
+++ b/Moonlight/Styles/components/helpers/_transform.scss
@@ -0,0 +1,8 @@
+//
+// Transform
+//
+
+.transform-90 {
+ transform: rotate(90deg);
+ transform-origin: right top;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/menu/_base.scss b/Moonlight/Styles/components/menu/_base.scss
new file mode 100644
index 00000000..bdbb3750
--- /dev/null
+++ b/Moonlight/Styles/components/menu/_base.scss
@@ -0,0 +1,307 @@
+//
+// Menu Base
+//
+
+// Menu group
+.menu-group {
+ display: flex;
+}
+
+// Menu & wrapper
+.menu,
+.menu-wrapper {
+ display: flex;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+// Sub inner
+.menu-inner {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+// Sub menu
+.menu-sub {
+ display: none;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ flex-direction: column;
+}
+
+// Menu item
+.menu-item {
+ display: block;
+ padding: $menu-item-padding-y $menu-item-padding-x;
+
+ // Menu Link
+ .menu-link {
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ padding: 0;
+ flex: 0 0 100%;
+ padding: $menu-link-padding-y $menu-link-padding-x;
+ transition: none;
+ outline: none !important;
+
+ .menu-icon {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: $menu-icon-size;
+ margin-right: $menu-icon-space;
+
+ i,
+ .svg-icon {
+ line-height: 1;
+ }
+ }
+
+ .menu-bullet {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: $menu-bullet-size;
+ margin-right: $menu-bullet-space;
+ }
+
+ .menu-title {
+ display: flex;
+ align-items: center;
+ flex-grow: 1;
+ }
+
+ .menu-badge {
+ display: flex;
+ align-items: center;
+ flex-shrink: 0;
+ margin-left: $menu-badge-space;
+ }
+
+ .menu-arrow {
+ display: flex;
+ align-items: stretch;
+ position: relative;
+ overflow: hidden;
+ flex-shrink: 0;
+ margin-left: $menu-arrow-space;
+ width: $menu-arrow-size;
+ height: $menu-arrow-size;
+
+ &:after {
+ display: block;
+ width: 100%;
+ content: " ";
+ will-change: transform;
+ background-size: 100% 100%;
+ @include svg-bg-icon(arrow-start, var(--#{$prefix}text-muted));
+ /*rtl:begin:remove*/
+ @include svg-bg-icon(arrow-end, var(--#{$prefix}text-muted));
+ /*rtl:end:remove*/
+ }
+ }
+ }
+
+ // Menu Content
+ .menu-content {
+ padding: $menu-link-padding-y $menu-link-padding-x;
+ }
+}
+
+// Accordion arrows
+.menu-item {
+ &.show {
+ .menu-link {
+ .menu-arrow:after {
+ backface-visibility: hidden;
+ transition: $menu-accordion-arrow-transition;
+ }
+ }
+ }
+}
+
+// Center alignment
+.menu-center {
+ justify-content: center;
+}
+
+// Heading
+.menu-heading {
+ color: var(--#{$prefix}menu-heading-color);
+}
+
+// Responsive
+@each $direction in (up, down) {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @if $infix and $direction == down {
+ $infix: $infix + "-" + $direction;
+ }
+
+ @include media-breakpoint-direction($direction, $breakpoint) {
+ // Accordion arrow
+ .menu-item.menu#{$infix}-accordion {
+ .menu-arrow:after {
+ @include menu-link-arrow-rotate(90deg, -90deg);
+ }
+
+ &.showing:not(.menu-dropdown),
+ &.show:not(.hiding):not(.menu-dropdown) {
+ > .menu-link {
+ .menu-arrow:after {
+ @include menu-link-arrow-rotate(-90deg, 90deg);
+ }
+ }
+ }
+ }
+
+ // Sub dropdown
+ .menu-sub#{$infix}-dropdown {
+ display: none;
+ border-radius: $menu-dropdown-border-radius;
+ background-color: var(--#{$prefix}menu-dropdown-bg-color);
+ box-shadow: var(--#{$prefix}menu-dropdown-box-shadow);
+ z-index: $menu-dropdown-z-index;
+
+ // Dropdown show
+ .show.menu-dropdown > &,
+ &.menu.show,
+ &.show[data-popper-placement] {
+ display: flex;
+ will-change: transform;
+
+ // Animation
+ @if ($menu-dropdown-animation == true) {
+ // Move up
+ animation: menu-sub-dropdown-animation-fade-in #{$menu-dropdown-animation-speed} ease 1, menu-sub-dropdown-animation-move-up #{$menu-dropdown-animation-speed} ease 1;
+ }
+ }
+ }
+
+ // Sub accordion
+ .menu-sub#{$infix}-accordion {
+ display: none;
+
+ .show:not(.menu-dropdown) > &,
+ &.show {
+ display: flex;
+ }
+ }
+
+ // Sub indention
+ .menu-sub#{$infix}-indention {
+ @include menu-sub-indention($menu-accordion-indention);
+
+ // Active link
+ .menu-item .menu-item .menu-link.active {
+ margin-right: $menu-link-padding-x;
+ }
+ }
+
+ // Inline
+ .menu#{$infix}-inline {
+ display: flex;
+ }
+
+ // Reset link left & right paddings of level 1 menu links
+ .menu#{$infix}-fit {
+ > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+ }
+ }
+
+ .menu#{$infix}-column {
+ flex-direction: column;
+ width: 100%;
+ }
+
+ .menu#{$infix}-row {
+ flex-direction: row;
+
+ > .menu-item {
+ display: flex;
+ align-items: center;
+
+ > .menu-link {
+ .menu-arrow:after {
+ @include menu-link-arrow-rotate(90deg, -90deg);
+ }
+ }
+ }
+ }
+
+ // Border radiuses
+ .menu#{$infix}-rounded {
+ .menu-link {
+ @include border-radius($menu-link-border-radius);
+ }
+ }
+
+ // Border radiuses
+ .menu#{$infix}-pill {
+ .menu-link {
+ border-radius: 50px;
+ }
+ }
+
+ // Reset border radiuses
+ .menu#{$infix}-rounded-0 {
+ .menu-link {
+ border-radius: 0 !important;
+ }
+ }
+ }
+ }
+}
+
+// Link indention
+.menu-link-indention {
+ .menu-item {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ @include menu-link-indention($menu-accordion-indention, $menu-link-padding-x);
+}
+
+// Menu animations
+@keyframes menu-sub-dropdown-animation-fade-in {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes menu-sub-dropdown-animation-move-up {
+ from {
+ margin-top: #{$menu-dropdown-animation-move-offset};
+ }
+
+ to {
+ margin-top: 0;
+ }
+}
+
+@keyframes menu-sub-dropdown-animation-move-down {
+ from {
+ margin-bottom: #{$menu-dropdown-animation-move-offset};
+ }
+
+ to {
+ margin-bottom: 0;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/menu/_theme.scss b/Moonlight/Styles/components/menu/_theme.scss
new file mode 100644
index 00000000..6f700bf4
--- /dev/null
+++ b/Moonlight/Styles/components/menu/_theme.scss
@@ -0,0 +1,510 @@
+//
+// Menu Theme
+//
+
+// Theme text colors
+@each $name, $color in $theme-text-colors {
+ .menu-#{$name} {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-default-state( var(--#{$prefix}#{$name}), var(--#{$prefix}#{$name}), var(--#{$prefix}#{$name}), var(--#{$prefix}#{$name}), null );
+ }
+ }
+
+ .menu-title-#{$name} {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-default-state( var(--#{$prefix}text-#{$name}), null, null, null, null );
+ }
+ }
+
+ .menu-icon-#{$name} {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-default-state( null, var(--#{$prefix}text-#{$name}), null, null, null );
+ }
+ }
+
+ .menu-bullet-#{$name} {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-default-state( null, null, var(--#{$prefix}text-#{$name}), null, null );
+ }
+ }
+
+ .menu-arrow-#{$name} {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-default-state( null, null, null, var(--#{$prefix}text-#{$name}), null );
+ }
+ }
+}
+
+// Default background states
+.menu-hover-bg {
+ .menu-item {
+ @include menu-link-hover-state(
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-bg-color-hover)
+ );
+ }
+}
+
+.menu-here-bg {
+ .menu-item {
+ @include menu-link-here-state(
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-bg-color-here)
+ );
+ }
+}
+
+.menu-root-here-bg {
+ > .menu-item {
+ @include menu-link-here-state(
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-bg-color-here)
+ );
+ }
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .menu-root-here-bg-desktop {
+ > .menu-item {
+ @include menu-link-here-state(
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-bg-color-here)
+ );
+ }
+ }
+}
+
+.menu-show-bg {
+ .menu-item {
+ @include menu-link-show-state(
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-bg-color-show)
+ );
+ }
+}
+
+.menu-active-bg {
+ .menu-item {
+ @include menu-link-active-state(
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-bg-color-active)
+ );
+ }
+}
+
+.menu-state-bg {
+ .menu-item {
+ @include menu-link-hover-state(
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-bg-color-hover)
+ );
+
+ @include menu-link-here-state(
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-bg-color-here)
+ );
+
+ @include menu-link-show-state(
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-bg-color-show)
+ );
+
+ @include menu-link-active-state(
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-bg-color-active)
+ );
+ }
+}
+
+.menu-state-color {
+ .menu-item {
+ @include menu-link-hover-state(
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ var(--#{$prefix}menu-link-color-hover),
+ null
+ );
+
+ @include menu-link-here-state(
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ var(--#{$prefix}menu-link-color-here),
+ null
+ );
+
+ @include menu-link-show-state(
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ var(--#{$prefix}menu-link-color-show),
+ null
+ );
+
+ @include menu-link-active-state(
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ var(--#{$prefix}menu-link-color-active),
+ null
+ );
+ }
+}
+
+// Primary background states
+.menu-hover-bg-primary {
+ .menu-item {
+ @include menu-link-hover-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+ }
+}
+
+.menu-show-bg-primary {
+ .menu-item {
+ @include menu-link-show-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+ }
+}
+
+.menu-here-bg-primary {
+ .menu-item {
+ @include menu-link-here-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+ }
+}
+
+.menu-active-bg-primary {
+ .menu-item {
+ @include menu-link-active-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+ }
+}
+
+.menu-state-bg-primary {
+ .menu-item {
+ @include menu-link-hover-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+
+ @include menu-link-show-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+
+ @include menu-link-here-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+
+ @include menu-link-active-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+
+ @include menu-link-show-state(
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary-inverse),
+ var(--#{$prefix}primary)
+ );
+ }
+}
+
+// Light primary background states
+.menu-show-bg-light-primary {
+ .menu-item {
+ @include menu-link-show-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ }
+}
+
+.menu-here-bg-light-primary {
+ .menu-item {
+ @include menu-link-here-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ }
+}
+
+.menu-hover-bg-light-primary {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ }
+}
+
+.menu-active-bg-light-primary {
+ .menu-item {
+ @include menu-link-active-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ }
+}
+
+.menu-state-bg-light-primary {
+ .menu-item {
+ @include menu-link-show-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ @include menu-link-here-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ @include menu-link-hover-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ @include menu-link-active-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary-light) );
+ }
+}
+
+// Primary color states
+.menu-hover-primary {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-show-primary {
+ .menu-item {
+ @include menu-link-show-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-here-primary {
+ .menu-item {
+ @include menu-link-here-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-active-primary {
+ .menu-item {
+ @include menu-link-active-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-state-primary {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ @include menu-link-show-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ @include menu-link-here-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ @include menu-link-active-state( var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-state-dark {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), null );
+ @include menu-link-show-state( var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), null );
+ @include menu-link-here-state( var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), null );
+ @include menu-link-active-state( var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), var(--#{$prefix}dark), null );
+ }
+}
+
+// Primary title color states
+.menu-hover-title-primary {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}primary), null, null, null, null );
+ }
+}
+
+.menu-here-title-primary {
+ .menu-item {
+ @include menu-link-here-state( var(--#{$prefix}primary), null, null, null, null );
+ }
+}
+
+.menu-show-title-primary {
+ .menu-item {
+ @include menu-link-show-state( var(--#{$prefix}primary), null, null, null, null );
+ }
+}
+
+.menu-active-title-primary {
+ .menu-item {
+ @include menu-link-active-state( var(--#{$prefix}primary), null, null, null, null );
+ }
+}
+
+.menu-state-title-primary {
+ .menu-item {
+ @include menu-link-hover-state( var(--#{$prefix}primary), null, null, null, null );
+ @include menu-link-here-state( var(--#{$prefix}primary), null, null, null, null );
+ @include menu-link-show-state( var(--#{$prefix}primary), null, null, null, null );
+ @include menu-link-active-state( var(--#{$prefix}primary), null, null, null, null );
+ }
+}
+
+// Primary icon color states
+.menu-hover-icon-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, var(--#{$prefix}primary), null, null, null );
+ }
+}
+
+.menu-here-icon-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-here-state( null, var(--#{$prefix}primary), null, null, null );
+ }
+}
+
+.menu-show-icon-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-show-state( null, var(--#{$prefix}primary), null, null, null );
+ }
+}
+
+.menu-active-icon-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-active-state( null, var(--#{$prefix}primary), null, null, null );
+ }
+}
+
+.menu-state-icon-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, var(--#{$prefix}primary), null, null, null );
+ @include menu-link-here-state( null, var(--#{$prefix}primary), null, null, null );
+ @include menu-link-show-state( null, var(--#{$prefix}primary), null, null, null );
+ @include menu-link-active-state( null, var(--#{$prefix}primary), null, null, null );
+ }
+}
+
+// Primary bullet color states
+.menu-hover-bullet-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, null, var(--#{$prefix}primary), null, null );
+ }
+}
+
+.menu-show-bullet-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-show-state( null, null, var(--#{$prefix}primary), null, null );
+ }
+}
+
+.menu-here-bullet-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-here-state( null, null, var(--#{$prefix}primary), null, null );
+ }
+}
+
+.menu-active-bullet-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-active-state( null, null, var(--#{$prefix}primary), null, null );
+ }
+}
+
+.menu-state-bullet-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, null, var(--#{$prefix}primary), null, null );
+ @include menu-link-here-state( null, null, var(--#{$prefix}primary), null, null );
+ @include menu-link-show-state( null, null, var(--#{$prefix}primary), null, null );
+ @include menu-link-active-state( null, null, var(--#{$prefix}primary), null, null );
+ }
+}
+
+// Primary arrow color states
+.menu-hover-arrow-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, null, null, var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-here-arrow-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-here-state( null, null, null, var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-show-arrow-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-show-state( null, null, null, var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-active-arrow-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-active-state( null, null, null, var(--#{$prefix}primary), null );
+ }
+}
+
+.menu-state-arrow-primary {
+ .menu-item {
+ //$title-color, $icon-color, $bullet-color, $arrow-color, $bg-color
+ @include menu-link-hover-state( null, null, null, var(--#{$prefix}primary), null );
+ @include menu-link-here-state( null, null, null, var(--#{$prefix}primary), null );
+ @include menu-link-show-state( null, null, null, var(--#{$prefix}primary), null );
+ @include menu-link-active-state( null, null, null, var(--#{$prefix}primary), null );
+ }
+}
diff --git a/Moonlight/Styles/components/mixins/_buttons.scss b/Moonlight/Styles/components/mixins/_buttons.scss
new file mode 100644
index 00000000..fd8ee49c
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_buttons.scss
@@ -0,0 +1,84 @@
+//
+// Button Mixins
+//
+
+// Custom variant
+@mixin button-custom-variant(
+ $color,
+ $icon-color,
+ $border-color,
+ $bg-color,
+ $color-active,
+ $icon-color-active,
+ $border-color-active,
+ $bg-color-active
+) {
+
+ @if ( $color != null ) {
+ color: $color;
+ }
+
+ @if ( $icon-color != null ) {
+ i,
+ .svg-icon {
+ color: $icon-color;
+ }
+
+ &.dropdown-toggle:after {
+ color: $icon-color;
+ }
+ }
+
+ @if ( $border-color != null ) {
+ border-color: $border-color;
+ }
+
+ @if ( $bg-color != null ) {
+ background-color: $bg-color;
+ }
+
+ .btn-check:checked + &,
+ .btn-check:active + &,
+ &:focus:not(.btn-active),
+ &:hover:not(.btn-active),
+ &:active:not(.btn-active),
+ &.active,
+ &.show,
+ .show > & {
+ @if ( $color-active != null ) {
+ color: $color-active;
+ }
+
+ @if ( $icon-color-active != null ) {
+ i,
+ .svg-icon {
+ color: $icon-color-active;
+ }
+
+ &.dropdown-toggle:after {
+ color: $icon-color-active;
+ }
+ }
+
+ @if ( $border-color-active != null ) {
+ border-color: $border-color-active;
+ }
+
+ @if ( $bg-color-active != null ) {
+ background-color: $bg-color-active !important;
+ }
+ }
+}
+
+@mixin button-active-state() {
+ .btn-check:checked + &,
+ .btn-check:active + &,
+ &:focus:not(.btn-active),
+ &:hover:not(.btn-active),
+ &:active:not(.btn-active),
+ &.active,
+ &.show,
+ .show > & {
+ @content;
+ }
+}
diff --git a/Moonlight/Styles/components/mixins/_ki.scss b/Moonlight/Styles/components/mixins/_ki.scss
new file mode 100644
index 00000000..c83273ad
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_ki.scss
@@ -0,0 +1,18 @@
+//
+// Keenthemes Icons
+//
+
+@mixin ki($icon) {
+ font-family: Ki;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ line-height: 1;
+ text-decoration: inherit;
+ text-rendering: optimizeLegibility;
+ text-transform: none;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-smoothing: antialiased;
+ content: "#{$icon}";
+}
diff --git a/Moonlight/Styles/components/mixins/_menu.scss b/Moonlight/Styles/components/mixins/_menu.scss
new file mode 100644
index 00000000..f4076186
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_menu.scss
@@ -0,0 +1,301 @@
+//
+// Label
+//
+
+// Set arrow direction
+@mixin menu-link-arrow-rotate($angle, $angleRtl) {
+ /*rtl:ignore*/
+ transform: rotateZ($angleRtl);
+ /*rtl:remove*/
+ transform: rotateZ($angle);
+ transition: $menu-accordion-arrow-transition;
+}
+
+// Set menu link padding x
+@mixin menu-link-padding-x($value) {
+ // Menu item
+ .menu-item {
+ .menu-link,
+ .menu-content {
+ padding-left: $value;
+ padding-right: $value;
+ }
+ }
+}
+
+// Set menu link padding y
+@mixin menu-link-padding-y($value) {
+ // Menu item
+ .menu-item {
+ .menu-link,
+ .menu-content {
+ padding-top: $value;
+ padding-bottom: $value;
+ }
+ }
+}
+
+// Set link indention
+@mixin menu-link-indention($value, $offset) {
+ .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{1 * $value} + #{$offset});
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{2 * $value} + #{$offset});
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{3 * $value} + #{$offset});
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{4 * $value} + #{$offset});
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ &.menu-fit {
+ .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: #{$value};
+ padding-right: 0;
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{2 * $value});
+ padding-right: 0;
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{3 * $value});
+ padding-right: 0;
+ }
+
+ > .menu-sub:not([data-popper-placement]) {
+ > .menu-item,
+ > .menu-inner > .menu-item {
+ > .menu-content,
+ > .menu-link {
+ padding-left: calc(#{4 * $value});
+ padding-right: 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Set sub indention
+@mixin menu-sub-indention($value) {
+ .menu-sub:not([data-popper-placement]) {
+ margin-left: $value;
+ }
+}
+
+// Set menu link theme
+@mixin menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null) {
+ @if ( $bg-color != null ) {
+ background-color: $bg-color;
+ }
+
+ @if ( $title-color != null ) {
+ color: $title-color;
+
+ .menu-title {
+ color: $title-color;
+ }
+ }
+
+ @if ( $icon-color != null ) {
+ .menu-icon {
+ &,
+ .svg-icon,
+ i {
+ color: $icon-color;
+ }
+ }
+ }
+
+ @if ( $bullet-color != null ) {
+ .menu-bullet {
+ .bullet {
+ background-color: $bullet-color;
+ }
+ }
+ }
+
+ @if ( $arrow-color != null ) {
+ // Arrow
+ .menu-arrow:after {
+ @include svg-bg-icon(arrow-start, $arrow-color);
+ /*rtl:begin:remove*/
+ @include svg-bg-icon(arrow-end, $arrow-color);
+ /*rtl:end:remove*/
+ }
+ }
+}
+
+// Set menu link default state
+@mixin menu-link-default-state($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null, $all-links: true) {
+ $sel: '';
+
+ @if ($all-links == false) {
+ $sel: '& > ';
+ }
+
+ #{$sel}.menu-link {
+ @include menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color);
+ }
+}
+
+// Set menu link hover state
+@mixin menu-link-hover-state($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null, $all-links: true) {
+ $sel: '&:not(.here) ';
+
+ @if ($all-links == false) {
+ $sel: '&:not(.here) > ';
+ }
+
+ &.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here),
+ #{$sel}.menu-link:hover:not(.disabled):not(.active):not(.here) {
+ transition: $transition-link;
+
+ @include menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color);
+ }
+}
+
+// Set menu link active state
+@mixin menu-link-active-state($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null, $all-links: true) {
+ $sel: '';
+
+ @if ($all-links == false) {
+ $sel: '& > ';
+ }
+
+ #{$sel}.menu-link.active {
+ transition: $transition-link;
+
+ @include menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color);
+ }
+}
+
+// Set menu link show state
+@mixin menu-link-show-state($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null, $all-links: true) {
+ //&.here > .menu-link,
+ &.show > .menu-link {
+ transition: $transition-link;
+
+ @include menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color);
+ }
+}
+
+// Set menu link here state
+@mixin menu-link-here-state($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color: null, $all-links: true) {
+ &.here > .menu-link {
+ transition: $transition-link;
+
+ @include menu-link-theme($title-color, $icon-color, $bullet-color, $arrow-color, $bg-color);
+ }
+}
+
+// Set menu link default
+@mixin menu-link-default($all-links: true) {
+ $sel: '';
+
+ @if ($all-links == false) {
+ $sel: '& > ';
+ }
+
+ #{$sel}.menu-link {
+ @content;
+ }
+}
+
+// Set menu link hover
+@mixin menu-link-hover($all-links: true) {
+ $sel: '&:not(.here) ';
+
+ @if ($all-links == false) {
+ $sel: '&:not(.here) > ';
+ }
+
+ &.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here),
+ #{$sel}.menu-link:hover:not(.disabled):not(.active):not(.here) {
+ transition: $transition-link;
+
+ @content;
+ }
+}
+
+// Set menu link active
+@mixin menu-link-active($all-links: true) {
+ $sel: '';
+
+ @if ($all-links == false) {
+ $sel: '& > ';
+ }
+
+ #{$sel}.menu-link.active {
+ transition: $transition-link;
+
+ @content;
+ }
+}
+
+// Set menu link show
+@mixin menu-link-show($all-links: true) {
+ //&.here > .menu-link,
+ &.show > .menu-link {
+ transition: $transition-link;
+
+ @content;
+ }
+}
+
+// Set menu link here
+@mixin menu-link-here($all-links: true) {
+ &.here > .menu-link {
+ transition: $transition-link;
+
+ @content;
+ }
+}
diff --git a/Moonlight/Styles/components/mixins/_scroll.scss b/Moonlight/Styles/components/mixins/_scroll.scss
new file mode 100644
index 00000000..e1bd6f73
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_scroll.scss
@@ -0,0 +1,34 @@
+//
+// Scroll mixins
+//
+
+@mixin scrollbar-color($color, $hover-color: null) {
+ // Firefox
+ scrollbar-color: $color transparent;
+
+ // Webkit
+ &::-webkit-scrollbar-thumb {
+ background-color: $color;
+ }
+
+ &::-webkit-scrollbar-corner {
+ background-color: transparent;
+ }
+
+ @if ($hover-color != null) {
+ // Hover state
+ &:hover {
+ // Firefox
+ scrollbar-color: $hover-color transparent;
+
+ // Webkit
+ &::-webkit-scrollbar-thumb {
+ background-color: $hover-color;
+ }
+
+ &::-webkit-scrollbar-corner {
+ background-color: transparent;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/mixins/_shape.scss b/Moonlight/Styles/components/mixins/_shape.scss
new file mode 100644
index 00000000..3395df05
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_shape.scss
@@ -0,0 +1,29 @@
+
+@use 'sass:math';
+
+@mixin shape($edges-number: 6, $main-radius: 30%, $rounding-radius: 10%, $rotated: true, $precision: 20) {
+ $central-angle: divide(360deg, $edges-number);
+ $angle: ($edges-number - 2) * divide(180deg, $edges-number);
+ $max-var-angle: 2 * (90deg - divide($angle, 2));
+ $precision: 6;
+ $unit-var-angle: divide($max-var-angle, $precision);
+ $r-diff: $main-radius + $rounding-radius;
+
+ $points: ();
+
+ @for $i from 0 to $edges-number {
+ $vertex-angle: $i * $central-angle + if($rotated, -90deg, 0deg);
+ $vertex-x: 50% + $r-diff * math.cos($vertex-angle);
+ $vertex-y: 50% + $r-diff * math.sin($vertex-angle);
+
+ @for $j from 0 through $precision {
+ $curr-angle: $vertex-angle + ($j - 0.5 * $precision) * $unit-var-angle;
+ $x: $vertex-x + $rounding-radius * math.cos($curr-angle);
+ $y: $vertex-y + $rounding-radius * math.sin($curr-angle);
+
+ $points: $points, $x $y;
+ }
+ }
+
+ clip-path: polygon($points);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/mixins/_svg-bg-icon.scss b/Moonlight/Styles/components/mixins/_svg-bg-icon.scss
new file mode 100644
index 00000000..48ee125a
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_svg-bg-icon.scss
@@ -0,0 +1,68 @@
+//
+// SVG Bg Icons
+//
+
+@mixin svg-bg-icon($type, $color: none, $update: false) {
+ $bg-image: '';
+
+ // Icon type;
+ @if ($type == close) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == check) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == arrow-top) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == arrow-bottom) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == arrow-start) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == arrow-end) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == sort) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == sort-asc) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == sort-desc) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == expand) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ @if ($type == collapse) {
+ $bg-image: url("data:image/svg+xml, ");
+ }
+
+ // Icon style
+ @if $update == false {
+ mask-repeat: no-repeat;
+ mask-position: center;
+ -webkit-mask-repeat: no-repeat;
+ -webkit-mask-position: center;
+ }
+
+ @if $color != none {
+ background-color: $color;
+ }
+
+ -webkit-mask-image: escape-svg($bg-image);
+ mask-image: escape-svg($bg-image);
+}
+
diff --git a/Moonlight/Styles/components/mixins/_svg-icon.scss b/Moonlight/Styles/components/mixins/_svg-icon.scss
new file mode 100644
index 00000000..35da08cf
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_svg-icon.scss
@@ -0,0 +1,11 @@
+//
+// SVG Icon
+//
+
+
+@mixin svg-icon-size($size, $important: false) {
+ svg {
+ height: $size valueif($important, !important, null);
+ width: $size valueif($important, !important, null);
+ }
+}
diff --git a/Moonlight/Styles/components/mixins/_symbol.scss b/Moonlight/Styles/components/mixins/_symbol.scss
new file mode 100644
index 00000000..904f3948
--- /dev/null
+++ b/Moonlight/Styles/components/mixins/_symbol.scss
@@ -0,0 +1,42 @@
+//
+// Symbol
+//
+
+@mixin symbol-size($size) {
+ > img {
+ width: $size;
+ height: $size;
+ }
+
+ .symbol-label {
+ width: $size;
+ height: $size;
+ }
+
+ &.symbol-fixed {
+ .symbol-label {
+ width: $size;
+ height: $size;
+ }
+
+ > img {
+ width: $size;
+ height: $size;
+ max-width: none;
+ }
+ }
+
+ // Ratios
+ &.symbol-2by3 {
+ .symbol-label {
+ height: $size;
+ width: $size * divide(3, 2);
+ }
+
+ > img {
+ height: $size;
+ width: $size * divide(3, 2);
+ max-width: none;
+ }
+ }
+}
diff --git a/Moonlight/Styles/components/stepper/_base.scss b/Moonlight/Styles/components/stepper/_base.scss
new file mode 100644
index 00000000..9e23710a
--- /dev/null
+++ b/Moonlight/Styles/components/stepper/_base.scss
@@ -0,0 +1,102 @@
+//
+// Stepper
+//
+
+// Base
+.stepper {
+ // Content
+ [data-kt-stepper-element="info"],
+ [data-kt-stepper-element="content"] {
+ display: none;
+
+ &.current {
+ display: flex;
+ }
+ }
+
+ // Enable cursor pointer on clickable steppers
+ .stepper-item[data-kt-stepper-action="step"] {
+ cursor: pointer;
+ }
+
+ // States
+ & {
+ [data-kt-stepper-action="final"] {
+ display: none;
+ }
+
+ [data-kt-stepper-action="previous"] {
+ display: none;
+ }
+
+ [data-kt-stepper-action="next"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="submit"] {
+ display: none;
+ }
+ }
+
+ &.first {
+ [data-kt-stepper-action="previous"] {
+ display: none;
+ }
+
+ [data-kt-stepper-action="next"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="submit"] {
+ display: none;
+ }
+ }
+
+ &.between {
+ [data-kt-stepper-action="previous"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="next"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="submit"] {
+ display: none;
+ }
+ }
+
+ &.last {
+ [data-kt-stepper-action="final"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="final"].btn-flex {
+ display: flex;
+ }
+
+ [data-kt-stepper-action="previous"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="previous"].btn-flex {
+ display: flex;
+ }
+
+ [data-kt-stepper-action="next"] {
+ display: none;
+ }
+
+ [data-kt-stepper-action="next"].btn-flex {
+ display: flex;
+ }
+
+ [data-kt-stepper-action="submit"] {
+ display: inline-block;
+ }
+
+ [data-kt-stepper-action="submit"].btn-flex {
+ display: flex;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/stepper/_links.scss b/Moonlight/Styles/components/stepper/_links.scss
new file mode 100644
index 00000000..0d8aba41
--- /dev/null
+++ b/Moonlight/Styles/components/stepper/_links.scss
@@ -0,0 +1,57 @@
+//
+// Stepper Links
+//
+
+// Base
+.stepper.stepper-links {
+ .stepper-nav {
+ display: flex;
+ margin: 0 auto;
+ justify-content: center;
+ align-items: center;
+ flex-wrap: wrap;
+
+ .stepper-item {
+ position: relative;
+ flex-shrink: 0;
+ margin: 1rem 1.5rem;
+
+ &:after {
+ content: " ";
+ position: absolute;
+ top: 2.3rem;
+ left: 0;
+ height: 2px;
+ width: 100%;
+ background-color: transparent;
+ transition: $transition-link;
+ }
+
+ .stepper-title {
+ color: var(--#{$prefix}dark);
+ font-weight: 600;
+ font-size: 1.25rem;
+ }
+
+ // Current
+ &.current {
+ transition: $transition-link;
+
+ .stepper-title {
+ color: var(--#{$prefix}primary);
+ }
+
+ &:after {
+ background-color: var(--#{$prefix}primary);
+ }
+ }
+
+ &.current.mark-completed:last-child,
+ &.completed {
+ .stepper-title {
+ color: var(--#{$prefix}gray-400);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/components/stepper/_multistep.scss b/Moonlight/Styles/components/stepper/_multistep.scss
new file mode 100644
index 00000000..0fa5ebaf
--- /dev/null
+++ b/Moonlight/Styles/components/stepper/_multistep.scss
@@ -0,0 +1,42 @@
+//
+// Multistep stepper
+//
+
+// Custom
+.stepper.stepper-pills.stepper-multistep {
+ --#{$prefix}stepper-pills-size: 46px;
+ --#{$prefix}stepper-icon-border-radius: 9px;
+ --#{$prefix}stepper-icon-check-size: 1.25rem;
+
+ --#{$prefix}stepper-icon-bg-color: rgba(255, 255, 255, 0.03);
+ --#{$prefix}stepper-icon-bg-color-current: var(--#{$prefix}success);
+ --#{$prefix}stepper-icon-bg-color-completed: rgba(255, 255, 255, 0.03);
+
+ --#{$prefix}stepper-icon-border: 1px dashed rgba(255, 255, 255, 0.3);
+ --#{$prefix}stepper-icon-border-current: 0;
+ --#{$prefix}stepper-icon-border-completed: 1px dashed rgba(255, 255, 255, 0.3);
+
+ --#{$prefix}stepper-icon-number-color: var(--#{$prefix}white);
+ --#{$prefix}stepper-icon-number-color-current: var(--#{$prefix}white);
+ --#{$prefix}stepper-icon-number-color-completed: var(--#{$prefix}white);
+
+ --#{$prefix}stepper-icon-check-color-completed: var(--#{$prefix}success);
+
+ --#{$prefix}stepper-label-title-opacity: 0.7;
+ --#{$prefix}stepper-label-title-opacity-current: 1;
+ --#{$prefix}stepper-label-title-opacity-completed: 1;
+
+ --#{$prefix}stepper-label-title-color: var(--#{$prefix}white);
+ --#{$prefix}stepper-label-title-color-current: var(--#{$prefix}white);
+ --#{$prefix}stepper-label-title-color-completed: var(--#{$prefix}white);
+
+ --#{$prefix}stepper-label-desc-opacity: 0.7;
+ --#{$prefix}stepper-label-desc-opacity-current: 0.7;
+ --#{$prefix}stepper-label-desc-opacity-completed: 0.7;
+
+ --#{$prefix}stepper-label-desc-color: var(--#{$prefix}white);
+ --#{$prefix}stepper-label-desc-color-current: var(--#{$prefix}white);
+ --#{$prefix}stepper-label-desc-color-completed: var(--#{$prefix}white);
+
+ --#{$prefix}stepper-line-border: 1px dashed rgba(255, 255, 255, 0.3);
+}
diff --git a/Moonlight/Styles/components/stepper/_pills.scss b/Moonlight/Styles/components/stepper/_pills.scss
new file mode 100644
index 00000000..58537d00
--- /dev/null
+++ b/Moonlight/Styles/components/stepper/_pills.scss
@@ -0,0 +1,201 @@
+//
+// Stepper Pills
+//
+
+// Base
+.stepper.stepper-pills {
+ --#{$prefix}stepper-pills-size: 40px;
+ --#{$prefix}stepper-icon-border-radius: 9px;
+ --#{$prefix}stepper-icon-check-size: 1rem;
+
+ --#{$prefix}stepper-icon-bg-color: var(--#{$prefix}primary-light);
+ --#{$prefix}stepper-icon-bg-color-current: var(--#{$prefix}primary);
+ --#{$prefix}stepper-icon-bg-color-completed: var(--#{$prefix}primary-light);
+
+ --#{$prefix}stepper-icon-border: 0;
+ --#{$prefix}stepper-icon-border-current: 0;
+ --#{$prefix}stepper-icon-border-completed: 0;
+
+ --#{$prefix}stepper-icon-number-color: var(--#{$prefix}primary);
+ --#{$prefix}stepper-icon-number-color-current: var(--#{$prefix}white);
+
+ --#{$prefix}stepper-icon-check-color-completed: var(--#{$prefix}primary);
+
+ --#{$prefix}stepper-label-title-opacity: 1;
+ --#{$prefix}stepper-label-title-opacity-current: 1;
+ --#{$prefix}stepper-label-title-opacity-completed: 1;
+
+ --#{$prefix}stepper-label-title-color: var(--#{$prefix}gray-800);
+ --#{$prefix}stepper-label-title-color-current: var(--#{$prefix}gray-600);
+ --#{$prefix}stepper-label-title-color-completed: var(--#{$prefix}text-muted);
+
+ --#{$prefix}stepper-label-desc-opacity: 1;
+ --#{$prefix}stepper-label-desc-opacity-current: 1;
+ --#{$prefix}stepper-label-desc-opacity-completed: 1;
+
+ --#{$prefix}stepper-label-desc-color: var(--#{$prefix}text-muted);
+ --#{$prefix}stepper-label-desc-color-current: var(--#{$prefix}gray-400);
+ --#{$prefix}stepper-label-desc-color-completed: var(--#{$prefix}gray-400);
+
+ --#{$prefix}stepper-line-border: 1px dashed var(--#{$prefix}gray-300);
+
+ // Nav
+ .stepper-nav {
+ display: flex;
+ }
+
+ // Item
+ .stepper-item {
+ display: flex;
+ align-items: center;
+ transition: $transition-link;
+
+ // Icon
+ .stepper-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ transition: $transition-link;
+ width: var(--#{$prefix}stepper-pills-size);
+ height: var(--#{$prefix}stepper-pills-size);
+ border-radius: var(--#{$prefix}stepper-icon-border-radius);
+ background-color: var(--#{$prefix}stepper-icon-bg-color);
+ border: var(--#{$prefix}stepper-icon-border);
+ margin-right: 1.5rem;
+
+ .stepper-check {
+ display: none;
+ font-size: var(--#{$prefix}stepper-icon-check-size);
+ }
+
+ .stepper-number {
+ font-weight: $font-weight-bold;
+ color: var(--#{$prefix}stepper-icon-number-color);
+ font-size: 1.25rem;
+ }
+ }
+
+ // Label
+ .stepper-label {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ .stepper-title {
+ color: var(--#{$prefix}stepper-label-title-color);
+ opacity: var(--#{$prefix}stepper-label-title-opacity);
+ font-weight: 600;
+ font-size: 1.25rem;
+ margin-bottom: .3rem;
+ }
+
+ .stepper-desc {
+ opacity: var(--#{$prefix}stepper-label-desc-opacity);
+ color: var(--#{$prefix}stepper-label-desc-color);
+ }
+ }
+
+ // Current
+ &.current {
+ transition: $transition-link;
+
+ .stepper-icon {
+ transition: $transition-link;
+ background-color: var(--#{$prefix}stepper-icon-bg-color-current);
+ border: var(--#{$prefix}stepper-icon-border-current);
+
+ .stepper-check {
+ display: none;
+ }
+
+ .stepper-number {
+ color: var(--#{$prefix}stepper-icon-number-color-current);
+ font-size: 1.35rem;
+ }
+ }
+
+ .stepper-label {
+ .stepper-title {
+ opacity: var(--#{$prefix}stepper-label-title-opacity-current);
+ color: var(--#{$prefix}stepper-label-title-color-current);
+ }
+
+ .stepper-desc {
+ opacity: var(--#{$prefix}stepper-label-desc-opacity-current);
+ color: var(--#{$prefix}stepper-label-desc-color-current);
+ }
+ }
+ }
+
+ // Completed
+ &.current.mark-completed:last-child,
+ &.completed {
+ .stepper-icon {
+ transition: $transition-link;
+ background-color: var(--#{$prefix}stepper-icon-bg-color-completed);
+ border: var(--#{$prefix}stepper-icon-border-completed);
+
+ .stepper-check {
+ color: var(--#{$prefix}stepper-icon-check-color-completed);
+ display: inline-block;
+ }
+
+ .stepper-number {
+ display: none;
+ }
+ }
+
+ .stepper-label {
+ .stepper-title {
+ opacity: var(--#{$prefix}stepper-label-title-opacity-completed);
+ color: var(--#{$prefix}stepper-label-title-color-completed);
+ }
+
+ .stepper-desc {
+ opacity: var(--#{$prefix}stepper-label-desc-opacity-completed);
+ color: var(--#{$prefix}stepper-label-desc-color-completed);
+ }
+ }
+ }
+ }
+
+ // Column
+ &.stepper-column {
+ // Nav
+ .stepper-nav {
+ flex-direction: column;
+ align-items: start;
+ }
+
+ // Item
+ .stepper-item {
+ flex-direction: column;
+ justify-content: start;
+ align-items: stretch;
+ padding: 0;
+ margin: 0;
+ }
+
+ // Wrapper
+ .stepper-wrapper {
+ display: flex;
+ align-items: center;
+ }
+
+ // Icon
+ .stepper-icon {
+ z-index: 1;
+ }
+
+ // Line
+ .stepper-line {
+ display: block;
+ flex-grow: 1;
+ margin-left: calc(var(--#{$prefix}stepper-pills-size) / 2);
+ border-left: var(--#{$prefix}stepper-line-border);
+ margin-top: 2px;
+ margin-bottom: 2px;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/docs/_aside.scss b/Moonlight/Styles/docs/_aside.scss
new file mode 100644
index 00000000..7d413e47
--- /dev/null
+++ b/Moonlight/Styles/docs/_aside.scss
@@ -0,0 +1,54 @@
+//
+// Aside Default
+//
+
+// General mode(all devices)
+.docs-aside {
+ display: flex;
+ flex-direction: column;
+ box-shadow: var(--#{$prefix}docs-aside-box-shadow);
+ background-color: var(--#{$prefix}docs-aside-bg-color);
+ padding: 0;
+}
+
+.docs-aside-select-menu {
+ width: 218px;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .docs-aside {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $docs-aside-z-index;
+ overflow: hidden;
+ width: $docs-aside-width;
+
+ // Logo
+ .docs-aside-logo {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 $docs-aside-padding-x;
+ }
+
+ // Aside menu
+ .docs-aside-menu {
+ width: $docs-aside-width;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .docs-aside {
+ display: none;
+
+ // Logo
+ .docs-aside-logo {
+ display: none;
+ }
+ }
+}
diff --git a/Moonlight/Styles/docs/_content.scss b/Moonlight/Styles/docs/_content.scss
new file mode 100644
index 00000000..81922eeb
--- /dev/null
+++ b/Moonlight/Styles/docs/_content.scss
@@ -0,0 +1,8 @@
+//
+// Card
+//
+
+.card.card-docs {
+ background-color: var(--#{$prefix}body-bg);
+ border: 0;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/docs/_header.scss b/Moonlight/Styles/docs/_header.scss
new file mode 100644
index 00000000..175f6b81
--- /dev/null
+++ b/Moonlight/Styles/docs/_header.scss
@@ -0,0 +1,26 @@
+//
+// Header
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .docs-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .docs-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ // Page title
+ .docs-page-title[data-kt-swapper="true"]{
+ display: none !important;
+ }
+ }
+}
diff --git a/Moonlight/Styles/docs/_layout.scss b/Moonlight/Styles/docs/_layout.scss
new file mode 100644
index 00000000..841deab0
--- /dev/null
+++ b/Moonlight/Styles/docs/_layout.scss
@@ -0,0 +1,12 @@
+//
+// Layout Initialization
+//
+
+// Import Dependencies
+@import "root";
+@import "print";
+@import "main";
+@import "header";
+@import "aside";
+@import "menu";
+@import "content";
diff --git a/Moonlight/Styles/docs/_main.scss b/Moonlight/Styles/docs/_main.scss
new file mode 100644
index 00000000..f2af08f7
--- /dev/null
+++ b/Moonlight/Styles/docs/_main.scss
@@ -0,0 +1,32 @@
+//
+// Main
+//
+
+// Wrapper
+.docs-wrapper {
+ background-color: var(--#{$prefix}docs-page-bg-color);
+}
+
+// Desktop Mode
+@include media-breakpoint-up(lg) {
+ // Containers
+ .container,
+ .container-fluid {
+ padding: 0 $docs-content-spacing-desktop;
+ }
+
+ // Wrapper
+ .docs-wrapper {
+ padding-left: $docs-aside-width;
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Containers
+ .container,
+ .container-fluid {
+ max-width: none;
+ padding: 0 $docs-content-spacing-tablet-and-mobile;
+ }
+}
diff --git a/Moonlight/Styles/docs/_menu.scss b/Moonlight/Styles/docs/_menu.scss
new file mode 100644
index 00000000..abcc3b7a
--- /dev/null
+++ b/Moonlight/Styles/docs/_menu.scss
@@ -0,0 +1,31 @@
+//
+// Menu
+//
+
+// Aside menu
+.docs-aside-menu {
+ .menu {
+ // Link padding x
+ @include menu-link-padding-x($docs-aside-padding-x);
+
+ // Menu indention
+ @include menu-link-indention($docs-aside-menu-indention, $docs-aside-padding-x);
+ }
+
+ // Item
+ .menu-item {
+ padding: 0;
+
+ // Menu Link
+ .menu-link {
+ font-weight: 500;
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+ }
+
+ // Icon
+ .menu-icon {
+ justify-content: flex-start;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/docs/_print.scss b/Moonlight/Styles/docs/_print.scss
new file mode 100644
index 00000000..d014cde8
--- /dev/null
+++ b/Moonlight/Styles/docs/_print.scss
@@ -0,0 +1,30 @@
+//
+// Print Mode
+//
+
+// Add .print-content-only class to body element in order to allow printing only the content area
+@media print {
+ .print-content-only {
+ padding: 0 !important;
+ background: none !important;
+
+ .docs-wrapper,
+ .docs-page,
+ .docs-page-title
+ .docs-content,
+ .container,
+ .container-fluid {
+ background: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ .docs-aside,docs-
+ .scrolltop,
+ .docs-header,
+ .drawer,
+ .btn {
+ display: none !important;
+ }
+ }
+}
diff --git a/Moonlight/Styles/docs/_root.scss b/Moonlight/Styles/docs/_root.scss
new file mode 100644
index 00000000..3c775598
--- /dev/null
+++ b/Moonlight/Styles/docs/_root.scss
@@ -0,0 +1,23 @@
+//
+// Root
+//
+
+// Light mode
+@include color-mode(light) {
+ // Content
+ --#{$prefix}docs-page-bg-color: #{$docs-page-bg-color};
+
+ // Aside
+ --#{$prefix}docs-aside-bg-color: #{$docs-aside-bg-color};
+ --#{$prefix}docs-aside-box-shadow: #{$docs-aside-box-shadow};
+}
+
+// Dark mode
+@include color-mode(dark) {
+ // Content
+ --#{$prefix}docs-page-bg-color: #{$docs-page-bg-color-dark};
+
+ // Aside
+ --#{$prefix}docs-aside-bg-color: #{$docs-aside-bg-color-dark};
+ --#{$prefix}docs-aside-box-shadow: #{$docs-aside-box-shadow-dark};
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/docs/_variables.scss b/Moonlight/Styles/docs/_variables.scss
new file mode 100644
index 00000000..02924b95
--- /dev/null
+++ b/Moonlight/Styles/docs/_variables.scss
@@ -0,0 +1,21 @@
+//
+// Layout Config
+//
+
+// Content background Color
+$docs-page-bg-color: $gray-100;
+$docs-page-bg-color-dark: #151521;
+
+// Content Spacing
+$docs-content-spacing-desktop: 30px;
+$docs-content-spacing-tablet-and-mobile: 15px;
+
+// Aside
+$docs-aside-z-index: 101;
+$docs-aside-padding-x: 25px;
+$docs-aside-menu-indention: 0.75rem;
+$docs-aside-width: 265px;
+$docs-aside-bg-color: white;
+$docs-aside-bg-color-dark: #1e1e2d;
+$docs-aside-box-shadow: 0 0 28px 0 rgba(82,63,105,.025);
+$docs-aside-box-shadow-dark: none;
diff --git a/Moonlight/Styles/layout/_base.scss b/Moonlight/Styles/layout/_base.scss
new file mode 100644
index 00000000..a2d8e618
--- /dev/null
+++ b/Moonlight/Styles/layout/_base.scss
@@ -0,0 +1,50 @@
+//
+// Root
+//
+
+html {
+ font-family: sans-serif;
+ text-size-adjust: 100%;
+}
+
+html,
+body {
+ height: 100%;
+ margin: 0px;
+ padding: 0px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-size: $root-font-size !important;
+ font-weight: $font-weight-base;
+ font-family: $font-family-sans-serif;
+
+ // Tablet mode
+ @include media-breakpoint-down(lg) {
+ font-size: $root-font-size-lg !important;
+ }
+
+ // Mobile mode
+ @include media-breakpoint-down(md) {
+ font-size: $root-font-size-md !important;
+ }
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+
+ a:hover,
+ a:active,
+ a:focus {
+ text-decoration: none !important;
+ }
+}
+
+canvas {
+ user-select: none;
+}
+
+// Angular integration
+router-outlet {
+ display: none;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/_header.scss b/Moonlight/Styles/layout/_header.scss
new file mode 100644
index 00000000..3da3f1e2
--- /dev/null
+++ b/Moonlight/Styles/layout/_header.scss
@@ -0,0 +1,22 @@
+//
+// Header
+//
+
+// General
+
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .app-header {
+ .app-navbar {
+ border-bottom: var(--#{$prefix}app-separator-border);
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .app-header {
+ border-bottom: var(--#{$prefix}app-separator-border);
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/_layout.scss b/Moonlight/Styles/layout/_layout.scss
new file mode 100644
index 00000000..830fff63
--- /dev/null
+++ b/Moonlight/Styles/layout/_layout.scss
@@ -0,0 +1,9 @@
+//
+// Layout
+//
+
+@import "root";
+@import "header";
+@import "sidebar";
+@import "sidebar-minimize";
+@import "page-title";
diff --git a/Moonlight/Styles/layout/_page-title.scss b/Moonlight/Styles/layout/_page-title.scss
new file mode 100644
index 00000000..d5094654
--- /dev/null
+++ b/Moonlight/Styles/layout/_page-title.scss
@@ -0,0 +1,22 @@
+//
+// Page title
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .app-header {
+ .page-heading {
+ color: $dark !important;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-header {
+ .page-title {
+ display: none !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/_root.scss b/Moonlight/Styles/layout/_root.scss
new file mode 100644
index 00000000..e4bebce1
--- /dev/null
+++ b/Moonlight/Styles/layout/_root.scss
@@ -0,0 +1,15 @@
+//
+// Root
+//
+
+// Light mode
+@include color-mode(light) {
+ // Separator
+ --#{$prefix}app-separator-border: #{$app-separator-border};
+}
+
+// Dark mode
+@include color-mode(dark) {
+ // Separator
+ --#{$prefix}app-separator-border: #{$app-separator-border-dark};
+}
diff --git a/Moonlight/Styles/layout/_sidebar-minimize.scss b/Moonlight/Styles/layout/_sidebar-minimize.scss
new file mode 100644
index 00000000..0ec26b58
--- /dev/null
+++ b/Moonlight/Styles/layout/_sidebar-minimize.scss
@@ -0,0 +1,43 @@
+//
+// Sidebar Minimize
+//
+
+// Desktop sidebar minimize mode
+@include app-layout-minimize(app-sidebar) {
+ .app-sidebar-header {
+ padding: 0 $app-sidebar-minimize-px;
+ justify-content: center !important;
+
+ .app-sidebar-logo {
+ display: none;
+ }
+ }
+
+ .app-sidebar-wrapper {
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ }
+
+ .app-sidebar-menu-primary,
+ .app-sidebar-menu-secondary {
+ padding: 0 $app-sidebar-minimize-px;
+
+ > .menu-item > .menu-link {
+ width: $app-sidebar-minimize-menu-link-width;
+ }
+
+ .menu-heading,
+ .separator,
+ .menu-content,
+ .menu-arrow,
+ .menu-title {
+ opacity: 0;
+ text-indent: -9999px;
+ }
+
+ .menu-item.show > .menu-sub {
+ height: 0;
+ overflow: hidden;
+ @include app-layout-transition(height);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/_sidebar.scss b/Moonlight/Styles/layout/_sidebar.scss
new file mode 100644
index 00000000..86885457
--- /dev/null
+++ b/Moonlight/Styles/layout/_sidebar.scss
@@ -0,0 +1,213 @@
+//
+// Sidebar
+//
+
+// General mode
+.app-sidebar {
+ border-right: var(--#{$prefix}app-separator-border) !important;
+
+ .separator {
+ border-bottom: var(--#{$prefix}app-separator-border);
+ margin: 0.75rem 0;
+ }
+
+ .menu-heading {
+ color: var(--#{$prefix}gray-700);
+ }
+}
+
+.app-sidebar-navs {
+ overflow: hidden;
+}
+
+.app-sidebar-header {
+ padding: 0 $app-sidebar-base-px;
+ @include app-layout-transition(padding);
+}
+
+.app-sidebar-menu-primary.menu {
+ padding: 0 $app-sidebar-base-px;
+ @include app-layout-transition(padding);
+
+ // Root items
+ > .menu-item {
+ > .menu-link {
+ .menu-title {
+ font-size: 1.1rem;
+ font-weight: $font-weight-bold;
+ }
+ }
+
+ @include menu-link-default-state(
+ $title-color: var(--#{$prefix}gray-700),
+ $icon-color: var(--#{$prefix}gray-500),
+ $bullet-color: var(--#{$prefix}gray-400),
+ $arrow-color: var(--#{$prefix}gray-500),
+ $bg-color: null,
+ $all-links: false
+ );
+
+ @include menu-link-hover-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: var(--#{$prefix}gray-500),
+ $arrow-color: var(--#{$prefix}gray-700),
+ $bg-color: null,
+ $all-links: false
+ );
+
+ @include menu-link-show-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: var(--#{$prefix}gray-500),
+ $arrow-color: var(--#{$prefix}gray-700),
+ $bg-color: null,
+ $all-links: false
+ );
+
+ @include menu-link-here-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: var(--#{$prefix}gray-500),
+ $arrow-color: var(--#{$prefix}gray-700),
+ $bg-color: null,
+ $all-links: false
+ );
+
+ @include menu-link-active-state(
+ $title-color: var(--#{$prefix}white),
+ $icon-color: var(--#{$prefix}white),
+ $bullet-color: var(--#{$prefix}white),
+ $arrow-color: var(--#{$prefix}white),
+ $bg-color: var(--#{$prefix}primary-active),
+ $all-links: false
+ );
+
+ // Child items
+ .menu-item {
+ > .menu-link {
+ .menu-title {
+ font-size: 1.1rem;
+ font-weight: $font-weight-bold;
+ }
+ }
+
+ @include menu-link-default-state(
+ $title-color: var(--#{$prefix}gray-600),
+ $icon-color: var(--#{$prefix}gray-400),
+ $bullet-color: var(--#{$prefix}gray-300),
+ $arrow-color: var(--#{$prefix}gray-400),
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-hover-state(
+ $title-color: var(--#{$prefix}gray-800),
+ $icon-color: var(--#{$prefix}gray-600),
+ $bullet-color: var(--#{$prefix}gray-400),
+ $arrow-color: var(--#{$prefix}gray-600),
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-show-state(
+ $title-color: var(--#{$prefix}gray-800),
+ $icon-color: var(--#{$prefix}gray-600),
+ $bullet-color: var(--#{$prefix}gray-400),
+ $arrow-color: var(--#{$prefix}gray-600),
+ $bg-color: null,
+ $all-links: false
+ );
+
+ @include menu-link-here-state(
+ $title-color: var(--#{$prefix}gray-800),
+ $icon-color: var(--#{$prefix}gray-600),
+ $bullet-color: var(--#{$prefix}gray-400),
+ $arrow-color: var(--#{$prefix}gray-600),
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-active-state(
+ $title-color: var(--#{$prefix}white),
+ $icon-color: var(--#{$prefix}white),
+ $bullet-color: var(--#{$prefix}white),
+ $arrow-color: var(--#{$prefix}white),
+ $bg-color: var(--#{$prefix}primary-active),
+ $all-links: true
+ );
+ }
+ }
+}
+
+.app-sidebar-menu-secondary.menu {
+ padding: 0 $app-sidebar-base-px;
+ @include app-layout-transition(padding);
+
+ @include menu-link-default-state(
+ $title-color: var(--#{$prefix}gray-700),
+ $icon-color: var(--#{$prefix}gray-500),
+ $bullet-color: null,
+ $arrow-color: null,
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-hover-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: null,
+ $arrow-color: null,
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-show-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: null,
+ $arrow-color: null,
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-here-state(
+ $title-color: var(--#{$prefix}gray-900),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: null,
+ $arrow-color: null,
+ $bg-color: null,
+ $all-links: true
+ );
+
+ @include menu-link-active-state(
+ $title-color: var(--#{$prefix}gray-700),
+ $icon-color: var(--#{$prefix}gray-700),
+ $bullet-color: null,
+ $arrow-color: null,
+ $bg-color: var(--#{$prefix}gray-100),
+ $all-links: true
+ );
+
+ .menu-link {
+ .menu-title {
+ font-size: 1.1rem;
+ font-weight: $font-weight-bold;
+ }
+
+ .menu-icon {
+ .bullet {
+ &.bullet-dot {
+ height: 12px;
+ width: 12px;
+ }
+ }
+ }
+
+ &.active {
+ border: var(--#{$prefix}app-separator-border);
+ }
+ }
+}
+
+
diff --git a/Moonlight/Styles/layout/_variables.custom.scss b/Moonlight/Styles/layout/_variables.custom.scss
new file mode 100644
index 00000000..a0ca7bc8
--- /dev/null
+++ b/Moonlight/Styles/layout/_variables.custom.scss
@@ -0,0 +1,68 @@
+//
+// Variables
+//
+
+// Custom
+$app-separator-border: 1px solid $gray-300;
+$app-separator-border-dark: 1px solid $gray-300-dark;
+
+// Reboot
+$app-bg-color: #FBFBFB;
+$app-bg-color-dark: #151521;
+
+// General
+$app-general-root-font-size-desktop: 13px;
+$app-general-root-font-size-tablet: 12px;
+$app-general-root-font-size-mobile: 12px;
+
+// Container
+$app-container-padding-x: 40px !default;
+$app-container-padding-x-mobile: 20px !default;
+
+// Content
+$app-content-padding-y: 30px;
+$app-content-padding-y-mobile: 20px;
+
+// Header base
+$app-header-base-height: 90px;
+$app-header-base-height-mobile: 60px;
+$app-header-base-bg-color: $app-bg-color;
+$app-header-base-bg-color-dark: $app-bg-color-dark;
+
+// Sidebar base
+$app-sidebar-base-width: 280px;
+$app-sidebar-base-width-mobile: 280px;
+$app-sidebar-base-px: 25px;
+$app-sidebar-base-separator-color: 1px solid rgba(217, 219, 228, 0.6);
+$app-sidebar-base-bg-color: $body-bg;
+$app-sidebar-base-bg-color-dark: $body-bg-dark;
+$app-sidebar-base-box-shadow: none;
+$app-sidebar-base-box-shadow-dark: none;
+$app-sidebar-base-menu-link-title: #9BA0B8;
+$app-sidebar-base-menu-link-icon: #A1A5B7;
+$app-sidebar-base-menu-link-icon-dark: $white;
+$app-sidebar-base-menu-link-active: #1E1F27;
+
+// Sidebar minimize
+$app-sidebar-minimize-width: 80px;
+$app-sidebar-minimize-bg-color: $body-bg;
+$app-sidebar-minimize-bg-color-dark: $body-bg-dark;
+$app-sidebar-minimize-menu-link-width: 53px;
+$app-sidebar-minimize-px: 13px;
+
+// Footer
+$app-footer-height: auto;
+$app-footer-height-mobile: auto;
+
+// Scrolltop
+$scrolltop-bottom: 43px;
+$scrolltop-bottom-mobile: 23px;
+$scrolltop-end: 7px;
+$scrolltop-end-mobile: 5px;
+
+// Layout builder toggle(used for Demo purposes only)
+$app-layout-builder-toggle-bg-color: $body-bg;
+$app-layout-builder-toggle-end: 50px;
+$app-layout-builder-toggle-end-mobile: 40px;
+$app-layout-builder-toggle-bottom: 40px;
+$app-layout-builder-toggle-bottom-mobile: 20px;
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_container.scss b/Moonlight/Styles/layout/base/_container.scss
new file mode 100644
index 00000000..8e19b06b
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_container.scss
@@ -0,0 +1,30 @@
+//
+// Container
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .app-container {
+ padding-left: $app-container-padding-x !important;
+ padding-right: $app-container-padding-x !important;
+ }
+
+ .app-container-fit-desktop {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .app-container {
+ max-width: none;
+ padding-left: $app-container-padding-x-mobile !important;
+ padding-right: $app-container-padding-x-mobile !important;
+ }
+
+ .app-container-fit-mobile {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+}
diff --git a/Moonlight/Styles/layout/base/_content.scss b/Moonlight/Styles/layout/base/_content.scss
new file mode 100644
index 00000000..6f9992e6
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_content.scss
@@ -0,0 +1,24 @@
+//
+// Content
+//
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ .app-content {
+ padding-top: $app-content-padding-y;
+ padding-bottom: $app-content-padding-y;
+ padding-left: $app-content-padding-x;
+ padding-right: $app-content-padding-x;
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .app-content {
+ max-width: none;
+ padding-top: $app-content-padding-y-mobile;
+ padding-bottom: $app-content-padding-y-mobile;
+ padding-left: $app-content-padding-x-mobile;
+ padding-right: $app-content-padding-x-mobile;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_footer.scss b/Moonlight/Styles/layout/base/_footer.scss
new file mode 100644
index 00000000..eef913b8
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_footer.scss
@@ -0,0 +1,99 @@
+//
+// Footer
+//
+
+// General mode
+.app-footer {
+ transition: $app-footer-transition;
+ display: flex;
+ align-items: center;
+ background-color: var(--#{$prefix}app-footer-bg-color);
+ border-top: var(--#{$prefix}app-footer-border-top);
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-footer {
+ @include property( z-index, $app-footer-z-index);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-footer-height: #{$app-footer-height};
+ }
+
+ // States
+ .app-footer {
+ height: var(--#{$prefix}app-footer-height);
+
+ [data-kt-app-footer-fixed="true"] & {
+ @include property( z-index, $app-footer-fixed-z-index);
+ box-shadow: var(--#{$prefix}app-footer-box-shadow);
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+ }
+
+ // Integration
+ .app-footer {
+ // Sidebar
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-footer="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-footer="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ // Aside
+ [data-kt-app-aside-fixed="true"][data-kt-app-aside-push-footer="true"] & {
+ right: calc(
+ var(--#{$prefix}app-aside-width) +
+ var(--#{$prefix}app-aside-gap-start, 0px) +
+ var(--#{$prefix}app-aside-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-footer {
+ @include property( z-index, $app-footer-z-index-mobile);
+ }
+
+ // Vars
+ body {
+ --#{$prefix}app-footer-height: #{$app-footer-height-mobile};
+ }
+
+ // States
+ .app-footer {
+ height: var(--#{$prefix}app-footer-height);
+
+ [data-kt-app-footer-fixed-mobile="true"] & {
+ @include property( z-index, $app-footer-fixed-z-index-mobile);
+ box-shadow: var(--#{$prefix}app-footer-box-shadow);
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_hero.scss b/Moonlight/Styles/layout/base/_hero.scss
new file mode 100644
index 00000000..bae8f7a9
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_hero.scss
@@ -0,0 +1,13 @@
+//
+// Hero
+//
+
+// General mode
+.app-hero {
+ display: flex;
+ align-items: stretch;
+ background-color: var(--#{$prefix}app-hero-bg-color);
+ box-shadow: var(--#{$prefix}app-hero-box-shadow);
+ border-top: var(--#{$prefix}app-hero-border-top);
+ border-bottom: var(--#{$prefix}app-hero-border-bottom);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_layout-builder.scss b/Moonlight/Styles/layout/base/_layout-builder.scss
new file mode 100644
index 00000000..513db2af
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_layout-builder.scss
@@ -0,0 +1,19 @@
+//
+// Layout builder
+//
+
+// General mode
+.app-layout-builder-toggle {
+ position: fixed;
+ z-index: $app-layout-builder-toggle-z-index;
+ bottom: $app-layout-builder-toggle-bottom;
+ right: $app-layout-builder-toggle-end;
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ .app-layout-builder-toggle {
+ bottom: $app-layout-builder-toggle-bottom-mobile;
+ right: $app-layout-builder-toggle-end-mobile;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_layout.scss b/Moonlight/Styles/layout/base/_layout.scss
new file mode 100644
index 00000000..8321a7e4
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_layout.scss
@@ -0,0 +1,29 @@
+//
+// App Layout
+//
+
+@import "mixins/layout-minimize";
+@import "mixins/layout-transition";
+@import "root";
+@import "reboot";
+@import "page";
+@import "page-loader";
+@import "container";
+@import "print";
+@import "navbar";
+@import "header/header";
+@import "header/header-primary";
+@import "header/header-secondary";
+@import "header/header-tertiary";
+@import "toolbar";
+@import "hero";
+@import "sidebar/sidebar";
+@import "sidebar/sidebar-primary";
+@import "sidebar/sidebar-secondary";
+@import "sidebar/sidebar-panel";
+@import "aside/aside";
+@import "wrapper";
+@import "main";
+@import "content";
+@import "footer";
+@import "layout-builder";
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_main.scss b/Moonlight/Styles/layout/base/_main.scss
new file mode 100644
index 00000000..99818ef0
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_main.scss
@@ -0,0 +1,75 @@
+//
+// Main
+//
+
+// General mode
+.app-main {
+ display: flex;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-main {
+ transition: $app-main-transition;
+
+ @include property( padding-left, $app-main-padding-x );
+ @include property( padding-right, $app-main-padding-x );
+ @include property( padding-top, $app-main-padding-y );
+ @include property( padding-bottom, $app-main-padding-y );
+
+ @include property( margin-left, $app-main-margin-x );
+ @include property( margin-right, $app-main-margin-x );
+ @include property( margin-top, $app-main-margin-y );
+ @include property( margin-bottom, $app-main-margin-y );
+ }
+
+ // Integration
+ .app-main {
+ // Sidebar
+ [data-kt-app-sidebar-sticky="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-sidebar-panel-sticky="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ // Aside
+ [data-kt-app-aside-sticky="true"] & {
+ margin-right: calc(
+ var(--#{$prefix}app-aside-width) +
+ var(--#{$prefix}app-aside-gap-start, 0px) +
+ var(--#{$prefix}app-aside-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-main {
+ @include property( padding-left, $app-main-padding-x-mobile );
+ @include property( padding-right, $app-main-padding-x-mobile );
+ @include property( padding-top, $app-main-padding-y-mobile );
+ @include property( padding-bottom, $app-main-padding-y-mobile );
+
+ @include property( margin-left, $app-main-margin-x-mobile );
+ @include property( margin-right, $app-main-margin-x-mobile );
+ @include property( margin-top, $app-main-margin-y-mobile );
+ @include property( margin-bottom, $app-main-margin-y-mobile );
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_navbar.scss b/Moonlight/Styles/layout/base/_navbar.scss
new file mode 100644
index 00000000..a6d329cb
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_navbar.scss
@@ -0,0 +1,19 @@
+//
+// App Navbar
+//
+
+.app-navbar {
+ display: flex;
+ align-items: stretch;
+
+ .app-navbar-item {
+ display: flex;
+ align-items: center;
+ }
+
+ &.app-navbar-stretch {
+ .app-navbar-item {
+ align-items: stretch;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_page-loader.scss b/Moonlight/Styles/layout/base/_page-loader.scss
new file mode 100644
index 00000000..d388e74e
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_page-loader.scss
@@ -0,0 +1,31 @@
+//
+// Page loader
+//
+
+// CSS3 Transitions only after page load(data-kt-app-page-loading="on" attribute added to body tag and removed with JS on page loaded)
+[data-kt-app-page-loading="on"] {
+ overflow: hidden;
+}
+
+[data-kt-app-page-loading="on"] * {
+ transition: none !important;
+}
+
+// Base
+.app-page-loader {
+ background: var(--#{$prefix}body-bg);
+ color: var(--#{$prefix}body-color);
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 10000;
+ display: none;
+
+ [data-kt-app-page-loading="on"] & {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+}
diff --git a/Moonlight/Styles/layout/base/_page.scss b/Moonlight/Styles/layout/base/_page.scss
new file mode 100644
index 00000000..78ec216b
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_page.scss
@@ -0,0 +1,7 @@
+//
+// Page
+//
+
+.app-page {
+ display: flex;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_print.scss b/Moonlight/Styles/layout/base/_print.scss
new file mode 100644
index 00000000..c4c76cbf
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_print.scss
@@ -0,0 +1,34 @@
+//
+// Print
+//
+
+// Add .app-print-content-only class to body element in order to allow printing only the content area
+@media print {
+ .app-print-content-only {
+ padding: 0 !important;
+ background: none !important;
+
+ .app-wrapper,
+ .app-page,
+ .app-page-title,
+ .app-content,
+ .app-container {
+ background: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ .app-aside,
+ .app-aside-panel,
+ .app-sidebar,
+ .app-sidebar-panel,
+ .app-header,
+ .app-footer,
+ .app-toolbar,
+ .drawer,
+ .scrolltop,
+ .btn {
+ display: none !important;
+ }
+ }
+}
diff --git a/Moonlight/Styles/layout/base/_reboot.scss b/Moonlight/Styles/layout/base/_reboot.scss
new file mode 100644
index 00000000..85b4f28e
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_reboot.scss
@@ -0,0 +1,65 @@
+//
+// Reboot
+//
+
+html {
+ font-family: sans-serif;
+ text-size-adjust: 100%;
+}
+
+html,
+body {
+ height: 100%;
+ margin: 0px;
+ padding: 0px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-size: $app-general-root-font-size-desktop !important;
+ font-weight: $font-weight-base;
+ font-family: $font-family-sans-serif;
+
+ // Tablet mode
+ @include media-breakpoint-down(lg) {
+ font-size: $app-general-root-font-size-tablet !important;
+ }
+
+ // Mobile mode
+ @include media-breakpoint-down(md) {
+ font-size: $app-general-root-font-size-mobile !important;
+ }
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+
+ a:hover,
+ a:active,
+ a:focus {
+ text-decoration: none !important;
+ }
+}
+
+canvas {
+ user-select: none;
+}
+
+// Angular integration
+router-outlet {
+ display: none;
+}
+
+// Layouts
+body,
+.app-default {
+ background-color: var(--#{$prefix}app-bg-color);
+}
+
+.app-blank {
+ background-color: var(--#{$prefix}app-blank-bg-color);
+}
+
+// Reset CSS3 Transitions for child elements
+[data-kt-app-reset-transition="true"] * {
+ transition: none !important;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_root.scss b/Moonlight/Styles/layout/base/_root.scss
new file mode 100644
index 00000000..d34538b5
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_root.scss
@@ -0,0 +1,368 @@
+//
+// Root
+//
+
+@include color-mode(light) {
+ // Layouts
+ @include property(--#{$prefix}app-bg-color, $app-bg-color);
+ @include property(--#{$prefix}app-blank-bg-color, $app-blank-bg-color);
+
+ // Header base
+ @include property(--#{$prefix}app-header-base-bg-color, $app-header-base-bg-color);
+ @include property(--#{$prefix}app-header-base-box-shadow, $app-header-base-box-shadow);
+ @include property(--#{$prefix}app-header-base-border-bottom, $app-header-base-border-bottom);
+
+ // Header minimize
+ @include property(--#{$prefix}app-header-minimize-bg-color, $app-header-minimize-bg-color);
+ @include property(--#{$prefix}app-header-minimize-box-shadow, $app-header-minimize-box-shadow);
+ @include property(--#{$prefix}app-header-minimize-border-bottom, $app-header-minimize-border-bottom);
+
+ // Header sticky
+ @include property(--#{$prefix}app-header-sticky-bg-color, $app-header-sticky-bg-color);
+ @include property(--#{$prefix}app-header-sticky-box-shadow, $app-header-sticky-box-shadow);
+ @include property(--#{$prefix}app-header-sticky-border-bottom, $app-header-sticky-border-bottom);
+
+ // Header primary
+ @include property(--#{$prefix}app-header-primary-base-bg-color, $app-header-primary-base-bg-color);
+ @include property(--#{$prefix}app-header-primary-base-box-shadow, $app-header-primary-base-box-shadow);
+ @include property(--#{$prefix}app-header-primary-base-border-bottom, $app-header-primary-base-border-bottom);
+
+ @include property(--#{$prefix}app-header-primary-minimize-bg-color, $app-header-primary-minimize-bg-color);
+ @include property(--#{$prefix}app-header-primary-minimize-box-shadow, $app-header-primary-minimize-box-shadow);
+ @include property(--#{$prefix}app-header-primary-minimize-border-top, $app-header-primary-minimize-border-top);
+ @include property(--#{$prefix}app-header-primary-minimize-border-bottom, $app-header-primary-minimize-border-bottom);
+
+ @include property(--#{$prefix}app-header-primary-sticky-bg-color, $app-header-primary-sticky-bg-color);
+ @include property(--#{$prefix}app-header-primary-sticky-box-shadow, $app-header-primary-sticky-box-shadow);
+ @include property(--#{$prefix}app-header-primary-sticky-border-top, $app-header-primary-sticky-border-top);
+ @include property(--#{$prefix}app-header-primary-sticky-border-bottom, $app-header-primary-sticky-border-bottom);
+
+ // Header secondary base
+ @include property(--#{$prefix}app-header-secondary-base-bg-color, $app-header-secondary-base-bg-color);
+ @include property(--#{$prefix}app-header-secondary-base-box-shadow, $app-header-secondary-base-box-shadow);
+ @include property(--#{$prefix}app-header-secondary-base-border-top, $app-header-secondary-base-border-top);
+ @include property(--#{$prefix}app-header-secondary-base-border-bottom, $app-header-secondary-base-border-bottom);
+
+ // Header secondary minimize
+ @include property(--#{$prefix}app-header-secondary-minimize-bg-color, $app-header-secondary-minimize-bg-color);
+ @include property(--#{$prefix}app-header-secondary-minimize-box-shadow, $app-header-secondary-minimize-box-shadow);
+ @include property(--#{$prefix}app-header-secondary-minimize-border-top, $app-header-secondary-minimize-border-top);
+ @include property(--#{$prefix}app-header-secondary-minimize-border-bottom, $app-header-secondary-minimize-border-bottom);
+
+ // Header secondary sticky
+ @include property(--#{$prefix}app-header-secondary-sticky-bg-color, $app-header-secondary-sticky-bg-color);
+ @include property(--#{$prefix}app-header-secondary-sticky-box-shadow, $app-header-secondary-sticky-box-shadow);
+ @include property(--#{$prefix}app-header-secondary-sticky-border-top, $app-header-secondary-sticky-border-top);
+ @include property(--#{$prefix}app-header-secondary-sticky-border-bottom, $app-header-secondary-sticky-border-bottom);
+
+ // Header tertiary base
+ @include property(--#{$prefix}app-header-tertiary-base-bg-color, $app-header-tertiary-base-bg-color);
+ @include property(--#{$prefix}app-header-tertiary-base-box-shadow, $app-header-tertiary-base-box-shadow);
+ @include property(--#{$prefix}app-header-tertiary-base-border-top, $app-header-tertiary-base-border-top);
+ @include property(--#{$prefix}app-header-tertiary-base-border-bottom, $app-header-tertiary-base-border-bottom);
+
+ // Header tertiary minimize
+ @include property(--#{$prefix}app-header-tertiary-minimize-bg-color, $app-header-tertiary-minimize-bg-color);
+ @include property(--#{$prefix}app-header-tertiary-minimize-box-shadow, $app-header-tertiary-minimize-box-shadow);
+ @include property(--#{$prefix}app-header-tertiary-minimize-border-top, $app-header-tertiary-minimize-border-top);
+ @include property(--#{$prefix}app-header-tertiary-minimize-border-bottom, $app-header-tertiary-minimize-border-bottom);
+
+ // Header tertiary sticky
+ @include property(--#{$prefix}app-header-tertiary-sticky-bg-color, $app-header-tertiary-sticky-bg-color);
+ @include property(--#{$prefix}app-header-tertiary-sticky-box-shadow, $app-header-tertiary-sticky-box-shadow);
+ @include property(--#{$prefix}app-header-tertiary-sticky-border-top, $app-header-tertiary-sticky-border-top);
+ @include property(--#{$prefix}app-header-tertiary-sticky-border-bottom, $app-header-tertiary-sticky-border-bottom);
+
+ // Toolbar base
+ @include property(--#{$prefix}app-toolbar-base-bg-color, $app-toolbar-base-bg-color);
+ @include property(--#{$prefix}app-toolbar-base-box-shadow, $app-toolbar-base-box-shadow);
+ @include property(--#{$prefix}app-toolbar-base-border-top, $app-toolbar-base-border-top);
+ @include property(--#{$prefix}app-toolbar-base-border-bottom, $app-toolbar-base-border-bottom);
+
+ // Toolbar minimize
+ @include property(--#{$prefix}app-toolbar-minimize-bg-color, $app-toolbar-minimize-bg-color);
+ @include property(--#{$prefix}app-toolbar-minimize-box-shadow, $app-toolbar-minimize-box-shadow);
+ @include property(--#{$prefix}app-toolbar-minimize-border-top, $app-toolbar-minimize-border-top);
+ @include property(--#{$prefix}app-toolbar-minimize-border-bottom, $app-toolbar-minimize-border-bottom);
+
+ // Toolbar sticky
+ @include property(--#{$prefix}app-toolbar-sticky-bg-color, $app-toolbar-sticky-bg-color);
+ @include property(--#{$prefix}app-toolbar-sticky-box-shadow, $app-toolbar-sticky-box-shadow);
+ @include property(--#{$prefix}app-toolbar-sticky-border-top, $app-toolbar-sticky-border-top);
+ @include property(--#{$prefix}app-toolbar-sticky-border-bottom, $app-toolbar-sticky-border-bottom);
+
+ // Sidebar base
+ @include property(--#{$prefix}app-sidebar-base-bg-color, $app-sidebar-base-bg-color);
+ @include property(--#{$prefix}app-sidebar-base-box-shadow, $app-sidebar-base-box-shadow);
+ @include property(--#{$prefix}app-sidebar-base-border-start, $app-sidebar-base-border-start);
+ @include property(--#{$prefix}app-sidebar-base-border-end, $app-sidebar-base-border-end);
+
+ // Hero
+ @include property(--#{$prefix}app-hero-bg-color, $app-hero-bg-color);
+ @include property(--#{$prefix}app-hero-box-shadow, $app-hero-box-shadow);
+ @include property(--#{$prefix}app-hero-border-top, $app-hero-border-top);
+ @include property(--#{$prefix}app-hero-border-bottom, $app-hero-border-bottom);
+
+ // Sidebar sticky
+ @include property(--#{$prefix}app-sidebar-sticky-bg-color, $app-sidebar-sticky-bg-color);
+ @include property(--#{$prefix}app-sidebar-sticky-box-shadow, $app-sidebar-sticky-box-shadow);
+ @include property(--#{$prefix}app-sidebar-sticky-border-start, $app-sidebar-sticky-border-start);
+ @include property(--#{$prefix}app-sidebar-sticky-border-end, $app-sidebar-sticky-border-end);
+
+ // Sidebar minimize
+ @include property(--#{$prefix}app-sidebar-minimize-bg-color, $app-sidebar-minimize-bg-color);
+ @include property(--#{$prefix}app-sidebar-minimize-box-shadow, $app-sidebar-minimize-box-shadow);
+ @include property(--#{$prefix}app-sidebar-minimize-hover-box-shadow, $app-sidebar-minimize-hover-box-shadow);
+ @include property(--#{$prefix}app-sidebar-minimize-border-start, $app-sidebar-minimize-border-start);
+ @include property(--#{$prefix}app-sidebar-minimize-border-end, $app-sidebar-minimize-border-end);
+
+ // Sidebar primary
+ @include property(--#{$prefix}app-sidebar-primary-base-bg-color, $app-sidebar-primary-base-bg-color);
+ @include property(--#{$prefix}app-sidebar-primary-base-box-shadow, $app-sidebar-primary-base-box-shadow);
+ @include property(--#{$prefix}app-sidebar-primary-base-border-start, $app-sidebar-primary-base-border-start);
+ @include property(--#{$prefix}app-sidebar-primary-base-border-end, $app-sidebar-primary-base-border-end);
+
+ // Sidebar primary minimize
+ @include property(--#{$prefix}app-sidebar-primary-minimize-bg-color, $app-sidebar-primary-minimize-bg-color);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-box-shadow, $app-sidebar-primary-minimize-box-shadow);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-hover-box-shadow, $app-sidebar-primary-minimize-hover-box-shadow);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-border-start, $app-sidebar-primary-minimize-border-start);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-border-end, $app-sidebar-primary-minimize-border-end);
+
+ // Sidebar secondary base
+ @include property(--#{$prefix}app-sidebar-secondary-base-bg-color, $app-sidebar-secondary-base-bg-color);
+ @include property(--#{$prefix}app-sidebar-secondary-base-box-shadow, $app-sidebar-secondary-base-box-shadow);
+ @include property(--#{$prefix}app-sidebar-secondary-base-border-start, $app-sidebar-secondary-base-border-start);
+ @include property(--#{$prefix}app-sidebar-secondary-base-border-end, $app-sidebar-secondary-base-border-end);
+
+ // Sidebar secondary minimize
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-bg-color, $app-sidebar-secondary-minimize-bg-color);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-box-shadow, $app-sidebar-secondary-minimize-box-shadow);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-hover-box-shadow, $app-sidebar-secondary-minimize-hover-box-shadow);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-border-start, $app-sidebar-secondary-minimize-border-start);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-border-end, $app-sidebar-secondary-minimize-border-end);
+
+ // Sidebar panel base
+ @include property(--#{$prefix}app-sidebar-panel-base-bg-color, $app-sidebar-panel-base-bg-color);
+ @include property(--#{$prefix}app-sidebar-panel-base-box-shadow, $app-sidebar-panel-base-box-shadow);
+ @include property(--#{$prefix}app-sidebar-panel-base-border-start, $app-sidebar-panel-base-border-start);
+ @include property(--#{$prefix}app-sidebar-panel-base-border-end, $app-sidebar-panel-base-border-end);
+
+ // Sidebar panel sticky
+ @include property(--#{$prefix}app-sidebar-panel-sticky-bg-color, $app-sidebar-panel-sticky-bg-color);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-box-shadow, $app-sidebar-panel-sticky-box-shadow);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-border-start, $app-sidebar-panel-sticky-border-start);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-border-end, $app-sidebar-panel-sticky-border-end);
+
+ // Sidebar panel minimize
+ @include property(--#{$prefix}app-sidebar-panel-minimize-bg-color, $app-sidebar-panel-minimize-bg-color);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-box-shadow, $app-sidebar-panel-minimize-box-shadow);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-hover-box-shadow, $app-sidebar-panel-minimize-hover-box-shadow);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-border-start, $app-sidebar-panel-minimize-border-start);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-border-end, $app-sidebar-panel-minimize-border-end);
+
+ // Aside base
+ @include property(--#{$prefix}app-aside-base-bg-color, $app-aside-base-bg-color);
+ @include property(--#{$prefix}app-aside-base-box-shadow, $app-aside-base-box-shadow);
+
+ // Aside sticky
+ @include property(--#{$prefix}app-aside-sticky-bg-color, $app-aside-sticky-bg-color);
+ @include property(--#{$prefix}app-aside-sticky-box-shadow, $app-aside-sticky-box-shadow);
+
+ // Aside minimize
+ @include property(--#{$prefix}app-aside-minimize-bg-color, $app-aside-minimize-bg-color);
+ @include property(--#{$prefix}app-aside-minimize-box-shadow, $app-aside-minimize-box-shadow);
+ @include property(--#{$prefix}app-aside-minimize-hover-box-shadow, $app-aside-minimize-hover-box-shadow);
+
+ // Page
+ @include property(--#{$prefix}app-page-bg-color, $app-page-bg-color);
+
+ // Wrapper
+ @include property(--#{$prefix}app-wrapper-bg-color, $app-wrapper-bg-color);
+
+ // Footer
+ @include property(--#{$prefix}app-footer-bg-color, $app-footer-bg-color);
+ @include property(--#{$prefix}app-footer-box-shadow, $app-footer-box-shadow);
+ @include property(--#{$prefix}app-footer-border-top, $app-footer-border-top);
+}
+
+@include color-mode(dark) {
+ // Layouts
+ @include property(--#{$prefix}app-bg-color, $app-bg-color-dark);
+ @include property(--#{$prefix}app-blank-bg-color, $app-blank-bg-color-dark);
+
+ // Header base
+ @include property(--#{$prefix}app-header-base-bg-color, $app-header-base-bg-color-dark);
+ @include property(--#{$prefix}app-header-base-box-shadow, $app-header-base-box-shadow-dark);
+ @include property(--#{$prefix}app-header-base-border-bottom, $app-header-base-border-bottom-dark);
+
+ // Header minimize
+ @include property(--#{$prefix}app-header-minimize-bg-color, $app-header-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-header-minimize-box-shadow, $app-header-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-header-minimize-border-bottom, $app-header-minimize-border-bottom-dark);
+
+ // Header sticky
+ @include property(--#{$prefix}app-header-sticky-bg-color, $app-header-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-header-sticky-box-shadow, $app-header-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-header-sticky-border-bottom, $app-header-sticky-border-bottom-dark);
+
+ // Header primary
+ @include property(--#{$prefix}app-header-primary-base-bg-color, $app-header-primary-base-bg-color-dark);
+ @include property(--#{$prefix}app-header-primary-base-box-shadow, $app-header-primary-base-box-shadow-dark);
+ @include property(--#{$prefix}app-header-primary-base-border-bottom, $app-header-primary-base-border-bottom-dark);
+
+ @include property(--#{$prefix}app-header-primary-minimize-bg-color, $app-header-primary-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-header-primary-minimize-box-shadow, $app-header-primary-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-header-primary-minimize-border-top, $app-header-primary-minimize-border-top-dark);
+ @include property(--#{$prefix}app-header-primary-minimize-border-bottom, $app-header-primary-minimize-border-bottom-dark);
+
+ @include property(--#{$prefix}app-header-primary-sticky-bg-color, $app-header-primary-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-header-primary-sticky-box-shadow, $app-header-primary-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-header-primary-sticky-border-top, $app-header-primary-sticky-border-top-dark);
+ @include property(--#{$prefix}app-header-primary-sticky-border-bottom, $app-header-primary-sticky-border-bottom-dark);
+
+ // Header secondary base
+ @include property(--#{$prefix}app-header-secondary-base-bg-color, $app-header-secondary-base-bg-color-dark);
+ @include property(--#{$prefix}app-header-secondary-base-box-shadow, $app-header-secondary-base-box-shadow-dark);
+ @include property(--#{$prefix}app-header-secondary-base-border-top, $app-header-secondary-base-border-top-dark);
+ @include property(--#{$prefix}app-header-secondary-base-border-bottom, $app-header-secondary-base-border-bottom-dark);
+
+ // Header secondary minimize
+ @include property(--#{$prefix}app-header-secondary-minimize-bg-color, $app-header-secondary-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-header-secondary-minimize-box-shadow, $app-header-secondary-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-header-secondary-minimize-border-top, $app-header-secondary-minimize-border-top-dark);
+ @include property(--#{$prefix}app-header-secondary-minimize-border-bottom, $app-header-secondary-minimize-border-bottom-dark);
+
+ // Header secondary sticky
+ @include property(--#{$prefix}app-header-secondary-sticky-bg-color, $app-header-secondary-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-header-secondary-sticky-box-shadow, $app-header-secondary-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-header-secondary-sticky-border-top, $app-header-secondary-sticky-border-top-dark);
+ @include property(--#{$prefix}app-header-secondary-sticky-border-bottom, $app-header-secondary-sticky-border-bottom-dark);
+
+ // Header tertiary base
+ @include property(--#{$prefix}app-header-tertiary-base-bg-color, $app-header-tertiary-base-bg-color-dark);
+ @include property(--#{$prefix}app-header-tertiary-base-box-shadow, $app-header-tertiary-base-box-shadow-dark);
+ @include property(--#{$prefix}app-header-tertiary-base-border-top, $app-header-tertiary-base-border-top-dark);
+ @include property(--#{$prefix}app-header-tertiary-base-border-bottom, $app-header-tertiary-base-border-bottom-dark);
+
+ // Header tertiary minimize
+ @include property(--#{$prefix}app-header-tertiary-minimize-bg-color, $app-header-tertiary-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-header-tertiary-minimize-box-shadow, $app-header-tertiary-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-header-tertiary-minimize-border-top, $app-header-tertiary-minimize-border-top-dark);
+ @include property(--#{$prefix}app-header-tertiary-minimize-border-bottom, $app-header-tertiary-minimize-border-bottom-dark);
+
+ // Header tertiary sticky
+ @include property(--#{$prefix}app-header-tertiary-sticky-bg-color, $app-header-tertiary-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-header-tertiary-sticky-box-shadow, $app-header-tertiary-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-header-tertiary-sticky-border-top, $app-header-tertiary-sticky-border-top-dark);
+ @include property(--#{$prefix}app-header-tertiary-sticky-border-bottom, $app-header-tertiary-sticky-border-bottom-dark);
+
+ // Toolbar base
+ @include property(--#{$prefix}app-toolbar-base-bg-color, $app-toolbar-base-bg-color-dark);
+ @include property(--#{$prefix}app-toolbar-base-box-shadow, $app-toolbar-base-box-shadow-dark);
+ @include property(--#{$prefix}app-toolbar-base-border-top, $app-toolbar-base-border-top-dark);
+ @include property(--#{$prefix}app-toolbar-base-border-bottom, $app-toolbar-base-border-bottom-dark);
+
+ // Toolbar minimize
+ @include property(--#{$prefix}app-toolbar-minimize-bg-color, $app-toolbar-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-toolbar-minimize-box-shadow, $app-toolbar-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-toolbar-minimize-border-top, $app-toolbar-minimize-border-top-dark);
+ @include property(--#{$prefix}app-toolbar-minimize-border-bottom, $app-toolbar-minimize-border-bottom-dark);
+
+ // Toolbar sticky
+ @include property(--#{$prefix}app-toolbar-sticky-bg-color, $app-toolbar-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-toolbar-sticky-box-shadow, $app-toolbar-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-toolbar-sticky-border-top, $app-toolbar-sticky-border-top-dark);
+ @include property(--#{$prefix}app-toolbar-sticky-border-bottom, $app-toolbar-sticky-border-bottom-dark);
+
+ // Hero
+ @include property(--#{$prefix}app-hero-bg-color, $app-hero-bg-color-dark);
+ @include property(--#{$prefix}app-hero-box-shadow, $app-hero-box-shadow-dark);
+ @include property(--#{$prefix}app-hero-border-top, $app-hero-border-top-dark);
+ @include property(--#{$prefix}app-hero-border-bottom, $app-hero-border-bottom-dark);
+
+ // Sidebar base
+ @include property(--#{$prefix}app-sidebar-base-bg-color, $app-sidebar-base-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-base-box-shadow, $app-sidebar-base-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-base-border-start, $app-sidebar-base-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-base-border-end, $app-sidebar-base-border-end-dark);
+
+ // Sidebar sticky
+ @include property(--#{$prefix}app-sidebar-sticky-bg-color, $app-sidebar-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-sticky-box-shadow, $app-sidebar-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-sticky-border-start, $app-sidebar-sticky-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-sticky-border-end, $app-sidebar-sticky-border-end-dark);
+
+ // Sidebar minimize
+ @include property(--#{$prefix}app-sidebar-minimize-bg-color, $app-sidebar-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-minimize-box-shadow, $app-sidebar-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-minimize-hover-box-shadow, $app-sidebar-minimize-hover-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-minimize-border-start, $app-sidebar-minimize-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-minimize-border-end, $app-sidebar-minimize-border-end-dark);
+
+ // Sidebar primary
+ @include property(--#{$prefix}app-sidebar-primary-base-bg-color, $app-sidebar-primary-base-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-primary-base-box-shadow, $app-sidebar-primary-base-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-primary-base-border-start, $app-sidebar-primary-base-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-primary-base-border-end, $app-sidebar-primary-base-border-end-dark);
+
+ @include property(--#{$prefix}app-sidebar-primary-minimize-bg-color, $app-sidebar-primary-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-box-shadow, $app-sidebar-primary-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-hover-box-shadow, $app-sidebar-primary-minimize-hover-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-border-start, $app-sidebar-primary-minimize-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-primary-minimize-border-end, $app-sidebar-primary-minimize-border-end-dark);
+
+ // Sidebar secondary
+ @include property(--#{$prefix}app-sidebar-secondary-base-bg-color, $app-sidebar-secondary-base-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-base-box-shadow, $app-sidebar-secondary-base-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-base-border-start, $app-sidebar-secondary-base-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-base-border-end, $app-sidebar-secondary-base-border-end-dark);
+
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-bg-color, $app-sidebar-secondary-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-box-shadow, $app-sidebar-secondary-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-hover-box-shadow, $app-sidebar-secondary-minimize-hover-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-border-start, $app-sidebar-secondary-minimize-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-secondary-minimize-border-end, $app-sidebar-secondary-minimize-border-end-dark);
+
+ // Sidebar panel base
+ @include property(--#{$prefix}app-sidebar-panel-base-bg-color, $app-sidebar-panel-base-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-panel-base-box-shadow, $app-sidebar-panel-base-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-panel-base-border-start, $app-sidebar-panel-base-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-panel-base-border-end, $app-sidebar-panel-base-border-end-dark);
+
+ // Sidebar panel sticky
+ @include property(--#{$prefix}app-sidebar-panel-sticky-bg-color, $app-sidebar-panel-sticky-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-box-shadow, $app-sidebar-panel-sticky-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-border-start, $app-sidebar-panel-sticky-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-panel-sticky-border-end, $app-sidebar-panel-sticky-border-end-dark);
+
+ // Sidebar panel minimize
+ @include property(--#{$prefix}app-sidebar-panel-minimize-bg-color, $app-sidebar-panel-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-box-shadow, $app-sidebar-panel-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-hover-box-shadow, $app-sidebar-panel-minimize-hover-box-shadow-dark);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-border-start, $app-sidebar-panel-minimize-border-start-dark);
+ @include property(--#{$prefix}app-sidebar-panel-minimize-border-end, $app-sidebar-panel-minimize-border-end-dark);
+
+ // Aside base
+ @include property(--#{$prefix}app-aside-base-bg-color, $app-aside-base-bg-color-dark);
+ @include property(--#{$prefix}app-aside-base-box-shadow, $app-aside-base-box-shadow-dark);
+
+ // Aside sticky
+ @include property(--#{$prefix}app-aside-sticky-bg-color, $app-aside-sticky-bg-color-dark);
+
+ // Aside minimize
+ @include property(--#{$prefix}app-aside-minimize-bg-color, $app-aside-minimize-bg-color-dark);
+ @include property(--#{$prefix}app-aside-minimize-box-shadow, $app-aside-minimize-box-shadow-dark);
+ @include property(--#{$prefix}app-aside-minimize-hover-box-shadow, $app-aside-minimize-hover-box-shadow-dark);
+
+ // Page
+ @include property(--#{$prefix}app-page-bg-color, $app-page-bg-color-dark);
+
+ // Wrapper
+ @include property(--#{$prefix}app-wrapper-bg-color, $app-wrapper-bg-color-dark);
+
+ // Footer
+ @include property(--#{$prefix}app-footer-bg-color, $app-footer-bg-color-dark);
+ @include property(--#{$prefix}app-footer-box-shadow, $app-footer-box-shadow-dark);
+ @include property(--#{$prefix}app-footer-border-top, $app-footer-border-top-dark);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_toolbar.scss b/Moonlight/Styles/layout/base/_toolbar.scss
new file mode 100644
index 00000000..f504c51a
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_toolbar.scss
@@ -0,0 +1,171 @@
+//
+// Toolbar
+//
+
+// General mode
+.app-toolbar {
+ display: flex;
+ align-items: stretch;
+ background-color: var(--#{$prefix}app-toolbar-base-bg-color);
+ box-shadow: var(--#{$prefix}app-toolbar-base-box-shadow);
+ border-top: var(--#{$prefix}app-toolbar-base-border-top);
+ border-bottom: var(--#{$prefix}app-toolbar-base-border-bottom);
+
+ &.app-toolbar-minimize {
+ transition: $app-toolbar-base-transition;
+ }
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Vars
+ :root {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-base-height};
+ --#{$prefix}app-toolbar-height-actual: #{$app-toolbar-base-height};
+ }
+
+ [data-kt-app-toolbar-sticky="on"] {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-sticky-height};
+ }
+
+ [data-kt-app-toolbar-minimize="on"] {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-minimize-height};
+ }
+
+ // States
+ .app-toolbar {
+ height: var(--#{$prefix}app-toolbar-height);
+
+ [data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"] & {
+ @include property( z-index, $app-toolbar-base-z-index);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-toolbar-sticky="on"] & {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+
+ box-shadow: var(--#{$prefix}app-toolbar-sticky-box-shadow);
+ background-color: var(--#{$prefix}app-toolbar-sticky-bg-color);
+ border-top: var(--#{$prefix}app-toolbar-sticky-border-top);
+ border-bottom: var(--#{$prefix}app-toolbar-sticky-border-bottom);
+
+ @include property( z-index, $app-toolbar-sticky-z-index);
+ @include property( backdrop-filter, $app-toolbar-sticky-backdrop-filter);
+ }
+
+ [data-kt-app-toolbar-minimize="on"] & {
+ transition: $app-toolbar-base-transition;
+
+ box-shadow: var(--#{$prefix}app-toolbar-minimize-box-shadow);
+ background-color: var(--#{$prefix}app-toolbar-minimize-bg-color);
+ border-top: var(--#{$prefix}app-toolbar-minimize-border-top);
+ border-bottom: var(--#{$prefix}app-toolbar-minimize-border-bottom);
+
+ @include property( z-index, $app-toolbar-minimize-z-index);
+ @include property( backdrop-filter, $app-toolbar-minimize-backdrop-filter);
+ }
+ }
+
+ // Integration
+ .app-toolbar {
+ // Header
+ [data-kt-app-toolbar-fixed="true"][data-kt-app-header-fixed="true"] & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Sidebar
+ [data-kt-app-toolbar-sticky="on"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-toolbar="true"] &,
+ [data-kt-app-toolbar-fixed="true"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-toolbar="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar panel
+ [data-kt-app-toolbar-sticky="on"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-toolbar="true"] &,
+ [data-kt-app-toolbar-fixed="true"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-toolbar="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ // Aside
+ [data-kt-app-toolbar-sticky="on"][data-kt-app-aside-fixed="true"][data-kt-app-aside-push-toolbar="true"] &,
+ [data-kt-app-toolbar-fixed="true"][data-kt-app-aside-fixed="true"][data-kt-app-aside-push-toolbar="true"] & {
+ right: calc(
+ var(--#{$prefix}app-aside-width) +
+ var(--#{$prefix}app-aside-gap-start, 0px) +
+ var(--#{$prefix}app-aside-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Vars
+ :root {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-base-height-mobile};
+ }
+
+ [data-kt-app-toolbar-sticky="on"] {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-sticky-height-mobile};
+ }
+
+ [data-kt-app-toolbar-minimize="on"] {
+ --#{$prefix}app-toolbar-height: #{$app-toolbar-minimize-height-mobile};
+ }
+
+ // States
+ .app-toolbar {
+ height: var(--#{$prefix}app-toolbar-height);
+
+ [data-kt-app-header-fixed-mobile="true"][data-kt-app-toolbar-fixed-mobile="true"] & {
+ @include property( z-index, $app-toolbar-base-z-index-mobile);
+ position: fixed;
+ top: calc(var(--#{$prefix}app-header-height, 0px) + var(--#{$prefix}app-header-mobile-height, 0px));
+ left: 0;
+ right: 0;
+ }
+
+ [data-kt-app-toolbar-sticky="on"] & {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: var(--#{$prefix}app-header-height, 0px);
+
+ box-shadow: var(--#{$prefix}app-toolbar-sticky-box-shadow);
+ background-color: var(--#{$prefix}app-toolbar-sticky-bg-color);
+ border-top: var(--#{$prefix}app-toolbar-sticky-border-top);
+ border-bottom: var(--#{$prefix}app-toolbar-sticky-border-bottom);
+
+ @include property( z-index, $app-toolbar-sticky-z-index-mobile);
+ @include property( backdrop-filter, $app-toolbar-sticky-backdrop-filter-mobile);
+ }
+
+ [data-kt-app-toolbar-minimize="on"] & {
+ transition: $app-toolbar-base-transition;
+
+ box-shadow: var(--#{$prefix}app-toolbar-minimize-box-shadow);
+ background-color: var(--#{$prefix}app-toolbar-minimize-bg-color);
+ border-top: var(--#{$prefix}app-toolbar-minimize-border-top);
+ border-bottom: var(--#{$prefix}app-toolbar-minimize-border-bottom);
+
+ @include property( z-index, $app-toolbar-minimize-z-index-mobile);
+ @include property( backdrop-filter, $app-toolbar-minimize-backdrop-filter-mobile);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_variables.scss b/Moonlight/Styles/layout/base/_variables.scss
new file mode 100644
index 00000000..6ecd03b0
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_variables.scss
@@ -0,0 +1,615 @@
+//
+// Variables
+//
+
+// Reboot
+$app-bg-color: #f5f8fa !default;
+$app-bg-color-dark: #151521 !default;
+$app-blank-bg-color: $white;
+$app-blank-bg-color-dark: $app-bg-color-dark;
+
+// General
+$app-general-transition-duration: .3s !default;
+$app-general-transition-timing: ease !default;
+$app-general-root-font-size-desktop: 13px !default;
+$app-general-root-font-size-tablet: 12px !default;
+$app-general-root-font-size-mobile: 12px !default;
+
+// Container
+$app-container-padding-x: 30px !default;
+$app-container-padding-x-mobile: 20px !default;
+
+// Page
+$app-page-bg-color: null !default;
+$app-page-bg-color-dark: null !default;
+
+// Main
+$app-main-transition: margin $app-general-transition-duration $app-general-transition-timing;
+$app-main-padding-y: null !default;
+$app-main-padding-y-mobile: null !default;
+$app-main-padding-x: null !default;
+$app-main-padding-x-mobile: 0 !default;
+$app-main-margin-y: null !default;
+$app-main-margin-y-mobile: null !default;
+$app-main-margin-x: null !default;
+$app-main-margin-x-mobile: null !default;
+
+// Wrapper
+$app-wrapper-transition: margin-left $app-general-transition-duration $app-general-transition-timing, margin-right $app-general-transition-duration $app-general-transition-timing;
+$app-wrapper-bg-color: null !default;
+$app-wrapper-bg-color-dark: null !default;
+
+// Content
+$app-content-padding-y: 30px !default;
+$app-content-padding-y-mobile: 20px !default;
+$app-content-padding-x: 0 !default;
+$app-content-padding-x-mobile: 0 !default;
+
+// Header base
+$app-header-base-transition: none !default;
+$app-header-base-height: 70px !default;
+$app-header-base-height-mobile: 70px !default;
+$app-header-base-z-index: null !default;
+$app-header-base-z-index-mobile: null !default;
+$app-header-base-bg-color: null !default;
+$app-header-base-bg-color-dark: null !default;
+$app-header-base-box-shadow: null !default;
+$app-header-base-box-shadow-dark: null !default;
+$app-header-base-border-bottom: null !default;
+$app-header-base-border-bottom-dark: null !default;
+
+// Header fixed
+$app-header-fixed-z-index: 100 !default;
+$app-header-fixed-z-index-mobile: 100 !default;
+
+// Header minimize
+$app-header-minimize-height: 70px !default;
+$app-header-minimize-height-mobile: 70px !default;
+$app-header-minimize-z-index: 100 !default;
+$app-header-minimize-z-index-mobile: 100 !default;
+$app-header-minimize-backdrop-filter: null !default;
+$app-header-minimize-backdrop-filter-mobile: null !default;
+$app-header-minimize-bg-color: null !default;
+$app-header-minimize-bg-color-dark: null !default;
+$app-header-minimize-box-shadow: null !default;
+$app-header-minimize-box-shadow-dark: null !default;
+$app-header-minimize-border-bottom: null !default;
+$app-header-minimize-border-bottom-dark: null !default;
+
+// Header sticky
+$app-header-sticky-height: 70px !default;
+$app-header-sticky-height-mobile: 70px !default;
+$app-header-sticky-z-index: 100 !default;
+$app-header-sticky-z-index-mobile: 100 !default;
+$app-header-sticky-backdrop-filter: null !default;
+$app-header-sticky-backdrop-filter-mobile: null !default;
+$app-header-sticky-bg-color: null !default;
+$app-header-sticky-bg-color-dark: null !default;
+$app-header-sticky-box-shadow: null !default;
+$app-header-sticky-box-shadow-dark: null !default;
+$app-header-sticky-border-bottom: null !default;
+$app-header-sticky-border-bottom-dark: null !default;
+
+// Header primary
+$app-header-primary-base-transition: none !default;
+$app-header-primary-base-height: 70px !default;
+$app-header-primary-base-height-mobile: 60px !default;
+$app-header-primary-base-z-index: null !default;
+$app-header-primary-base-z-index-mobile: null !default;
+$app-header-primary-base-bg-color: null !default;
+$app-header-primary-base-bg-color-dark: null !default;
+$app-header-primary-base-box-shadow: null !default;
+$app-header-primary-base-box-shadow-dark: null !default;
+$app-header-primary-base-border-bottom: null !default;
+$app-header-primary-base-border-bottom-dark: null !default;
+
+$app-header-primary-fixed-z-index: 100 !default;
+
+$app-header-primary-minimize-height: 70px !default;
+$app-header-primary-minimize-height-mobile: 60px !default;
+$app-header-primary-minimize-z-index: 100 !default;
+$app-header-primary-minimize-bg-color: null !default;
+$app-header-primary-minimize-bg-color-dark: null !default;
+$app-header-primary-minimize-box-shadow: null !default;
+$app-header-primary-minimize-box-shadow-dark: null !default;
+$app-header-primary-minimize-border-top: null !default;
+$app-header-primary-minimize-border-top-dark: null !default;
+$app-header-primary-minimize-border-bottom: null !default;
+$app-header-primary-minimize-border-bottom-dark: null !default;
+
+$app-header-primary-sticky-height: 70px !default;
+$app-header-primary-sticky-height-mobile: 60px !default;
+$app-header-primary-sticky-z-index: 100 !default;
+$app-header-primary-sticky-bg-color: null !default;
+$app-header-primary-sticky-bg-color-dark: null !default;
+$app-header-primary-sticky-box-shadow: null !default;
+$app-header-primary-sticky-box-shadow-dark: null !default;
+$app-header-primary-sticky-border-top: null !default;
+$app-header-primary-sticky-border-top-dark: null !default;
+$app-header-primary-sticky-border-bottom: null !default;
+$app-header-primary-sticky-border-bottom-dark: null !default;
+
+// Header secondary
+$app-header-secondary-base-transition: none !default;
+$app-header-secondary-base-height: 70px !default;
+$app-header-secondary-base-height-mobile: 60px !default;
+$app-header-secondary-base-z-index: null !default;
+$app-header-secondary-base-z-index-mobile: null !default;
+$app-header-secondary-base-bg-color: null !default;
+$app-header-secondary-base-bg-color-dark: null !default;
+$app-header-secondary-base-box-shadow: null !default;
+$app-header-secondary-base-box-shadow-dark: null !default;
+$app-header-secondary-base-border-top: null !default;
+$app-header-secondary-base-border-top-dark: null !default;
+$app-header-secondary-base-border-bottom: null !default;
+$app-header-secondary-base-border-bottom-dark: null !default;
+
+$app-header-secondary-fixed-z-index: 100 !default;
+
+$app-header-secondary-minimize-height: 70px !default;
+$app-header-secondary-minimize-height-mobile: 60px !default;
+$app-header-secondary-minimize-z-index: 100 !default;
+$app-header-secondary-minimize-bg-color: null !default;
+$app-header-secondary-minimize-bg-color-dark: null !default;
+$app-header-secondary-minimize-box-shadow: null !default;
+$app-header-secondary-minimize-box-shadow-dark: null !default;
+$app-header-secondary-minimize-border-top: null !default;
+$app-header-secondary-minimize-border-top-dark: null !default;
+$app-header-secondary-minimize-border-bottom: null !default;
+$app-header-secondary-minimize-border-bottom-dark: null !default;
+
+$app-header-secondary-sticky-height: 70px !default;
+$app-header-secondary-sticky-height-mobile: 60px !default;
+$app-header-secondary-sticky-z-index: 100 !default;
+$app-header-secondary-sticky-bg-color: null !default;
+$app-header-secondary-sticky-bg-color-dark: null !default;
+$app-header-secondary-sticky-box-shadow: null !default;
+$app-header-secondary-sticky-box-shadow-dark: null !default;
+$app-header-secondary-sticky-border-top: null !default;
+$app-header-secondary-sticky-border-top-dark: null !default;
+$app-header-secondary-sticky-border-bottom: null !default;
+$app-header-secondary-sticky-border-bottom-dark: null !default;
+
+// Header tertiary
+$app-header-tertiary-base-transition: none !default;
+$app-header-tertiary-base-height: 70px !default;
+$app-header-tertiary-base-height-mobile: 70px !default;
+$app-header-tertiary-base-z-index: null !default;
+$app-header-tertiary-base-z-index-mobile: null !default;
+$app-header-tertiary-base-bg-color: null !default;
+$app-header-tertiary-base-bg-color-dark: null !default;
+$app-header-tertiary-base-box-shadow: null !default;
+$app-header-tertiary-base-box-shadow-dark: null !default;
+$app-header-tertiary-base-border-top: null !default;
+$app-header-tertiary-base-border-top-dark: null !default;
+$app-header-tertiary-base-border-bottom: null !default;
+$app-header-tertiary-base-border-bottom-dark: null !default;
+
+$app-header-tertiary-fixed-z-index: 100 !default;
+
+$app-header-tertiary-minimize-height: 70px !default;
+$app-header-tertiary-minimize-height-mobile: 60px !default;
+$app-header-tertiary-minimize-z-index: 100 !default;
+$app-header-tertiary-minimize-bg-color: null !default;
+$app-header-tertiary-minimize-bg-color-dark: null !default;
+$app-header-tertiary-minimize-box-shadow: null !default;
+$app-header-tertiary-minimize-box-shadow-dark: null !default;
+$app-header-tertiary-minimize-border-top: null !default;
+$app-header-tertiary-minimize-border-top-dark: null !default;
+$app-header-tertiary-minimize-border-bottom: null !default;
+$app-header-tertiary-minimize-border-bottom-dark: null !default;
+
+$app-header-tertiary-sticky-height: 70px !default;
+$app-header-tertiary-sticky-height-mobile: 60px !default;
+$app-header-tertiary-sticky-z-index: 100 !default;
+$app-header-tertiary-sticky-bg-color: null !default;
+$app-header-tertiary-sticky-bg-color-dark: null !default;
+$app-header-tertiary-sticky-box-shadow: null !default;
+$app-header-tertiary-sticky-box-shadow-dark: null !default;
+$app-header-tertiary-sticky-border-top: null !default;
+$app-header-tertiary-sticky-border-top-dark: null !default;
+$app-header-tertiary-sticky-border-bottom: null !default;
+$app-header-tertiary-sticky-border-bottom-dark: null !default;
+
+// Toolbar base
+$app-toolbar-base-transition: none !default;
+$app-toolbar-base-height: null !default;
+$app-toolbar-base-height-mobile: null !default;
+$app-toolbar-base-z-index: 99 !default;
+$app-toolbar-base-z-index-mobile: 99 !default;
+$app-toolbar-base-bg-color: null !default;
+$app-toolbar-base-bg-color-dark: null !default;
+$app-toolbar-base-box-shadow: null !default;
+$app-toolbar-base-box-shadow-dark: null !default;
+$app-toolbar-base-border-top: null !default;
+$app-toolbar-base-border-top-dark: null !default;
+$app-toolbar-base-border-bottom: null !default;
+$app-toolbar-base-border-bottom-dark: null !default;
+
+// Toolbar minimize
+$app-toolbar-minimize-height: 70px !default;
+$app-toolbar-minimize-height-mobile: 70px !default;
+$app-toolbar-minimize-z-index: 99 !default;
+$app-toolbar-minimize-z-index-mobile: 99 !default;
+$app-toolbar-minimize-backdrop-filter: null !default;
+$app-toolbar-minimize-backdrop-filter-mobile: null !default;
+$app-toolbar-minimize-bg-color: null !default;
+$app-toolbar-minimize-bg-color-dark: null !default;
+$app-toolbar-minimize-box-shadow: null !default;
+$app-toolbar-minimize-box-shadow-dark: null !default;
+$app-toolbar-minimize-border-top: null !default;
+$app-toolbar-minimize-border-top-dark: null !default;
+$app-toolbar-minimize-border-bottom: null !default;
+$app-toolbar-minimize-border-bottom-dark: null !default;
+
+// Toolbar sticky
+$app-toolbar-sticky-height: 70px !default;
+$app-toolbar-sticky-height-mobile: 70px !default;
+$app-toolbar-sticky-z-index: 99 !default;
+$app-toolbar-sticky-z-index-mobile: 99 !default;
+$app-toolbar-sticky-backdrop-filter: null !default;
+$app-toolbar-sticky-backdrop-filter-mobile: null !default;
+$app-toolbar-sticky-bg-color: null !default;
+$app-toolbar-sticky-bg-color-dark: null !default;
+$app-toolbar-sticky-box-shadow: null !default;
+$app-toolbar-sticky-box-shadow-dark: null !default;
+$app-toolbar-sticky-border-top: null !default;
+$app-toolbar-sticky-border-top-dark: null !default;
+$app-toolbar-sticky-border-bottom: null !default;
+$app-toolbar-sticky-border-bottom-dark: null !default;
+
+// Hero
+$app-hero-bg-color: null !default;
+$app-hero-bg-color-dark: null !default;
+$app-hero-box-shadow: null !default;
+$app-hero-box-shadow-dark: null !default;
+$app-hero-border-top: null !default;
+$app-hero-border-top-dark: null !default;
+$app-hero-border-bottom: null !default;
+$app-hero-border-bottom-dark: null !default;
+
+// Sidebar base
+$app-sidebar-base-transition: width $app-general-transition-duration $app-general-transition-timing !default;
+$app-sidebar-base-width: 300px !default;
+$app-sidebar-base-width-mobile: 275px !default;
+$app-sidebar-base-z-index: null !default;
+$app-sidebar-base-z-index-mobile: 106 !default;
+$app-sidebar-base-bg-color: null !default;
+$app-sidebar-base-bg-color-dark: null !default;
+$app-sidebar-base-box-shadow: null !default;
+$app-sidebar-base-box-shadow-dark: null !default;
+$app-sidebar-base-border-start: null !default;
+$app-sidebar-base-border-start-dark: null !default;
+$app-sidebar-base-border-end: null !default;
+$app-sidebar-base-border-end-dark: null !default;
+$app-sidebar-base-gap-start: 0px !default;
+$app-sidebar-base-gap-end: 0px !default;
+$app-sidebar-base-gap-top: 0px !default;
+$app-sidebar-base-gap-bottom: 0px !default;
+$app-sidebar-base-gap-start-mobile: 0px !default;
+$app-sidebar-base-gap-end-mobile: 0px !default;
+$app-sidebar-base-gap-top-mobile: 0px !default;
+$app-sidebar-base-gap-bottom-mobile: 0px !default;
+
+// Sidebar fixed
+$app-sidebar-fixed-z-index: 105 !default;
+$app-sidebar-fixed-left: 0 !default;
+$app-sidebar-fixed-top: 0 !default;
+$app-sidebar-fixed-bottom: 0 !default;
+
+// Sidebar sticky
+$app-sidebar-sticky-top: auto !default;
+$app-sidebar-sticky-bottom: auto !default;
+$app-sidebar-sticky-left: auto !default;
+$app-sidebar-sticky-width: 300px !default;
+$app-sidebar-sticky-z-index: 105 !default;
+$app-sidebar-sticky-bg-color: null !default;
+$app-sidebar-sticky-bg-color-dark: null !default;
+$app-sidebar-sticky-box-shadow: null !default;
+$app-sidebar-sticky-box-shadow-dark: null !default;
+$app-sidebar-sticky-border-start: null !default;
+$app-sidebar-sticky-border-start-dark: null !default;
+$app-sidebar-sticky-border-end: null !default;
+$app-sidebar-sticky-border-end-dark: null !default;
+$app-sidebar-sticky-gap-start: 0px !default;
+$app-sidebar-sticky-gap-end: 0px !default;
+$app-sidebar-sticky-gap-top: 0px !default;
+$app-sidebar-sticky-gap-bottom: 0px !default;
+$app-sidebar-sticky-gap-start-mobile: 0px !default;
+$app-sidebar-sticky-gap-end-mobile: 0px !default;
+$app-sidebar-sticky-gap-top-mobile: 0px !default;
+$app-sidebar-sticky-gap-bottom-mobile: 0px !default;
+
+// Sidebar minimize
+$app-sidebar-minimize-width: 75px !default;
+$app-sidebar-minimize-width-mobile: 75px !default;
+$app-sidebar-minimize-bg-color: null !default;
+$app-sidebar-minimize-bg-color-dark: null !default;
+$app-sidebar-minimize-box-shadow: null !default;
+$app-sidebar-minimize-box-shadow-dark: null !default;
+$app-sidebar-minimize-hover-box-shadow: null !default;
+$app-sidebar-minimize-hover-box-shadow-dark: null !default;
+$app-sidebar-minimize-border-start: null !default;
+$app-sidebar-minimize-border-start-dark: null !default;
+$app-sidebar-minimize-border-end: null !default;
+$app-sidebar-minimize-border-end-dark: null !default;
+$app-sidebar-minimize-gap-start: 0px !default;
+$app-sidebar-minimize-gap-end: 0px !default;
+$app-sidebar-minimize-gap-top: 0px !default;
+$app-sidebar-minimize-gap-bottom: 0px !default;
+$app-sidebar-minimize-gap-start-mobile: 0px !default;
+$app-sidebar-minimize-gap-end-mobile: 0px !default;
+$app-sidebar-minimize-gap-top-mobile: 0px !default;
+$app-sidebar-minimize-gap-bottom-mobile: 0px !default;
+
+// Sidebar primary
+$app-sidebar-primary-base-transition: none !default;
+$app-sidebar-primary-base-width: 100px !default;
+$app-sidebar-primary-base-width-mobile: 100px !default;
+$app-sidebar-primary-base-z-index: 1 !default;
+$app-sidebar-primary-base-z-index-mobile: 1 !default;
+$app-sidebar-primary-base-bg-color: null !default;
+$app-sidebar-primary-base-bg-color-dark: null !default;
+$app-sidebar-primary-base-box-shadow: null !default;
+$app-sidebar-primary-base-box-shadow-dark: null !default;
+$app-sidebar-primary-base-border-start: null !default;
+$app-sidebar-primary-base-border-start-dark: null !default;
+$app-sidebar-primary-base-border-end: null !default;
+$app-sidebar-primary-base-border-end-dark: null !default;
+$app-sidebar-primary-base-gap-start: 0px !default;
+$app-sidebar-primary-base-gap-end: 0px !default;
+$app-sidebar-primary-base-gap-top: 0px !default;
+$app-sidebar-primary-base-gap-bottom: 0px !default;
+$app-sidebar-primary-base-gap-start-mobile: 0px !default;
+$app-sidebar-primary-base-gap-end-mobile: 0px !default;
+$app-sidebar-primary-base-gap-top-mobile: 0px !default;
+$app-sidebar-primary-base-gap-bottom-mobile: 0px !default;
+
+$app-sidebar-primary-minimize-width: 75px !default;
+$app-sidebar-primary-minimize-width-mobile: 75px !default;
+$app-sidebar-primary-minimize-z-index: null !default;
+$app-sidebar-primary-minimize-bg-color: null !default;
+$app-sidebar-primary-minimize-bg-color-dark: null !default;
+$app-sidebar-primary-minimize-box-shadow: null !default;
+$app-sidebar-primary-minimize-box-shadow-dark: null !default;
+$app-sidebar-primary-minimize-hover-box-shadow: null !default;
+$app-sidebar-primary-minimize-hover-box-shadow-dark: null !default;
+$app-sidebar-primary-minimize-border-start: null !default;
+$app-sidebar-primary-minimize-border-start-dark: null !default;
+$app-sidebar-primary-minimize-border-end: null !default;
+$app-sidebar-primary-minimize-border-end-dark: null !default;
+$app-sidebar-primary-minimize-gap-start: 0px !default;
+$app-sidebar-primary-minimize-gap-end: 0px !default;
+$app-sidebar-primary-minimize-gap-top: 0px !default;
+$app-sidebar-primary-minimize-gap-bottom: 0px !default;
+$app-sidebar-primary-minimize-gap-start-mobile: 0px !default;
+$app-sidebar-primary-minimize-gap-end-mobile: 0px !default;
+$app-sidebar-primary-minimize-gap-top-mobile: 0px !default;
+$app-sidebar-primary-minimize-gap-bottom-mobile: 0px !default;
+
+
+// Sidebar secondary
+$app-sidebar-secondary-base-transition: width $app-general-transition-duration $app-general-transition-timing, margin $app-general-transition-duration $app-general-transition-timing !default;
+$app-sidebar-secondary-base-z-index: null !default;
+$app-sidebar-secondary-base-z-index-mobile: null !default;
+$app-sidebar-secondary-base-bg-color: null !default;
+$app-sidebar-secondary-base-bg-color-dark: null !default;
+$app-sidebar-secondary-base-box-shadow: null !default;
+$app-sidebar-secondary-base-box-shadow-dark: null !default;
+$app-sidebar-secondary-base-border-start: null !default;
+$app-sidebar-secondary-base-border-start-dark: null !default;
+$app-sidebar-secondary-base-border-end: null !default;
+$app-sidebar-secondary-base-border-end-dark: null !default;
+$app-sidebar-secondary-base-gap-start: 0px !default;
+$app-sidebar-secondary-base-gap-end: 0px !default;
+$app-sidebar-secondary-base-gap-top: 0px !default;
+$app-sidebar-secondary-base-gap-bottom: 0px !default;
+$app-sidebar-secondary-base-gap-start-mobile: 0px !default;
+$app-sidebar-secondary-base-gap-end-mobile: 0px !default;
+$app-sidebar-secondary-base-gap-top-mobile: 0px !default;
+$app-sidebar-secondary-base-gap-bottom-mobile: 0px !default;
+
+$app-sidebar-secondary-minimize-width: 75px !default;
+$app-sidebar-secondary-minimize-width-mobile: 75px !default;
+$app-sidebar-secondary-minimize-z-index: null !default;
+$app-sidebar-secondary-minimize-bg-color: null !default;
+$app-sidebar-secondary-minimize-bg-color-dark: null !default;
+$app-sidebar-secondary-minimize-box-shadow: null !default;
+$app-sidebar-secondary-minimize-box-shadow-dark: null !default;
+$app-sidebar-secondary-minimize-hover-box-shadow: null !default;
+$app-sidebar-secondary-minimize-hover-box-shadow-dark: null !default;
+$app-sidebar-secondary-minimize-border-start: null !default;
+$app-sidebar-secondary-minimize-border-start-dark: null !default;
+$app-sidebar-secondary-minimize-border-end: null !default;
+$app-sidebar-secondary-minimize-border-end-dark: null !default;
+$app-sidebar-secondary-minimize-gap-start: 0px !default;
+$app-sidebar-secondary-minimize-gap-end: 0px !default;
+$app-sidebar-secondary-minimize-gap-top: 0px !default;
+$app-sidebar-secondary-minimize-gap-bottom: 0px !default;
+$app-sidebar-secondary-minimize-gap-start-mobile: 0px !default;
+$app-sidebar-secondary-minimize-gap-end-mobile: 0px !default;
+$app-sidebar-secondary-minimize-gap-top-mobile: 0px !default;
+$app-sidebar-secondary-minimize-gap-bottom-mobile: 0px !default;
+
+// Sidebar panel base
+$app-sidebar-panel-base-transition: none !default;
+$app-sidebar-panel-base-width: 300px !default;
+$app-sidebar-panel-base-width-mobile: 300px !default;
+$app-sidebar-panel-base-z-index: null !default;
+$app-sidebar-panel-base-z-index-mobile: null !default;
+$app-sidebar-panel-base-bg-color: null !default;
+$app-sidebar-panel-base-bg-color-dark: null !default;
+$app-sidebar-panel-base-bg-color-mobile: null !default;
+$app-sidebar-panel-base-bg-color-mobile-dark: null !default;
+$app-sidebar-panel-base-box-shadow: null !default;
+$app-sidebar-panel-base-box-shadow-dark: null !default;
+$app-sidebar-panel-base-box-shadow-mobile: null !default;
+$app-sidebar-panel-base-box-shadow-mobile-dark: null !default;
+$app-sidebar-panel-base-border-start: null !default;
+$app-sidebar-panel-base-border-start-dark: null !default;
+$app-sidebar-panel-base-border-start-mobile: null !default;
+$app-sidebar-panel-base-border-start-mobile-dark: null !default;
+$app-sidebar-panel-base-border-end: null !default;
+$app-sidebar-panel-base-border-end-dark: null !default;
+$app-sidebar-panel-base-border-end-mobile: null !default;
+$app-sidebar-panel-base-border-end-mobile-dark: null !default;
+$app-sidebar-panel-base-gap-start: 0px !default;
+$app-sidebar-panel-base-gap-end: 0px !default;
+$app-sidebar-panel-base-gap-top: 0px !default;
+$app-sidebar-panel-base-gap-bottom: 0px !default;
+$app-sidebar-panel-base-gap-start-mobile: 0px !default;
+$app-sidebar-panel-base-gap-end-mobile: 0px !default;
+$app-sidebar-panel-base-gap-top-mobile: 0px !default;
+$app-sidebar-panel-base-gap-bottom-mobile: 0px !default;
+
+// Sidebar panel fixed
+$app-sidebar-panel-fixed-z-index: 104 !default;
+$app-sidebar-panel-fixed-z-index-mobile: 105 !default;
+
+// Sidebar panel sticky
+$app-sidebar-panel-sticky-top: auto !default;
+$app-sidebar-panel-sticky-bottom: auto !default;
+$app-sidebar-panel-sticky-width: 300px !default;
+$app-sidebar-panel-sticky-z-index: 104 !default;
+$app-sidebar-panel-sticky-bg-color: null !default;
+$app-sidebar-panel-sticky-bg-color-dark: null !default;
+$app-sidebar-panel-sticky-box-shadow: null !default;
+$app-sidebar-panel-sticky-box-shadow-dark: null !default;
+$app-sidebar-panel-sticky-border-start: null !default;
+$app-sidebar-panel-sticky-border-start-dark: null !default;
+$app-sidebar-panel-sticky-border-end: null !default;
+$app-sidebar-panel-sticky-border-end-dark: null !default;
+$app-sidebar-panel-sticky-gap-start: 0px !default;
+$app-sidebar-panel-sticky-gap-end: 0px !default;
+$app-sidebar-panel-sticky-gap-top: 0px !default;
+$app-sidebar-panel-sticky-gap-bottom: 0px !default;
+$app-sidebar-panel-sticky-gap-start-mobile: 0px !default;
+$app-sidebar-panel-sticky-gap-end-mobile: 0px !default;
+$app-sidebar-panel-sticky-gap-top-mobile: 0px !default;
+$app-sidebar-panel-sticky-gap-bottom-mobile: 0px !default;
+
+// Sidebar panel minimize
+$app-sidebar-panel-minimize-width: 75px !default;
+$app-sidebar-panel-minimize-width-mobile: 75px !default;
+$app-sidebar-panel-minimize-bg-color: null !default;
+$app-sidebar-panel-minimize-bg-color-dark: null !default;
+$app-sidebar-panel-minimize-bg-color-mobile: null !default;
+$app-sidebar-panel-minimize-bg-color-mobile-dark: null !default;
+$app-sidebar-panel-minimize-box-shadow: null !default;
+$app-sidebar-panel-minimize-box-shadow-dark: null !default;
+$app-sidebar-panel-minimize-box-shadow-mobile: null !default;
+$app-sidebar-panel-minimize-box-shadow-mobile-dark: null !default;
+$app-sidebar-panel-minimize-hover-box-shadow: null !default;
+$app-sidebar-panel-minimize-hover-box-shadow-dark: null !default;
+$app-sidebar-panel-minimize-hover-box-shadow-mobile: null !default;
+$app-sidebar-panel-minimize-hover-box-shadow-mobile-dark: null !default;
+$app-sidebar-panel-minimize-border-start: null !default;
+$app-sidebar-panel-minimize-border-start-dark: null !default;
+$app-sidebar-panel-minimize-border-start-mobile: null !default;
+$app-sidebar-panel-minimize-border-start-mobile-dark: null !default;
+$app-sidebar-panel-minimize-border-end: null !default;
+$app-sidebar-panel-minimize-border-end-dark: null !default;
+$app-sidebar-panel-minimize-border-end-mobile: null !default;
+$app-sidebar-panel-minimize-border-end-mobile-dark: null !default;
+$app-sidebar-panel-minimize-gap-start: 0px !default;
+$app-sidebar-panel-minimize-gap-end: 0px !default;
+$app-sidebar-panel-minimize-gap-top: 0px !default;
+$app-sidebar-panel-minimize-gap-bottom: 0px !default;
+$app-sidebar-panel-minimize-gap-start-mobile: 0px !default;
+$app-sidebar-panel-minimize-gap-end-mobile: 0px !default;
+$app-sidebar-panel-minimize-gap-top-mobile: 0px !default;
+$app-sidebar-panel-minimize-gap-bottom-mobile: 0px !default;
+
+// Aside base
+$app-aside-base-transition: none;
+$app-aside-base-width: 300px !default;
+$app-aside-base-width-mobile: 275px !default;
+$app-aside-base-z-index: null !default;
+$app-aside-base-z-index-mobile: 106 !default;
+$app-aside-base-bg-color: null !default;
+$app-aside-base-bg-color-dark: null !default;
+$app-aside-base-box-shadow: null !default;
+$app-aside-base-box-shadow-dark: null !default;
+$app-aside-base-gap-start: 0px !default;
+$app-aside-base-gap-end: 0px !default;
+$app-aside-base-gap-top: 0px !default;
+$app-aside-base-gap-bottom: 0px !default;
+$app-aside-base-gap-start-mobile: 0px !default;
+$app-aside-base-gap-end-mobile: 0px !default;
+$app-aside-base-gap-top-mobile: 0px !default;
+$app-aside-base-gap-bottom-mobile: 0px !default;
+
+// Aside fixed
+$app-aside-fixed-z-index: 99 !default;
+$app-aside-fixed-right: 0 !default;
+$app-aside-fixed-top: 0 !default;
+$app-aside-fixed-bottom: 0 !default;
+
+// Aside sticky
+$app-aside-sticky-top: auto !default;
+$app-aside-sticky-bottom: auto !default;
+$app-aside-sticky-left: auto !default;
+$app-aside-sticky-width: 300px !default;
+$app-aside-sticky-z-index: 99 !default;
+$app-aside-sticky-bg-color: null !default;
+$app-aside-sticky-bg-color-dark: null !default;
+$app-aside-sticky-box-shadow: null !default;
+$app-aside-sticky-box-shadow-dark: null !default;
+$app-aside-sticky-gap-start: 0px !default;
+$app-aside-sticky-gap-end: 0px !default;
+$app-aside-sticky-gap-top: 0px !default;
+$app-aside-sticky-gap-bottom: 0px !default;
+$app-aside-sticky-gap-start-mobile: 0px !default;
+$app-aside-sticky-gap-end-mobile: 0px !default;
+$app-aside-sticky-gap-top-mobile: 0px !default;
+$app-aside-sticky-gap-bottom-mobile: 0px !default;
+
+// Aside minimize
+$app-aside-minimize-width: 75px !default;
+$app-aside-minimize-width-mobile: 75px !default;
+$app-aside-minimize-bg-color: null !default;
+$app-aside-minimize-bg-color-dark: null !default;
+$app-aside-minimize-bg-color-mobile: null !default;
+$app-aside-minimize-bg-color-mobile-dark: null !default;
+$app-aside-minimize-box-shadow: null !default;
+$app-aside-minimize-box-shadow-dark: null !default;
+$app-aside-minimize-box-shadow-mobile: null !default;
+$app-aside-minimize-box-shadow-mobile-dark: null !default;
+$app-aside-minimize-hover-box-shadow: null !default;
+$app-aside-minimize-hover-box-shadow-dark: null !default;
+$app-aside-minimize-border-start: null !default;
+$app-aside-minimize-border-start-dark: null !default;
+$app-aside-minimize-border-end: null !default;
+$app-aside-minimize-border-end-dark: null !default;
+$app-aside-minimize-gap-start: 0px !default;
+$app-aside-minimize-gap-end: 0px !default;
+$app-aside-minimize-gap-top: 0px !default;
+$app-aside-minimize-gap-bottom: 0px !default;
+$app-aside-minimize-gap-start-mobile: 0px !default;
+$app-aside-minimize-gap-end-mobile: 0px !default;
+$app-aside-minimize-gap-top-mobile: 0px !default;
+$app-aside-minimize-gap-bottom-mobile: 0px !default;
+
+// Footer
+$app-footer-transition: left $app-general-transition-duration $app-general-transition-timing, right $app-general-transition-duration $app-general-transition-timing;
+$app-footer-height: auto !default;
+$app-footer-height-mobile: auto !default;
+$app-footer-z-index: null !default;
+$app-footer-z-index-mobile: null !default;
+$app-footer-bg-color: null !default;
+$app-footer-bg-color-dark: null !default;
+$app-footer-box-shadow: null !default;
+$app-footer-box-shadow-dark: null !default;
+$app-footer-border-top: null !default;
+$app-footer-border-top-dark: null !default;
+
+// Footer fixed
+$app-footer-fixed-z-index: 100 !default;
+$app-footer-fixed-z-index-mobile: 100 !default;
+
+// Layout Builder
+$app-layout-builder-toggle-z-index: 105 !default;
+$app-layout-builder-toggle-bottom: 40px !default;
+$app-layout-builder-toggle-bottom-mobile: 15px !default;
+$app-layout-builder-toggle-end: 40px !default;
+$app-layout-builder-toggle-end-mobile: 15px !default;
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/_wrapper.scss b/Moonlight/Styles/layout/base/_wrapper.scss
new file mode 100644
index 00000000..bcf24dee
--- /dev/null
+++ b/Moonlight/Styles/layout/base/_wrapper.scss
@@ -0,0 +1,100 @@
+//
+// Wrapper
+//
+
+// General mode
+.app-wrapper {
+ display: flex;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Integration
+ .app-wrapper {
+ transition: $app-wrapper-transition;
+
+ // Header
+ [data-kt-app-header-sticky="on"] & {
+ margin-top: var(--#{$prefix}app-header-height-actual);
+ }
+
+ [data-kt-app-header-fixed="true"] & {
+ margin-top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-toolbar-sticky="on"] & {
+ margin-top: var(--#{$prefix}app-toolbar-height);
+ }
+
+ [data-kt-app-header-fixed="true"][data-kt-app-toolbar-sticky="on"] & {
+ margin-top: calc(var(--#{$prefix}app-header-height-actual) + var(--#{$prefix}app-toolbar-height-actual));
+ }
+
+ [data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"] & {
+ margin-top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height));
+ }
+
+ // Sidebar
+ [data-kt-app-sidebar-fixed="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-sidebar-panel-fixed="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ // Aside
+ [data-kt-app-aside-fixed="true"] & {
+ margin-right: calc(
+ var(--#{$prefix}app-aside-width) +
+ var(--#{$prefix}app-aside-gap-start, 0px) +
+ var(--#{$prefix}app-aside-gap-end, 0px)
+ );
+ }
+
+ // Footer
+ [data-kt-app-footer-fixed="true"] & {
+ margin-bottom: var(--#{$prefix}app-footer-height);
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Integration
+ .app-wrapper {
+ transition: $app-wrapper-transition;
+
+ // Header
+ [data-kt-app-header-sticky="on"] & {
+ margin-top: var(--#{$prefix}app-header-height-actual);
+ }
+
+ [data-kt-app-header-fixed-mobile="true"] & {
+ margin-top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-header-fixed-mobile="true"][data-kt-app-toolbar-sticky="on"] & {
+ margin-top: calc(var(--#{$prefix}app-header-height-actual) + var(--#{$prefix}app-toolbar-height-actual));
+ }
+
+ // Footer
+ [data-kt-app-footer-fixed-mobile="true"] & {
+ margin-bottom: var(--#{$prefix}app-footer-height);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/aside/_aside.scss b/Moonlight/Styles/layout/base/aside/_aside.scss
new file mode 100644
index 00000000..61eab75f
--- /dev/null
+++ b/Moonlight/Styles/layout/base/aside/_aside.scss
@@ -0,0 +1,275 @@
+//
+// Aside
+//
+
+// General mode
+.app-aside {
+ transition: $app-aside-base-transition;
+ background-color: var(--#{$prefix}app-aside-base-bg-color);
+ box-shadow: var(--#{$prefix}app-aside-base-box-shadow);
+}
+
+// Utilities
+.app-aside-minimize-d-flex,
+.app-aside-sticky-d-flex,
+.app-aside-collapse-d-flex,
+.app-aside-minimize-mobile-d-flex,
+.app-aside-collapse-mobile-d-flex {
+ display: none;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-aside {
+ display: flex;
+ flex-shrink: 0;
+ width: var(--#{$prefix}app-aside-width);
+ @include property( z-index, $app-aside-base-z-index);
+ @include property( margin-left, $app-aside-base-gap-start);
+ @include property( margin-right, $app-aside-base-gap-end);
+ @include property( margin-top, $app-aside-base-gap-top);
+ @include property( margin-bottom, $app-aside-base-gap-bottom);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-aside-width: #{$app-aside-base-width};
+ --#{$prefix}app-aside-width-actual: #{$app-aside-base-width};
+ --#{$prefix}app-aside-gap-start: #{$app-aside-base-gap-start};
+ --#{$prefix}app-aside-gap-end: #{$app-aside-base-gap-end};
+ --#{$prefix}app-aside-gap-top: #{$app-aside-base-gap-top};
+ --#{$prefix}app-aside-gap-bottom: #{$app-aside-base-gap-bottom};
+ }
+
+ [data-kt-app-aside-stacked="true"] {
+ --#{$prefix}app-aside-width: calc(var(--#{$prefix}app-aside-primary-width) + var(--#{$prefix}app-aside-secondary-width));
+ }
+
+ [data-kt-app-aside-minimize="on"] {
+ --#{$prefix}app-aside-width: #{$app-aside-minimize-width};
+ --#{$prefix}app-aside-gap-start: #{$app-aside-minimize-gap-start};
+ --#{$prefix}app-aside-gap-end: #{$app-aside-minimize-gap-end};
+ --#{$prefix}app-aside-gap-top: #{$app-aside-minimize-gap-top};
+ --#{$prefix}app-aside-gap-bottom: #{$app-aside-minimize-gap-bottom};
+ }
+
+ [data-kt-app-aside-sticky="on"] {
+ --#{$prefix}app-aside-width: #{$app-aside-sticky-width};
+ --#{$prefix}app-aside-gap-start: #{$app-aside-sticky-gap-start};
+ --#{$prefix}app-aside-gap-end: #{$app-aside-sticky-gap-end};
+ --#{$prefix}app-aside-gap-top: #{$app-aside-sticky-gap-top};
+ --#{$prefix}app-aside-gap-bottom: #{$app-aside-sticky-gap-bottom};
+ }
+
+ [data-kt-app-aside-collapse="on"] {
+ --#{$prefix}app-aside-width: 0px;
+ }
+
+ // States
+ .app-aside {
+ [data-kt-app-aside-static="true"] & {
+ position: relative;
+ }
+
+ [data-kt-app-aside-offcanvas="true"] & {
+ display: none;
+ }
+
+ [data-kt-app-aside-fixed="true"] & {
+ position: fixed;
+ @include property( z-index, $app-aside-fixed-z-index);
+ @include property( top, $app-aside-fixed-top);
+ @include property( bottom, $app-aside-fixed-bottom);
+ @include property( right, $app-aside-fixed-right);
+ }
+
+ [data-kt-app-aside-stacked="true"] & {
+ align-items: stretch;
+ }
+
+ [data-kt-app-aside-sticky="on"] & {
+ position: fixed;
+ transition: $app-aside-base-transition;
+
+ box-shadow: var(--#{$prefix}app-aside-sticky-box-shadow);
+ border-left: var(--#{$prefix}aside-sticky-border-start);
+ border-right: var(--#{$prefix}app-aside-sticky-border-end);
+
+ @include property( top, $app-aside-sticky-top);
+ @include property( bottom, $app-aside-sticky-bottom);
+ @include property( left, $app-aside-sticky-left);
+ @include property( z-index, $app-aside-sticky-z-index);
+ @include property( margin-left, $app-aside-sticky-gap-start);
+ @include property( margin-right, $app-aside-sticky-gap-end);
+ @include property( margin-top, $app-aside-sticky-gap-top);
+ @include property( margin-bottom, $app-aside-sticky-gap-bottom);
+ }
+
+ [data-kt-app-aside-minimize="on"] & {
+ transition: $app-aside-base-transition;
+
+ //background-color: var(--#{$prefix}app-aside-minimize-bg-color);
+ //box-shadow: var(--#{$prefix}app-aside-minimize-box-shadow);
+ //border-start: var(--#{$prefix}app-aside-minimize-border-start);
+ //border-end: var(--#{$prefix}app-aside-minimize-border-end);
+
+ @include property( margin-left, $app-aside-minimize-gap-start);
+ @include property( margin-right, $app-aside-minimize-gap-end);
+ @include property( margin-top, $app-aside-minimize-gap-top);
+ @include property( margin-bottom, $app-aside-minimize-gap-bottom);
+ }
+
+ [data-kt-app-aside-hoverable="true"] & {
+ .app-aside-wrapper {
+ width: var(--#{$prefix}app-aside-width-actual);
+ }
+ }
+
+ [data-kt-app-aside-hoverable="true"][data-kt-app-aside-minimize="on"] &:hover:not(.animating) {
+ transition: $app-aside-base-transition;
+ width: var(--#{$prefix}app-aside-width-actual);
+ box-shadow: var(--#{$prefix}app-aside-minimize-hover-box-shadow);
+ }
+
+ [data-kt-app-aside-collapse="on"] & {
+ transition: $app-aside-base-transition;
+ width: var(--#{$prefix}app-aside-width-actual);
+ margin-right: calc( -1 * var(--#{$prefix}app-aside-width-actual));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-aside-minimize="on"] {
+ .app-aside-minimize-d-none {
+ display: none !important;
+ }
+
+ .app-aside-minimize-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-aside-sticky="on"] {
+ .app-aside-sticky-d-none {
+ display: none !important;
+ }
+
+ .app-aside-sticky-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-aside-collapse="on"] {
+ .app-aside-collapse-d-none {
+ display: none !important;
+ }
+
+ .app-aside-collapse-d-flex {
+ display: flex !important;
+ }
+ }
+
+ // Integration
+ .app-aside {
+ // Header
+ [data-kt-app-aside-fixed="true"][data-kt-app-header-fixed="true"]:not([data-kt-app-aside-push-header="true"]) & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-aside-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"]:not([data-kt-app-aside-push-toolbar="true"]) & {
+ top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height, 0px));
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-aside {
+ display: none;
+ width: var(--#{$prefix}app-aside-width);
+ @include property( z-index, $app-aside-base-z-index-mobile);
+ @include property( margin-left, $app-aside-base-gap-start-mobile);
+ @include property( margin-right, $app-aside-base-gap-end-mobile);
+ @include property( margin-top, $app-aside-base-gap-top-mobile);
+ @include property( margin-bottom, $app-aside-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-aside-width: #{$app-aside-base-width-mobile};
+ --#{$prefix}app-aside-width-actual: #{$app-aside-base-width-mobile};
+ --#{$prefix}app-aside-gap-start: #{$app-aside-base-gap-start-mobile};
+ --#{$prefix}app-aside-gap-end: #{$app-aside-base-gap-end-mobile};
+ --#{$prefix}app-aside-gap-top: #{$app-aside-base-gap-top-mobile};
+ --#{$prefix}app-aside-gap-bottom: #{$app-aside-base-gap-bottom-mobile};
+ }
+
+ [data-kt-app-aside-minimize-mobile="on"] {
+ --#{$prefix}app-aside-width: #{$app-aside-minimize-width-mobile};
+ --#{$prefix}app-aside-gap-start: #{$app-aside-minimize-gap-start-mobile};
+ --#{$prefix}app-aside-gap-end: #{$app-aside-minimize-gap-end-mobile};
+ --#{$prefix}app-aside-gap-top: #{$app-aside-minimize-gap-top-mobile};
+ --#{$prefix}app-aside-gap-bottom: #{$app-aside-minimize-gap-bottom-mobile};
+ }
+
+ [data-kt-app-aside-collapse-mobile="on"] {
+ --#{$prefix}app-aside-width: 0px;
+ }
+
+ // States
+ .app-aside {
+ [data-kt-app-aside-stacked="true"] & {
+ align-items: stretch;
+ }
+
+ [data-kt-app-aside-minimize-mobile="on"] & {
+ transition: $app-aside-base-transition;
+ @include property( margin-left, $app-aside-minimize-gap-start-mobile);
+ @include property( margin-right, $app-aside-minimize-gap-end-mobile);
+ @include property( margin-top, $app-aside-minimize-gap-top-mobile);
+ @include property( margin-bottom, $app-aside-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-aside-hoverable-mobile="true"] & {
+ .app-aside-wrapper {
+ width: var(--#{$prefix}app-aside-width-actual);
+ }
+ }
+
+ [data-kt-app-aside-hoverable-mobile="true"][data-kt-app-aside-minimize-mobile="on"] &:hover:not(.animating) {
+ transition: $app-aside-base-transition;
+ width: var(--#{$prefix}app-aside-width-actual);
+ box-shadow: var(--#{$prefix}app-aside-minimize-hover-box-shadow-mobile);
+ }
+
+ [data-kt-app-aside-collapse-mobile="on"] & {
+ transition: $app-aside-base-transition;
+ width: var(--#{$prefix}app-aside-width-actual);
+ margin-right: calc( -1 * var(--#{$prefix}app-aside-width-actual));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-aside-minimize-mobile="on"] {
+ .app-aside-minimize-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-aside-minimize-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-aside-collapse-mobile="on"] {
+ .app-aside-collapse-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-aside-collapse-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/header/_header-primary.scss b/Moonlight/Styles/layout/base/header/_header-primary.scss
new file mode 100644
index 00000000..245554f1
--- /dev/null
+++ b/Moonlight/Styles/layout/base/header/_header-primary.scss
@@ -0,0 +1,135 @@
+//
+// Header primary
+//
+
+// General mode
+.app-header-primary {
+ transition: $app-header-primary-base-transition;
+ display: flex;
+ align-items: stretch;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-header-primary {
+ @include property( z-index, $app-header-primary-base-z-index);
+ background-color: var(--#{$prefix}app-header-primary-base-bg-color);
+ box-shadow: var(--#{$prefix}app-header-primary-base-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-primary-base-border-bottom);
+ }
+
+ // Vars
+ [data-kt-app-header-primary-enabled="true"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-base-height};
+ }
+
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-sticky-height};
+ }
+
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-minimize-height};
+ }
+
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-header-sticky="on"][data-kt-app-header-primary-sticky-hide="true"] {
+ --#{$prefix}app-header-primary-height: 0;
+ }
+
+ // States
+ .app-header-primary {
+ height: var(--#{$prefix}app-header-primary-height);
+
+ [data-kt-app-header-primary-fixed="true"] & {
+ @include property( z-index, $app-header-primary-fixed-z-index);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-header-primary-static="true"] & {
+ position: relative;
+ }
+
+ [data-kt-app-header-primary-sticky="on"] & {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ @include property( height, $app-header-primary-sticky-height);
+ @include property( z-index, $app-header-primary-sticky-z-index);
+
+ background-color: var(--#{$prefix}app-header-primary-sticky-bg-color);
+ box-shadow: var(--#{$prefix}app-header-primary-sticky-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-primary-sticky-border-bottom);
+ }
+
+ [data-kt-app-header-primary-minimize="on"] & {
+ transition: $app-header-primary-base-transition;
+ @include property( height, $app-header-primary-minimize-height);
+ @include property( z-index, $app-header-primary-minimize-z-index);
+
+ background-color: var(--#{$prefix}app-header-primary-minimize-bg-color);
+ box-shadow: var(--#{$prefix}app-header-primary-minimize-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-primary-minimize-border-bottom);
+ }
+
+ [data-kt-app-header-sticky="on"][data-kt-app-header-primary-sticky-hide="true"] & {
+ display: none !important;
+ }
+ }
+
+ // Integration
+ .app-header-primary {
+ // Sidebar
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-header .app-header-primary {
+ flex-grow: 1;
+ @include property( z-index, $app-header-primary-base-z-index-mobile);
+ height: var(--#{$prefix}app-header-primary-height);
+ border-bottom: var(--#{$prefix}app-header-primary-base-border-bottom);
+ box-shadow: var(--#{$prefix}app-header-primary-base-box-shadow);
+ }
+
+ .app-header-primary {
+ background-color: var(--#{$prefix}app-header-primary-base-bg-color);
+ }
+
+ // Vars
+ [data-kt-app-header-primary-enabled="true"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-base-height-mobile};
+ }
+
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-sticky-height-mobile};
+ }
+
+ [data-kt-app-header-primary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-primary-height: #{$app-header-primary-minimize-height-mobile};
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/header/_header-secondary.scss b/Moonlight/Styles/layout/base/header/_header-secondary.scss
new file mode 100644
index 00000000..d2802ed6
--- /dev/null
+++ b/Moonlight/Styles/layout/base/header/_header-secondary.scss
@@ -0,0 +1,139 @@
+//
+// Header secondary
+//
+
+// General mode
+.app-header-secondary {
+ transition: $app-header-secondary-base-transition;
+ display: flex;
+ align-items: stretch;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-header-secondary {
+ @include property( z-index, $app-header-secondary-base-z-index);
+
+ background-color: var(--#{$prefix}app-header-secondary-base-bg-color);
+ box-shadow: var(--#{$prefix}app-header-secondary-base-box-shadow);
+ border-top: var(--#{$prefix}app-header-secondary-base-border-top);
+ border-bottom: var(--#{$prefix}app-header-secondary-base-border-bottom);
+ }
+
+ // Vars
+ [data-kt-app-header-secondary-enabled="true"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-base-height};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-sticky-height};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-minimize-height};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-sticky="on"][data-kt-app-header-secondary-sticky-hide="true"] {
+ --#{$prefix}app-header-secondary-height: 0;
+ }
+
+ // States
+ .app-header-secondary {
+ height: var(--#{$prefix}app-header-secondary-height);
+
+ [data-kt-app-header-secondary-fixed="true"] & {
+ @include property( z-index, $app-header-secondary-fixed-z-index);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-header-secondary-static="true"] & {
+ position: static;
+ }
+
+ [data-kt-app-header-secondary-sticky="on"] & {
+ transition: $app-header-secondary-base-transition;
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ @include property( height, $app-header-secondary-sticky-height);
+ @include property( z-index, $app-header-secondary-sticky-z-index);
+
+ background-color: var(--#{$prefix}app-header-secondary-sticky-bg-color);
+ box-shadow: var(--#{$prefix}app-header-secondary-sticky-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-secondary-sticky-border-bottom);
+ }
+
+ [data-kt-app-header-secondary-minimize="on"] & {
+ transition: $app-header-secondary-base-transition;
+ @include property( height, $app-header-secondary-minimize-height);
+ @include property( z-index, $app-header-secondary-minimize-z-index);
+
+ background-color: var(--#{$prefix}app-header-secondary-minimize-bg-color);
+ box-shadow: var(--#{$prefix}app-header-secondary-minimize-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-secondary-minimize-border-bottom);
+ }
+
+ [data-kt-app-header-sticky="on"][data-kt-app-header-secondary-sticky-hide="true"] & {
+ display: none !important;
+ }
+ }
+
+ // Integration
+ .app-header-secondary {
+ // Sidebar
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-header .app-header-secondary {
+ flex-grow: 1;
+ height: var(--#{$prefix}app-header-secondary-height);
+ box-shadow: var(--#{$prefix}app-header-secondary-base-box-shadow);
+ border-top: var(--#{$prefix}app-header-secondary-base-border-top);
+ border-bottom: var(--#{$prefix}app-header-secondary-base-border-bottom);
+ @include property( z-index, $app-header-secondary-base-z-index-mobile);
+ }
+
+ .app-header-secondary {
+ background-color: var(--#{$prefix}app-header-secondary-base-bg-color);
+ }
+
+ // Vars
+ [data-kt-app-header-secondary-enabled="true"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-base-height-mobile};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-sticky-height-mobile};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-secondary-height: #{$app-header-secondary-minimize-height-mobile};
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/header/_header-tertiary.scss b/Moonlight/Styles/layout/base/header/_header-tertiary.scss
new file mode 100644
index 00000000..afb5d35b
--- /dev/null
+++ b/Moonlight/Styles/layout/base/header/_header-tertiary.scss
@@ -0,0 +1,138 @@
+//
+// Header tertiary
+//
+
+// General mode
+.app-header-tertiary {
+ transition: $app-header-tertiary-base-transition;
+ display: flex;
+ align-items: stretch;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-header-tertiary {
+ @include property( z-index, $app-header-tertiary-base-z-index);
+
+ background-color: var(--#{$prefix}app-header-tertiary-base-bg-color);
+ box-shadow: var(--#{$prefix}app-header-tertiary-base-box-shadow);
+ border-top: var(--#{$prefix}app-header-tertiary-base-border-top);
+ border-bottom: var(--#{$prefix}app-header-tertiary-base-border-bottom);
+ }
+
+ // Vars
+ [data-kt-app-header-tertiary-enabled="true"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-base-height};
+ }
+
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-sticky-height};
+ }
+
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-minimize-height};
+ }
+
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-header-sticky="on"][data-kt-app-header-tertiary-sticky-hide="true"] {
+ --#{$prefix}app-header-tertiary-height: 0;
+ }
+
+ // States
+ .app-header-tertiary {
+ height: var(--#{$prefix}app-header-tertiary-height);
+
+ [data-kt-app-header-tertiary-fixed="true"] & {
+ @include property( z-index, $app-header-tertiary-fixed-z-index);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-header-tertiary-static="true"] & {
+ position: static;
+ }
+
+ [data-kt-app-header-tertiary-sticky="on"] & {
+ transition: $app-header-tertiary-base-transition;
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ @include property( height, $app-header-tertiary-sticky-height);
+ @include property( z-index, $app-header-tertiary-sticky-z-index);
+
+ background-color: var(--#{$prefix}app-header-tertiary-sticky-bg-color);
+ box-shadow: var(--#{$prefix}app-header-tertiary-sticky-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-tertiary-sticky-border-bottom);
+ }
+
+ [data-kt-app-header-tertiary-minimize="on"] & {
+ transition: $app-header-tertiary-base-transition;
+ @include property( height, $app-header-tertiary-minimize-height);
+ @include property( z-index, $app-header-tertiary-minimize-z-index);
+
+ background-color: var(--#{$prefix}app-header-tertiary-minimize-bg-color);
+ box-shadow: var(--#{$prefix}app-header-tertiary-minimize-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-tertiary-minimize-border-bottom);
+ }
+
+ [data-kt-app-header-sticky="on"][data-kt-app-header-tertiary-sticky-hide="true"] & {
+ display: none !important;
+ }
+ }
+
+ // Integration
+ .app-header-tertiary {
+ // Sidebar
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-header .app-header-tertiary {
+ flex-grow: 1;
+ height: var(--#{$prefix}app-header-tertiary-height);
+ border-top: var(--#{$prefix}app-header-tertiary-base-border-top);
+ box-shadow: var(--#{$prefix}app-header-tertiary-base-box-shadow);
+ @include property( z-index, $app-header-tertiary-base-z-index-mobile);
+ }
+
+ .app-header-tertiary {
+ background-color: var(--#{$prefix}app-header-tertiary-base-bg-color);
+ }
+
+ // Vars
+ [data-kt-app-header-tertiary-enabled="true"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-base-height-mobile};
+ }
+
+ [data-kt-app-header-tertiary-enabled="true"][data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-sticky-height-mobile};
+ }
+
+ [data-kt-app-header-secondary-enabled="true"][data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-tertiary-height: #{$app-header-tertiary-minimize-height-mobile};
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/header/_header.scss b/Moonlight/Styles/layout/base/header/_header.scss
new file mode 100644
index 00000000..aa9a26c2
--- /dev/null
+++ b/Moonlight/Styles/layout/base/header/_header.scss
@@ -0,0 +1,224 @@
+//
+// sidebar
+//
+
+// General mode
+.app-header {
+ transition: $app-header-base-transition;
+ display: flex;
+ align-items: stretch;
+ background-color: var(--#{$prefix}app-header-base-bg-color);
+ box-shadow: var(--#{$prefix}app-header-base-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-base-border-bottom);
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-header {
+ @include property( z-index, $app-header-base-z-index);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-header-height: #{$app-header-base-height};
+ --#{$prefix}app-header-height-actual: #{$app-header-base-height};
+ }
+
+ [data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-height: #{$app-header-sticky-height};
+ --#{$prefix}app-header-height-actual: #{$app-header-base-height};
+ }
+
+ [data-kt-app-header-sticky="on"][data-kt-app-header-stacked="true"] {
+ --#{$prefix}app-header-height: calc(var(--#{$prefix}app-header-primary-height, 0px) + var(--#{$prefix}app-header-secondary-height, 0px) + var(--#{$prefix}app-header-tertiary-height, 0px));
+ --#{$prefix}app-header-height-actual: calc(#{$app-header-primary-base-height} + #{$app-header-secondary-base-height} + #{$app-header-tertiary-base-height});
+ }
+
+ [data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-height: #{$app-header-minimize-height};
+ }
+
+ // States
+ .app-header {
+ height: var(--#{$prefix}app-header-height);
+
+ [data-kt-app-header-fixed="true"] & {
+ @include property( z-index, $app-header-fixed-z-index);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-header-static="true"] & {
+ position: relative;
+ }
+
+ [data-kt-app-header-stacked="true"] & {
+ flex-direction: column;
+ height: calc(var(--#{$prefix}app-header-primary-height) + var(--#{$prefix}app-header-secondary-height, 0px) + var(--#{$prefix}app-header-tertiary-height, 0px));
+ }
+
+ [data-kt-app-header-sticky="on"] & {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ @include property( z-index, $app-header-sticky-z-index);
+ @include property( backdrop-filter, $app-header-sticky-backdrop-filter);
+
+ background-color: var(--#{$prefix}app-header-sticky-bg-color);
+ box-shadow: var(--#{$prefix}app-header-sticky-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-sticky-border-bottom);
+ }
+
+ [data-kt-app-header-minimize="on"] & {
+ transition: $app-header-base-transition;
+ @include property( z-index, $app-header-minimize-z-index);
+ @include property( backdrop-filter, $app-header-minimize-backdrop-filter);
+
+ background-color: var(--#{$prefix}app-header-minimize-bg-color);
+ box-shadow: var(--#{$prefix}app-header-minimize-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-minimize-border-bottom);
+ }
+
+ .app-header-mobile-drawer {
+ display: flex;
+ }
+ }
+
+ // Integration
+ .app-header {
+ // Sidebar
+ [data-kt-app-header-fixed="true"][data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-header="true"] &,
+ [data-kt-app-header-fixed="true"][data-kt-app-sidebar-sticky="on"][data-kt-app-sidebar-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ body:not([data-kt-app-header-fixed="true"])[data-kt-app-sidebar-fixed="true"][data-kt-app-sidebar-push-header="true"] &,
+ body:not([data-kt-app-header-fixed="true"])[data-kt-app-sidebar-sticky="on"][data-kt-app-sidebar-push-header="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px)
+ );
+ }
+
+ // Sidebar Panel
+ [data-kt-app-header-fixed="true"][data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-header="true"] &,
+ [data-kt-app-header-fixed="true"][data-kt-app-sidebar-panel-sticky="on"][data-kt-app-sidebar-panel-push-header="true"] & {
+ left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ body:not([data-kt-app-header-fixed="true"])[data-kt-app-sidebar-panel-fixed="true"][data-kt-app-sidebar-panel-push-header="true"] &,
+ body:not([data-kt-app-header-fixed="true"])[data-kt-app-sidebar-panel-sticky="on"][data-kt-app-sidebar-panel-push-header="true"] & {
+ margin-left: calc(
+ var(--#{$prefix}app-sidebar-width) +
+ var(--#{$prefix}app-sidebar-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-gap-end, 0px) +
+ var(--#{$prefix}app-sidebar-panel-width) +
+ var(--#{$prefix}app-sidebar-panel-gap-start, 0px) +
+ var(--#{$prefix}app-sidebar-panel-gap-end, 0px)
+ );
+ }
+
+ // Toolbar
+ [data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"] & {
+ box-shadow: none;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-header {
+ @include property( z-index, $app-header-base-z-index-mobile);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-header-height: #{$app-header-base-height-mobile};
+ }
+
+ [data-kt-app-header-sticky="on"] {
+ --#{$prefix}app-header-height: #{$app-header-sticky-height-mobile};
+ --#{$prefix}app-header-height-actual: #{$app-header-sticky-height-mobile};
+ }
+
+ [data-kt-app-header-minimize="on"] {
+ --#{$prefix}app-header-height: #{$app-header-minimize-height-mobile};
+ --#{$prefix}app-header-height-actual: #{$app-header-minimize-height-mobile};
+ }
+
+ // States
+ .app-header {
+ height: var(--#{$prefix}app-header-height);
+ align-items: stretch;
+
+ .app-header-mobile-drawer {
+ display: none;
+ }
+
+ [data-kt-app-header-stacked="true"] & {
+ flex-direction: column;
+ height: calc(var(--#{$prefix}app-header-primary-height) + var(--#{$prefix}app-header-secondary-height, 0px) + var(--#{$prefix}app-header-tertiary-height, 0px));
+ }
+
+ [data-kt-app-header-fixed-mobile="true"] & {
+ @include property( z-index, $app-header-fixed-z-index-mobile);
+ transition: $app-header-base-transition;
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+
+ [data-kt-app-header-sticky="on"] & {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ @include property( z-index, $app-header-sticky-z-index-mobile);
+ @include property( backdrop-filter, $app-header-sticky-backdrop-filter-mobile);
+
+ background-color: var(--#{$prefix}app-header-sticky-bg-color);
+ box-shadow: var(--#{$prefix}app-header-sticky-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-sticky-border-bottom);
+ }
+
+ [data-kt-app-header-minimize="on"] & {
+ @include property( z-index, $app-header-minimize-z-index-mobile);
+ @include property( backdrop-filter, $app-header-minimize-backdrop-filter-mobile);
+
+ transition: $app-header-base-transition;
+ background-color: var(--#{$prefix}app-header-minimize-bg-color);
+ box-shadow: var(--#{$prefix}app-header-minimize-box-shadow);
+ border-bottom: var(--#{$prefix}app-header-minimize-border-bottom);
+ }
+ }
+
+ // Integration
+ .app-header {
+ // Toolbar
+ [data-kt-app-header-fixed-mobile="true"][data-kt-app-toolbar-fixed-mobile="true"] & {
+ box-shadow: none;
+ }
+
+ [data-kt-app-header-fixed-mobile="true"][data-kt-app-toolbar-sticky="on"] & {
+ box-shadow: none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/mixins/_layout-minimize.scss b/Moonlight/Styles/layout/base/mixins/_layout-minimize.scss
new file mode 100644
index 00000000..31b88d04
--- /dev/null
+++ b/Moonlight/Styles/layout/base/mixins/_layout-minimize.scss
@@ -0,0 +1,41 @@
+//
+// Hoverable
+//
+
+@mixin app-layout-minimize($class) {
+ // Desktop mode
+ @include media-breakpoint-up(lg) {
+ [data-kt-#{$class}-minimize="on"]:not([data-kt-#{$class}-hoverable="true"]) {
+ .#{$class} {
+ @content;
+ }
+ }
+
+ [data-kt-#{$class}-minimize="on"][data-kt-#{$class}-hoverable="true"] {
+ .#{$class} {
+ &:not(:hover) {
+ @content;
+ }
+ }
+ }
+ }
+}
+
+@mixin app-layout-minimize-mobile($class) {
+ // Tablet & mobile modes
+ @include media-breakpoint-down(lg) {
+ [data-kt-#{$class}-minimize-mobile="on"]:not[data-kt-#{$class}-hoverable-mobile="true"] {
+ .#{$class} {
+ @content;
+ }
+ }
+
+ [data-kt-#{$class}-minimize-mobile="on"][data-kt-#{$class}-hoverable-mobile="true"] {
+ .#{$class} {
+ &:not(:hover) {
+ @content;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/mixins/_layout-transition.scss b/Moonlight/Styles/layout/base/mixins/_layout-transition.scss
new file mode 100644
index 00000000..4e0a84d4
--- /dev/null
+++ b/Moonlight/Styles/layout/base/mixins/_layout-transition.scss
@@ -0,0 +1,7 @@
+//
+// Layout Transition Mixin
+//
+
+@mixin app-layout-transition($properties: all) {
+ transition: $properties $app-general-transition-duration $app-general-transition-timing !important;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/sidebar/_sidebar-panel.scss b/Moonlight/Styles/layout/base/sidebar/_sidebar-panel.scss
new file mode 100644
index 00000000..e03c2ce3
--- /dev/null
+++ b/Moonlight/Styles/layout/base/sidebar/_sidebar-panel.scss
@@ -0,0 +1,281 @@
+//
+// sidebar
+//
+
+// General mode
+.app-sidebar-panel {
+ transition: $app-sidebar-panel-base-transition;
+ background-color: var(--#{$prefix}app-sidebar-panel-base-bg-color);
+ box-shadow: var(--#{$prefix}app-sidebar-panel-base-box-shadow);
+ border-left: var(--#{$prefix}app-sidebar-panel-base-border-start);
+ border-right: var(--#{$prefix}app-sidebar-panel-base-border-end);
+}
+
+// Utilities
+.app-sidebar-panel-minimize-d-flex,
+.app-sidebar-panel-sticky-d-flex,
+.app-sidebar-panel-collapse-d-flex,
+.app-sidebar-panel-minimize-mobile-d-flex,
+.app-sidebar-panel-collapse-mobile-d-flex {
+ display: none;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-sidebar-panel {
+ display: flex;
+ flex-shrink: 0;
+ width: var(--#{$prefix}app-sidebar-panel-width);
+
+ @include property( z-index, $app-sidebar-panel-base-z-index);
+ @include property( margin-left, $app-sidebar-panel-base-gap-start);
+ @include property( margin-right, $app-sidebar-panel-base-gap-end);
+ @include property( margin-top, $app-sidebar-panel-base-gap-top);
+ @include property( margin-bottom, $app-sidebar-panel-base-gap-bottom);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-panel-width: #{$app-sidebar-panel-base-width};
+ --#{$prefix}app-sidebar-panel-width-actual: #{$app-sidebar-panel-base-width};
+
+ --#{$prefix}app-sidebar-panel-gap-start: #{$app-sidebar-panel-base-gap-start};
+ --#{$prefix}app-sidebar-panel-gap-end: #{$app-sidebar-panel-base-gap-end};
+ --#{$prefix}app-sidebar-panel-gap-top: #{$app-sidebar-panel-base-gap-top};
+ --#{$prefix}app-sidebar-panel-gap-bottom: #{$app-sidebar-panel-base-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-panel-minimize="on"] {
+ --#{$prefix}app-sidebar-panel-width: #{$app-sidebar-panel-minimize-width};
+
+ --#{$prefix}app-sidebar-panel-gap-start: #{$app-sidebar-panel-minimize-gap-start};
+ --#{$prefix}app-sidebar-panel-gap-end: #{$app-sidebar-panel-minimize-gap-end};
+ --#{$prefix}app-sidebar-panel-gap-top: #{$app-sidebar-panel-minimize-gap-top};
+ --#{$prefix}app-sidebar-panel-gap-bottom: #{$app-sidebar-panel-minimize-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-panel-sticky="on"] {
+ --#{$prefix}app-sidebar-panel-width: #{$app-sidebar-panel-sticky-width};
+
+ --#{$prefix}app-sidebar-panel-gap-start: #{$app-sidebar-panel-sticky-gap-start};
+ --#{$prefix}app-sidebar-panel-gap-end: #{$app-sidebar-panel-sticky-gap-end};
+ --#{$prefix}app-sidebar-panel-gap-top: #{$app-sidebar-panel-sticky-gap-top};
+ --#{$prefix}app-sidebar-panel-gap-bottom: #{$app-sidebar-panel-sticky-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-panel-collapse="on"] {
+ --#{$prefix}app-sidebar-panel-width-actual: #{$app-sidebar-panel-base-width};
+ --#{$prefix}app-sidebar-panel-width: 0px;
+ }
+
+ // States
+ .app-sidebar-panel {
+ [data-kt-app-sidebar-panel-static="true"] & {
+ position: relative;
+ }
+
+ [data-kt-app-sidebar-panel-offcanvas="true"] & {
+ display: none;
+ }
+
+ [data-kt-app-sidebar-panel-fixed="true"] & {
+ @include property( z-index, $app-sidebar-panel-fixed-z-index);
+ position: fixed;
+ left: calc(var(--#{$prefix}app-sidebar-width) + var(--#{$prefix}app-sidebar-gap-start, 0px) + var(--#{$prefix}app-sidebar-gap-end, 0px));
+ top: 0;
+ bottom: 0;
+ }
+
+ [data-kt-app-sidebar-panel-sticky="on"] & {
+ position: fixed;
+ left: calc(var(--#{$prefix}app-sidebar-width) + var(--#{$prefix}app-sidebar-gap-start, 0px) + var(--#{$prefix}app-sidebar-gap-end, 0px));
+ top: 0;
+ bottom: 0;
+ transition: $app-sidebar-panel-base-transition;
+
+ //box-shadow: var(--#{$prefix}app-sidebar-panel-sticky-box-shadow);
+ //border-left: var(--#{$prefix}app-sidebar-panel-sticky-border-start);
+ //border-right: var(--#{$prefix}app-sidebar-panel-sticky-border-end);
+
+ @include property( z-index, $app-sidebar-panel-sticky-z-index);
+ @include property( margin-left, $app-sidebar-panel-sticky-gap-start);
+ @include property( margin-right, $app-sidebar-panel-sticky-gap-end);
+ @include property( margin-top, $app-sidebar-panel-sticky-gap-top);
+ @include property( margin-bottom, $app-sidebar-panel-sticky-gap-bottom);
+ }
+
+ [data-kt-app-sidebar-panel-minimize="on"] & {
+ transition: $app-sidebar-panel-base-transition;
+
+ //background-color: var(--#{$prefix}app-sidebar-panel-minimize-bg-color);
+ //box-shadow: var(--#{$prefix}app-sidebar-panel-minimize-box-shadow);
+ //border-left: var(--#{$prefix}app-sidebar-panel-minimize-border-start);
+ //border-right: var(--#{$prefix}app-sidebar-panel-minimize-border-end);
+
+ @include property( margin-left, $app-sidebar-panel-minimize-gap-start);
+ @include property( margin-right, $app-sidebar-panel-minimize-gap-end);
+ @include property( margin-top, $app-sidebar-panel-minimize-gap-top);
+ @include property( margin-bottom, $app-sidebar-panel-minimize-gap-bottom);
+ }
+
+ [data-kt-app-sidebar-panel-hoverable="true"] & {
+ .app-sidebar-panel-hoverable {
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-panel-hoverable="true"][data-kt-app-sidebar-panel-minimize="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-panel-base-transition;
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-panel-minimize-hover-box-shadow);
+ }
+
+ [data-kt-app-sidebar-panel-collapse="on"] & {
+ transition: $app-sidebar-panel-base-transition;
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+ margin-left: calc( -1 * (var(--#{$prefix}app-sidebar-panel-width-actual) + var(--#{$prefix}app-sidebar-gap-start, 0px) + var(--#{$prefix}app-sidebar-gap-end, 0px)));
+ }
+ }
+
+ // Integration
+ .app-sidebar-panel {
+ // Header
+ [data-kt-app-sidebar-panel-fixed="true"][data-kt-app-header-fixed="true"]:not([data-kt-app-sidebar-panel-push-header="true"]) & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-sidebar-panel-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"]:not([data-kt-app-sidebar-panel-push-toolbar="true"]) & {
+ top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height, 0));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-panel-minimize="on"] {
+ .app-sidebar-panel-minimize-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-panel-minimize-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-panel-sticky="on"] {
+ .app-sidebar-panel-sticky-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-panel-sticky-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-panel-collapse="on"] {
+ .app-sidebar-panel-collapse-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-panel-collapse-d-flex {
+ display: flex !important;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-sidebar-panel {
+ display: none;
+ width: var(--#{$prefix}app-sidebar-panel-width);
+
+ @include property( z-index, $app-sidebar-panel-base-z-index-mobile);
+ @include property( margin-left, $app-sidebar-panel-base-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-panel-base-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-panel-base-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-panel-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-panel-width: #{$app-sidebar-panel-base-width-mobile};
+ --#{$prefix}app-sidebar-panel-width-actual: #{$app-sidebar-panel-base-width-mobile};
+
+ --#{$prefix}app-sidebar-panel-gap-start: #{$app-sidebar-panel-base-gap-start-mobile};
+ --#{$prefix}app-sidebar-panel-gap-end: #{$app-sidebar-panel-base-gap-end-mobile};
+ --#{$prefix}app-sidebar-panel-gap-top: #{$app-sidebar-panel-base-gap-top-mobile};
+ --#{$prefix}app-sidebar-panel-gap-bottom: #{$app-sidebar-panel-base-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-panel-minimize-mobile="on"] {
+ --#{$prefix}app-sidebar-panel-width: #{$app-sidebar-panel-minimize-width-mobile};
+
+ --#{$prefix}app-sidebar-panel-gap-start: #{$app-sidebar-panel-minimize-gap-start-mobile};
+ --#{$prefix}app-sidebar-panel-gap-end: #{$app-sidebar-panel-minimize-gap-end-mobile};
+ --#{$prefix}app-sidebar-panel-gap-top: #{$app-sidebar-panel-minimize-gap-top-mobile};
+ --#{$prefix}app-sidebar-panel-gap-bottom: #{$app-sidebar-panel-minimize-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-panel-collapse-mobile="on"] {
+ --#{$prefix}app-sidebar-panel-width-actual: #{$app-sidebar-panel-base-width-mobile};
+ --#{$prefix}app-sidebar-panel-width: 0px;
+ }
+
+ // States
+ .app-sidebar-panel {
+ [data-kt-app-sidebar-panel-minimize-mobile="on"] & {
+ transition: $app-sidebar-panel-base-transition;
+
+ background-color: var(--#{$prefix}app-sidebar-panel-minimize-bg-color-mobile);
+ box-shadow: var(--#{$prefix}app-sidebar-panel-minimize-box-shadow-mobile);
+ border-left: var(--#{$prefix}app-sidebar-panel-minimize-border-start-mobile);
+ border-right: var(--#{$prefix}app-sidebar-panel-minimize-border-end-mobile);
+
+ @include property( margin-left, $app-sidebar-panel-minimize-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-panel-minimize-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-panel-minimize-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-panel-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-sidebar-panel-hoverable-mobile="true"] & {
+ .app-sidebar-panel-hoverable {
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-panel-hoverable-mobile="true"][data-kt-app-sidebar-panel-minimize-mobile="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-panel-base-transition;
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+
+ box-shadow: var(--#{$prefix}app-sidebar-panel-minimize-hover-box-shadow-mobile);
+ }
+
+ [data-kt-app-sidebar-panel-collapse-mobile="on"] & {
+ transition: $app-sidebar-panel-base-transition;
+ width: var(--#{$prefix}app-sidebar-panel-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-panel-width-actual));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-panel-minimize-mobile="on"] {
+ .app-sidebar-panel-minimize-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-panel-minimize-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-panel-collapse-mobile="on"] {
+ .app-sidebar-panel-collapse-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-panel-collapse-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/sidebar/_sidebar-primary.scss b/Moonlight/Styles/layout/base/sidebar/_sidebar-primary.scss
new file mode 100644
index 00000000..7bd4b8d5
--- /dev/null
+++ b/Moonlight/Styles/layout/base/sidebar/_sidebar-primary.scss
@@ -0,0 +1,230 @@
+//
+// sidebar Primary
+//
+
+// General mode
+.app-sidebar-primary {
+ transition: $app-sidebar-primary-base-transition;
+ position: relative;
+ flex-shrink: 0;
+ background-color: var(--#{$prefix}app-sidebar-primary-base-bg-color);
+ box-shadow: var(--#{$prefix}app-sidebar-primary-base-box-shadow);
+ border-left: var(--#{$prefix}app-sidebar-primary-base-border-start);
+ border-right: var(--#{$prefix}app-sidebar-primary-base-border-end);
+}
+
+// Utilities
+.app-sidebar-primary-collapse-d-flex,
+.app-sidebar-primary-minimize-d-flex,
+.app-sidebar-primary-collapse-mobile-d-flex,
+.app-sidebar-primary-minimize-mobile-d-flex {
+ display: none;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-sidebar-primary {
+ @include property( z-index, $app-sidebar-primary-base-z-index);
+ @include property( margin-left, $app-sidebar-primary-base-gap-start);
+ @include property( margin-right, $app-sidebar-primary-base-gap-end);
+ @include property( margin-top, $app-sidebar-primary-base-gap-top);
+ @include property( margin-bottom, $app-sidebar-primary-base-gap-bottom);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-primary-width-actual: #{$app-sidebar-primary-base-width};
+ }
+
+ [data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-primary-width: #{$app-sidebar-primary-base-width};
+
+ --#{$prefix}app-sidebar-primary-gap-start: #{$app-sidebar-primary-base-gap-start};
+ --#{$prefix}app-sidebar-primary-gap-end: #{$app-sidebar-primary-base-gap-end};
+ --#{$prefix}app-sidebar-primary-gap-top: #{$app-sidebar-primary-base-gap-top};
+ --#{$prefix}app-sidebar-primary-gap-bottom: #{$app-sidebar-primary-base-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-primary-minimize="on"] {
+ --#{$prefix}app-sidebar-primary-width: #{$app-sidebar-primary-minimize-width};
+
+ --#{$prefix}app-sidebar-primary-gap-start: #{$app-sidebar-primary-minimize-gap-start};
+ --#{$prefix}app-sidebar-primary-gap-end: #{$app-sidebar-primary-minimize-gap-end};
+ --#{$prefix}app-sidebar-primary-gap-top: #{$app-sidebar-primary-minimize-gap-top};
+ --#{$prefix}app-sidebar-primary-gap-bottom: #{$app-sidebar-primary-minimize-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-primary-collapse="on"] {
+ --#{$prefix}app-sidebar-primary-width: 0px;
+ }
+
+ // States
+ .app-sidebar-primary {
+ width: var(--#{$prefix}app-sidebar-primary-width);
+
+ [data-kt-app-sidebar-primary-collapse="on"] & {
+ transition: $app-sidebar-primary-base-transition;
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-primary-width-actual));
+ }
+
+ [data-kt-app-sidebar-primary-minimize="on"] & {
+ transition: $app-sidebar-primary-base-transition;
+
+ //background-color: var(--#{$prefix}app-sidebar-primary-minimize-bg-color);
+ //box-shadow: var(--#{$prefix}app-sidebar-primary-minimize-box-shadow);
+ //border-left: var(--#{$prefix}app-sidebar-primary-minimize-border-start);
+ //border-right: var(--#{$prefix}app-sidebar-primary-minimize-border-end);
+
+ @include property( margin-left, $app-sidebar-primary-minimize-gap-start);
+ @include property( margin-right, $app-sidebar-primary-minimize-gap-end);
+ @include property( margin-top, $app-sidebar-primary-minimize-gap-top);
+ @include property( margin-bottom, $app-sidebar-primary-minimize-gap-bottom);
+ }
+
+ [data-kt-app-sidebar-primary-hoverable="true"] & {
+ .app-sidebar-primary-hoverable {
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ }
+ }
+
+ // Hover minimized
+ [data-kt-app-sidebar-primary-hoverable="true"][data-kt-app-sidebar-primary-minimize="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-primary-base-transition;
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-primary-minimize-hover-box-shadow);
+ }
+ }
+
+ // Integration
+ .app-sidebar-primary {
+ // Header
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-sidebar-primary-below-header="true"] & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"][data-kt-app-sidebar-primary-below-toolbar="true"] & {
+ top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height, 0));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-primary-minimize="on"] {
+ .app-sidebar-primary-minimize-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-primary-minimize-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-primary-collapse="on"] {
+ .app-sidebar-primary-collapse-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-primary-collapse-d-flex {
+ display: flex !important;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-sidebar-primary {
+ @include property( z-index, $app-sidebar-primary-base-z-index-mobile);
+ @include property( margin-left, $app-sidebar-primary-base-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-primary-base-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-primary-base-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-primary-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-primary-width-actual: #{$app-sidebar-primary-base-width-mobile};
+ }
+
+ [data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-primary-width: #{$app-sidebar-primary-base-width-mobile};
+
+ --#{$prefix}app-sidebar-primary-gap-start: #{$app-sidebar-primary-base-gap-start-mobile};
+ --#{$prefix}app-sidebar-primary-gap-end: #{$app-sidebar-primary-base-gap-end-mobile};
+ --#{$prefix}app-sidebar-primary-gap-top: #{$app-sidebar-primary-base-gap-top-mobile};
+ --#{$prefix}app-sidebar-primary-gap-bottom: #{$app-sidebar-primary-base-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-primary-minimize-mobile="on"] {
+ --#{$prefix}app-sidebar-primary-width: #{$app-sidebar-primary-minimize-width-mobile};
+
+ --#{$prefix}app-sidebar-primary-gap-start: #{$app-sidebar-primary-minimize-gap-start-mobile};
+ --#{$prefix}app-sidebar-primary-gap-end: #{$app-sidebar-primary-minimize-gap-end-mobile};
+ --#{$prefix}app-sidebar-primary-gap-top: #{$app-sidebar-primary-minimize-gap-top-mobile};
+ --#{$prefix}app-sidebar-primary-gap-bottom: #{$app-sidebar-primary-minimize-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-primary-collapse-mobile="on"] {
+ --#{$prefix}app-sidebar-primary-width: 0px;
+ }
+
+ // States
+ .app-sidebar-primary {
+ width: var(--#{$prefix}app-sidebar-primary-width);
+
+ [data-kt-app-sidebar-primary-collapse-mobile="on"] & {
+ transition: $app-sidebar-primary-base-transition;
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-primary-width-actual));
+ }
+
+ [data-kt-app-sidebar-primary-minimize-mobile="on"] & {
+ transition: $app-sidebar-primary-base-transition;
+
+ //background-color: var(--#{$prefix}app-sidebar-primary-minimize-bg-color-mobile);
+ //box-shadow: var(--#{$prefix}app-sidebar-primary-base-box-shadow-mobile);
+ //border-left: var(--#{$prefix}app-sidebar-primary-minimize-border-start-mobile);
+ //border-left: var(--#{$prefix}app-sidebar-primary-minimize-border-end-mobile);
+
+ @include property( margin-left, $app-sidebar-primary-minimize-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-primary-minimize-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-primary-minimize-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-primary-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-sidebar-primary-hoverable-mobile="true"] & {
+ .app-sidebar-primary-hoverable {
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-primary-hoverable-mobile="true"][data-kt-app-sidebar-primary-minimize-mobile="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-primary-base-transition;
+ width: var(--#{$prefix}app-sidebar-primary-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-primary-minimize-hover-box-shadow-mobile);
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-primary-minimize-mobile="on"] {
+ .app-sidebar-primary-minimize-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-primary-minimize-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-primary-collapse-mobile="on"] {
+ .app-sidebar-primary-collapse-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-primary-collapse-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/sidebar/_sidebar-secondary.scss b/Moonlight/Styles/layout/base/sidebar/_sidebar-secondary.scss
new file mode 100644
index 00000000..9c5816b7
--- /dev/null
+++ b/Moonlight/Styles/layout/base/sidebar/_sidebar-secondary.scss
@@ -0,0 +1,274 @@
+//
+// sidebar Secondary
+//
+
+// General mode
+.app-sidebar-secondary {
+ transition: $app-sidebar-secondary-base-transition;
+ position: relative;
+ flex-shrink: 0;
+ background-color: var(--#{$prefix}app-sidebar-secondary-base-bg-color);
+ box-shadow: var(--#{$prefix}app-sidebar-secondary-base-box-shadow);
+ border-left: var(--#{$prefix}app-sidebar-secondary-base-border-start);
+ border-right: var(--#{$prefix}app-sidebar-secondary-base-border-end);
+}
+
+// Utilities
+.app-sidebar-secondary-collapse-d-flex,
+.app-sidebar-secondary-minimize-d-flex,
+.app-sidebar-secondary-collapse-mobile-d-flex,
+.app-sidebar-secondary-minimize-mobile-d-flex {
+ display: none;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-sidebar-secondary {
+ @include property( z-index, $app-sidebar-secondary-base-z-index);
+ @include property( margin-left, $app-sidebar-secondary-base-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-secondary-base-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-secondary-base-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-secondary-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ [data-kt-app-sidebar-secondary-enabled="true"] {
+ --#{$prefix}app-sidebar-secondary-width-actual: calc(
+ #{$app-sidebar-base-width} -
+ #{$app-sidebar-primary-base-width} -
+ #{$app-sidebar-primary-base-gap-start} -
+ #{$app-sidebar-primary-base-gap-end} -
+ #{$app-sidebar-secondary-base-gap-start} -
+ #{$app-sidebar-secondary-base-gap-end}
+ );
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-secondary-width: calc(
+ #{$app-sidebar-base-width} -
+ #{$app-sidebar-primary-base-width} -
+ #{$app-sidebar-primary-base-gap-start} -
+ #{$app-sidebar-primary-base-gap-end} -
+ #{$app-sidebar-secondary-base-gap-start} -
+ #{$app-sidebar-secondary-base-gap-end}
+ );
+
+ --#{$prefix}app-sidebar-secondary-gap-start: #{$app-sidebar-secondary-base-gap-start};
+ --#{$prefix}app-sidebar-secondary-gap-end: #{$app-sidebar-secondary-base-gap-end};
+ --#{$prefix}app-sidebar-secondary-gap-top: #{$app-sidebar-secondary-base-gap-top};
+ --#{$prefix}app-sidebar-secondary-gap-bottom: #{$app-sidebar-secondary-base-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-minimize="on"] {
+ --#{$prefix}app-sidebar-secondary-width: #{$app-sidebar-secondary-minimize-width};
+
+ --#{$prefix}app-sidebar-secondary-gap-start: #{$app-sidebar-secondary-minimize-gap-start};
+ --#{$prefix}app-sidebar-secondary-gap-end: #{$app-sidebar-secondary-minimize-gap-end};
+ --#{$prefix}app-sidebar-secondary-gap-top: #{$app-sidebar-secondary-minimize-gap-top};
+ --#{$prefix}app-sidebar-secondary-gap-bottom: #{$app-sidebar-secondary-minimize-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-collapse="on"] {
+ --#{$prefix}app-sidebar-secondary-width-actual: calc(
+ #{$app-sidebar-base-width} -
+ #{$app-sidebar-primary-base-width} -
+ #{$app-sidebar-primary-base-gap-start} -
+ #{$app-sidebar-primary-base-gap-end} -
+ #{$app-sidebar-secondary-base-gap-start} -
+ #{$app-sidebar-secondary-base-gap-end}
+ );
+
+ --#{$prefix}app-sidebar-secondary-width: 0px;
+ }
+
+ // States
+ .app-sidebar-secondary {
+ width: var(--#{$prefix}app-sidebar-secondary-width);
+
+ [data-kt-app-sidebar-secondary-collapse="on"] & {
+ transition: $app-sidebar-secondary-base-transition;
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-secondary-width-actual));
+ }
+
+ [data-kt-app-sidebar-secondary-minimize="on"] & {
+ transition: $app-sidebar-secondary-base-transition;
+
+ //background-color: var(--#{$prefix}app-sidebar-secondary-minimize-bg-color);
+ //box-shadow: var(--#{$prefix}app-sidebar-secondary-minimize-box-shadow);
+ //border-left: var(--#{$prefix}app-sidebar-secondary-minimize-border-start);
+ //border-right: var(--#{$prefix}app-sidebar-secondary-minimize-border-end);
+
+ @include property( margin-left, $app-sidebar-secondary-minimize-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-secondary-minimize-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-secondary-minimize-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-secondary-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-sidebar-secondary-hoverable="true"] & {
+ .app-sidebar-secondary-hoverable {
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-secondary-hoverable="true"][data-kt-app-sidebar-secondary-minimize="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-secondary-base-transition;
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-secondary-minimize-hover-box-shadow);
+ }
+ }
+
+ // Integration
+ .app-sidebar-secondary {
+ // Header
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-sidebar-secondary-below-header="true"] & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"][data-kt-app-sidebar-secondary-below-toolbar="true"] & {
+ top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height, 0));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-minimize="on"] {
+ .app-sidebar-secondary-minimize-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-secondary-minimize-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-collapse="on"] {
+ .app-sidebar-secondary-collapse-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-secondary-collapse-d-flex {
+ display: flex !important;
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-sidebar-secondary {
+ @include property( z-index, $app-sidebar-secondary-base-z-index-mobile);
+ @include property( margin-left, $app-sidebar-secondary-base-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-secondary-base-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-secondary-base-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-secondary-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ [data-kt-app-sidebar-secondary-enabled="true"] {
+ --#{$prefix}app-sidebar-secondary-width-actual: calc(
+ #{$app-sidebar-base-width-mobile} -
+ #{$app-sidebar-primary-base-width-mobile} -
+ #{$app-sidebar-primary-base-gap-start-mobile} -
+ #{$app-sidebar-primary-base-gap-end-mobile} -
+ #{$app-sidebar-secondary-base-gap-start-mobile} -
+ #{$app-sidebar-secondary-base-gap-end-mobile}
+ );
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-secondary-width: calc(
+ #{$app-sidebar-base-width-mobile} -
+ #{$app-sidebar-primary-base-width-mobile} -
+ #{$app-sidebar-primary-base-gap-start-mobile} -
+ #{$app-sidebar-primary-base-gap-end-mobile} -
+ #{$app-sidebar-secondary-base-gap-start-mobile} -
+ #{$app-sidebar-secondary-base-gap-end-mobile}
+ );
+
+ --#{$prefix}app-sidebar-secondary-gap-start: #{$app-sidebar-secondary-base-gap-start-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-end: #{$app-sidebar-secondary-base-gap-end-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-top: #{$app-sidebar-secondary-base-gap-top-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-bottom: #{$app-sidebar-secondary-base-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-minimize-mobile="on"] {
+ --#{$prefix}app-sidebar-secondary-width: #{$app-sidebar-secondary-minimize-width-mobile};
+
+ --#{$prefix}app-sidebar-secondary-gap-start: #{$app-sidebar-secondary-minimize-gap-start-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-end: #{$app-sidebar-secondary-minimize-gap-end-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-top: #{$app-sidebar-secondary-minimize-gap-top-mobile};
+ --#{$prefix}app-sidebar-secondary-gap-bottom: #{$app-sidebar-secondary-minimize-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-collapse-mobile="on"] {
+ --#{$prefix}app-sidebar-secondary-width-actual: calc(
+ #{$app-sidebar-base-width-mobile} -
+ #{$app-sidebar-primary-base-width-mobile} -
+ #{$app-sidebar-primary-base-gap-start-mobile} -
+ #{$app-sidebar-primary-base-gap-end-mobile} -
+ #{$app-sidebar-secondary-base-gap-start-mobile} -
+ #{$app-sidebar-secondary-base-gap-end-mobile}
+ );
+
+ --#{$prefix}app-sidebar-secondary-width: 0px;
+ }
+
+ // States
+ .app-sidebar-secondary {
+ width: var(--#{$prefix}app-sidebar-secondary-width);
+
+ [data-kt-app-sidebar-secondary-collapse-mobile="on"] & {
+ transition: $app-sidebar-secondary-base-transition;
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-secondary-width-actual));
+ }
+
+ [data-kt-app-sidebar-secondary-minimize-mobile="on"] & {
+ transition: $app-sidebar-secondary-base-transition;
+ background-color: var(--#{$prefix}app-sidebar-secondary-minimize-bg-color-mobile);
+ box-shadow: var(--#{$prefix}app-sidebar-secondary-minimize-box-shadow-mobile);
+ border-left: var(--#{$prefix}app-sidebar-secondary-minimize-border-start-mobile);
+ border-right: var(--#{$prefix}app-sidebar-secondary-minimize-border-end-mobile);
+
+ //@include property( margin-left, $app-sidebar-secondary-minimize-gap-start-mobile);
+ //@include property( margin-right, $app-sidebar-secondary-minimize-gap-end-mobile);
+ //@include property( margin-top, $app-sidebar-secondary-minimize-gap-top-mobile);
+ //@include property( margin-bottom, $app-sidebar-secondary-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-sidebar-secondary-hoverable-mobile="true"] & {
+ .app-sidebar-secondary-hoverable {
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-secondary-hoverable-mobile="true"][data-kt-app-sidebar-secondary-minimize-mobile="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-secondary-base-transition;
+ width: var(--#{$prefix}app-sidebar-secondary-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-secondary-minimize-hover-box-shadow-mobile);
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-minimize-mobile="on"] {
+ .app-sidebar-secondary-minimize-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-secondary-minimize-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-secondary-enabled="true"][data-kt-app-sidebar-secondary-collapse="on"] {
+ .app-sidebar-secondary-collapse-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-secondary-collapse-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/layout/base/sidebar/_sidebar.scss b/Moonlight/Styles/layout/base/sidebar/_sidebar.scss
new file mode 100644
index 00000000..382f80d1
--- /dev/null
+++ b/Moonlight/Styles/layout/base/sidebar/_sidebar.scss
@@ -0,0 +1,284 @@
+//
+// sidebar
+//
+
+// General mode
+.app-sidebar {
+ transition: $app-sidebar-base-transition;
+ background-color: var(--#{$prefix}app-sidebar-base-bg-color);
+ box-shadow: var(--#{$prefix}app-sidebar-base-box-shadow);
+ border-left: var(--#{$prefix}app-sidebar-base-border-start);
+ border-right: var(--#{$prefix}app-sidebar-base-border-end);
+}
+
+// Utilities
+.app-sidebar-minimize-d-flex,
+.app-sidebar-sticky-d-flex,
+.app-sidebar-collapse-d-flex,
+.app-sidebar-minimize-mobile-d-flex,
+.app-sidebar-collapse-mobile-d-flex {
+ display: none;
+}
+
+// Desktop mode
+@include media-breakpoint-up(lg) {
+ // Base
+ .app-sidebar {
+ display: flex;
+ flex-shrink: 0;
+ width: var(--#{$prefix}app-sidebar-width);
+
+ @include property( z-index, $app-sidebar-base-z-index);
+ @include property( margin-left, $app-sidebar-base-gap-start);
+ @include property( margin-right, $app-sidebar-base-gap-end);
+ @include property( margin-top, $app-sidebar-base-gap-top);
+ @include property( margin-bottom, $app-sidebar-base-gap-bottom);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-width: #{$app-sidebar-base-width};
+ --#{$prefix}app-sidebar-width-actual: #{$app-sidebar-base-width};
+
+ --#{$prefix}app-sidebar-gap-start: #{$app-sidebar-base-gap-start};
+ --#{$prefix}app-sidebar-gap-end: #{$app-sidebar-base-gap-end};
+ --#{$prefix}app-sidebar-gap-top: #{$app-sidebar-base-gap-top};
+ --#{$prefix}app-sidebar-gap-bottom: #{$app-sidebar-base-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-width: calc(var(--#{$prefix}app-sidebar-primary-width) + var(--#{$prefix}app-sidebar-secondary-width, 0px));
+ }
+
+ [data-kt-app-sidebar-minimize="on"] {
+ --#{$prefix}app-sidebar-width: #{$app-sidebar-minimize-width};
+
+ --#{$prefix}app-sidebar-gap-start: #{$app-sidebar-minimize-gap-start};
+ --#{$prefix}app-sidebar-gap-end: #{$app-sidebar-minimize-gap-end};
+ --#{$prefix}app-sidebar-gap-top: #{$app-sidebar-minimize-gap-top};
+ --#{$prefix}app-sidebar-gap-bottom: #{$app-sidebar-minimize-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-sticky="on"] {
+ --#{$prefix}app-sidebar-width: #{$app-sidebar-sticky-width};
+
+ --#{$prefix}app-sidebar-gap-start: #{$app-sidebar-sticky-gap-start};
+ --#{$prefix}app-sidebar-gap-end: #{$app-sidebar-sticky-gap-end};
+ --#{$prefix}app-sidebar-gap-top: #{$app-sidebar-sticky-gap-top};
+ --#{$prefix}app-sidebar-gap-bottom: #{$app-sidebar-sticky-gap-bottom};
+ }
+
+ [data-kt-app-sidebar-collapse="on"] {
+ --#{$prefix}app-sidebar-width: 0px;
+ }
+
+ // States
+ .app-sidebar {
+ [data-kt-app-sidebar-static="true"] & {
+ position: relative;
+ }
+
+ [data-kt-app-sidebar-offcanvas="true"] & {
+ display: none;
+ }
+
+ [data-kt-app-sidebar-fixed="true"] & {
+ position: fixed;
+ @include property( z-index, $app-sidebar-fixed-z-index);
+ @include property( top, $app-sidebar-fixed-top);
+ @include property( bottom, $app-sidebar-fixed-bottom);
+ @include property( left, $app-sidebar-fixed-left);
+ }
+
+ [data-kt-app-sidebar-stacked="true"] & {
+ align-items: stretch;
+ }
+
+ [data-kt-app-sidebar-sticky="on"] & {
+ position: fixed;
+ transition: $app-sidebar-base-transition;
+ @include property( top, $app-sidebar-sticky-top);
+ @include property( bottom, $app-sidebar-sticky-bottom);
+ @include property( left, $app-sidebar-sticky-left);
+ @include property( z-index, $app-sidebar-sticky-z-index);
+
+ box-shadow: var(--#{$prefix}app-sidebar-sticky-box-shadow);
+ border-left: var(--#{$prefix}app-sidebar-sticky-border-start);
+ border-right: var(--#{$prefix}app-sidebar-sticky-border-end);
+
+ @include property( margin-left, $app-sidebar-sticky-gap-start);
+ @include property( margin-right, $app-sidebar-sticky-gap-end);
+ @include property( margin-top, $app-sidebar-sticky-gap-top);
+ @include property( margin-bottom, $app-sidebar-sticky-gap-bottom);
+ }
+
+ [data-kt-app-sidebar-minimize="on"] & {
+ transition: $app-sidebar-base-transition;
+
+ @include property( margin-left, $app-sidebar-minimize-gap-start);
+ @include property( margin-right, $app-sidebar-minimize-gap-end);
+ @include property( margin-top, $app-sidebar-minimize-gap-top);
+ @include property( margin-bottom, $app-sidebar-minimize-gap-bottom);
+ }
+
+ [data-kt-app-sidebar-hoverable="true"] & {
+ .app-sidebar-wrapper {
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-hoverable="true"][data-kt-app-sidebar-minimize="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-base-transition;
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ @include property( box-shadow, $app-sidebar-minimize-hover-box-shadow);
+ }
+
+ [data-kt-app-sidebar-collapse="on"] & {
+ transition: $app-sidebar-base-transition;
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-width-actual));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-minimize="on"] {
+ .app-sidebar-minimize-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-minimize-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-sticky="on"] {
+ .app-sidebar-sticky-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-sticky-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-collapse="on"] {
+ .app-sidebar-collapse-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-collapse-d-flex {
+ display: flex !important;
+ }
+ }
+
+ // Integration
+ .app-sidebar {
+ // Header
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"]:not([data-kt-app-sidebar-push-header="true"]) & {
+ top: var(--#{$prefix}app-header-height);
+ }
+
+ // Toolbar
+ [data-kt-app-sidebar-fixed="true"][data-kt-app-header-fixed="true"][data-kt-app-toolbar-fixed="true"]:not([data-kt-app-sidebar-push-toolbar="true"]) & {
+ top: calc(var(--#{$prefix}app-header-height) + var(--#{$prefix}app-toolbar-height, 0px));
+ }
+ }
+}
+
+// Tablet & mobile modes
+@include media-breakpoint-down(lg) {
+ // Base
+ .app-sidebar {
+ display: none;
+ width: var(--#{$prefix}app-sidebar-width);
+
+ @include property( z-index, $app-sidebar-base-z-index-mobile);
+ @include property( margin-left, $app-sidebar-base-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-base-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-base-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-base-gap-bottom-mobile);
+ }
+
+ // Vars
+ :root {
+ --#{$prefix}app-sidebar-width: #{$app-sidebar-base-width-mobile};
+ --#{$prefix}app-sidebar-width-actual: #{$app-sidebar-base-width-mobile};
+
+ --#{$prefix}app-sidebar-gap-start: #{$app-sidebar-base-gap-start-mobile};
+ --#{$prefix}app-sidebar-gap-end: #{$app-sidebar-base-gap-end-mobile};
+ --#{$prefix}app-sidebar-gap-top: #{$app-sidebar-base-gap-top-mobile};
+ --#{$prefix}app-sidebar-gap-bottom: #{$app-sidebar-base-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-stacked="true"] {
+ --#{$prefix}app-sidebar-width: calc(var(--#{$prefix}app-sidebar-primary-width) + var(--#{$prefix}app-sidebar-secondary-width, 0));
+ }
+
+ [data-kt-app-sidebar-minimize-mobile="on"] {
+ --#{$prefix}app-sidebar-width: #{$app-sidebar-minimize-width-mobile};
+
+ --#{$prefix}app-sidebar-gap-start: #{$app-sidebar-minimize-gap-start-mobile};
+ --#{$prefix}app-sidebar-gap-end: #{$app-sidebar-minimize-gap-end-mobile};
+ --#{$prefix}app-sidebar-gap-top: #{$app-sidebar-minimize-gap-top-mobile};
+ --#{$prefix}app-sidebar-gap-bottom: #{$app-sidebar-minimize-gap-bottom-mobile};
+ }
+
+ [data-kt-app-sidebar-collapse-mobile="on"] {
+ --#{$prefix}app-sidebar-width: 0px;
+ }
+
+ // States
+ .app-sidebar {
+ [data-kt-app-sidebar-stacked="true"] & {
+ align-items: stretch;
+ }
+
+ [data-kt-app-sidebar-minimize-mobile="on"] & {
+ transition: $app-sidebar-base-transition;
+
+ @include property( margin-left, $app-sidebar-minimize-gap-start-mobile);
+ @include property( margin-right, $app-sidebar-minimize-gap-end-mobile);
+ @include property( margin-top, $app-sidebar-minimize-gap-top-mobile);
+ @include property( margin-bottom, $app-sidebar-minimize-gap-bottom-mobile);
+ }
+
+ [data-kt-app-sidebar-hoverable-mobile="true"] & {
+ .app-sidebar-wrapper {
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ }
+ }
+
+ [data-kt-app-sidebar-hoverable-mobile="true"][data-kt-app-sidebar-minimize-mobile="on"] &:hover:not(.animating) {
+ transition: $app-sidebar-base-transition;
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ box-shadow: var(--#{$prefix}app-sidebar-minimize-hover-box-shadow-mobile);
+ }
+
+ [data-kt-app-sidebar-collapse-mobile="on"] & {
+ transition: $app-sidebar-base-transition;
+ width: var(--#{$prefix}app-sidebar-width-actual);
+ margin-left: calc( -1 * var(--#{$prefix}app-sidebar-width-actual));
+ }
+ }
+
+ // Utilities
+ [data-kt-app-sidebar-minimize-mobile="on"] {
+ .app-sidebar-minimize-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-minimize-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+
+ [data-kt-app-sidebar-collapse-mobile="on"] {
+ .app-sidebar-collapse-mobile-d-none {
+ display: none !important;
+ }
+
+ .app-sidebar-collapse-mobile-d-flex {
+ display: flex !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/plugins.scss b/Moonlight/Styles/plugins.scss
new file mode 100644
index 00000000..5e7497b4
--- /dev/null
+++ b/Moonlight/Styles/plugins.scss
@@ -0,0 +1,13 @@
+//
+// Vendors customization
+//
+
+////////////////////////////////////////////////////////////////
+///////////// DO NOT MODIFY BELOW INCLUDE ORDER ////////////////
+////////////////////////////////////////////////////////////////
+
+// Initialize
+@import "init";
+
+// Plugins
+@import "vendors/plugins/plugins";
diff --git a/Moonlight/Styles/style.scss b/Moonlight/Styles/style.scss
new file mode 100644
index 00000000..0c805f1d
--- /dev/null
+++ b/Moonlight/Styles/style.scss
@@ -0,0 +1,14 @@
+//
+// Theme style
+//
+
+// Initialize
+@import "init";
+
+// Components
+@import "components/components";
+
+
+// Layout
+@import "layout/base/layout";
+@import "layout/layout";
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_apexcharts.scss b/Moonlight/Styles/vendors/plugins/_apexcharts.scss
new file mode 100644
index 00000000..73f9bbc1
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_apexcharts.scss
@@ -0,0 +1,129 @@
+//
+// Apexcharts
+//
+
+// Text
+.apexcharts-text,
+.apexcharts-title-text,
+.apexcharts-legend-text {
+ font-family: $font-family-sans-serif !important;
+}
+
+.apexcharts-title-text {
+ font-weight: $font-weight-normal;
+}
+
+.apexcharts-pie-label {
+ font-weight: $font-weight-normal;
+ font-size: $font-size-sm;
+}
+
+// Dropdown
+.apexcharts-toolbar{
+ text-align: left !important;
+}
+
+.apexcharts-menu {
+ background: var(--#{$prefix}body-bg) !important;
+ border: 0 !important;
+ padding: 0.5rem 0 !important;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ border-radius: $border-radius !important;
+ overflow: hidden;
+ min-width: 10rem !important;
+
+ .apexcharts-menu-item {
+ padding: $dropdown-item-padding-y $dropdown-item-padding-x;
+ transition: $transition-base;
+
+ &:hover{
+ background-color: var(--#{$prefix}component-hover-bg) !important;
+ }
+ }
+}
+
+// Tooltips
+.apexcharts-tooltip {
+ &.apexcharts-theme-light {
+ @include border-radius($border-radius);
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ border: 0 !important;
+ background: var(--#{$prefix}body-bg) !important;
+ color: var(--#{$prefix}gray-800);
+
+ .apexcharts-tooltip-title {
+ background: var(--#{$prefix}body-bg) !important;
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-800);
+ border-bottom: 1px solid var(--#{$prefix}gray-100) !important;
+ }
+ }
+
+ .apexcharts-tooltip-title {
+ padding: 0.5rem 1rem;
+ }
+
+ .apexcharts-tooltip-series-group {
+ }
+}
+
+.apexcharts-xaxistooltip {
+ &.apexcharts-theme-light {
+ @include border-radius($border-radius !important);
+ box-shadow: var(--#{$prefix}dropdown-box-shadow) !important;
+ border: 0 !important;
+ background: var(--#{$prefix}dropdown-box-shadow) !important;
+ color: var(--#{$prefix}gray-800);
+
+ &:before {
+ border-bottom: 0 !important;
+ }
+
+ &:after {
+ border-bottom-color: var(--#{$prefix}dropdown-box-shadow) !important;
+ }
+ }
+}
+
+// Border radius integration
+.card-rounded-bottom {
+ .apexcharts-canvas {
+ svg {
+ border-bottom-left-radius: $card-border-radius;
+ border-bottom-right-radius: $card-border-radius;
+ }
+ }
+}
+
+// Border radius options
+.rounded {
+ .apexcharts-canvas {
+ svg {
+ border-radius: $border-radius !important;
+ }
+ }
+}
+
+.rounded-sm {
+ .apexcharts-canvas {
+ svg {
+ border-radius: $border-radius-sm !important;
+ }
+ }
+}
+
+.rounded-lg {
+ .apexcharts-canvas {
+ svg {
+ border-radius: $border-radius-lg !important;
+ }
+ }
+}
+
+.rounded-xl {
+ .apexcharts-canvas {
+ svg {
+ border-radius: $border-radius-xl !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_bootstrap-maxlength.scss b/Moonlight/Styles/vendors/plugins/_bootstrap-maxlength.scss
new file mode 100644
index 00000000..a4509798
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_bootstrap-maxlength.scss
@@ -0,0 +1,16 @@
+//
+// Bootstrap Maxlength
+//
+
+.bootstrap-maxlength {
+ z-index: $bootstrap-maxlength-z-index !important;
+
+ // In modal
+ .modal-open & {
+ z-index: #{$zindex-modal + 5} !important;
+ }
+
+ &.badge {
+ display: inline-flex !important;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_ckeditor.scss b/Moonlight/Styles/vendors/plugins/_ckeditor.scss
new file mode 100644
index 00000000..a659b747
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_ckeditor.scss
@@ -0,0 +1,54 @@
+//
+// CKEditor
+//
+
+
+// Base
+.ck-target{
+ display: none;
+}
+
+.ck-toolbar{
+ @include border-radius($border-radius !important);
+}
+
+.ck-content{
+ min-height: 200px;
+ @include border-radius($border-radius !important);
+
+ &.ck-focused{
+ border-color: var(--#{$prefix}primary) !important;
+ box-shadow: none !important;
+ }
+}
+
+// CKEditor Classic & Document
+.ck-editor{
+ .ck-toolbar{
+ @include border-top-radius($border-radius !important);
+ @include border-bottom-radius(0 !important);
+ }
+ .ck-content{
+ @include border-bottom-radius($border-radius !important);
+ @include border-top-radius(0 !important);
+ }
+}
+
+// CKEditor Inline / Balloon / Balloon Block
+.ck-body {
+ .ck-balloon-panel{
+ .ck-content{
+ min-height: 200px;
+ border-color: transparent !important;
+
+ &.ck-focused{
+ border-color: var(--#{$prefix}primary) !important;
+ }
+ }
+
+ &.ck-toolbar-container,
+ .ck-toolbar {
+ @include border-radius($border-radius !important);
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_datatables.scss b/Moonlight/Styles/vendors/plugins/_datatables.scss
new file mode 100644
index 00000000..3b67545e
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_datatables.scss
@@ -0,0 +1,272 @@
+//
+// DataTables
+//
+
+$toolbar-spacing: 1rem 0;
+
+// Base
+table.dataTable {
+ width: 100% !important;
+ margin: 0 !important;
+
+ th {
+ border-bottom-color: var(--#{$prefix}table-border-color);
+ }
+}
+
+// Toolbar
+div.dataTables_wrapper div.dataTables_length {
+ padding: $toolbar-spacing;
+}
+
+div.dataTables_wrapper div.dataTables_filter {
+ padding: $toolbar-spacing;
+}
+
+div.dataTables_wrapper div.dataTables_info {
+ display: flex;
+ flex-direction: column;
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-700);
+ padding: $toolbar-spacing;
+
+ .select-info,
+ .select-item {
+ margin-left: 0;
+ font-size: 0.9rem;
+ color: var(--#{$prefix}text-muted);
+ }
+}
+
+div.dataTables_length + div.dataTables_info {
+ margin-left: 1rem;
+}
+
+// Pagination
+div.dataTables_wrapper div.dataTables_paginate {
+ padding: $toolbar-spacing;
+ margin-left: 0.5rem;
+
+ .pagination {
+ margin: 0;
+ }
+}
+
+// Head
+table.dataTable>thead>tr> {
+ td, th {
+ &:not(.sorting_disabled) {
+ padding-right: 0;
+ }
+ }
+}
+
+// Sorting
+table.dataTable > thead {
+ .sorting {
+ &:after,
+ &:before {
+ display: none !important;
+ }
+ }
+
+ .sorting_asc,
+ .sorting_desc {
+ vertical-align: middle;
+
+ &:before,
+ &:after {
+ position: relative !important;
+ opacity: 1 !important;
+ display: inline-block !important;
+ width: 0.75rem;
+ height: 0.75rem;
+ content: " " !important;
+ //top: 50%;
+ bottom: auto;
+ right: auto !important;
+ left: auto;
+ margin-left: 0.5rem;
+ }
+
+ &:before {
+ display: none !important;
+ }
+ }
+}
+
+table.dataTable > thead .sorting_asc:after {
+ opacity: 1;
+ @include svg-bg-icon(arrow-top, var(--#{$prefix}text-muted));
+}
+
+table.dataTable > thead .sorting_desc:after {
+ opacity: 1;
+ @include svg-bg-icon(arrow-bottom, var(--#{$prefix}text-muted));
+}
+
+// Processing
+div.dataTables_wrapper {
+ .table-responsive {
+ position: relative;
+ }
+
+ div.dataTables_processing {
+ @include border-radius($border-radius);
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ background-color: var(--#{$prefix}tooltip-bg);
+ color: var(--#{$prefix}gray-700);
+ font-weight: $font-weight-semibold;
+ margin: 0 !important;
+ width: auto;
+ padding: 1rem 2rem !important;
+ transform: translateX(-50%) translateY(-50%);
+
+ > div {
+ display: none;
+ }
+ }
+}
+
+// Responsive
+table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control,
+table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control,
+table.dataTable.dtr-column.collapsed > tbody > tr > td.dtr-control,
+table.dataTable.dtr-column.collapsed > tbody > tr > th.dtr-control {
+ $icon-size: 1.35rem;
+
+ &:before {
+ top: 50%;
+ left: 0;
+ height: $icon-size;
+ width: $icon-size;
+ line-height: 1.5;
+ text-indent: -999px !important;
+ margin-top: -(divide($icon-size, 2));
+ margin-right: divide($icon-size, 2);
+ display: inline-block;
+ position: relative;
+ font-size: 1.05rem;
+ border: 0;
+ box-shadow: none;
+ mask-size: 85%;
+ -webkit-mask-size: 85%;
+ content: ".";
+
+ :root &,
+ [data-bs-theme="light"] & {
+ @include svg-bg-icon(expand, $gray-600);
+ }
+
+ [data-bs-theme="dark"] & {
+ @include svg-bg-icon(expand, $gray-600-dark);
+ }
+ }
+
+ &.dtr-control-last {
+ &:before {
+ left: 100%;
+ right: 0;
+ }
+ }
+}
+
+table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td.dtr-control:before,
+table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th.dtr-control:before,
+table.dataTable.dtr-column.collapsed > tbody > tr.parent > td.dtr-control:before,
+table.dataTable.dtr-column.collapsed > tbody > tr.parent > th.dtr-control:before {
+ @include svg-bg-icon(collapse, $primary);
+}
+
+table.dataTable > tbody > tr.child span.dtr-title {
+ display: inline-block;
+ min-width: 100px;
+ font-weight: $font-weight-semibold;
+}
+
+table.dataTable > tbody > tr.child span.dtr-data {
+ font-weight: $font-weight-normal;
+}
+
+// Striped
+table.dataTable.table-striped > tbody > tr.odd > * {
+ box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-striped-bg);
+}
+
+table.dataTable > tbody > tr.selected > * {
+ box-shadow: inset 0 0 0 9999px var(--#{$prefix}primary);
+ color: var(--#{$prefix}primary-inverse);
+
+ a:not([class="btn"]) {
+ color: var(--#{$prefix}primary-light);
+ font-weight: $font-weight-semibold;
+ text-decoration: underline;
+ text-decoration-style: dotted;
+
+ &:hover {
+ color: var(--#{$prefix}primary-inverse);
+ }
+ }
+}
+
+// Scroll
+div.dataTables_scrollBody {
+ border-left: 0 !important;
+
+ .sorting_disabled.sorting_asc,
+ .sorting_disabled.sorting_desc {
+ &:after {
+ display: none !important;
+ }
+ }
+}
+
+.dataTables_scroll > .dataTables_scrollBody > .table > thead {
+ line-height: 0;
+
+ .sorting {
+ &:after,
+ &:before {
+ display: none !important;
+ }
+ }
+}
+
+div.dtfc-right-top-blocker,
+div.dtfc-left-top-blocker {
+ background-color: var(--#{$prefix}body-bg);
+}
+
+// Fixed column
+table.dataTable thead tr > .dtfc-fixed-left,
+table.dataTable thead tr > .dtfc-fixed-right {
+ background-color: var(--#{$prefix}body-bg);
+}
+
+table.dataTable tbody tr > .dtfc-fixed-left,
+table.dataTable tbody tr > .dtfc-fixed-right {
+ background-color: var(--#{$prefix}body-bg);
+}
+
+// Fixed header
+.dtfh-floatingparent {
+ box-shadow: var(--#{$prefix}box-shadow-sm);
+
+ .table {
+ background-color: var(--#{$prefix}body-bg) !important;
+ }
+
+ &,
+ .table,
+ .table th {
+ border-top-left-radius: 0 !important;
+ border-top-right-radius: 0 !important;
+ }
+}
+
+// Child details
+.dtr-details {
+ li {
+ display: flex;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_daterangepicker.scss b/Moonlight/Styles/vendors/plugins/_daterangepicker.scss
new file mode 100644
index 00000000..6c67af20
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_daterangepicker.scss
@@ -0,0 +1,272 @@
+//
+// Bootstrap Daterangepicker plugin customization: https://www.daterangepicker.com
+//
+
+
+// Base
+.daterangepicker {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ width: auto;
+ background-color: var(--#{$prefix}body-bg);
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ font-family: $font-family-sans-serif;
+ z-index: $zindex-dropdown;
+ @include border-radius($dropdown-border-radius);
+
+ &:after,
+ &:before {
+ display: none;
+ }
+
+ td {
+ &.off,
+ &.off.in-range,
+ &.off.start-date,
+ &.off.end-date {
+ background-color: transparent;
+ }
+ }
+
+ .modal-open & {
+ z-index: $zindex-modal + 1;
+ }
+
+ .calendar-table {
+ background-color: var(--#{$prefix}body-bg);
+ border: 0;
+ }
+
+ .ranges {
+ @include border-radius($dropdown-border-radius);
+ background-color: var(--#{$prefix}body-bg);
+ position: relative;
+ overflow: hidden;
+
+ ul {
+ padding: 1rem 0;
+ width: $daterangepicker-ranges-list-width;
+ overflow: auto;
+ max-height: $daterangepicker-ranges-list-height;
+ }
+
+ li {
+ padding: 0.7rem 1.75rem;
+ font-weight: 500;
+ font-size: 1rem;
+ color: var(--#{$prefix}gray-600);
+ transition: $transition-link;
+
+ &:hover {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ transition: $transition-link;
+ }
+
+ &.active {
+ background-color: var(--#{$prefix}component-active-bg);
+ color: var(--#{$prefix}component-active-color);
+ transition: $transition-link;
+ }
+ }
+ }
+
+ &.show-calendar {
+ .ranges {
+ @include border-radius(0);
+ @include border-top-start-radius($dropdown-border-radius);
+ margin-top: 0;
+ height: 297px;
+ }
+ }
+
+ &.show-ranges {
+ &.show-calendar {
+ .ranges {
+ border-right: 1px solid var(--#{$prefix}gray-200);
+ }
+ }
+
+ .drp-calendar.left {
+ border-left: 0;
+ }
+ }
+
+ .drp-buttons {
+ padding: 1rem 1.75rem;
+ border-top: 1px solid var(--#{$prefix}gray-200);
+
+ .btn {
+ font-size: 1rem;
+ font-weight: $font-weight-semibold;
+ padding: 0.5rem 1rem;
+ }
+
+ .cancelBtn {
+ @include button-custom-variant(
+ $color: var(--#{$prefix}light-inverse),
+ $icon-color: var(--#{$prefix}light-inverse),
+ $border-color: var(--#{$prefix}light),
+ $bg-color: var(--#{$prefix}light),
+ $color-active: var(--#{$prefix}light-inverse),
+ $icon-color-active: var(--#{$prefix}light-inverse),
+ $border-color-active: var(--#{$prefix}light-active),
+ $bg-color-active: var(--#{$prefix}light-active)
+ );
+ }
+ }
+
+ .drp-selected {
+ font-size: 0.9rem;
+ }
+
+ .drp-calendar {
+ &.left,
+ &.right {
+ padding: 1rem 1rem;
+ }
+
+ &.left {
+ border-left: 0 !important;
+ }
+
+ th,
+ td {
+ font-size: 1rem;
+ font-weight: $font-weight-normal;
+ width: 33px;
+ height: 33px;
+
+ &.available:hover {
+ @include border-radius($border-radius);
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ }
+ }
+
+ th {
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-800);
+
+ &.month {
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-800);
+ }
+
+ &.next,
+ &.prev {
+ span {
+ border-width: 0 1px 1px 0;
+ border-color: var(--#{$prefix}gray-600);
+ }
+
+ &.available:hover {
+ span {
+ border-color: var(--#{$prefix}component-hover-color);
+ }
+ }
+ }
+
+ &.next {
+ span {
+ margin-right: 1px;
+ }
+ }
+
+ &.prev {
+ span {
+ margin-left: 1px;
+ }
+ }
+ }
+
+ td {
+ color: var(--#{$prefix}gray-700);
+
+ &.available.off {
+ color: var(--#{$prefix}gray-400);
+ }
+
+ &.active {
+ background-color: var(--#{$prefix}component-active-bg) !important;
+ color: var(--#{$prefix}component-active-color) !important;
+ @include border-radius($border-radius);
+
+ &.start-date {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ &.end-date {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ &.start-date.end-date {
+ @include border-radius($border-radius);
+ }
+ }
+
+ &.today,
+ &.today.active {
+ background: var(--#{$prefix}gray-200) !important;
+ color: var(--#{$prefix}gray-700) !important;
+ @include border-radius($border-radius);
+ }
+
+ &.in-range.available:not(.active):not(.off):not(.today) {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ }
+
+ &:hover {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ }
+ }
+ }
+
+ select.ampmselect,
+ select.minuteselect,
+ select.hourselect,
+ select.monthselect,
+ select.yearselect {
+ padding-top: 0.35rem;
+ padding-bottom: 0.35rem;
+ @include border-radius($border-radius);
+ background-color: var(--#{$prefix}body-bg) !important;
+ border-color: transparent;
+ color: var(--#{$prefix}input-color);
+ font-weight: $font-weight-semibold;
+ outline: 0 !important;
+
+ &:focus {
+ background-color: var(--#{$prefix}gray-100);
+ }
+ }
+}
+
+// Tablet mode
+@include media-breakpoint-down(md) {
+ .daterangepicker {
+ &.show-calendar {
+ .ranges {
+ float: none !important;
+ height: auto !important;
+
+ ul {
+ width: 100%;
+ }
+ }
+
+ .drp-calendar {
+ float: none !important;
+ max-width: unset !important;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_draggable.scss b/Moonlight/Styles/vendors/plugins/_draggable.scss
new file mode 100644
index 00000000..6527cc97
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_draggable.scss
@@ -0,0 +1,28 @@
+//
+// Draggable plugin customization: https://shopify.github.io/draggable
+//
+
+.draggable {
+ transition: opacity 0.3s ease;
+ outline: none !important;
+
+ &.draggable-mirror {
+ opacity: 0.8;
+ transition: opacity 0.3s ease;
+ border: 2px dashed var(--#{$prefix}gray-300) !important;
+ @include border-radius($border-radius);
+ }
+
+ &.draggable--original {
+ opacity: 0 !important;
+ }
+
+ &.draggable-source--is-dragging.draggable--over {
+ opacity: 0 !important;
+ }
+
+ // Handle
+ .draggable-handle {
+ cursor: move;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_dropzone.scss b/Moonlight/Styles/vendors/plugins/_dropzone.scss
new file mode 100644
index 00000000..56231bde
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_dropzone.scss
@@ -0,0 +1,188 @@
+//
+// Dropzone plugin customization: https://www.dropzonejs.com
+//
+
+// Basic
+.dropzone {
+ min-height: auto;
+ padding: 1.5rem 1.75rem;
+ text-align: center;
+ cursor: pointer;
+ border: 1px dashed var(--#{$prefix}primary);
+ background-color: var(--#{$prefix}primary-light);
+ border-radius: $border-radius !important;
+
+ .dz-message{
+ margin: 0;
+ display: flex;
+ text-align: left;
+ }
+
+ .dz-preview {
+ border-radius: $border-radius !important;
+ margin: 0.75rem;
+
+ .dz-image {
+ border-radius: $border-radius !important;
+ z-index: 1;
+ }
+
+ &.dz-file-preview {
+ .dz-image {
+ background: var(--#{$prefix}gray-200);
+ }
+ }
+ }
+
+ .dz-success-mark,
+ .dz-error-mark {
+ $size: 40px;
+
+ margin-left: -(divide($size, 2)) !important;
+ margin-top: -(divide($size, 2)) !important;
+
+ svg {
+ height: $size !important;
+ width: $size !important;
+ }
+ }
+
+ .dz-remove {
+ $size: 1.65rem;
+ display:flex;
+ justify-content: center;
+ align-items: center;
+ height: $size;
+ width: $size;
+ font-size: 1rem;
+ text-indent: -9999px;
+ white-space: nowrap;
+ position: absolute;
+ z-index: 2;
+ background-color: var(--#{$prefix}body-bg) !important;
+ box-shadow: var(--#{$prefix}box-shadow);
+ border-radius: 100%;
+ top: -(divide($size,2));
+ right: -(divide($size,2));
+
+ &:after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ display: block;
+ content: "";
+ mask-size: 40%;
+ -webkit-mask-size: 40%;
+ @include svg-bg-icon(close, var(--#{$prefix}gray-600));
+ }
+
+ &:hover {
+ &:after {
+ @include svg-bg-icon(close, var(--#{$prefix}primary));
+ }
+ }
+ }
+
+ .dz-error-message {
+ color: var(--#{$prefix}danger-inverse);
+ background: var(--#{$prefix}danger);
+ }
+}
+
+// Queue upload
+.dropzone.dropzone-queue {
+ border: 0;
+ padding: 0;
+ background-color: transparent;
+ text-align: left;
+
+ .dz-message{
+ display: none;
+ }
+
+ .dropzone-panel {
+ .dropzone-upload,
+ .dropzone-remove-all{
+ display: none;
+ }
+ }
+
+ .dropzone-item {
+ display: flex;
+ align-items: center;
+ margin-top: 0.75rem;
+ @include border-radius($border-radius);
+ padding: 0.5rem 1rem;
+ background-color: var(--#{$prefix}gray-100);
+
+ .dropzone-file {
+ flex-grow: 1;
+
+ .dropzone-filename {
+ font-size: 0.9rem;
+ font-weight: 500;
+ color: var(--#{$prefix}gray-600);
+ text-overflow: ellipsis;
+ margin-right: 0.5rem;
+
+ &:hover {
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ .dropzone-error {
+ margin-top: 0.25rem;
+ font-size: 0.9rem;
+ font-weight: 400;
+ color: var(--#{$prefix}danger);
+ text-overflow: ellipsis;
+ }
+ }
+
+ .dropzone-progress {
+ width: 15%;
+
+ .progress {
+ height: 5px;
+ @include transition;
+ }
+ }
+
+ .dropzone-toolbar {
+ margin-left: 1rem;
+ display: flex;
+ flex-wrap: nowrap;
+
+ .dropzone-start,
+ .dropzone-cancel,
+ .dropzone-delete {
+ height: 25px;
+ width: 25px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: $transition-link;
+
+ > i {
+ transition: $transition-link;
+ font-size: 0.8rem;
+ color: var(--#{$prefix}gray-600);
+ }
+
+ &:hover {
+ transition: $transition-link;
+ > i {
+ color: var(--#{$prefix}primary);
+ }
+ }
+ }
+
+ .dropzone-start{
+ transition: $transition-link;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_flatpickr.scss b/Moonlight/Styles/vendors/plugins/_flatpickr.scss
new file mode 100644
index 00000000..a42ce15f
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_flatpickr.scss
@@ -0,0 +1,407 @@
+//
+// Flatpickr
+//
+
+$flatpickr-padding-y: 0.5rem;
+$flatpickr-padding-x: 1rem;
+$flatpickr-width: 280px;
+$flatpickr-width-week-numbers: 325px;
+$flatpickr-day-height: 36px;
+$flatpickr-day-width: 100%;
+$flatpickr-time-height: 46px;
+
+// Container
+.flatpickr-calendar {
+ width: $flatpickr-width !important;
+ font-family: inherit;
+ border: 0;
+ border-radius: 0;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ background-color: var(--#{$prefix}body-bg);
+ @include border-radius($dropdown-border-radius);
+
+ // Remow arrows
+ &:before,
+ &:after {
+ display: none;
+ }
+
+ // Week numbers
+ &.hasWeeks {
+ width: $flatpickr-width-week-numbers !important;
+ }
+}
+
+// Months container
+.flatpickr-months {
+ padding: 0 $flatpickr-padding-x;
+ padding-top: $flatpickr-padding-y;
+}
+
+// Inner container
+.flatpickr-innerContainer {
+ padding: $flatpickr-padding-y $flatpickr-padding-x;
+}
+
+// Day containers
+.flatpickr-days,
+.dayContainer {
+ width: 100% !important;
+ min-width: 100% !important;
+ max-width: 100% !important;
+}
+
+// Months
+.flatpickr-months {
+ .flatpickr-month {
+ background: transparent;
+ color: var(--#{$prefix}gray-600);
+ fill: var(--#{$prefix}gray-600);
+ height: 46px;
+ }
+
+ .flatpickr-prev-month,
+ .flatpickr-next-month {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ @include border-radius($border-radius);
+ top: 1rem;
+
+ svg {
+ fill: var(--#{$prefix}gray-500);
+ height: 13px;
+ width: 13px;
+ }
+
+ &:hover {
+ background: var(--#{$prefix}gray-100);
+
+ svg {
+ fill: var(--#{$prefix}gray-700);
+ }
+ }
+ }
+
+ .flatpickr-prev-month.flatpickr-prev-month,
+ .flatpickr-next-month.flatpickr-prev-month {
+ /*rtl:begin:ignore*/
+ left: $flatpickr-padding-x;
+ /*rtl:end:ignore*/
+ }
+
+ .flatpickr-prev-month.flatpickr-next-month,
+ .flatpickr-next-month.flatpickr-next-month {
+ /*rtl:begin:ignore*/
+ right: $flatpickr-padding-x;
+ /*rtl:end:ignore*/
+ }
+}
+
+// Month selector
+.flatpickr-current-month {
+ font-weight: $font-weight-semibold;
+ color: inherit;
+
+ .numInputWrapper {
+ @include border-radius($border-radius);
+ width: 65px;
+
+ span {
+ &.arrowUp {
+ @include border-top-end-radius($border-radius);
+ }
+
+ &.arrowDown {
+ @include border-bottom-end-radius($border-radius);
+ }
+ }
+ }
+
+ .flatpickr-monthDropdown-months {
+ border: 0 !important;
+ background-color: var(--#{$prefix}body-bg);
+ font-size: 1rem;
+ color: var(--#{$prefix}gray-700);
+ font-weight: $font-weight-semibold;
+ padding: 0.5rem 0.75rem;
+ margin-right: 0.5rem;
+ outline: none !important;
+ @include border-radius($border-radius);
+ appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+
+ &:hover {
+ background: var(--#{$prefix}gray-100);
+ }
+
+ .flatpickr-monthDropdown-month {
+ font-size: 1rem;
+ color: var(--#{$prefix}gray-700);
+ font-weight: $font-weight-semibold;
+ background-color: transparent;
+ outline: none;
+ padding: 0;
+ }
+ }
+
+ span.cur-month {
+ color: var(--#{$prefix}gray-700);
+ font-size: 1rem;
+ font-weight: $font-weight-semibold;
+
+ &:hover {
+ background: var(--#{$prefix}gray-100);
+ }
+ }
+
+ input.cur-year {
+ color: var(--#{$prefix}gray-700);
+ font-size: 1.1rem !important;
+ padding: 0.5rem 0.75rem;
+ font-weight: $font-weight-semibold;
+ outline: 0 !important;
+ }
+}
+
+// Week days
+span.flatpickr-weekday {
+ color: var(--#{$prefix}gray-800);
+ font-size: 1rem;
+ font-weight: $font-weight-bold;
+}
+
+// Time
+.flatpickr-time {
+ @include border-bottom-radius($border-radius);
+
+ .flatpickr-calendar.hasTime & {
+ height: height;
+ line-height: height;
+ max-height: height;
+ border-top: 1px solid var(--#{$prefix}gray-100);
+ }
+
+ .numInputWrapper {
+ height: height;
+ }
+
+ .flatpickr-am-pm {
+ color: var(--#{$prefix}gray-700);
+ font-size: 1rem;
+ font-weight: $font-weight-semibold;
+ }
+
+ input {
+ &.flatpickr-hour,
+ &.flatpickr-minute {
+ color: var(--#{$prefix}gray-700);
+ font-size: 1rem;
+ font-weight: $font-weight-semibold;
+ }
+ }
+
+ input:hover,
+ .flatpickr-am-pm:hover,
+ input:focus,
+ .flatpickr-am-pm:focus {
+ background: transparent;
+ }
+}
+
+// Number input
+.numInputWrapper {
+ span {
+ border-left: 0 !important;
+ border-top: 0 !important;
+ border-bottom: 0 !important;
+ border-right: 0 !important;
+
+ &:hover {
+ background: transparent !important;
+ }
+
+ &:after {
+ top: 50% !important;
+ transform: translateY(-50%);
+ }
+
+ &.arrowUp {
+ &:after {
+ border-bottom-color: var(--#{$prefix}gray-500) !important;
+ }
+
+ &:hover {
+ &:after {
+ border-bottom-color: var(--#{$prefix}gray-700) !important;
+ }
+ }
+ }
+
+ &.arrowDown {
+ &:after {
+ border-top-color: var(--#{$prefix}gray-500) !important;
+ }
+
+ &:hover {
+ &:after {
+ border-top-color: var(--#{$prefix}gray-700) !important;
+ }
+ }
+ }
+ }
+
+ &:hover {
+ background: transparent;
+ }
+}
+
+// Day
+.flatpickr-day {
+ font-size: 1rem;
+ @include border-radius($border-radius);
+ box-shadow: none !important;
+ height: $flatpickr-day-height;
+ width: $flatpickr-day-width;
+ max-width: 100% !important;
+ margin: 0;
+ line-height: $flatpickr-day-height;
+ color: var(--#{$prefix}gray-600);
+ margin-top: 0 !important;
+
+ &.inRange,
+ &.prevMonthDay.inRange,
+ &.nextMonthDay.inRange,
+ &.today.inRange,
+ &.prevMonthDay.today.inRange,
+ &.nextMonthDay.today.inRange,
+ &:hover,
+ &.prevMonthDay:hover,
+ &.nextMonthDay:hover,
+ &:focus,
+ &.prevMonthDay:focus,
+ &.nextMonthDay:focus {
+ cursor: pointer;
+ outline: 0;
+ background: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ border-color: transparent;
+ }
+
+ // Today
+ &.today {
+ background: var(--#{$prefix}gray-100);
+ color: var(--#{$prefix}gray-600);
+ border-color: transparent;
+
+ &:hover,
+ &:focus {
+ border-color: transparent;
+ background: var(--#{$prefix}gray-200);
+ color: var(--#{$prefix}gray-700);
+ }
+ }
+
+ // Selected
+ &.selected,
+ &.startRange,
+ &.endRange,
+ &.selected.inRange,
+ &.startRange.inRange,
+ &.endRange.inRange,
+ &.selected:focus,
+ &.startRange:focus,
+ &.endRange:focus,
+ &.selected:hover,
+ &.startRange:hover,
+ &.endRange:hover,
+ &.selected.prevMonthDay,
+ &.startRange.prevMonthDay,
+ &.endRange.prevMonthDay,
+ &.selected.nextMonthDay,
+ &.startRange.nextMonthDay,
+ &.endRange.nextMonthDay {
+ background: var(--#{$prefix}component-active-bg);
+ color: var(--#{$prefix}component-active-color);;
+ border-color: transparent;
+ }
+
+ &.inRange,
+ &.prevMonthDay.inRange,
+ &.nextMonthDay.inRange,
+ &.today.inRange,
+ &.prevMonthDay.today.inRange,
+ &.nextMonthDay.today.inRange,
+ &:hover,
+ &.prevMonthDay:hover,
+ &.nextMonthDay:hover,
+ &:focus,
+ &.prevMonthDay:focus,
+ &.nextMonthDay:focus {
+ cursor: pointer;
+ outline: 0;
+ background: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ border-color: transparent;
+ }
+
+ // Today
+ &.today {
+ border-color: transparent;
+ }
+
+ &.today:hover,
+ &.today:focus {
+ border-color: transparent;
+ background: var(--#{$prefix}gray-100);
+ color: var(--#{$prefix}gray-600);
+ }
+
+ // Selected
+ &.selected,
+ &.startRange,
+ &.endRange,
+ &.selected.inRange,
+ &.startRange.inRange,
+ &.endRange.inRange,
+ &.selected:focus,
+ &.startRange:focus,
+ &.endRange:focus,
+ &.selected:hover,
+ &.startRange:hover,
+ &.endRange:hover,
+ &.selected.prevMonthDay,
+ &.startRange.prevMonthDay,
+ &.endRange.prevMonthDay,
+ &.selected.nextMonthDay,
+ &.startRange.nextMonthDay,
+ &.endRange.nextMonthDay {
+ background: var(--#{$prefix}component-active-bg);
+ color: var(--#{$prefix}component-active-color);;
+ border-color: transparent;
+ }
+
+ // Disabled
+ &.flatpickr-disabled,
+ &.flatpickr-disabled:hover,
+ &.prevMonthDay,
+ &.nextMonthDay,
+ &.notAllowed,
+ &.notAllowed.prevMonthDay,
+ &.notAllowed.nextMonthDay {
+ color: var(--#{$prefix}gray-400);
+ background: transparent;
+ border-color: transparent;
+ }
+ &.flatpickr-disabled,
+ &.flatpickr-disabled:hover {
+ cursor: not-allowed;
+ color: var(--#{$prefix}gray-400);
+ }
+}
+
+// Week numbers
+.flatpickr-weekwrapper {
+ margin-right: 5px;
+}
diff --git a/Moonlight/Styles/vendors/plugins/_formvalidation.scss b/Moonlight/Styles/vendors/plugins/_formvalidation.scss
new file mode 100644
index 00000000..91d798ac
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_formvalidation.scss
@@ -0,0 +1,20 @@
+//
+// FormValidation Customization. More info: https://formvalidation.io/
+//
+
+.fv-plugins-message-container {
+ --input-invalid-color: var(--#{$prefix}danger);
+ margin-top: 0.3rem;
+
+ .fv-help-block {
+ color: var(--#{$prefix}danger);
+ font-size: 1rem;
+ font-weight: $font-weight-normal;
+ }
+
+ &.valid-feedback,
+ &.invalid-feedback {
+ display: block;
+ font-weight: $font-weight-normal;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_fslightbox.scss b/Moonlight/Styles/vendors/plugins/_fslightbox.scss
new file mode 100644
index 00000000..a9390cfc
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_fslightbox.scss
@@ -0,0 +1,11 @@
+//
+// fslightbox
+//
+
+.fslightbox-slide-btn {
+ border-radius: $border-radius;
+}
+
+.fslightbox-toolbar {
+ border-bottom-left-radius: $border-radius;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_fullcalendar.scss b/Moonlight/Styles/vendors/plugins/_fullcalendar.scss
new file mode 100644
index 00000000..1b67c5e8
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_fullcalendar.scss
@@ -0,0 +1,297 @@
+//
+// Fullcalendar plugin customization: https://fullcalendar.io/
+//
+
+body {
+ --fc-event-border-color: var(--#{$prefix}primary);
+ --fc-event-bg-color: var(--#{$prefix}primary);
+ --fc-event-text-color: var(--#{$prefix}primary-inverse);
+}
+
+// Base
+.fc {
+ // Border color
+ --fc-border-color: #{var(--#{$prefix}gray-200)};
+ --fc-page-bg-color: #{$white};
+ --fc-small-font-size: 0.95rem;
+
+ // General
+ --fc-highlight-color: var(--#{$prefix}light);
+ //--fc-non-business-color:
+ //--fc-bg-event-color:
+ --fc-bg-event-opacity: 0.3;
+ --fc-neutral-bg-color: var(--#{$prefix}light);
+ //--fc-event-selected-overlay-color:
+ --fc-today-bg-color: var(--#{$prefix}success-light);
+ //--fc-neutral-bg-color:
+ //--fc-neutral-text-color:
+ //--fc-more-link-text-color:
+ //--fc-more-link-bg-color:
+ --fc-now-indicator-color: var(--#{$prefix}danger);
+ --fc-list-event-hover-bg-color: var(--#{$prefix}light);
+
+ // Buttons
+ --fc-button-text-color: var(--#{$prefix}gray-600);
+ --fc-button-bg-color: var(--#{$prefix}gray-100);
+ --fc-button-border-color: var(--#{$prefix}gray-100);
+
+ --fc-button-hover-bg-color: var(--#{$prefix}gray-100);
+ --fc-button-hover-border-color: var(--#{$prefix}gray-100);
+
+ --fc-button-active-bg-color: var(--#{$prefix}gray-200);
+ --fc-button-active-border-color: var(--#{$prefix}gray-200);
+
+ // Table
+ table {
+ font-size: 1rem;
+ }
+
+ // Button
+ .fc-button {
+ padding: 0.75rem 1.25rem;
+ box-shadow: none !important;
+ border: 0 !important;
+ border-radius: $btn-border-radius;
+ vertical-align: middle;
+ font-weight: $font-weight-semibold;
+ text-transform: capitalize;
+ }
+
+ // Primary button
+ .fc-button-primary {
+ margin: 0;
+
+ // Icon
+ .fc-icon {
+ font-size: 1.35rem;
+ margin-bottom: 0.15rem;
+ }
+
+ &:not(:disabled):not(.fc-button-active) {
+ &:focus,
+ &:hover,
+ &:active {
+ color: var(--#{$prefix}gray-900);
+
+ .fc-icon {
+ color: var(--#{$prefix}gray-900);
+ }
+ }
+ }
+
+ &:not(:disabled).fc-button-active {
+ color: var(--#{$prefix}gray-900);
+
+ .fc-icon {
+ color: var(--#{$prefix}gray-900);
+ }
+ }
+ }
+
+ // Button group
+ .fc-button-group {
+ .fc-button {
+ margin: 0 !important;
+ }
+ }
+
+ // Toolbar title
+ .fc-toolbar-title {
+ font-size: 1.5rem;
+ font-weight: $font-weight-bold;
+ color: var(--#{$prefix}gray-800);
+ }
+
+ // Header cell
+ .fc-col-header-cell {
+ padding: 0.75rem 0.5rem;
+
+ .fc-col-header-cell-cushion {
+ font-size: 1.1rem;
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-800);
+ }
+ }
+
+ // Border radius
+ .fc-scrollgrid {
+ @include border-radius($border-radius);
+
+ thead > tr {
+ td:first-child {
+ @include border-top-start-radius($border-radius);
+ }
+
+ td:last-child {
+ @include border-top-end-radius($border-radius);
+ }
+ }
+
+ tbody > tr:last-child {
+ td:first-child {
+ @include border-bottom-start-radius($border-radius);
+ }
+
+ td:last-child {
+ @include border-bottom-end-radius($border-radius);
+ }
+ }
+ }
+
+ // Event
+ .fc-daygrid-event {
+ margin-top: 3px;
+ }
+
+ // Event title
+ .fc-daygrid-dot-event,
+ .fc-daygrid-block-event {
+ .fc-event-title,
+ .fc-event-time {
+ padding: 0.25rem 0.25rem;
+ }
+ }
+
+ // Day number
+ .fc-daygrid-day-number {
+ color: var(--#{$prefix}gray-800);
+ }
+
+ // Dot event
+ .fc-daygrid-dot-event {
+ background-color: var(--#{$prefix}light);
+ color: var(--#{$prefix}gray-600);
+
+ .fc-event-title {
+ font-weight: $font-weight-semibold;
+ }
+
+ &:hover,
+ &.fc-event-mirror {
+ background-color: var(--#{$prefix}light);
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ // Event dot
+ .fc-daygrid-event-dot {
+ margin-left: 0.5rem;
+ margin-right: 0.1rem;
+ }
+
+ // Popover
+ .fc-popover {
+ border: 0 !important;
+ background-color: $tooltip-bg;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ @include border-radius($dropdown-border-radius);
+
+ .fc-popover-header {
+ @include border-top-radius($dropdown-border-radius);
+ padding: 0.65rem 0.75rem;
+ background-color: var(--#{$prefix}tooltip-bg);
+
+ .fc-popover-title {
+ color: var(--#{$prefix}gray-800);
+ font-size: 1rem;
+ font-weight: $font-weight-semibold;
+ }
+
+ .fc-popover-close {
+ font-size: 1rem;
+ color: var(--#{$prefix}gray-600);
+
+ &:hover {
+ color: var(--#{$prefix}primary);
+ }
+ }
+ }
+
+ .fc-popover-body {
+ padding: 0.5rem 0.75rem 0.75rem 0.75rem;
+ }
+ }
+
+ // More link
+ .fc-daygrid-more-link {
+ font-weight: $font-weight-semibold;
+ }
+
+ // Slot
+ .fc-timegrid-slot {
+ height: 2rem;
+ font-size: 0.95rem;
+ }
+
+ // List
+ .fc-list-day-cushion,
+ .fc-list-table td {
+ padding: 0.85rem 1.15rem;
+ }
+
+ .fc-list-day-text,
+ .fc-list-day-side-text {
+ font-size: 1.1rem;
+ color: var(--#{$prefix}gray-900);
+ font-weight: $font-weight-bold;
+ }
+
+ .fc-list,
+ //.fc-scroller,
+ .fc-list-table {
+ @include border-radius($border-radius);
+ }
+
+ .fc-list {
+ overflow: hidden;
+ position: relative;
+ }
+
+ // Week
+ .fc-timegrid-axis {
+ padding-left: 0rem;
+ padding-right: 0;
+ }
+
+ // Main
+ .fc-timegrid-event .fc-event-main {
+ padding: 0.25rem 0.25rem;
+ }
+
+ // Indicator arrow
+ .fc-timegrid-now-indicator-arrow {
+ margin-top: -1px;
+ }
+}
+
+// Event
+.fc-h-event {
+ font-weight: $font-weight-normal;
+}
+
+// Mobile mode
+@include media-breakpoint-down(md) {
+ .fc {
+ // Header toolbar
+ .fc-header-toolbar {
+ flex-direction: column;
+ align-items: flex-start;
+
+ .fc-toolbar-chunk {
+ &:nth-child(1),
+ &:nth-child(3) {
+ order: 2;
+ }
+
+ &:nth-child(2) {
+ order: 1;
+ }
+
+ &:nth-child(2),
+ &:nth-child(1) {
+ margin-bottom: 1rem;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_gmaps.scss b/Moonlight/Styles/vendors/plugins/_gmaps.scss
new file mode 100644
index 00000000..0f9dd4c9
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_gmaps.scss
@@ -0,0 +1,18 @@
+//
+// Gmaps Plugin
+//
+
+.gmaps {
+ /* important! bootstrap sets max-width on img to 100% which conflicts with google map canvas*/
+ img {
+ max-width: none;
+ }
+
+ &.gmaps-static {
+ > div {
+ background-repeat: no-repeat ;
+ background-position: 50% 50% ;
+ display:block;
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_jkanban.scss b/Moonlight/Styles/vendors/plugins/_jkanban.scss
new file mode 100644
index 00000000..60b41e3e
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_jkanban.scss
@@ -0,0 +1,94 @@
+//
+// Kanban Board
+//
+
+// Variables
+$kanban-spacer-y: 1.25rem;
+$kanban-spacer-x: 1.25rem;
+
+.kanban-container {
+ width: 100% !important;
+ display: flex;
+ flex-wrap: wrap;
+
+ .kanban-board {
+ float: none;
+ flex-shrink: 0;
+ margin-bottom: $kanban-spacer-y;
+ margin-right: $kanban-spacer-x !important;
+ background-color: var(--#{$prefix}gray-100);
+ @include border-radius($border-radius);
+
+ &:last-child {
+ margin-right: 0 !important;
+ }
+
+ .kanban-board-header {
+ @include border-top-start-radius($border-radius);
+ @include border-top-end-radius($border-radius);
+
+ .kanban-title-board {
+ font-size: 1.2rem;
+ font-weight: 500;
+ color: var(--#{$prefix}gray-900);
+ }
+
+ @each $name, $color in $theme-colors {
+ &.#{$name} {
+ background-color: var(--#{$prefix}#{$name});
+ box-shadow: none;
+
+ .kanban-title-board {
+ color: var(--#{$prefix}#{$name}-inverse);
+ }
+ }
+
+ &.light-#{$name} {
+ color: rgba(var(--#{$prefix}#{$name}), 0.1);
+ box-shadow: none;
+
+ .kanban-title-board {
+ color: var(--#{$prefix}#{$name});
+ }
+ }
+ }
+ }
+
+ .kanban-drag {
+ .kanban-item {
+ @include border-radius($border-radius);
+ box-shadow: 0px 0px 13px 0px rgba(0, 0, 0, 0.05);
+ background: var(--#{$prefix}body-bg);
+
+ @each $name, $color in $theme-colors {
+ &[data-class="#{$name}"] {
+ background-color: var(--#{$prefix}#{$name});
+ color: var(--#{$prefix}#{$name}-inverse);
+ box-shadow: none;
+ }
+
+ &[data-class="light-#{$name}"] {
+ background-color: var(--#{$prefix}#{$name}-light);
+ color: var(--#{$prefix}#{$name});
+ box-shadow: none;
+ }
+ }
+ }
+ }
+
+ footer {
+ }
+ }
+}
+
+// Fixed height
+.kanban-fixed-height {
+ .kanban-container {
+ .kanban-board {
+ .kanban-drag {
+ position: relative;
+ overflow-y: auto;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_jstree.scss b/Moonlight/Styles/vendors/plugins/_jstree.scss
new file mode 100644
index 00000000..82c472eb
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_jstree.scss
@@ -0,0 +1,150 @@
+//
+// jsTree
+//
+
+.jstree-default {
+ .jstree-anchor {
+ color: var(--#{$prefix}gray-700);
+ padding: 0 8px 0 4px;
+ }
+
+ .jstree-icon {
+ color: var(--#{$prefix}gray-700);
+
+ font-size: 1.3rem;
+
+ &.la {
+ font-size: 1.5rem;
+ }
+ &.fa {
+ font-size: 1.2rem;
+ }
+ }
+
+ .jstree-disabled {
+ cursor: not-allowed;
+ line-height: auto;
+ height: auto;
+ opacity: 0.7;
+
+ .jstree-icon {
+ color: var(--#{$prefix}gray-700);
+ }
+ }
+
+ .jstree-clicked {
+ border: 0;
+ background: var(--#{$prefix}gray-100);
+ box-shadow: none;
+ }
+
+ .jstree-hovered {
+ border: 0;
+ background-color: var(--#{$prefix}gray-100);
+ box-shadow: none;
+ }
+
+ .jstree-wholerow-clicked,
+ .jstree-wholerow-clicked {
+ background: var(--#{$prefix}gray-200);
+ box-shadow: none;
+ }
+
+ .jstree-wholerow-hovered,
+ &.jstree-wholerow .jstree-wholerow-hovered {
+ border: 0;
+ background-color: var(--#{$prefix}gray-100);
+ box-shadow: none;
+ }
+}
+
+.jstree-open>.jstree-anchor>.fa-folder:before {
+ margin-left: 2px;
+ content: "\f07c";
+}
+
+.jstree-open>.jstree-anchor>.la-folder:before {
+ margin-left: 2px;
+ content: "\f200";
+}
+
+.jstree-default.jstree-rtl .jstree-node {
+ background-position: 100% 1px#{'/*rtl:ignore*/'} !important;
+}
+
+.jstree-default.jstree-rtl .jstree-last {
+ background: transparent #{'/*rtl:ignore*/'};
+ background-repeat: no-repeat;
+}
+
+.jstree-rtl .jstree-anchor {
+ padding: 0 4px 0 8px#{'/*rtl:ignore*/'};
+}
+
+// context menu
+.vakata-context,
+.vakata-context ul {
+ padding: 0.5rem 0;
+ min-width: 150px;
+ font-size: 1rem;
+ font-family: $font-family-base;
+ background: var(--#{$prefix}body-bg);
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ border: 0;
+ @include border-radius($border-radius);
+
+ li {
+ padding: 0;
+ border: 0;
+
+ a {
+ padding: 0rem 1.2rem;
+ border: 0;
+ //line-height: 2.2em;
+
+ i {
+ display: none;
+ }
+
+ .vakata-contextmenu-sep {
+ display: none;
+ }
+
+ span,
+ ins {
+ display: none;
+ border: 0 !important;
+ }
+ }
+ }
+
+ .vakata-context-hover>a,
+ li a:hover {
+ margin: 0;
+ background-color: var(--#{$prefix}gray-100);
+ color: var(--#{$prefix}primary);
+ box-shadow: none;
+
+ .span,
+ .ins {
+ border: 0 !important;
+ }
+ }
+}
+
+.vakata-context .vakata-context-separator a,
+.vakata-context-rtl .vakata-context-separator a {
+ margin: 0;
+ border: 0;
+ height: 2px;
+ background-color: var(--#{$prefix}gray-200);
+}
+
+.jstree-rename-input {
+ outline: none !important;
+ padding: 2px 6px !important;
+ margin-right: -4px !important;
+ background-color: var(--#{$prefix}gray-100) !important;
+ border: 1px solid var(--#{$prefix}gray-100) !important;
+ @include border-radius($border-radius);
+}
diff --git a/Moonlight/Styles/vendors/plugins/_keenicons.scss b/Moonlight/Styles/vendors/plugins/_keenicons.scss
new file mode 100644
index 00000000..23ace9e1
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_keenicons.scss
@@ -0,0 +1,12 @@
+//
+// Keenicons
+//
+
+.ki-duotone,
+.ki-outline,
+.ki-solid {
+ line-height: 1;
+ font-size: 1rem;
+ color: var(--#{$prefix}text-muted);
+}
+
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_leaflet.scss b/Moonlight/Styles/vendors/plugins/_leaflet.scss
new file mode 100644
index 00000000..56682a15
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_leaflet.scss
@@ -0,0 +1,23 @@
+//
+// leaflet
+//
+
+.leaflet-container {
+ .leaflet-pane,
+ .leaflet-top,
+ .leaflet-bottom,
+ .leaflet-control {
+ z-index: 1 !important;
+ }
+
+ .leaflet-popup-content-wrapper {
+ border-radius: $border-radius !important;
+ text-align: center;
+ box-shadow: var(--#{$prefix}box-shadow) !important;
+
+ .leaflet-popup-content {
+ font-family: $font-family-sans-serif;
+ font-size: $font-size-base;
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_mixins.scss b/Moonlight/Styles/vendors/plugins/_mixins.scss
new file mode 100644
index 00000000..c22460ef
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_mixins.scss
@@ -0,0 +1,5 @@
+//
+// Mixins
+//
+
+@import "mixins/nouislider";
diff --git a/Moonlight/Styles/vendors/plugins/_nouislider.scss b/Moonlight/Styles/vendors/plugins/_nouislider.scss
new file mode 100644
index 00000000..405f9b09
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_nouislider.scss
@@ -0,0 +1,103 @@
+//
+// NoUiSlider
+//
+
+
+// Base
+.noUi-target {
+ border: 0;
+ background: var(--#{$prefix}gray-100);
+ box-shadow:none;
+
+ &.noUi-horizontal {
+ height: 15px;
+
+ .noUi-handle {
+ width: 24px;
+ height: 24px;
+ top: -4.5px;
+ border-radius: 50%;
+ outline: none;
+
+ &::before {
+ display: none;
+ }
+
+ &::after {
+ display: none;
+ }
+ }
+ }
+
+ &.noUi-vertical {
+ height: 150px;
+ width: 15px;
+
+ .noUi-handle {
+ width: 24px;
+ height: 24px;
+ right: -4.5px;
+ border-radius: 50%;
+ outline: none;
+
+ &::before {
+ display: none;
+ }
+
+ &::after {
+ display: none;
+ }
+ }
+ }
+
+ .noUi-connect {
+ background: var(--#{$prefix}component-active-bg);
+ }
+
+ .noUi-handle {
+ background-color: $white; //var(--#{$prefix}body-bg);
+ border: 1px solid var(--#{$prefix}gray-200);
+ box-shadow:var(--#{$prefix}box-shadow-sm)
+ }
+
+ // Small size
+ &.noUi-sm {
+ @include nouislider-size(6px, 20px, 20px, 7px);
+ }
+
+ // Large size
+ &.noUi-lg {
+ @include nouislider-size(18px, 30px, 30px, 6px);
+ }
+}
+
+// Theme colors
+@each $name, $value in $theme-colors {
+ // NoUiSlider success color option
+ .noUi-target.noUi-target-#{$name} {
+ .noUi-connects {
+ background-color: var(--#{$prefix}#{$name}-light);
+
+ .noUi-connect {
+ background-color: var(--#{$prefix}#{$name});
+ }
+ }
+
+ .noUi-handle {
+ border: 1px solid var(--#{$prefix}#{$name});
+ box-shadow: 0 3px 6px -3px rgba(var(--#{$prefix}#{$name}), 0.7);
+ background-color: var(--#{$prefix}#{$name});
+ }
+ }
+}
+
+// Tooltip
+.noUi-tooltip {
+ box-shadow: var(--#{$prefix}tooltip-box-shadow);
+ background: var(--#{$prefix}tooltip-bg);
+ color: var(--#{$prefix}tooltip-color);
+ font-size: $tooltip-font-size;
+ border: 0;
+ padding: 0.5rem 0.75rem;
+ @include border-radius($tooltip-border-radius);
+}
diff --git a/Moonlight/Styles/vendors/plugins/_plugins.angular.scss b/Moonlight/Styles/vendors/plugins/_plugins.angular.scss
new file mode 100644
index 00000000..0242e131
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_plugins.angular.scss
@@ -0,0 +1,12 @@
+//
+// Plugins
+//
+
+// Import Dependencies
+@import "root";
+@import "prismjs";
+@import "nouislider";
+@import "apexcharts";
+@import "fslightbox";
+@import "tiny-slider";
+@import "fullcalendar";
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_plugins.react.scss b/Moonlight/Styles/vendors/plugins/_plugins.react.scss
new file mode 100644
index 00000000..0242e131
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_plugins.react.scss
@@ -0,0 +1,12 @@
+//
+// Plugins
+//
+
+// Import Dependencies
+@import "root";
+@import "prismjs";
+@import "nouislider";
+@import "apexcharts";
+@import "fslightbox";
+@import "tiny-slider";
+@import "fullcalendar";
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_plugins.scss b/Moonlight/Styles/vendors/plugins/_plugins.scss
new file mode 100644
index 00000000..cf76d235
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_plugins.scss
@@ -0,0 +1,34 @@
+//
+// Plugins
+//
+
+// Import Dependencies
+@import "root";
+@import "prismjs";
+@import "fslightbox";
+@import "select2";
+@import "formvalidation";
+@import "daterangepicker";
+@import "flatpickr";
+@import "tagify";
+@import "bootstrap-maxlength";
+@import "ckeditor";
+@import "datatables";
+@import "dropzone";
+@import "gmaps";
+@import "nouislider";
+@import "quill";
+@import "recaptcha";
+@import "sweetalert2";
+@import "tinymce";
+@import "toastr";
+@import "draggable";
+@import "apexcharts";
+@import "leaflet";
+@import "tiny-slider";
+@import "fullcalendar";
+@import "jkanban";
+@import "jstree";
+@import "vis-timeline";
+@import "tempus-dominus";
+@import "keenicons";
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_plugins.vue.scss b/Moonlight/Styles/vendors/plugins/_plugins.vue.scss
new file mode 100644
index 00000000..0242e131
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_plugins.vue.scss
@@ -0,0 +1,12 @@
+//
+// Plugins
+//
+
+// Import Dependencies
+@import "root";
+@import "prismjs";
+@import "nouislider";
+@import "apexcharts";
+@import "fslightbox";
+@import "tiny-slider";
+@import "fullcalendar";
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_prismjs.scss b/Moonlight/Styles/vendors/plugins/_prismjs.scss
new file mode 100644
index 00000000..1e9b4ebb
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_prismjs.scss
@@ -0,0 +1,84 @@
+//
+// Prismjs
+//
+
+// Highlight
+.highlight {
+ position: relative;
+ background: var(--#{$prefix}prismjs-bg);
+ border-radius: $border-radius;
+ padding: 1.75rem 1.5rem 1.75rem 1.5rem;
+
+ // Tabs
+ .nav {
+ border-bottom: 1px solid var(--#{$prefix}prismjs-border);
+ padding-bottom: 1rem;
+ margin-bottom: 1rem;
+ margin-top: -0.25rem;
+
+ .nav-item {
+ margin-right: 0.75rem;
+ }
+
+ .nav-link {
+ font-size: 0.9rem;
+ font-weight: 500;
+ padding: 0.35rem 1rem;
+ border-radius: $border-radius;
+ color: var(--#{$prefix}prismjs-btn-color);
+ transition: $transition-base;
+ background-color: transparent;
+
+ &:focus,
+ &.active {
+ transition: $transition-base;
+ background-color: var(--#{$prefix}prismjs-btn-bg-hover);
+ color: var(--#{$prefix}prismjs-btn-color-hover);
+ }
+ }
+ }
+
+ .highlight-copy {
+ display: none;
+ position: absolute;
+ right: 1.75rem;
+ top: 1.5rem;
+ font-size: 0.85rem;
+ font-weight: 500;
+ padding: 0.35rem 1rem !important;
+ transition: $transition-base;
+ background-color: var(--#{$prefix}prismjs-btn-bg);
+ color: var(--#{$prefix}prismjs-btn-color);
+
+ &:focus,
+ &:hover {
+ transition: $transition-base;
+ background-color: var(--#{$prefix}prismjs-btn-bg-hover);
+ color: var(--#{$prefix}prismjs-btn-color-hover);
+ }
+ }
+
+ &:hover {
+ .highlight-copy {
+ display: flex;
+ }
+ }
+
+ // Code
+ .highlight-code {
+ pre {
+ background-color: transparent;
+ overflow: auto;
+ padding: 0;
+ margin: 0;
+
+ @include scrollbar-color( var(--#{$prefix}prismjs-scrollbar-color), var(--#{$prefix}prismjs-scrollbar-color-hover));
+
+ code[class*="language-"] {
+ padding: 0;
+ margin: 0;
+ font-size: 1rem !important;
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_quill.scss b/Moonlight/Styles/vendors/plugins/_quill.scss
new file mode 100644
index 00000000..ceab78c3
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_quill.scss
@@ -0,0 +1,196 @@
+//
+// Quill
+//
+
+// Base
+.ql-toolbar {
+ font-family: $font-family-sans-serif;
+
+ &.ql-snow {
+ border: 1px solid var(--#{$prefix}border-color);
+ @include border-top-radius($border-radius);
+
+ .ql-picker,
+ button {
+ .ql-fill,
+ .ql-stroke {
+ stroke: var(--#{$prefix}gray-500);
+ }
+
+ .ql-fill {
+ fill: var(--#{$prefix}gray-500);
+ }
+
+ &.ql-expanded,
+ &.ql-active,
+ &:focus,
+ &:hover {
+ .ql-fill,
+ .ql-stroke {
+ stroke: var(--#{$prefix}primary);
+ }
+
+ .ql-fill {
+ fill: var(--#{$prefix}primary);
+ }
+ }
+ }
+ }
+}
+
+.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg {
+ right: 0;
+
+ [direction="rtl"] &,
+ [dir="rtl"] & {
+ left: 0;
+ right: auto;
+ }
+}
+
+.ql-editor {
+ color: var(--#{$prefix}input-color);
+ text-align: initial;
+
+ &.ql-blank {
+ &:before {
+ left: auto !important;
+ right: auto !important;
+ color: var(--#{$prefix}text-muted) !important;
+ font-style: normal !important;
+ }
+ }
+}
+
+.ql-container {
+ &.ql-snow {
+ background-color: var(--#{$prefix}input-bg);
+ border: 1px solid var(--#{$prefix}gray-200);
+ border-top: 0;
+ @include border-bottom-radius($border-radius);
+ }
+}
+
+.ql-snow {
+ .ql-picker {
+ .ql-picker-label {
+ color: var(--#{$prefix}gray-500);
+
+ &.ql-active,
+ &:hover {
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ &.ql-expanded {
+ outline: none !important;
+ border-color: transparent !important;
+
+ .ql-picker-label {
+ border-color: transparent !important;
+ color: var(--#{$prefix}primary);
+ outline: none !important;
+
+ &.ql-active,
+ &:hover {
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ .ql-picker-options {
+ border: 0;
+ padding: 0.5rem 1rem;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ background-color: var(--#{$prefix}body-bg);
+ @include border-radius($border-radius);
+
+ .ql-picker-item {
+ color: var(--#{$prefix}gray-600);
+ outline: none;
+
+ &.ql-selected,
+ &.ql-active,
+ &:hover {
+ color: var(--#{$prefix}primary);
+ }
+ }
+ }
+ }
+ }
+
+ .ql-tooltip {
+ border: 0;
+ padding: 0.5rem 1rem;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ @include border-radius($border-radius);
+
+ input[type=text] {
+ @include input-reset();
+ border: 1px solid var(--#{$prefix}border-color);
+ color: $input-plaintext-color;
+ outline: none !important;
+ @include border-radius($border-radius);
+
+ &:active,
+ &:focus {
+ border-color: var(--#{$prefix}input-focus-border-color) !important;
+ }
+ }
+
+ .ql-preview {
+ color: var(--#{$prefix}gray-600);
+ }
+
+ .ql-action {
+ transition: color 0.3s ease;
+ color: var(--#{$prefix}gray-600);
+
+ &:hover {
+ transition: color 0.3s ease;
+ color: var(--#{$prefix}primary);
+ }
+ }
+
+ // Tooltip adjustment in modal
+ .modal & {
+ &.ql-editing {
+ left: 20px !important;
+ }
+ }
+ }
+
+ .ql-editor {
+ pre.ql-syntax {
+ background-color: var(--#{$prefix}gray-900);
+ color: var(--#{$prefix}text-muted);
+ overflow: visible;
+ @include border-radius($border-radius);
+ }
+ }
+}
+
+// Plain Style
+.ql-quil.ql-quil-plain {
+ .ql-toolbar {
+ padding: 0;
+ margin: 0;
+ border: 0;
+
+ &:after {
+ display: none;
+ }
+
+ .ql-picker-label {
+ padding-left: 0;
+ }
+ }
+
+ .ql-container {
+ border: 0;
+ }
+
+ .ql-editor {
+ border: 0;
+ padding: 0;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_recaptcha.scss b/Moonlight/Styles/vendors/plugins/_recaptcha.scss
new file mode 100644
index 00000000..c15c0a73
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_recaptcha.scss
@@ -0,0 +1,32 @@
+//
+// Recaptcha
+//
+
+
+// Base
+.recaptcha {
+ padding: 15px;
+ border: 1px solid var(--#{$prefix}gray-200);
+ @include border-radius($border-radius);
+
+ .recaptcha-img {
+ margin-bottom: 10px;
+ }
+
+ .recaptcha_only_if_incorrect_sol {
+ color: var(--#{$prefix}danger);
+ }
+
+ .input-group {
+ .btn {
+ i {
+ padding-right: 0;
+ }
+ }
+
+ .form-control {
+ @include border-top-start-radius($border-radius !important);
+ @include border-bottom-start-radius($border-radius !important);
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_root.scss b/Moonlight/Styles/vendors/plugins/_root.scss
new file mode 100644
index 00000000..a328d5aa
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_root.scss
@@ -0,0 +1,36 @@
+//
+// CSS Variables
+//
+
+:root,
+[data-bs-theme="light"] {
+ // Select2
+
+ // Prismjs
+ --#{$prefix}prismjs-bg: #{$prismjs-bg};
+
+ --#{$prefix}prismjs-border: #{$prismjs-border};
+
+ --#{$prefix}prismjs-btn-bg: #{$prismjs-btn-bg};
+ --#{$prefix}prismjs-btn-bg-hover: #{$prismjs-btn-bg-hover};
+ --#{$prefix}prismjs-btn-color: #{$prismjs-btn-color};
+ --#{$prefix}prismjs-btn-color-hover: #{$prismjs-btn-color-hover};
+
+ --#{$prefix}prismjs-scrollbar-color: #{$prismjs-scrollbar-color};
+ --#{$prefix}prismjs-scrollbar-color-hover: #{$prismjs-scrollbar-color-hover};
+}
+
+[data-bs-theme="dark"] {
+ // Prismjs
+ --#{$prefix}prismjs-bg: #{$prismjs-bg-dark};
+
+ --#{$prefix}prismjs-border: #{$prismjs-border-dark};
+
+ --#{$prefix}prismjs-btn-bg: #{$prismjs-btn-bg-dark};
+ --#{$prefix}prismjs-btn-bg-hover: #{$prismjs-btn-bg-hover-dark};
+ --#{$prefix}prismjs-btn-color: #{$prismjs-btn-color-dark};
+ --#{$prefix}prismjs-btn-color-hover: #{$prismjs-btn-color-hover-dark};
+
+ --#{$prefix}prismjs-scrollbar-color: #{$prismjs-scrollbar-color-dark};
+ --#{$prefix}prismjs-scrollbar-color-hover: #{$prismjs-scrollbar-color-hover-dark};
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_select2.scss b/Moonlight/Styles/vendors/plugins/_select2.scss
new file mode 100644
index 00000000..6670b930
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_select2.scss
@@ -0,0 +1,418 @@
+//
+// Select2 plugin customization: https://select2.org
+//
+
+$select2-dropdown-padding: 1rem 0;
+$select2-dropdown-option-padding: 0.75rem 1.25rem;
+$select2-dropdown-option-margin: 0 0;
+$select2-dropdown-option-check-padding: 1.25rem;
+
+$select2-dropdown-group-padding: 0 1.25rem 0 1.25rem;
+$select2-dropdown-group-margin: 0 0 0.25rem 0;
+
+$select2-search-padding: 0.5rem 1.25rem;
+$select2-search-margin: 0 0 0.5rem 0;
+
+$select2-clear-size: 0.7rem;
+$select2-clear-color: var(--#{$prefix}gray-700);
+$select2-clear-color-dark: var(--#{$prefix}gray-700);
+$select2-clear-color-hover: var(--#{$prefix}primary);
+$select2-clear-right: $form-select-indicator-padding; //$form-select-padding-x +
+
+
+// Bootstrap .form-control sizing integration
+$select2-tag-clear-size: 0.6rem;
+
+$select2-tag-padding-y-sm: 0.1rem;
+$select2-tag-padding-x-sm: 0.35rem;
+$select2-input-padding-y-sm: $input-padding-y-sm - $select2-tag-padding-y-sm * 2;
+
+$select2-tag-padding-y: 0.1rem;
+$select2-tag-padding-x: 0.5rem;
+$select2-input-padding-y: $input-padding-y - $select2-tag-padding-y * 2;
+
+$select2-tag-padding-y-lg: 0.15rem;
+$select2-tag-padding-x-lg: 0.65rem;
+$select2-input-padding-y-lg: $input-padding-y-lg - $select2-tag-padding-y-lg * 2;
+
+// Bootstrapa 5 Theme
+.select2-container--bootstrap5 {
+ // Selection
+ .select2-selection {
+ box-shadow: none;
+ height: auto;
+ outline: none !important;
+ }
+
+ // Selection focus & open states
+ &.select2-container--focus:not(.select2-container--disabled),
+ &.select2-container--open:not(.select2-container--disabled) {
+ .form-select-solid {
+ background-color: $input-solid-bg-focus;
+ }
+
+ .form-select:not(.form-select-solid):not(.form-select-transparent) {
+ border-color: $input-focus-border-color;
+ }
+ }
+
+ &.select2-container--disabled {
+ .form-select {
+ background-color: $form-select-disabled-bg;
+ border-color: $form-select-disabled-border-color;
+
+ .select2-selection__rendered,
+ .select2-selection__placeholder {
+ color: $form-select-disabled-color !important;
+ }
+
+ &.form-select-transparent {
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+ }
+
+ // Search
+ .select2-search.select2-search--inline {
+ flex-grow: 1;
+
+ .select2-search__field {
+ color: $input-color;
+ @include placeholder($input-placeholder-color);
+ font-weight: $input-font-weight;
+ font-family: inherit !important;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ outline: none;
+ line-height: 1;
+ margin: 0;
+ padding: 0;
+ }
+ }
+
+ .form-select-solid .select2-search.select2-search--inline {
+ .select2-search__field {
+ color: $input-solid-color;
+ font-family: inherit !important;
+ @include placeholder($input-solid-placeholder-color);
+ }
+ }
+
+ // Single mode
+ .select2-selection--single {
+ display: flex;
+ align-items: center;
+
+ // Selected
+ .select2-selection__rendered {
+ display: block;
+ padding-left: 0;
+ padding-right: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: var(--#{$prefix}input-color);
+ }
+
+ // Placeholder
+ .select2-selection__placeholder {
+ color: $input-solid-placeholder-color;
+ }
+
+ // Form select solid
+ &.form-select-solid {
+ // Selected
+ .select2-selection__rendered {
+ color: $input-solid-color;
+ }
+
+ // Placeholder
+ .select2-selection__placeholder {
+ color: $input-solid-placeholder-color;
+ }
+ }
+
+ // Form select transparent
+ &.form-select-transparent {
+ // Selected
+ .select2-selection__rendered {
+ color: var(--#{$prefix}gray-800);
+ }
+
+ // Placeholder
+ .select2-selection__placeholder {
+ color: var(--#{$prefix}gray-800);
+ }
+ }
+
+ // Form select dark color
+ &.form-select-dark {
+ // Selected
+ .select2-selection__rendered {
+ color: var(--#{$prefix}gray-900);
+ }
+ }
+ }
+
+ // Multiple mode
+ .select2-selection--multiple {
+ display: flex;
+ align-items: center;
+
+ // Search
+ .select2-search.select2-search--inline {
+ display: inline-flex;
+ }
+
+ // Selected
+ .select2-selection__rendered {
+ display: inline;
+ margin: 0;
+ padding: 0;
+
+ .select2-selection__choice {
+ display: inline-flex;
+ align-items: center;
+ position: relative;
+ background-color: var(--#{$prefix}gray-300);
+
+ .select2-selection__choice__remove {
+ @include svg-bg-icon(close, var(--#{$prefix}gray-700));
+ display: block;
+ position: absolute;
+ transform: translateY(-50%);
+ opacity: 0.5;
+ border: 0;
+ transition: $transition-link;
+ top: 50%;
+
+ span {
+ display: none;
+ }
+
+ &:hover {
+ opacity: 1;
+ @include svg-bg-icon(close, var(--#{$prefix}primary));
+ transition: $transition-link;
+ }
+ }
+
+ .select2-selection__choice__display {
+ font-weight: $font-weight-semibold;
+ }
+ }
+ }
+
+ // Choice
+ .select2-selection__choice {
+ .select2-selection__choice__remove {
+ height: $select2-tag-clear-size;
+ width: $select2-tag-clear-size;
+ }
+ }
+
+ // Sizes
+ &.form-select-sm {
+ min-height: $input-height-sm;
+ padding-top: $select2-input-padding-y-sm;
+ padding-bottom: $select2-input-padding-y-sm;
+
+ .select2-selection__choice {
+ border-radius: $btn-border-radius-sm;
+ padding: $select2-tag-padding-y-sm $select2-tag-padding-x-sm;
+ margin-right: $select2-tag-padding-x-sm;
+ margin-top: $select2-tag-padding-y-sm;
+ margin-bottom: $select2-tag-padding-y-sm;
+
+ .select2-selection__choice__display {
+ margin-left: $select2-tag-padding-x-sm + $select2-tag-clear-size;
+ font-size: $input-btn-font-size-sm;
+ }
+ }
+
+ .select2-search__field {
+ height: 14px;
+ }
+ }
+
+ &:not(.form-select-sm):not(.form-select-lg) {
+ min-height: $input-height;
+ padding-top: $select2-input-padding-y;
+ padding-bottom: $select2-input-padding-y;
+
+ .select2-selection__choice {
+ border-radius: $btn-border-radius;
+ padding: $select2-tag-padding-y $select2-tag-padding-x;
+ margin-right: $select2-tag-padding-x;
+ margin-top: $select2-tag-padding-y;
+ margin-bottom: $select2-tag-padding-y;
+
+ .select2-selection__choice__display {
+ margin-left: $select2-tag-padding-x + $select2-tag-clear-size;
+ font-size: $input-btn-font-size;
+ }
+ }
+
+ .select2-search__field {
+ height: 16px;
+ }
+ }
+
+ &.form-select-lg {
+ min-height: $input-height-lg;
+ padding-top: $select2-input-padding-y-lg;
+ padding-bottom: $select2-input-padding-y-lg;
+
+ .select2-selection__choice {
+ border-radius: $btn-border-radius-lg;
+ padding: $select2-tag-padding-y-lg $select2-tag-padding-x-lg;
+ margin-right: $select2-tag-padding-x-lg;
+ margin-top: $select2-tag-padding-y-lg;
+ margin-bottom: $select2-tag-padding-y-lg;
+
+ .select2-selection__choice__display {
+ margin-left: $select2-tag-padding-x-lg + $select2-tag-clear-size;
+ font-size: $input-btn-font-size-lg;
+ }
+ }
+
+ .select2-search__field {
+ height: 18px;
+ }
+ }
+ }
+
+ // Dropdown
+ .select2-dropdown {
+ border: 0;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ border-radius: $dropdown-border-radius;
+ padding: $select2-dropdown-padding;
+ background-color: var(--#{$prefix}dropdown-bg);
+
+ // In modal
+ .modal-open & {
+ z-index: $zindex-modal + 1;
+ }
+
+ // Search
+ .select2-search {
+ padding: $select2-search-padding;
+ margin: $select2-search-margin;
+
+ .select2-search__field {
+ background-color: var(--#{$prefix}body-bg);
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ color: $input-color;
+ font-size: $input-font-size-sm;
+ border: 1px solid $input-border-color;
+ border-radius: $input-border-radius-sm;
+ outline: 0 !important;
+
+ &:focus,
+ &:active {
+ border: 1px solid $input-focus-border-color;
+ }
+ }
+ }
+
+ // Options
+ .select2-results > .select2-results__options {
+ max-height: 250px;
+ overflow-y: auto;
+ }
+
+ // Option
+ .select2-results__option {
+ color: var(--#{$prefix}gray-700);
+ transition: $transition-link;
+ padding: $select2-dropdown-option-padding;
+ margin: $select2-dropdown-option-margin;
+
+ &.select2-results__option--highlighted {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ transition: $transition-link;
+ }
+
+ &.select2-results__option--selected {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ transition: $transition-link;
+ position: relative;
+
+ &:after {
+ top: 50%;
+ display: block;
+ position: absolute;
+ transform: translateY(-50%);
+ height: 0.75rem;
+ width: 0.75rem;
+ content: "";
+ @include svg-bg-icon(check, var(--#{$prefix}component-hover-color));
+ mask-position: center;
+ -webkit-mask-position: center;
+ right: $select2-dropdown-option-check-padding;
+ }
+ }
+
+ &.select2-results__option--disabled {
+ color: var(--#{$prefix}gray-400);
+ }
+
+ &.select2-results__message {
+ color: var(--#{$prefix}gray-600);
+ }
+
+ &.select2-results__option--group {
+ padding-left: 0;
+ padding-right: 0;
+
+ .select2-results__group {
+ display: block;
+ color: var(--#{$prefix}gray-800);
+ font-weight: $font-weight-semibold;
+ font-size: $h5-font-size;
+ padding: $select2-dropdown-group-padding;
+ margin: $select2-dropdown-group-margin;
+ }
+
+ .select2-results__option {
+ padding: $select2-dropdown-option-padding;
+ margin: $select2-dropdown-option-margin;
+ }
+ }
+ }
+ }
+
+ // Clear
+ .select2-selection__clear {
+ display: block;
+ height: $select2-clear-size;
+ width: $select2-clear-size;
+ top: 50%;
+ right: $select2-clear-right;
+ position: absolute;
+ transform: translateY(-50%);
+ background-color: var(--#{$prefix}gray-700) !important;
+ @include svg-bg-icon(close, var(--#{$prefix}gray-700));
+
+ span {
+ display: none;
+ }
+
+ &:hover {
+ background-color: var(--#{$prefix}primary) !important;
+ @include svg-bg-icon(close, var(--#{$prefix}primary));
+ }
+ }
+}
+
+// Floating label integration
+.form-floating {
+ .form-select {
+ padding-top: $form-floating-input-padding-t !important;
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_sweetalert2.scss b/Moonlight/Styles/vendors/plugins/_sweetalert2.scss
new file mode 100644
index 00000000..df29b875
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_sweetalert2.scss
@@ -0,0 +1,112 @@
+//
+// SweetAlert2
+//
+
+// Base
+html.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown),
+body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown):not(.modal-open) {
+ overflow-y: initial !important;
+
+ &:not(.sweetalert2-nopadding) {
+ padding-right: 0 !important;
+ }
+}
+
+// Popup
+.swal2-popup {
+ background-color: var(--#{$prefix}body-bg);
+ padding: 2rem;
+ @include border-radius($border-radius);
+
+ .swal2-title {
+ font-weight: 500;
+ font-size: 1.3rem;
+ color: var(--#{$prefix}dark);
+ }
+
+ .swal2-html-container,
+ .swal2-content {
+ font-weight: normal;
+ font-size: 1.1rem;
+ margin-top: 1.5rem;
+ color: var(--#{$prefix}gray-800);
+ }
+
+ .btn {
+ margin: 15px 5px 0;
+ }
+
+ .swal2-styled {
+ &:focus {
+ box-shadow: none;
+ }
+ }
+
+ .swal2-actions {
+ margin: 1.5rem auto 1rem auto;
+ }
+}
+
+// Container
+.swal2-container {
+ overflow-y: hidden !important;
+
+ &.swal2-shown {
+ background-color: rgba($black, 0.2);
+ }
+
+ // Content
+ .swal2-html-container {
+ max-height: 200px;
+ overflow: auto;
+ }
+}
+
+body.swal2-height-auto {
+ height: 100% !important;
+}
+
+// State Colors
+.swal2-icon {
+ // Warning
+ &.swal2-warning {
+ border-color: var(--#{$prefix}warning);
+ color: var(--#{$prefix}warning);
+ }
+
+ // Error
+ &.swal2-error {
+ border-color: var(--#{$prefix}danger);
+ color: var(--#{$prefix}danger);
+
+ [class^=swal2-x-mark-line] {
+ background-color: rgba(var(--#{$prefix}danger-rgb), 0.75);
+ }
+ }
+
+ // Success
+ &.swal2-success {
+ border-color: var(--#{$prefix}success);
+ color: var(--#{$prefix}success);
+
+ [class^=swal2-success-line] {
+ background-color: var(--#{$prefix}success);
+ }
+
+ .swal2-success-ring {
+ border-color: rgba(var(--#{$prefix}success-rgb), 0.3);
+ }
+ }
+
+ // Info
+ &.swal2-info {
+ border-color: var(--#{$prefix}info);
+ color: var(--#{$prefix}info);
+ }
+
+ // Question
+ &.swal2-question {
+ border-color: var(--#{$prefix}primary);
+ color: var(--#{$prefix}primary);
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_tagify.scss b/Moonlight/Styles/vendors/plugins/_tagify.scss
new file mode 100644
index 00000000..65cee5bc
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_tagify.scss
@@ -0,0 +1,222 @@
+//
+// Tagify
+//
+
+// Bootstrap .form-control sizing integration
+$tagify-tag-padding-y-sm: 0.3rem;
+$tagify-tag-padding-x-sm: 0.3rem;
+$tagify-input-padding-y-sm: #{$input-padding-y-sm - $tagify-tag-padding-y-sm};
+
+$tagify-tag-padding-y: 0.4rem;
+$tagify-tag-padding-x: 0.4rem;
+$tagify-input-padding-y: $input-padding-y - $tagify-tag-padding-y;
+
+$tagify-tag-padding-y-lg: 0.5rem;
+$tagify-tag-padding-x-lg: 0.5rem;
+$tagify-input-padding-y-lg: $input-padding-y-lg - $tagify-tag-padding-y-lg;
+
+// Base
+.tagify {
+ --tagify-dd-bg-color : var(--#{$prefix}body-bg);
+ --tags-border-color : #{$input-border-color};
+ --tags-hover-border-color : #{$input-border-color};
+ --tags-focus-border-color : #{$input-focus-border-color};
+ --tag-bg : var(--#{$prefix}gray-200);
+ --tag-hover : var(--#{$prefix}gray-200);
+ --tag-text-color : var(--#{$prefix}gray-700);
+ --tag-text-color--edit : var(--#{$prefix}gray-700);
+ --tag-pad : 0 0.5rem;
+ --tag-inset-shadow-size : 1rem;
+ --tag-invalid-color : var(--#{$prefix}danger);
+ --tag-invalid-bg : var(--#{$prefix}danger-light);
+ --tag-remove-bg : var(--#{$prefix}gray-200);
+ --tag-remove-btn-color : transparent;
+ --tag-remove-btn-bg : transparent;
+ --tag-remove-btn-bg--hover : transparent;
+ --input-color : var(--#{$prefix}gray-700);
+ --placeholder-color : var(--#{$prefix}gray-400);
+ --placeholder-color-focus : var(--#{$prefix}gray-500);
+ --loader-size : .8rem;
+ --tagify-dd-item--hidden-duration : 0.3s;
+
+ .tagify__tag {
+ background-color: var(--tag-bg);
+ margin: 0;
+ line-height: 1;
+
+ div {
+ border-radius: inherit;
+ }
+
+ .tagify__tag-text {
+ overflow: visible;
+ }
+
+ .tagify__tag__removeBtn {
+ width: 0.6rem;
+ height: 0.6rem;
+ margin: 0 0.5rem 0 0;
+ border-radius: 0;
+ content: " ";
+ @include svg-bg-icon(close, var(--#{$prefix}gray-500));
+
+ &:after {
+ display: none;
+ }
+
+ &:hover {
+ @include svg-bg-icon(close, var(--#{$prefix}primary));
+ }
+ }
+
+ // Not allowed state
+ &.tagify--notAllowed {
+ div {
+ .tagify__tag-text {
+ color: var(--#{$prefix}danger);
+ opacity: .5;
+ }
+ }
+
+ .tagify__tag__removeBtn {
+ opacity: .5;
+ @include svg-bg-icon(close, var(--#{$prefix}danger));
+
+ &:hover {
+ background: transparent;
+ opacity: .75;
+ }
+ }
+ }
+ }
+
+ .tagify__input {
+ margin: 0;
+
+ &:before {
+ font-size: inherit;
+ line-height: inherit;
+ font-weight: inherit;
+ }
+ }
+
+ // Sizing
+ &.form-control {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ }
+
+ &.form-control-sm {
+ border-radius: $btn-border-radius-sm;
+ min-height: $input-height-sm;
+ padding-top: $tagify-input-padding-y-sm;
+ padding-bottom: $tagify-input-padding-y-sm;
+
+ .tagify__tag {
+ padding: $tagify-tag-padding-y-sm $tagify-tag-padding-x-sm;
+ border-radius: $btn-border-radius-sm;
+
+ .tagify__tag-text {
+ font-size: $input-btn-font-size-sm;
+ }
+ }
+ }
+
+ &:not(.form-control-sm):not(.form-control-lg) {
+ border-radius: $btn-border-radius;
+ min-height: $input-height;
+ padding-top: $tagify-input-padding-y;
+ padding-bottom: $tagify-input-padding-y;
+
+ .tagify__tag {
+ padding: $tagify-tag-padding-y $tagify-tag-padding-x;
+ border-radius: $btn-border-radius;
+
+ .tagify__tag-text {
+ font-size: $input-btn-font-size;
+ }
+ }
+ }
+
+ &.form-control-lg {
+ border-radius: $btn-border-radius-lg;
+ min-height: $input-height-lg;
+ padding-top: $tagify-input-padding-y-lg;
+ padding-bottom: $tagify-input-padding-y-lg;
+
+ .tagify__tag {
+ padding: $tagify-tag-padding-y-lg $tagify-tag-padding-x-lg;
+ border-radius: $btn-border-radius-lg;
+
+ .tagify__tag-text {
+ font-size: $input-btn-font-size-lg;
+ }
+ }
+ }
+}
+
+// Dropdown
+.tagify__dropdown {
+ box-shadow: var(--#{$prefix}dropdown-box-shadow);
+ border: 0 !important;
+ outline: none !important;
+ padding: 0.75rem 0;
+ z-index: $zindex-dropdown;
+ background-color: var(--#{$prefix}body-bg);
+ @include border-radius($border-radius);
+
+ // Wrapper
+ ._wrapper {
+ max-height: none;
+ @include border-radius($border-radius);
+ }
+
+ // In modal
+ .modal-open & {
+ z-index: $zindex-modal + 1;
+ }
+
+ .tagify__dropdown__wrapper {
+ background-color: var(--#{$prefix}body-bg);
+ border: 0 !important;
+ outline: none !important;
+ box-shadow: none;
+ }
+
+ .tagify__dropdown__item {
+ color: var(--#{$prefix}gray-700);
+ border-radius: 0;
+ padding: 0.75rem 1.5rem;
+ margin: 0;
+ box-shadow: none;
+ font-weight: $font-weight-semibold;
+
+ &:hover,
+ &.tagify__dropdown__item--active {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ }
+ }
+
+ // Suggestions
+ &.tagify__inline__suggestions {
+ padding: $input-padding-y $input-padding-x;
+
+ .tagify__dropdown__item {
+ display: inline-block;
+ font-size: $font-size-sm;
+ padding: 0.35rem 0.5rem;
+ margin: 0.25rem 0.5rem 0.25rem 0;
+ background-color: var(--#{$prefix}gray-200);
+ color: var(--#{$prefix}gray-700);
+ @include border-radius($border-radius);
+
+ &:hover,
+ &.tagify__dropdown__item--active {
+ background-color: var(--#{$prefix}component-hover-bg);
+ color: var(--#{$prefix}component-hover-color);
+ }
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_tempus-dominus.scss b/Moonlight/Styles/vendors/plugins/_tempus-dominus.scss
new file mode 100644
index 00000000..42088f5e
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_tempus-dominus.scss
@@ -0,0 +1,163 @@
+//
+// Tempus Dominus
+//
+
+$td-light: var(--#{$prefix}body-bg);
+$td-widget-background: $td-light;
+$td-font-color: var(--#{$prefix}gray-900);
+$td-active-bg: var(--#{$prefix}primary);
+$td-active-color: $td-light;
+$td-active-border-color: $td-light;
+$td-btn-hover-bg: var(--#{$prefix}gray-200);
+$td-disabled-color: var(--#{$prefix}gray-400);
+$td-alternate-color: rgba(var(--#{$prefix}gray-900-rgb), 0.38);
+$td-secondary-border-color: var(--#{$prefix}border-color);
+$td-secondary-border-color-rgba: rgba(var(--#{$prefix}gray-900-rgb), 0.2);
+$td-primary-border-color: $td-light;
+$td-text-shadow: 0 -1px 0 rgba(var(--#{$prefix}gray-900-rgb), 0.25);
+$td-dow-color: var(--#{$prefix}gray-700);
+
+.tempus-dominus-widget {
+ padding: 1rem 0.5rem 0.5rem 0.5rem;
+ width: 280px !important;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow) !important;
+ background-color: var(--#{$prefix}body-bg) !important;
+ @include border-radius($dropdown-border-radius);
+
+ i:not(.ki-outline):not(.ki-solid):not(.ki-duotone) {
+ font-size: 0.9rem !important;
+ }
+
+ .picker-switch {
+ font-size: 1.05rem;
+ font-weight: $font-weight-bold;
+ }
+
+ .date-container-days {
+ grid-auto-rows: 36px;
+
+ .day {
+ @include border-radius($btn-border-radius !important);
+ }
+ }
+
+ .date-container-months {
+ grid-auto-rows: 36px;
+
+ .month {
+ @include border-radius($btn-border-radius !important);
+ }
+ }
+
+ .date-container-years {
+ grid-auto-rows: 36px;
+
+ .year {
+ @include border-radius($btn-border-radius !important);
+ }
+ }
+
+ .time-container {
+ .separator {
+ border: 0px !important;
+ }
+
+ .time-container-clock {
+ div {
+ @include border-radius($btn-border-radius !important);
+ }
+ }
+ }
+
+ .toolbar div {
+ @include border-radius($btn-border-radius);
+
+ i:not(.ki-outline):not(.ki-solid):not(.ki-duotone) {
+ font-size: 1.1rem !important;
+ }
+ }
+
+ // Theming
+ &.light,
+ &.dark {
+ color: $td-font-color;
+
+ [data-action] {
+ &.disabled,
+ &.disabled:hover {
+ color: $td-disabled-color;
+ }
+ }
+
+ .toolbar {
+ div {
+ &:hover {
+ background: $td-btn-hover-bg;
+ }
+ }
+ }
+
+ .date-container-days {
+ .dow {
+ color: $td-dow-color !important;
+ }
+
+ .cw {
+ color: $td-alternate-color;
+ }
+ }
+
+ .date-container-decades,
+ .date-container-years,
+ .date-container-months,
+ .date-container-days,
+ .time-container-clock,
+ .time-container-hour,
+ .time-container-minute,
+ .time-container-second {
+ div:not(.no-highlight) {
+ &:hover {
+ background: $td-btn-hover-bg;
+ }
+
+ &.active {
+ background-color: $td-active-bg;
+ color: $td-active-color;
+ text-shadow: $td-text-shadow;
+
+ &.old,
+ &.new {
+ color: $td-active-color;
+ }
+ }
+
+ &.active.today:before {
+ border-bottom-color: $td-active-border-color;
+ }
+
+ &.old,
+ &.new {
+ color: $td-alternate-color;
+ }
+
+ &.disabled,
+ &.disabled:hover {
+ color: $td-disabled-color;
+ }
+
+ &.today {
+ &:before {
+ border-bottom-color: $td-active-bg;
+ border-top-color: $td-secondary-border-color-rgba;
+ }
+ }
+ }
+ }
+
+ button {
+ color: $td-active-color;
+ background-color: $td-active-bg;
+ border-color: $td-active-bg;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_tiny-slider.scss b/Moonlight/Styles/vendors/plugins/_tiny-slider.scss
new file mode 100644
index 00000000..9fc8de6f
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_tiny-slider.scss
@@ -0,0 +1,141 @@
+//
+// Slider
+//
+
+// Base
+.tns {
+ position: relative;
+ overflow: hidden;
+
+ [data-tns="true"] {
+ display: none;
+ }
+
+ .tns-item {
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
+
+ .tns-controls {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ button {
+ outline: none;
+ border: 0;
+ margin: 0 0.25rem;
+ @include border-radius($btn-border-radius);
+ padding: 0.5rem 0.75rem;
+ background-color: var(--#{$prefix}primary);
+ color: var(--#{$prefix}primary-inverse);
+
+ &:hover {
+ background-color: var(--#{$prefix}primary-active);
+ }
+ }
+ }
+
+ .tns-nav {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+
+ button {
+ display: block;
+ outline: none;
+ width: 1.25rem;
+ height: 0.75rem;
+ background-color: var(--#{$prefix}gray-200);
+ margin: 0 0.25rem;
+ border: 0;
+ @include border-radius(0.35rem);
+
+ &.tns-nav-active{
+ background-color: var(--#{$prefix}primary);
+ }
+ }
+ }
+
+ &.tns-initiazlied {
+ [data-tns="true"] {
+ display: flex;
+ }
+
+ .tns-item {
+ opacity: 1;
+ transition: all 0.3s ease;
+ }
+ }
+
+ // Default
+ &.tns-default {
+ position: relative;
+
+ // Navs
+ [data-controls="prev"],
+ [data-controls="next"] {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ }
+
+ [data-controls="prev"] {
+ left: 0;
+ }
+
+ [data-controls="next"] {
+ right: 0;
+ }
+
+ .tns-outer {
+ margin: 0 4rem;
+
+ // Tablet mode
+ @include media-breakpoint-down(md) {
+ margin: 0 2rem;
+ }
+ }
+ }
+
+ &.tns-flush {
+ .tns-outer {
+ margin: 0;
+ }
+ }
+
+ &.tns-circle-nav {
+ .tns-nav {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+
+ button {
+ display: block;
+ outline: none;
+ width: 1.15rem;
+ height: 1.15rem;
+ background-color: var(--#{$prefix}gray-200);
+ margin: 0 0.55rem;
+ border: 0;
+ @include border-radius(50%);
+
+ &.tns-nav-active{
+ background-color: var(--#{$prefix}gray-400);
+ }
+ }
+ }
+ }
+}
+
+
+// Utils
+.tns-hide-disabled-nav {
+ [disabled] {
+ display: none !important;
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/_tinymce.scss b/Moonlight/Styles/vendors/plugins/_tinymce.scss
new file mode 100644
index 00000000..bc9f6248
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_tinymce.scss
@@ -0,0 +1,13 @@
+//
+// TinyMCE
+//
+
+
+// Base
+.tox-target{
+ display: none;
+}
+
+.tox-tinymce{
+ @include border-radius($border-radius !important);
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_toastr.scss b/Moonlight/Styles/vendors/plugins/_toastr.scss
new file mode 100644
index 00000000..539bad11
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_toastr.scss
@@ -0,0 +1,87 @@
+//
+// Toastr
+//
+
+// Base
+.toastr {
+ // this is for RTL
+ background-position: calc(100% - 1.5rem) center !important;
+ /*rtl:ignore*/
+ background-position: 1.5rem center !important;
+ box-shadow: var(--#{$prefix}dropdown-box-shadow) !important;
+ border-radius: $dropdown-border-radius !important;
+ border: 0 !important;
+ background-color: var(--#{$prefix}gray-100);
+ color: var(--#{$prefix}gray-700);
+ padding: 1.25rem 1.25rem 1.25rem 4.5rem !important;
+
+ .toastr-close-button {
+ outline: none !important;
+ font-size: 0;
+ width: 0.85rem;
+ height: 0.85rem;
+ }
+
+ // Title
+ .toastr-title {
+ font-size: 1.15rem;
+ font-weight: $font-weight-semibold;
+
+ & + .toastr-message {
+ margin-top: 0.25rem;
+ }
+ }
+
+ // Message
+ .toastr-message {
+ font-size: 1rem;
+ font-weight: $font-weight-normal;
+ }
+
+ // States
+ &.toastr-success {
+ background-color: var(--#{$prefix}success);
+ color: var(--#{$prefix}success-inverse);
+
+ .toastr-close-button {
+ @include svg-bg-icon(close, var(--#{$prefix}success-inverse));
+ }
+ }
+
+ &.toastr-info {
+ background-color: var(--#{$prefix}info);
+ color: var(--#{$prefix}info-inverse);
+
+ .toastr-close-button {
+ @include svg-bg-icon(close, var(--#{$prefix}info-inverse));
+ }
+ }
+
+ &.toastr-warning {
+ background-color: var(--#{$prefix}warning);
+ color: var(--#{$prefix}warning-inverse);
+
+ .toastr-close-button {
+ @include svg-bg-icon(close, var(--#{$prefix}warning-inverse));
+ }
+ }
+
+ &.toastr-error {
+ background-color: var(--#{$prefix}danger);
+ color: var(--#{$prefix}danger-inverse);
+
+ .toastr-close-button {
+ @include svg-bg-icon(close, var(--#{$prefix}danger-inverse));
+ }
+ }
+}
+
+
+// Placements
+.toastr-top-center {
+ top: 12px;
+}
+
+.toastr-bottom-center {
+ bottom: 12px;
+}
\ No newline at end of file
diff --git a/Moonlight/Styles/vendors/plugins/_variables-dark.scss b/Moonlight/Styles/vendors/plugins/_variables-dark.scss
new file mode 100644
index 00000000..ffa45130
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_variables-dark.scss
@@ -0,0 +1,18 @@
+//
+// 3rd-party config
+//
+
+
+// Prismjs
+$prismjs-bg-dark: #151521;
+
+$prismjs-border-dark: rgba($white, 0.1);
+
+$prismjs-btn-bg-dark: lighten($prismjs-bg-dark, 9%);
+$prismjs-btn-bg-hover-dark: lighten($prismjs-bg-dark, 9%);
+
+$prismjs-btn-color-dark: rgba($white, 0.75);
+$prismjs-btn-color-hover-dark: $primary;
+
+$prismjs-scrollbar-color-dark: lighten($prismjs-bg-dark, 12%);
+$prismjs-scrollbar-color-hover-dark: lighten($prismjs-bg-dark, 15%);
diff --git a/Moonlight/Styles/vendors/plugins/_variables.scss b/Moonlight/Styles/vendors/plugins/_variables.scss
new file mode 100644
index 00000000..4126f664
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_variables.scss
@@ -0,0 +1,27 @@
+//
+// 3rd-party config
+//
+
+
+// Prismjs
+$prismjs-bg: #1e1e3f;
+
+$prismjs-border: rgba($white, 0.1);
+
+$prismjs-btn-bg: lighten($prismjs-bg, 9%);
+$prismjs-btn-bg-hover: lighten($prismjs-bg, 9%);
+
+$prismjs-btn-color: rgba($white, 0.75);
+$prismjs-btn-color-hover: $primary;
+
+$prismjs-scrollbar-color: lighten($prismjs-bg, 12%);
+$prismjs-scrollbar-color-hover: lighten($prismjs-bg, 15%);
+
+// Bootstrap Maxlength
+$bootstrap-maxlength-z-index: 1040;
+
+// Daterangepicker
+$daterangepicker-ranges-list-height: 260px;
+$daterangepicker-ranges-list-width: 150px;
+
+
diff --git a/Moonlight/Styles/vendors/plugins/_vis-timeline.scss b/Moonlight/Styles/vendors/plugins/_vis-timeline.scss
new file mode 100644
index 00000000..186ed7b5
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/_vis-timeline.scss
@@ -0,0 +1,131 @@
+//
+// Vis Timeline
+//
+
+// Variables
+$vis-border-color: var(--#{$prefix}border-color);
+$vis-border-dashed-color: var(--#{$prefix}border-dashed-color);
+
+// General
+.vis-timeline {
+ border: 1px solid $vis-border-color !important;
+
+ @if ($enable-rounded) {
+ border-radius: $border-radius !important;
+ }
+
+ .vis-labelset {
+ .vis-label {
+ display: flex;
+ align-items: center;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ border-bottom: none;
+ font-size: $h4-font-size;
+ font-weight: $font-weight-semibold;
+ color: var(--#{$prefix}gray-900);
+ }
+ }
+
+ .vis-itemset {
+ }
+
+ .vis-foreground {
+ .vis-group {
+ border-bottom: none;
+ }
+ }
+
+ .vis-item {
+ position: absolute;
+ color: var(--#{$prefix}gray-700);
+ border-color: var(--#{$prefix}primary);
+ border-width: 1px;
+ background-color: var(--#{$prefix}gray-100);
+
+ @if ($enable-rounded) {
+ border-radius: $border-radius !important;
+ }
+
+ &.vis-selected {
+ background-color: var(--#{$prefix}warning-light);
+ color: var(--#{$prefix}gray-700);
+ border-color: var(--#{$prefix}warning);
+ }
+
+ .vis-item-content {
+ padding: 0.75rem 1rem;
+ width: 100%;
+ transform: none !important;
+ }
+ }
+
+ .vis-time-axis {
+ font-size: $font-size-sm;
+ text-transform: uppercase;
+ font-weight: $font-weight-semibold;
+
+ .vis-text {
+ color: var(--#{$prefix}gray-400);
+ }
+
+ .vis-grid.vis-minor {
+ border-left-color: $vis-border-dashed-color !important;
+ }
+
+ .vis-grid.vis-vertical {
+ border-left-style: dashed !important;
+ }
+ }
+
+ .vis-panel {
+ .vis-shadow {
+ box-shadow: none !important;
+ }
+ }
+
+ .vis-panel {
+ &.vis-bottom,
+ &.vis-center,
+ &.vis-left,
+ &.vis-right,
+ &.vis-top {
+ border-color: $vis-border-color !important;
+ }
+ }
+
+ .vis-current-time {
+ background-color: var(--#{$prefix}success);
+ }
+}
+
+// Custom style
+.vis-timeline-custom {
+ .vis-timeline {
+ border: 0 !important;
+
+ .vis-label {
+ padding-left: 0 !important;
+ }
+ }
+
+ .vis-panel {
+ &.vis-bottom,
+ &.vis-center,
+ &.vis-left,
+ &.vis-right,
+ &.vis-top {
+ border: 0 !important;
+ }
+ }
+
+ .vis-item {
+ background-color: transparent;
+ border: 0 !important;
+ border-radius: 0 !important;
+
+ .vis-item-content {
+ padding: 0 !important;
+ }
+ }
+}
diff --git a/Moonlight/Styles/vendors/plugins/mixins/_nouislider.scss b/Moonlight/Styles/vendors/plugins/mixins/_nouislider.scss
new file mode 100644
index 00000000..455a2b25
--- /dev/null
+++ b/Moonlight/Styles/vendors/plugins/mixins/_nouislider.scss
@@ -0,0 +1,13 @@
+//
+// noUiSlider Mixins
+//
+
+@mixin nouislider-size($height, $handle-width, $handle-height, $handle-pos-top) {
+ height: $height;
+
+ .noUi-handle {
+ width: $handle-width;
+ height: $handle-height;
+ top: -#{$handle-pos-top};
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/_Imports.razor b/Moonlight/_Imports.razor
new file mode 100644
index 00000000..3c109dca
--- /dev/null
+++ b/Moonlight/_Imports.razor
@@ -0,0 +1,5 @@
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.JSInterop
+@using Moonlight
+@using Moonlight.Shared.Components.Partials
\ No newline at end of file
diff --git a/Moonlight/wwwroot/css/blazor.css b/Moonlight/wwwroot/css/blazor.css
new file mode 100644
index 00000000..685e0b04
--- /dev/null
+++ b/Moonlight/wwwroot/css/blazor.css
@@ -0,0 +1,51 @@
+.my-reconnect-modal {
+ display: none;
+}
+
+.components-reconnect-hide > div {
+ display: none;
+}
+
+.components-reconnect-show > div {
+ display: none;
+}
+
+.components-reconnect-failed > div {
+ display: none;
+}
+
+.components-reconnect-rejected > div {
+ display: none;
+}
+
+.components-reconnect-show > .show {
+ display: block;
+}
+
+.components-reconnect-failed > .failed {
+ display: block;
+}
+
+.components-reconnect-rejected > .rejected {
+ display: block;
+}
+
+.components-reconnect-hide > .default {
+ display: block;
+}
+
+.components-reconnect-hide {
+ display: block;
+}
+
+.components-reconnect-show {
+ display: block;
+}
+
+.components-reconnect-failed {
+ display: block;
+}
+
+.components-reconnect-rejected {
+ display: block;
+}
\ No newline at end of file
diff --git a/Moonlight/wwwroot/css/boxicons.min.css b/Moonlight/wwwroot/css/boxicons.min.css
new file mode 100644
index 00000000..ed39ac52
--- /dev/null
+++ b/Moonlight/wwwroot/css/boxicons.min.css
@@ -0,0 +1 @@
+@font-face{font-family:boxicons;font-weight:400;font-style:normal;src:url(../fonts/boxicons.eot);src:url(../fonts/boxicons.eot) format('embedded-opentype'),url(../fonts/boxicons.woff2) format('woff2'),url(../fonts/boxicons.woff) format('woff'),url(../fonts/boxicons.ttf) format('truetype'),url(../fonts/boxicons.svg?#boxicons) format('svg')}.bx{font-family:boxicons!important;font-weight:400;font-style:normal;font-variant:normal;line-height:1;text-rendering:auto;display:inline-block;text-transform:none;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bx-ul{margin-left:2em;padding-left:0;list-style:none}.bx-ul>li{position:relative}.bx-ul .bx{font-size:inherit;line-height:inherit;position:absolute;left:-2em;width:2em;text-align:center}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes burst{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}90%{-webkit-transform:scale(1.5);transform:scale(1.5);opacity:0}}@keyframes burst{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}90%{-webkit-transform:scale(1.5);transform:scale(1.5);opacity:0}}@-webkit-keyframes flashing{0%{opacity:1}45%{opacity:0}90%{opacity:1}}@keyframes flashing{0%{opacity:1}45%{opacity:0}90%{opacity:1}}@-webkit-keyframes fade-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(-20px);transform:translateX(-20px);opacity:0}}@keyframes fade-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(-20px);transform:translateX(-20px);opacity:0}}@-webkit-keyframes fade-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(20px);transform:translateX(20px);opacity:0}}@keyframes fade-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(20px);transform:translateX(20px);opacity:0}}@-webkit-keyframes fade-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}@keyframes fade-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}@-webkit-keyframes fade-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(20px);transform:translateY(20px);opacity:0}}@keyframes fade-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(20px);transform:translateY(20px);opacity:0}}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg);transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,10deg)}40%,60%,80%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,-10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,-10deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg);transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,10deg)}40%,60%,80%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bx-spin{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.bx-spin-hover:hover{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.bx-tada{-webkit-animation:tada 1.5s ease infinite;animation:tada 1.5s ease infinite}.bx-tada-hover:hover{-webkit-animation:tada 1.5s ease infinite;animation:tada 1.5s ease infinite}.bx-flashing{-webkit-animation:flashing 1.5s infinite linear;animation:flashing 1.5s infinite linear}.bx-flashing-hover:hover{-webkit-animation:flashing 1.5s infinite linear;animation:flashing 1.5s infinite linear}.bx-burst{-webkit-animation:burst 1.5s infinite linear;animation:burst 1.5s infinite linear}.bx-burst-hover:hover{-webkit-animation:burst 1.5s infinite linear;animation:burst 1.5s infinite linear}.bx-fade-up{-webkit-animation:fade-up 1.5s infinite linear;animation:fade-up 1.5s infinite linear}.bx-fade-up-hover:hover{-webkit-animation:fade-up 1.5s infinite linear;animation:fade-up 1.5s infinite linear}.bx-fade-down{-webkit-animation:fade-down 1.5s infinite linear;animation:fade-down 1.5s infinite linear}.bx-fade-down-hover:hover{-webkit-animation:fade-down 1.5s infinite linear;animation:fade-down 1.5s infinite linear}.bx-fade-left{-webkit-animation:fade-left 1.5s infinite linear;animation:fade-left 1.5s infinite linear}.bx-fade-left-hover:hover{-webkit-animation:fade-left 1.5s infinite linear;animation:fade-left 1.5s infinite linear}.bx-fade-right{-webkit-animation:fade-right 1.5s infinite linear;animation:fade-right 1.5s infinite linear}.bx-fade-right-hover:hover{-webkit-animation:fade-right 1.5s infinite linear;animation:fade-right 1.5s infinite linear}.bx-xs{font-size:1rem!important}.bx-sm{font-size:1.55rem!important}.bx-md{font-size:2.25rem!important}.bx-lg{font-size:3rem!important}.bx-fw{font-size:1.2857142857em;line-height:.8em;width:1.2857142857em;height:.8em;margin-top:-.2em!important;vertical-align:middle}.bx-pull-left{float:left;margin-right:.3em!important}.bx-pull-right{float:right;margin-left:.3em!important}.bx-rotate-90{transform:rotate(90deg)}.bx-rotate-180{transform:rotate(180deg)}.bx-rotate-270{transform:rotate(270deg)}.bx-flip-horizontal{transform:scaleX(-1)}.bx-flip-vertical{transform:scaleY(-1)}.bx-border{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:.25em}.bx-border-circle{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:50%}.bxs-balloon:before{content:"\eb60"}.bxs-castle:before{content:"\eb79"}.bxs-coffee-bean:before{content:"\eb92"}.bxs-objects-horizontal-center:before{content:"\ebab"}.bxs-objects-horizontal-left:before{content:"\ebc4"}.bxs-objects-horizontal-right:before{content:"\ebdd"}.bxs-objects-vertical-bottom:before{content:"\ebf6"}.bxs-objects-vertical-center:before{content:"\ef40"}.bxs-objects-vertical-top:before{content:"\ef41"}.bxs-pear:before{content:"\ef42"}.bxs-shield-minus:before{content:"\ef43"}.bxs-shield-plus:before{content:"\ef44"}.bxs-shower:before{content:"\ef45"}.bxs-sushi:before{content:"\ef46"}.bxs-universal-access:before{content:"\ef47"}.bx-child:before{content:"\ef48"}.bx-horizontal-left:before{content:"\ef49"}.bx-horizontal-right:before{content:"\ef4a"}.bx-objects-horizontal-center:before{content:"\ef4b"}.bx-objects-horizontal-left:before{content:"\ef4c"}.bx-objects-horizontal-right:before{content:"\ef4d"}.bx-objects-vertical-bottom:before{content:"\ef4e"}.bx-objects-vertical-center:before{content:"\ef4f"}.bx-objects-vertical-top:before{content:"\ef50"}.bx-rfid:before{content:"\ef51"}.bx-shield-minus:before{content:"\ef52"}.bx-shield-plus:before{content:"\ef53"}.bx-shower:before{content:"\ef54"}.bx-sushi:before{content:"\ef55"}.bx-universal-access:before{content:"\ef56"}.bx-vertical-bottom:before{content:"\ef57"}.bx-vertical-top:before{content:"\ef58"}.bxl-graphql:before{content:"\ef59"}.bxl-typescript:before{content:"\ef5a"}.bxs-color:before{content:"\ef39"}.bx-reflect-horizontal:before{content:"\ef3a"}.bx-reflect-vertical:before{content:"\ef3b"}.bx-color:before{content:"\ef3c"}.bxl-mongodb:before{content:"\ef3d"}.bxl-postgresql:before{content:"\ef3e"}.bxl-deezer:before{content:"\ef3f"}.bxs-hard-hat:before{content:"\ef2a"}.bxs-home-alt-2:before{content:"\ef2b"}.bxs-cheese:before{content:"\ef2c"}.bx-home-alt-2:before{content:"\ef2d"}.bx-hard-hat:before{content:"\ef2e"}.bx-cheese:before{content:"\ef2f"}.bx-cart-add:before{content:"\ef30"}.bx-cart-download:before{content:"\ef31"}.bx-no-signal:before{content:"\ef32"}.bx-signal-1:before{content:"\ef33"}.bx-signal-2:before{content:"\ef34"}.bx-signal-3:before{content:"\ef35"}.bx-signal-4:before{content:"\ef36"}.bx-signal-5:before{content:"\ef37"}.bxl-xing:before{content:"\ef38"}.bxl-meta:before{content:"\ef27"}.bx-lemon:before{content:"\ef28"}.bxs-lemon:before{content:"\ef29"}.bx-cricket-ball:before{content:"\ef0c"}.bx-baguette:before{content:"\ef0d"}.bx-bowl-hot:before{content:"\ef0e"}.bx-bowl-rice:before{content:"\ef0f"}.bx-cable-car:before{content:"\ef10"}.bx-candles:before{content:"\ef11"}.bx-circle-half:before{content:"\ef12"}.bx-circle-quarter:before{content:"\ef13"}.bx-circle-three-quarter:before{content:"\ef14"}.bx-cross:before{content:"\ef15"}.bx-fork:before{content:"\ef16"}.bx-knife:before{content:"\ef17"}.bx-money-withdraw:before{content:"\ef18"}.bx-popsicle:before{content:"\ef19"}.bx-scatter-chart:before{content:"\ef1a"}.bxs-baguette:before{content:"\ef1b"}.bxs-bowl-hot:before{content:"\ef1c"}.bxs-bowl-rice:before{content:"\ef1d"}.bxs-cable-car:before{content:"\ef1e"}.bxs-circle-half:before{content:"\ef1f"}.bxs-circle-quarter:before{content:"\ef20"}.bxs-circle-three-quarter:before{content:"\ef21"}.bxs-cricket-ball:before{content:"\ef22"}.bxs-invader:before{content:"\ef23"}.bx-male-female:before{content:"\ef24"}.bxs-popsicle:before{content:"\ef25"}.bxs-tree-alt:before{content:"\ef26"}.bxl-venmo:before{content:"\e900"}.bxl-upwork:before{content:"\e901"}.bxl-netlify:before{content:"\e902"}.bxl-java:before{content:"\e903"}.bxl-heroku:before{content:"\e904"}.bxl-go-lang:before{content:"\e905"}.bxl-gmail:before{content:"\e906"}.bxl-flask:before{content:"\e907"}.bxl-99designs:before{content:"\e908"}.bxl-500px:before{content:"\e909"}.bxl-adobe:before{content:"\e90a"}.bxl-airbnb:before{content:"\e90b"}.bxl-algolia:before{content:"\e90c"}.bxl-amazon:before{content:"\e90d"}.bxl-android:before{content:"\e90e"}.bxl-angular:before{content:"\e90f"}.bxl-apple:before{content:"\e910"}.bxl-audible:before{content:"\e911"}.bxl-aws:before{content:"\e912"}.bxl-baidu:before{content:"\e913"}.bxl-behance:before{content:"\e914"}.bxl-bing:before{content:"\e915"}.bxl-bitcoin:before{content:"\e916"}.bxl-blender:before{content:"\e917"}.bxl-blogger:before{content:"\e918"}.bxl-bootstrap:before{content:"\e919"}.bxl-chrome:before{content:"\e91a"}.bxl-codepen:before{content:"\e91b"}.bxl-c-plus-plus:before{content:"\e91c"}.bxl-creative-commons:before{content:"\e91d"}.bxl-css3:before{content:"\e91e"}.bxl-dailymotion:before{content:"\e91f"}.bxl-deviantart:before{content:"\e920"}.bxl-dev-to:before{content:"\e921"}.bxl-digg:before{content:"\e922"}.bxl-digitalocean:before{content:"\e923"}.bxl-discord:before{content:"\e924"}.bxl-discord-alt:before{content:"\e925"}.bxl-discourse:before{content:"\e926"}.bxl-django:before{content:"\e927"}.bxl-docker:before{content:"\e928"}.bxl-dribbble:before{content:"\e929"}.bxl-dropbox:before{content:"\e92a"}.bxl-drupal:before{content:"\e92b"}.bxl-ebay:before{content:"\e92c"}.bxl-edge:before{content:"\e92d"}.bxl-etsy:before{content:"\e92e"}.bxl-facebook:before{content:"\e92f"}.bxl-facebook-circle:before{content:"\e930"}.bxl-facebook-square:before{content:"\e931"}.bxl-figma:before{content:"\e932"}.bxl-firebase:before{content:"\e933"}.bxl-firefox:before{content:"\e934"}.bxl-flickr:before{content:"\e935"}.bxl-flickr-square:before{content:"\e936"}.bxl-flutter:before{content:"\e937"}.bxl-foursquare:before{content:"\e938"}.bxl-git:before{content:"\e939"}.bxl-github:before{content:"\e93a"}.bxl-gitlab:before{content:"\e93b"}.bxl-google:before{content:"\e93c"}.bxl-google-cloud:before{content:"\e93d"}.bxl-google-plus:before{content:"\e93e"}.bxl-google-plus-circle:before{content:"\e93f"}.bxl-html5:before{content:"\e940"}.bxl-imdb:before{content:"\e941"}.bxl-instagram:before{content:"\e942"}.bxl-instagram-alt:before{content:"\e943"}.bxl-internet-explorer:before{content:"\e944"}.bxl-invision:before{content:"\e945"}.bxl-javascript:before{content:"\e946"}.bxl-joomla:before{content:"\e947"}.bxl-jquery:before{content:"\e948"}.bxl-jsfiddle:before{content:"\e949"}.bxl-kickstarter:before{content:"\e94a"}.bxl-kubernetes:before{content:"\e94b"}.bxl-less:before{content:"\e94c"}.bxl-linkedin:before{content:"\e94d"}.bxl-linkedin-square:before{content:"\e94e"}.bxl-magento:before{content:"\e94f"}.bxl-mailchimp:before{content:"\e950"}.bxl-markdown:before{content:"\e951"}.bxl-mastercard:before{content:"\e952"}.bxl-mastodon:before{content:"\e953"}.bxl-medium:before{content:"\e954"}.bxl-medium-old:before{content:"\e955"}.bxl-medium-square:before{content:"\e956"}.bxl-messenger:before{content:"\e957"}.bxl-microsoft:before{content:"\e958"}.bxl-microsoft-teams:before{content:"\e959"}.bxl-nodejs:before{content:"\e95a"}.bxl-ok-ru:before{content:"\e95b"}.bxl-opera:before{content:"\e95c"}.bxl-patreon:before{content:"\e95d"}.bxl-paypal:before{content:"\e95e"}.bxl-periscope:before{content:"\e95f"}.bxl-php:before{content:"\e960"}.bxl-pinterest:before{content:"\e961"}.bxl-pinterest-alt:before{content:"\e962"}.bxl-play-store:before{content:"\e963"}.bxl-pocket:before{content:"\e964"}.bxl-product-hunt:before{content:"\e965"}.bxl-python:before{content:"\e966"}.bxl-quora:before{content:"\e967"}.bxl-react:before{content:"\e968"}.bxl-redbubble:before{content:"\e969"}.bxl-reddit:before{content:"\e96a"}.bxl-redux:before{content:"\e96b"}.bxl-sass:before{content:"\e96c"}.bxl-shopify:before{content:"\e96d"}.bxl-sketch:before{content:"\e96e"}.bxl-skype:before{content:"\e96f"}.bxl-slack:before{content:"\e970"}.bxl-slack-old:before{content:"\e971"}.bxl-snapchat:before{content:"\e972"}.bxl-soundcloud:before{content:"\e973"}.bxl-spotify:before{content:"\e974"}.bxl-spring-boot:before{content:"\e975"}.bxl-squarespace:before{content:"\e976"}.bxl-stack-overflow:before{content:"\e977"}.bxl-steam:before{content:"\e978"}.bxl-stripe:before{content:"\e979"}.bxl-tailwind-css:before{content:"\e97a"}.bxl-telegram:before{content:"\e97b"}.bxl-tiktok:before{content:"\e97c"}.bxl-trello:before{content:"\e97d"}.bxl-trip-advisor:before{content:"\e97e"}.bxl-tumblr:before{content:"\e97f"}.bxl-tux:before{content:"\e980"}.bxl-twitch:before{content:"\e981"}.bxl-twitter:before{content:"\e982"}.bxl-unity:before{content:"\e983"}.bxl-unsplash:before{content:"\e984"}.bxl-vimeo:before{content:"\e985"}.bxl-visa:before{content:"\e986"}.bxl-visual-studio:before{content:"\e987"}.bxl-vk:before{content:"\e988"}.bxl-vuejs:before{content:"\e989"}.bxl-whatsapp:before{content:"\e98a"}.bxl-whatsapp-square:before{content:"\e98b"}.bxl-wikipedia:before{content:"\e98c"}.bxl-windows:before{content:"\e98d"}.bxl-wix:before{content:"\e98e"}.bxl-wordpress:before{content:"\e98f"}.bxl-yahoo:before{content:"\e990"}.bxl-yelp:before{content:"\e991"}.bxl-youtube:before{content:"\e992"}.bxl-zoom:before{content:"\e993"}.bx-collapse-alt:before{content:"\e994"}.bx-collapse-horizontal:before{content:"\e995"}.bx-collapse-vertical:before{content:"\e996"}.bx-expand-horizontal:before{content:"\e997"}.bx-expand-vertical:before{content:"\e998"}.bx-injection:before{content:"\e999"}.bx-leaf:before{content:"\e99a"}.bx-math:before{content:"\e99b"}.bx-party:before{content:"\e99c"}.bx-abacus:before{content:"\e99d"}.bx-accessibility:before{content:"\e99e"}.bx-add-to-queue:before{content:"\e99f"}.bx-adjust:before{content:"\e9a0"}.bx-alarm:before{content:"\e9a1"}.bx-alarm-add:before{content:"\e9a2"}.bx-alarm-exclamation:before{content:"\e9a3"}.bx-alarm-off:before{content:"\e9a4"}.bx-alarm-snooze:before{content:"\e9a5"}.bx-album:before{content:"\e9a6"}.bx-align-justify:before{content:"\e9a7"}.bx-align-left:before{content:"\e9a8"}.bx-align-middle:before{content:"\e9a9"}.bx-align-right:before{content:"\e9aa"}.bx-analyse:before{content:"\e9ab"}.bx-anchor:before{content:"\e9ac"}.bx-angry:before{content:"\e9ad"}.bx-aperture:before{content:"\e9ae"}.bx-arch:before{content:"\e9af"}.bx-archive:before{content:"\e9b0"}.bx-archive-in:before{content:"\e9b1"}.bx-archive-out:before{content:"\e9b2"}.bx-area:before{content:"\e9b3"}.bx-arrow-back:before{content:"\e9b4"}.bx-arrow-from-bottom:before{content:"\e9b5"}.bx-arrow-from-left:before{content:"\e9b6"}.bx-arrow-from-right:before{content:"\e9b7"}.bx-arrow-from-top:before{content:"\e9b8"}.bx-arrow-to-bottom:before{content:"\e9b9"}.bx-arrow-to-left:before{content:"\e9ba"}.bx-arrow-to-right:before{content:"\e9bb"}.bx-arrow-to-top:before{content:"\e9bc"}.bx-at:before{content:"\e9bd"}.bx-atom:before{content:"\e9be"}.bx-award:before{content:"\e9bf"}.bx-badge:before{content:"\e9c0"}.bx-badge-check:before{content:"\e9c1"}.bx-ball:before{content:"\e9c2"}.bx-band-aid:before{content:"\e9c3"}.bx-bar-chart:before{content:"\e9c4"}.bx-bar-chart-alt:before{content:"\e9c5"}.bx-bar-chart-alt-2:before{content:"\e9c6"}.bx-bar-chart-square:before{content:"\e9c7"}.bx-barcode:before{content:"\e9c8"}.bx-barcode-reader:before{content:"\e9c9"}.bx-baseball:before{content:"\e9ca"}.bx-basket:before{content:"\e9cb"}.bx-basketball:before{content:"\e9cc"}.bx-bath:before{content:"\e9cd"}.bx-battery:before{content:"\e9ce"}.bx-bed:before{content:"\e9cf"}.bx-been-here:before{content:"\e9d0"}.bx-beer:before{content:"\e9d1"}.bx-bell:before{content:"\e9d2"}.bx-bell-minus:before{content:"\e9d3"}.bx-bell-off:before{content:"\e9d4"}.bx-bell-plus:before{content:"\e9d5"}.bx-bible:before{content:"\e9d6"}.bx-bitcoin:before{content:"\e9d7"}.bx-blanket:before{content:"\e9d8"}.bx-block:before{content:"\e9d9"}.bx-bluetooth:before{content:"\e9da"}.bx-body:before{content:"\e9db"}.bx-bold:before{content:"\e9dc"}.bx-bolt-circle:before{content:"\e9dd"}.bx-bomb:before{content:"\e9de"}.bx-bone:before{content:"\e9df"}.bx-bong:before{content:"\e9e0"}.bx-book:before{content:"\e9e1"}.bx-book-add:before{content:"\e9e2"}.bx-book-alt:before{content:"\e9e3"}.bx-book-bookmark:before{content:"\e9e4"}.bx-book-content:before{content:"\e9e5"}.bx-book-heart:before{content:"\e9e6"}.bx-bookmark:before{content:"\e9e7"}.bx-bookmark-alt:before{content:"\e9e8"}.bx-bookmark-alt-minus:before{content:"\e9e9"}.bx-bookmark-alt-plus:before{content:"\e9ea"}.bx-bookmark-heart:before{content:"\e9eb"}.bx-bookmark-minus:before{content:"\e9ec"}.bx-bookmark-plus:before{content:"\e9ed"}.bx-bookmarks:before{content:"\e9ee"}.bx-book-open:before{content:"\e9ef"}.bx-book-reader:before{content:"\e9f0"}.bx-border-all:before{content:"\e9f1"}.bx-border-bottom:before{content:"\e9f2"}.bx-border-inner:before{content:"\e9f3"}.bx-border-left:before{content:"\e9f4"}.bx-border-none:before{content:"\e9f5"}.bx-border-outer:before{content:"\e9f6"}.bx-border-radius:before{content:"\e9f7"}.bx-border-right:before{content:"\e9f8"}.bx-border-top:before{content:"\e9f9"}.bx-bot:before{content:"\e9fa"}.bx-bowling-ball:before{content:"\e9fb"}.bx-box:before{content:"\e9fc"}.bx-bracket:before{content:"\e9fd"}.bx-braille:before{content:"\e9fe"}.bx-brain:before{content:"\e9ff"}.bx-briefcase:before{content:"\ea00"}.bx-briefcase-alt:before{content:"\ea01"}.bx-briefcase-alt-2:before{content:"\ea02"}.bx-brightness:before{content:"\ea03"}.bx-brightness-half:before{content:"\ea04"}.bx-broadcast:before{content:"\ea05"}.bx-brush:before{content:"\ea06"}.bx-brush-alt:before{content:"\ea07"}.bx-bug:before{content:"\ea08"}.bx-bug-alt:before{content:"\ea09"}.bx-building:before{content:"\ea0a"}.bx-building-house:before{content:"\ea0b"}.bx-buildings:before{content:"\ea0c"}.bx-bulb:before{content:"\ea0d"}.bx-bullseye:before{content:"\ea0e"}.bx-buoy:before{content:"\ea0f"}.bx-bus:before{content:"\ea10"}.bx-bus-school:before{content:"\ea11"}.bx-cabinet:before{content:"\ea12"}.bx-cake:before{content:"\ea13"}.bx-calculator:before{content:"\ea14"}.bx-calendar:before{content:"\ea15"}.bx-calendar-alt:before{content:"\ea16"}.bx-calendar-check:before{content:"\ea17"}.bx-calendar-edit:before{content:"\ea18"}.bx-calendar-event:before{content:"\ea19"}.bx-calendar-exclamation:before{content:"\ea1a"}.bx-calendar-heart:before{content:"\ea1b"}.bx-calendar-minus:before{content:"\ea1c"}.bx-calendar-plus:before{content:"\ea1d"}.bx-calendar-star:before{content:"\ea1e"}.bx-calendar-week:before{content:"\ea1f"}.bx-calendar-x:before{content:"\ea20"}.bx-camera:before{content:"\ea21"}.bx-camera-home:before{content:"\ea22"}.bx-camera-movie:before{content:"\ea23"}.bx-camera-off:before{content:"\ea24"}.bx-capsule:before{content:"\ea25"}.bx-captions:before{content:"\ea26"}.bx-car:before{content:"\ea27"}.bx-card:before{content:"\ea28"}.bx-caret-down:before{content:"\ea29"}.bx-caret-down-circle:before{content:"\ea2a"}.bx-caret-down-square:before{content:"\ea2b"}.bx-caret-left:before{content:"\ea2c"}.bx-caret-left-circle:before{content:"\ea2d"}.bx-caret-left-square:before{content:"\ea2e"}.bx-caret-right:before{content:"\ea2f"}.bx-caret-right-circle:before{content:"\ea30"}.bx-caret-right-square:before{content:"\ea31"}.bx-caret-up:before{content:"\ea32"}.bx-caret-up-circle:before{content:"\ea33"}.bx-caret-up-square:before{content:"\ea34"}.bx-carousel:before{content:"\ea35"}.bx-cart:before{content:"\ea36"}.bx-cart-alt:before{content:"\ea37"}.bx-cast:before{content:"\ea38"}.bx-category:before{content:"\ea39"}.bx-category-alt:before{content:"\ea3a"}.bx-cctv:before{content:"\ea3b"}.bx-certification:before{content:"\ea3c"}.bx-chair:before{content:"\ea3d"}.bx-chalkboard:before{content:"\ea3e"}.bx-chart:before{content:"\ea3f"}.bx-chat:before{content:"\ea40"}.bx-check:before{content:"\ea41"}.bx-checkbox:before{content:"\ea42"}.bx-checkbox-checked:before{content:"\ea43"}.bx-checkbox-minus:before{content:"\ea44"}.bx-checkbox-square:before{content:"\ea45"}.bx-check-circle:before{content:"\ea46"}.bx-check-double:before{content:"\ea47"}.bx-check-shield:before{content:"\ea48"}.bx-check-square:before{content:"\ea49"}.bx-chevron-down:before{content:"\ea4a"}.bx-chevron-down-circle:before{content:"\ea4b"}.bx-chevron-down-square:before{content:"\ea4c"}.bx-chevron-left:before{content:"\ea4d"}.bx-chevron-left-circle:before{content:"\ea4e"}.bx-chevron-left-square:before{content:"\ea4f"}.bx-chevron-right:before{content:"\ea50"}.bx-chevron-right-circle:before{content:"\ea51"}.bx-chevron-right-square:before{content:"\ea52"}.bx-chevrons-down:before{content:"\ea53"}.bx-chevrons-left:before{content:"\ea54"}.bx-chevrons-right:before{content:"\ea55"}.bx-chevrons-up:before{content:"\ea56"}.bx-chevron-up:before{content:"\ea57"}.bx-chevron-up-circle:before{content:"\ea58"}.bx-chevron-up-square:before{content:"\ea59"}.bx-chip:before{content:"\ea5a"}.bx-church:before{content:"\ea5b"}.bx-circle:before{content:"\ea5c"}.bx-clinic:before{content:"\ea5d"}.bx-clipboard:before{content:"\ea5e"}.bx-closet:before{content:"\ea5f"}.bx-cloud:before{content:"\ea60"}.bx-cloud-download:before{content:"\ea61"}.bx-cloud-drizzle:before{content:"\ea62"}.bx-cloud-lightning:before{content:"\ea63"}.bx-cloud-light-rain:before{content:"\ea64"}.bx-cloud-rain:before{content:"\ea65"}.bx-cloud-snow:before{content:"\ea66"}.bx-cloud-upload:before{content:"\ea67"}.bx-code:before{content:"\ea68"}.bx-code-alt:before{content:"\ea69"}.bx-code-block:before{content:"\ea6a"}.bx-code-curly:before{content:"\ea6b"}.bx-coffee:before{content:"\ea6c"}.bx-coffee-togo:before{content:"\ea6d"}.bx-cog:before{content:"\ea6e"}.bx-coin:before{content:"\ea6f"}.bx-coin-stack:before{content:"\ea70"}.bx-collapse:before{content:"\ea71"}.bx-collection:before{content:"\ea72"}.bx-color-fill:before{content:"\ea73"}.bx-columns:before{content:"\ea74"}.bx-command:before{content:"\ea75"}.bx-comment:before{content:"\ea76"}.bx-comment-add:before{content:"\ea77"}.bx-comment-check:before{content:"\ea78"}.bx-comment-detail:before{content:"\ea79"}.bx-comment-dots:before{content:"\ea7a"}.bx-comment-edit:before{content:"\ea7b"}.bx-comment-error:before{content:"\ea7c"}.bx-comment-minus:before{content:"\ea7d"}.bx-comment-x:before{content:"\ea7e"}.bx-compass:before{content:"\ea7f"}.bx-confused:before{content:"\ea80"}.bx-conversation:before{content:"\ea81"}.bx-cookie:before{content:"\ea82"}.bx-cool:before{content:"\ea83"}.bx-copy:before{content:"\ea84"}.bx-copy-alt:before{content:"\ea85"}.bx-copyright:before{content:"\ea86"}.bx-credit-card:before{content:"\ea87"}.bx-credit-card-alt:before{content:"\ea88"}.bx-credit-card-front:before{content:"\ea89"}.bx-crop:before{content:"\ea8a"}.bx-crosshair:before{content:"\ea8b"}.bx-crown:before{content:"\ea8c"}.bx-cube:before{content:"\ea8d"}.bx-cube-alt:before{content:"\ea8e"}.bx-cuboid:before{content:"\ea8f"}.bx-current-location:before{content:"\ea90"}.bx-customize:before{content:"\ea91"}.bx-cut:before{content:"\ea92"}.bx-cycling:before{content:"\ea93"}.bx-cylinder:before{content:"\ea94"}.bx-data:before{content:"\ea95"}.bx-desktop:before{content:"\ea96"}.bx-detail:before{content:"\ea97"}.bx-devices:before{content:"\ea98"}.bx-dialpad:before{content:"\ea99"}.bx-dialpad-alt:before{content:"\ea9a"}.bx-diamond:before{content:"\ea9b"}.bx-dice-1:before{content:"\ea9c"}.bx-dice-2:before{content:"\ea9d"}.bx-dice-3:before{content:"\ea9e"}.bx-dice-4:before{content:"\ea9f"}.bx-dice-5:before{content:"\eaa0"}.bx-dice-6:before{content:"\eaa1"}.bx-directions:before{content:"\eaa2"}.bx-disc:before{content:"\eaa3"}.bx-dish:before{content:"\eaa4"}.bx-dislike:before{content:"\eaa5"}.bx-dizzy:before{content:"\eaa6"}.bx-dna:before{content:"\eaa7"}.bx-dock-bottom:before{content:"\eaa8"}.bx-dock-left:before{content:"\eaa9"}.bx-dock-right:before{content:"\eaaa"}.bx-dock-top:before{content:"\eaab"}.bx-dollar:before{content:"\eaac"}.bx-dollar-circle:before{content:"\eaad"}.bx-donate-blood:before{content:"\eaae"}.bx-donate-heart:before{content:"\eaaf"}.bx-door-open:before{content:"\eab0"}.bx-dots-horizontal:before{content:"\eab1"}.bx-dots-horizontal-rounded:before{content:"\eab2"}.bx-dots-vertical:before{content:"\eab3"}.bx-dots-vertical-rounded:before{content:"\eab4"}.bx-doughnut-chart:before{content:"\eab5"}.bx-down-arrow:before{content:"\eab6"}.bx-down-arrow-alt:before{content:"\eab7"}.bx-down-arrow-circle:before{content:"\eab8"}.bx-download:before{content:"\eab9"}.bx-downvote:before{content:"\eaba"}.bx-drink:before{content:"\eabb"}.bx-droplet:before{content:"\eabc"}.bx-dumbbell:before{content:"\eabd"}.bx-duplicate:before{content:"\eabe"}.bx-edit:before{content:"\eabf"}.bx-edit-alt:before{content:"\eac0"}.bx-envelope:before{content:"\eac1"}.bx-envelope-open:before{content:"\eac2"}.bx-equalizer:before{content:"\eac3"}.bx-eraser:before{content:"\eac4"}.bx-error:before{content:"\eac5"}.bx-error-alt:before{content:"\eac6"}.bx-error-circle:before{content:"\eac7"}.bx-euro:before{content:"\eac8"}.bx-exclude:before{content:"\eac9"}.bx-exit:before{content:"\eaca"}.bx-exit-fullscreen:before{content:"\eacb"}.bx-expand:before{content:"\eacc"}.bx-expand-alt:before{content:"\eacd"}.bx-export:before{content:"\eace"}.bx-extension:before{content:"\eacf"}.bx-face:before{content:"\ead0"}.bx-fast-forward:before{content:"\ead1"}.bx-fast-forward-circle:before{content:"\ead2"}.bx-female:before{content:"\ead3"}.bx-female-sign:before{content:"\ead4"}.bx-file:before{content:"\ead5"}.bx-file-blank:before{content:"\ead6"}.bx-file-find:before{content:"\ead7"}.bx-film:before{content:"\ead8"}.bx-filter:before{content:"\ead9"}.bx-filter-alt:before{content:"\eada"}.bx-fingerprint:before{content:"\eadb"}.bx-first-aid:before{content:"\eadc"}.bx-first-page:before{content:"\eadd"}.bx-flag:before{content:"\eade"}.bx-folder:before{content:"\eadf"}.bx-folder-minus:before{content:"\eae0"}.bx-folder-open:before{content:"\eae1"}.bx-folder-plus:before{content:"\eae2"}.bx-font:before{content:"\eae3"}.bx-font-color:before{content:"\eae4"}.bx-font-family:before{content:"\eae5"}.bx-font-size:before{content:"\eae6"}.bx-food-menu:before{content:"\eae7"}.bx-food-tag:before{content:"\eae8"}.bx-football:before{content:"\eae9"}.bx-fridge:before{content:"\eaea"}.bx-fullscreen:before{content:"\eaeb"}.bx-game:before{content:"\eaec"}.bx-gas-pump:before{content:"\eaed"}.bx-ghost:before{content:"\eaee"}.bx-gift:before{content:"\eaef"}.bx-git-branch:before{content:"\eaf0"}.bx-git-commit:before{content:"\eaf1"}.bx-git-compare:before{content:"\eaf2"}.bx-git-merge:before{content:"\eaf3"}.bx-git-pull-request:before{content:"\eaf4"}.bx-git-repo-forked:before{content:"\eaf5"}.bx-glasses:before{content:"\eaf6"}.bx-glasses-alt:before{content:"\eaf7"}.bx-globe:before{content:"\eaf8"}.bx-globe-alt:before{content:"\eaf9"}.bx-grid:before{content:"\eafa"}.bx-grid-alt:before{content:"\eafb"}.bx-grid-horizontal:before{content:"\eafc"}.bx-grid-small:before{content:"\eafd"}.bx-grid-vertical:before{content:"\eafe"}.bx-group:before{content:"\eaff"}.bx-handicap:before{content:"\eb00"}.bx-happy:before{content:"\eb01"}.bx-happy-alt:before{content:"\eb02"}.bx-happy-beaming:before{content:"\eb03"}.bx-happy-heart-eyes:before{content:"\eb04"}.bx-hash:before{content:"\eb05"}.bx-hdd:before{content:"\eb06"}.bx-heading:before{content:"\eb07"}.bx-headphone:before{content:"\eb08"}.bx-health:before{content:"\eb09"}.bx-heart:before{content:"\eb0a"}.bx-heart-circle:before{content:"\eb0b"}.bx-heart-square:before{content:"\eb0c"}.bx-help-circle:before{content:"\eb0d"}.bx-hide:before{content:"\eb0e"}.bx-highlight:before{content:"\eb0f"}.bx-history:before{content:"\eb10"}.bx-hive:before{content:"\eb11"}.bx-home:before{content:"\eb12"}.bx-home-alt:before{content:"\eb13"}.bx-home-circle:before{content:"\eb14"}.bx-home-heart:before{content:"\eb15"}.bx-home-smile:before{content:"\eb16"}.bx-horizontal-center:before{content:"\eb17"}.bx-hotel:before{content:"\eb18"}.bx-hourglass:before{content:"\eb19"}.bx-id-card:before{content:"\eb1a"}.bx-image:before{content:"\eb1b"}.bx-image-add:before{content:"\eb1c"}.bx-image-alt:before{content:"\eb1d"}.bx-images:before{content:"\eb1e"}.bx-import:before{content:"\eb1f"}.bx-infinite:before{content:"\eb20"}.bx-info-circle:before{content:"\eb21"}.bx-info-square:before{content:"\eb22"}.bx-intersect:before{content:"\eb23"}.bx-italic:before{content:"\eb24"}.bx-joystick:before{content:"\eb25"}.bx-joystick-alt:before{content:"\eb26"}.bx-joystick-button:before{content:"\eb27"}.bx-key:before{content:"\eb28"}.bx-label:before{content:"\eb29"}.bx-landscape:before{content:"\eb2a"}.bx-laptop:before{content:"\eb2b"}.bx-last-page:before{content:"\eb2c"}.bx-laugh:before{content:"\eb2d"}.bx-layer:before{content:"\eb2e"}.bx-layer-minus:before{content:"\eb2f"}.bx-layer-plus:before{content:"\eb30"}.bx-layout:before{content:"\eb31"}.bx-left-arrow:before{content:"\eb32"}.bx-left-arrow-alt:before{content:"\eb33"}.bx-left-arrow-circle:before{content:"\eb34"}.bx-left-down-arrow-circle:before{content:"\eb35"}.bx-left-indent:before{content:"\eb36"}.bx-left-top-arrow-circle:before{content:"\eb37"}.bx-library:before{content:"\eb38"}.bx-like:before{content:"\eb39"}.bx-line-chart:before{content:"\eb3a"}.bx-line-chart-down:before{content:"\eb3b"}.bx-link:before{content:"\eb3c"}.bx-link-alt:before{content:"\eb3d"}.bx-link-external:before{content:"\eb3e"}.bx-lira:before{content:"\eb3f"}.bx-list-check:before{content:"\eb40"}.bx-list-minus:before{content:"\eb41"}.bx-list-ol:before{content:"\eb42"}.bx-list-plus:before{content:"\eb43"}.bx-list-ul:before{content:"\eb44"}.bx-loader:before{content:"\eb45"}.bx-loader-alt:before{content:"\eb46"}.bx-loader-circle:before{content:"\eb47"}.bx-location-plus:before{content:"\eb48"}.bx-lock:before{content:"\eb49"}.bx-lock-alt:before{content:"\eb4a"}.bx-lock-open:before{content:"\eb4b"}.bx-lock-open-alt:before{content:"\eb4c"}.bx-log-in:before{content:"\eb4d"}.bx-log-in-circle:before{content:"\eb4e"}.bx-log-out:before{content:"\eb4f"}.bx-log-out-circle:before{content:"\eb50"}.bx-low-vision:before{content:"\eb51"}.bx-magnet:before{content:"\eb52"}.bx-mail-send:before{content:"\eb53"}.bx-male:before{content:"\eb54"}.bx-male-sign:before{content:"\eb55"}.bx-map:before{content:"\eb56"}.bx-map-alt:before{content:"\eb57"}.bx-map-pin:before{content:"\eb58"}.bx-mask:before{content:"\eb59"}.bx-medal:before{content:"\eb5a"}.bx-meh:before{content:"\eb5b"}.bx-meh-alt:before{content:"\eb5c"}.bx-meh-blank:before{content:"\eb5d"}.bx-memory-card:before{content:"\eb5e"}.bx-menu:before{content:"\eb5f"}.bx-menu-alt-left:before{content:"\ef5b"}.bx-menu-alt-right:before{content:"\eb61"}.bx-merge:before{content:"\eb62"}.bx-message:before{content:"\eb63"}.bx-message-add:before{content:"\eb64"}.bx-message-alt:before{content:"\eb65"}.bx-message-alt-add:before{content:"\eb66"}.bx-message-alt-check:before{content:"\eb67"}.bx-message-alt-detail:before{content:"\eb68"}.bx-message-alt-dots:before{content:"\eb69"}.bx-message-alt-edit:before{content:"\eb6a"}.bx-message-alt-error:before{content:"\eb6b"}.bx-message-alt-minus:before{content:"\eb6c"}.bx-message-alt-x:before{content:"\eb6d"}.bx-message-check:before{content:"\eb6e"}.bx-message-detail:before{content:"\eb6f"}.bx-message-dots:before{content:"\eb70"}.bx-message-edit:before{content:"\eb71"}.bx-message-error:before{content:"\eb72"}.bx-message-minus:before{content:"\eb73"}.bx-message-rounded:before{content:"\eb74"}.bx-message-rounded-add:before{content:"\eb75"}.bx-message-rounded-check:before{content:"\eb76"}.bx-message-rounded-detail:before{content:"\eb77"}.bx-message-rounded-dots:before{content:"\eb78"}.bx-message-rounded-edit:before{content:"\ef5c"}.bx-message-rounded-error:before{content:"\eb7a"}.bx-message-rounded-minus:before{content:"\eb7b"}.bx-message-rounded-x:before{content:"\eb7c"}.bx-message-square:before{content:"\eb7d"}.bx-message-square-add:before{content:"\eb7e"}.bx-message-square-check:before{content:"\eb7f"}.bx-message-square-detail:before{content:"\eb80"}.bx-message-square-dots:before{content:"\eb81"}.bx-message-square-edit:before{content:"\eb82"}.bx-message-square-error:before{content:"\eb83"}.bx-message-square-minus:before{content:"\eb84"}.bx-message-square-x:before{content:"\eb85"}.bx-message-x:before{content:"\eb86"}.bx-meteor:before{content:"\eb87"}.bx-microchip:before{content:"\eb88"}.bx-microphone:before{content:"\eb89"}.bx-microphone-off:before{content:"\eb8a"}.bx-minus:before{content:"\eb8b"}.bx-minus-back:before{content:"\eb8c"}.bx-minus-circle:before{content:"\eb8d"}.bx-minus-front:before{content:"\eb8e"}.bx-mobile:before{content:"\eb8f"}.bx-mobile-alt:before{content:"\eb90"}.bx-mobile-landscape:before{content:"\eb91"}.bx-mobile-vibration:before{content:"\ef5d"}.bx-money:before{content:"\eb93"}.bx-moon:before{content:"\eb94"}.bx-mouse:before{content:"\eb95"}.bx-mouse-alt:before{content:"\eb96"}.bx-move:before{content:"\eb97"}.bx-move-horizontal:before{content:"\eb98"}.bx-move-vertical:before{content:"\eb99"}.bx-movie:before{content:"\eb9a"}.bx-movie-play:before{content:"\eb9b"}.bx-music:before{content:"\eb9c"}.bx-navigation:before{content:"\eb9d"}.bx-network-chart:before{content:"\eb9e"}.bx-news:before{content:"\eb9f"}.bx-no-entry:before{content:"\eba0"}.bx-note:before{content:"\eba1"}.bx-notepad:before{content:"\eba2"}.bx-notification:before{content:"\eba3"}.bx-notification-off:before{content:"\eba4"}.bx-outline:before{content:"\eba5"}.bx-package:before{content:"\eba6"}.bx-paint:before{content:"\eba7"}.bx-paint-roll:before{content:"\eba8"}.bx-palette:before{content:"\eba9"}.bx-paperclip:before{content:"\ebaa"}.bx-paper-plane:before{content:"\ef61"}.bx-paragraph:before{content:"\ebac"}.bx-paste:before{content:"\ebad"}.bx-pause:before{content:"\ebae"}.bx-pause-circle:before{content:"\ebaf"}.bx-pen:before{content:"\ebb0"}.bx-pencil:before{content:"\ebb1"}.bx-phone:before{content:"\ebb2"}.bx-phone-call:before{content:"\ebb3"}.bx-phone-incoming:before{content:"\ebb4"}.bx-phone-off:before{content:"\ebb5"}.bx-phone-outgoing:before{content:"\ebb6"}.bx-photo-album:before{content:"\ebb7"}.bx-pie-chart:before{content:"\ebb8"}.bx-pie-chart-alt:before{content:"\ebb9"}.bx-pie-chart-alt-2:before{content:"\ebba"}.bx-pin:before{content:"\ebbb"}.bx-planet:before{content:"\ebbc"}.bx-play:before{content:"\ebbd"}.bx-play-circle:before{content:"\ebbe"}.bx-plug:before{content:"\ebbf"}.bx-plus:before{content:"\ebc0"}.bx-plus-circle:before{content:"\ebc1"}.bx-plus-medical:before{content:"\ebc2"}.bx-podcast:before{content:"\ebc3"}.bx-pointer:before{content:"\ef5e"}.bx-poll:before{content:"\ebc5"}.bx-polygon:before{content:"\ebc6"}.bx-pound:before{content:"\ebc7"}.bx-power-off:before{content:"\ebc8"}.bx-printer:before{content:"\ebc9"}.bx-pulse:before{content:"\ebca"}.bx-purchase-tag:before{content:"\ebcb"}.bx-purchase-tag-alt:before{content:"\ebcc"}.bx-pyramid:before{content:"\ebcd"}.bx-qr:before{content:"\ebce"}.bx-qr-scan:before{content:"\ebcf"}.bx-question-mark:before{content:"\ebd0"}.bx-radar:before{content:"\ebd1"}.bx-radio:before{content:"\ebd2"}.bx-radio-circle:before{content:"\ebd3"}.bx-radio-circle-marked:before{content:"\ebd4"}.bx-receipt:before{content:"\ebd5"}.bx-rectangle:before{content:"\ebd6"}.bx-recycle:before{content:"\ebd7"}.bx-redo:before{content:"\ebd8"}.bx-refresh:before{content:"\ebd9"}.bx-registered:before{content:"\ebda"}.bx-rename:before{content:"\ebdb"}.bx-repeat:before{content:"\ebdc"}.bx-reply:before{content:"\ef5f"}.bx-reply-all:before{content:"\ebde"}.bx-repost:before{content:"\ebdf"}.bx-reset:before{content:"\ebe0"}.bx-restaurant:before{content:"\ebe1"}.bx-revision:before{content:"\ebe2"}.bx-rewind:before{content:"\ebe3"}.bx-rewind-circle:before{content:"\ebe4"}.bx-right-arrow:before{content:"\ebe5"}.bx-right-arrow-alt:before{content:"\ebe6"}.bx-right-arrow-circle:before{content:"\ebe7"}.bx-right-down-arrow-circle:before{content:"\ebe8"}.bx-right-indent:before{content:"\ebe9"}.bx-right-top-arrow-circle:before{content:"\ebea"}.bx-rocket:before{content:"\ebeb"}.bx-rotate-left:before{content:"\ebec"}.bx-rotate-right:before{content:"\ebed"}.bx-rss:before{content:"\ebee"}.bx-ruble:before{content:"\ebef"}.bx-ruler:before{content:"\ebf0"}.bx-run:before{content:"\ebf1"}.bx-rupee:before{content:"\ebf2"}.bx-sad:before{content:"\ebf3"}.bx-save:before{content:"\ebf4"}.bx-scan:before{content:"\ebf5"}.bx-screenshot:before{content:"\ef60"}.bx-search:before{content:"\ebf7"}.bx-search-alt:before{content:"\ebf8"}.bx-search-alt-2:before{content:"\ebf9"}.bx-selection:before{content:"\ebfa"}.bx-select-multiple:before{content:"\ebfb"}.bx-send:before{content:"\ebfc"}.bx-server:before{content:"\ebfd"}.bx-shape-circle:before{content:"\ebfe"}.bx-shape-polygon:before{content:"\ebff"}.bx-shape-square:before{content:"\ec00"}.bx-shape-triangle:before{content:"\ec01"}.bx-share:before{content:"\ec02"}.bx-share-alt:before{content:"\ec03"}.bx-shekel:before{content:"\ec04"}.bx-shield:before{content:"\ec05"}.bx-shield-alt:before{content:"\ec06"}.bx-shield-alt-2:before{content:"\ec07"}.bx-shield-quarter:before{content:"\ec08"}.bx-shield-x:before{content:"\ec09"}.bx-shocked:before{content:"\ec0a"}.bx-shopping-bag:before{content:"\ec0b"}.bx-show:before{content:"\ec0c"}.bx-show-alt:before{content:"\ec0d"}.bx-shuffle:before{content:"\ec0e"}.bx-sidebar:before{content:"\ec0f"}.bx-sitemap:before{content:"\ec10"}.bx-skip-next:before{content:"\ec11"}.bx-skip-next-circle:before{content:"\ec12"}.bx-skip-previous:before{content:"\ec13"}.bx-skip-previous-circle:before{content:"\ec14"}.bx-sleepy:before{content:"\ec15"}.bx-slider:before{content:"\ec16"}.bx-slider-alt:before{content:"\ec17"}.bx-slideshow:before{content:"\ec18"}.bx-smile:before{content:"\ec19"}.bx-sort:before{content:"\ec1a"}.bx-sort-alt-2:before{content:"\ec1b"}.bx-sort-a-z:before{content:"\ec1c"}.bx-sort-down:before{content:"\ec1d"}.bx-sort-up:before{content:"\ec1e"}.bx-sort-z-a:before{content:"\ec1f"}.bx-spa:before{content:"\ec20"}.bx-space-bar:before{content:"\ec21"}.bx-speaker:before{content:"\ec22"}.bx-spray-can:before{content:"\ec23"}.bx-spreadsheet:before{content:"\ec24"}.bx-square:before{content:"\ec25"}.bx-square-rounded:before{content:"\ec26"}.bx-star:before{content:"\ec27"}.bx-station:before{content:"\ec28"}.bx-stats:before{content:"\ec29"}.bx-sticker:before{content:"\ec2a"}.bx-stop:before{content:"\ec2b"}.bx-stop-circle:before{content:"\ec2c"}.bx-stopwatch:before{content:"\ec2d"}.bx-store:before{content:"\ec2e"}.bx-store-alt:before{content:"\ec2f"}.bx-street-view:before{content:"\ec30"}.bx-strikethrough:before{content:"\ec31"}.bx-subdirectory-left:before{content:"\ec32"}.bx-subdirectory-right:before{content:"\ec33"}.bx-sun:before{content:"\ec34"}.bx-support:before{content:"\ec35"}.bx-swim:before{content:"\ec36"}.bx-sync:before{content:"\ec37"}.bx-tab:before{content:"\ec38"}.bx-table:before{content:"\ec39"}.bx-tachometer:before{content:"\ec3a"}.bx-tag:before{content:"\ec3b"}.bx-tag-alt:before{content:"\ec3c"}.bx-target-lock:before{content:"\ec3d"}.bx-task:before{content:"\ec3e"}.bx-task-x:before{content:"\ec3f"}.bx-taxi:before{content:"\ec40"}.bx-tennis-ball:before{content:"\ec41"}.bx-terminal:before{content:"\ec42"}.bx-test-tube:before{content:"\ec43"}.bx-text:before{content:"\ec44"}.bx-time:before{content:"\ec45"}.bx-time-five:before{content:"\ec46"}.bx-timer:before{content:"\ec47"}.bx-tired:before{content:"\ec48"}.bx-toggle-left:before{content:"\ec49"}.bx-toggle-right:before{content:"\ec4a"}.bx-tone:before{content:"\ec4b"}.bx-traffic-cone:before{content:"\ec4c"}.bx-train:before{content:"\ec4d"}.bx-transfer:before{content:"\ec4e"}.bx-transfer-alt:before{content:"\ec4f"}.bx-trash:before{content:"\ec50"}.bx-trash-alt:before{content:"\ec51"}.bx-trending-down:before{content:"\ec52"}.bx-trending-up:before{content:"\ec53"}.bx-trim:before{content:"\ec54"}.bx-trip:before{content:"\ec55"}.bx-trophy:before{content:"\ec56"}.bx-tv:before{content:"\ec57"}.bx-underline:before{content:"\ec58"}.bx-undo:before{content:"\ec59"}.bx-unite:before{content:"\ec5a"}.bx-unlink:before{content:"\ec5b"}.bx-up-arrow:before{content:"\ec5c"}.bx-up-arrow-alt:before{content:"\ec5d"}.bx-up-arrow-circle:before{content:"\ec5e"}.bx-upload:before{content:"\ec5f"}.bx-upside-down:before{content:"\ec60"}.bx-upvote:before{content:"\ec61"}.bx-usb:before{content:"\ec62"}.bx-user:before{content:"\ec63"}.bx-user-check:before{content:"\ec64"}.bx-user-circle:before{content:"\ec65"}.bx-user-minus:before{content:"\ec66"}.bx-user-pin:before{content:"\ec67"}.bx-user-plus:before{content:"\ec68"}.bx-user-voice:before{content:"\ec69"}.bx-user-x:before{content:"\ec6a"}.bx-vector:before{content:"\ec6b"}.bx-vertical-center:before{content:"\ec6c"}.bx-vial:before{content:"\ec6d"}.bx-video:before{content:"\ec6e"}.bx-video-off:before{content:"\ec6f"}.bx-video-plus:before{content:"\ec70"}.bx-video-recording:before{content:"\ec71"}.bx-voicemail:before{content:"\ec72"}.bx-volume:before{content:"\ec73"}.bx-volume-full:before{content:"\ec74"}.bx-volume-low:before{content:"\ec75"}.bx-volume-mute:before{content:"\ec76"}.bx-walk:before{content:"\ec77"}.bx-wallet:before{content:"\ec78"}.bx-wallet-alt:before{content:"\ec79"}.bx-water:before{content:"\ec7a"}.bx-webcam:before{content:"\ec7b"}.bx-wifi:before{content:"\ec7c"}.bx-wifi-0:before{content:"\ec7d"}.bx-wifi-1:before{content:"\ec7e"}.bx-wifi-2:before{content:"\ec7f"}.bx-wifi-off:before{content:"\ec80"}.bx-wind:before{content:"\ec81"}.bx-window:before{content:"\ec82"}.bx-window-alt:before{content:"\ec83"}.bx-window-close:before{content:"\ec84"}.bx-window-open:before{content:"\ec85"}.bx-windows:before{content:"\ec86"}.bx-wine:before{content:"\ec87"}.bx-wink-smile:before{content:"\ec88"}.bx-wink-tongue:before{content:"\ec89"}.bx-won:before{content:"\ec8a"}.bx-world:before{content:"\ec8b"}.bx-wrench:before{content:"\ec8c"}.bx-x:before{content:"\ec8d"}.bx-x-circle:before{content:"\ec8e"}.bx-yen:before{content:"\ec8f"}.bx-zoom-in:before{content:"\ec90"}.bx-zoom-out:before{content:"\ec91"}.bxs-party:before{content:"\ec92"}.bxs-hot:before{content:"\ec93"}.bxs-droplet:before{content:"\ec94"}.bxs-cat:before{content:"\ec95"}.bxs-dog:before{content:"\ec96"}.bxs-injection:before{content:"\ec97"}.bxs-leaf:before{content:"\ec98"}.bxs-add-to-queue:before{content:"\ec99"}.bxs-adjust:before{content:"\ec9a"}.bxs-adjust-alt:before{content:"\ec9b"}.bxs-alarm:before{content:"\ec9c"}.bxs-alarm-add:before{content:"\ec9d"}.bxs-alarm-exclamation:before{content:"\ec9e"}.bxs-alarm-off:before{content:"\ec9f"}.bxs-alarm-snooze:before{content:"\eca0"}.bxs-album:before{content:"\eca1"}.bxs-ambulance:before{content:"\eca2"}.bxs-analyse:before{content:"\eca3"}.bxs-angry:before{content:"\eca4"}.bxs-arch:before{content:"\eca5"}.bxs-archive:before{content:"\eca6"}.bxs-archive-in:before{content:"\eca7"}.bxs-archive-out:before{content:"\eca8"}.bxs-area:before{content:"\eca9"}.bxs-arrow-from-bottom:before{content:"\ecaa"}.bxs-arrow-from-left:before{content:"\ecab"}.bxs-arrow-from-right:before{content:"\ecac"}.bxs-arrow-from-top:before{content:"\ecad"}.bxs-arrow-to-bottom:before{content:"\ecae"}.bxs-arrow-to-left:before{content:"\ecaf"}.bxs-arrow-to-right:before{content:"\ecb0"}.bxs-arrow-to-top:before{content:"\ecb1"}.bxs-award:before{content:"\ecb2"}.bxs-baby-carriage:before{content:"\ecb3"}.bxs-backpack:before{content:"\ecb4"}.bxs-badge:before{content:"\ecb5"}.bxs-badge-check:before{content:"\ecb6"}.bxs-badge-dollar:before{content:"\ecb7"}.bxs-ball:before{content:"\ecb8"}.bxs-band-aid:before{content:"\ecb9"}.bxs-bank:before{content:"\ecba"}.bxs-bar-chart-alt-2:before{content:"\ecbb"}.bxs-bar-chart-square:before{content:"\ecbc"}.bxs-barcode:before{content:"\ecbd"}.bxs-baseball:before{content:"\ecbe"}.bxs-basket:before{content:"\ecbf"}.bxs-basketball:before{content:"\ecc0"}.bxs-bath:before{content:"\ecc1"}.bxs-battery:before{content:"\ecc2"}.bxs-battery-charging:before{content:"\ecc3"}.bxs-battery-full:before{content:"\ecc4"}.bxs-battery-low:before{content:"\ecc5"}.bxs-bed:before{content:"\ecc6"}.bxs-been-here:before{content:"\ecc7"}.bxs-beer:before{content:"\ecc8"}.bxs-bell:before{content:"\ecc9"}.bxs-bell-minus:before{content:"\ecca"}.bxs-bell-off:before{content:"\eccb"}.bxs-bell-plus:before{content:"\eccc"}.bxs-bell-ring:before{content:"\eccd"}.bxs-bible:before{content:"\ecce"}.bxs-binoculars:before{content:"\eccf"}.bxs-blanket:before{content:"\ecd0"}.bxs-bolt:before{content:"\ecd1"}.bxs-bolt-circle:before{content:"\ecd2"}.bxs-bomb:before{content:"\ecd3"}.bxs-bone:before{content:"\ecd4"}.bxs-bong:before{content:"\ecd5"}.bxs-book:before{content:"\ecd6"}.bxs-book-add:before{content:"\ecd7"}.bxs-book-alt:before{content:"\ecd8"}.bxs-book-bookmark:before{content:"\ecd9"}.bxs-book-content:before{content:"\ecda"}.bxs-book-heart:before{content:"\ecdb"}.bxs-bookmark:before{content:"\ecdc"}.bxs-bookmark-alt:before{content:"\ecdd"}.bxs-bookmark-alt-minus:before{content:"\ecde"}.bxs-bookmark-alt-plus:before{content:"\ecdf"}.bxs-bookmark-heart:before{content:"\ece0"}.bxs-bookmark-minus:before{content:"\ece1"}.bxs-bookmark-plus:before{content:"\ece2"}.bxs-bookmarks:before{content:"\ece3"}.bxs-bookmark-star:before{content:"\ece4"}.bxs-book-open:before{content:"\ece5"}.bxs-book-reader:before{content:"\ece6"}.bxs-bot:before{content:"\ece7"}.bxs-bowling-ball:before{content:"\ece8"}.bxs-box:before{content:"\ece9"}.bxs-brain:before{content:"\ecea"}.bxs-briefcase:before{content:"\eceb"}.bxs-briefcase-alt:before{content:"\ecec"}.bxs-briefcase-alt-2:before{content:"\eced"}.bxs-brightness:before{content:"\ecee"}.bxs-brightness-half:before{content:"\ecef"}.bxs-brush:before{content:"\ecf0"}.bxs-brush-alt:before{content:"\ecf1"}.bxs-bug:before{content:"\ecf2"}.bxs-bug-alt:before{content:"\ecf3"}.bxs-building:before{content:"\ecf4"}.bxs-building-house:before{content:"\ecf5"}.bxs-buildings:before{content:"\ecf6"}.bxs-bulb:before{content:"\ecf7"}.bxs-bullseye:before{content:"\ecf8"}.bxs-buoy:before{content:"\ecf9"}.bxs-bus:before{content:"\ecfa"}.bxs-business:before{content:"\ecfb"}.bxs-bus-school:before{content:"\ecfc"}.bxs-cabinet:before{content:"\ecfd"}.bxs-cake:before{content:"\ecfe"}.bxs-calculator:before{content:"\ecff"}.bxs-calendar:before{content:"\ed00"}.bxs-calendar-alt:before{content:"\ed01"}.bxs-calendar-check:before{content:"\ed02"}.bxs-calendar-edit:before{content:"\ed03"}.bxs-calendar-event:before{content:"\ed04"}.bxs-calendar-exclamation:before{content:"\ed05"}.bxs-calendar-heart:before{content:"\ed06"}.bxs-calendar-minus:before{content:"\ed07"}.bxs-calendar-plus:before{content:"\ed08"}.bxs-calendar-star:before{content:"\ed09"}.bxs-calendar-week:before{content:"\ed0a"}.bxs-calendar-x:before{content:"\ed0b"}.bxs-camera:before{content:"\ed0c"}.bxs-camera-home:before{content:"\ed0d"}.bxs-camera-movie:before{content:"\ed0e"}.bxs-camera-off:before{content:"\ed0f"}.bxs-camera-plus:before{content:"\ed10"}.bxs-capsule:before{content:"\ed11"}.bxs-captions:before{content:"\ed12"}.bxs-car:before{content:"\ed13"}.bxs-car-battery:before{content:"\ed14"}.bxs-car-crash:before{content:"\ed15"}.bxs-card:before{content:"\ed16"}.bxs-caret-down-circle:before{content:"\ed17"}.bxs-caret-down-square:before{content:"\ed18"}.bxs-caret-left-circle:before{content:"\ed19"}.bxs-caret-left-square:before{content:"\ed1a"}.bxs-caret-right-circle:before{content:"\ed1b"}.bxs-caret-right-square:before{content:"\ed1c"}.bxs-caret-up-circle:before{content:"\ed1d"}.bxs-caret-up-square:before{content:"\ed1e"}.bxs-car-garage:before{content:"\ed1f"}.bxs-car-mechanic:before{content:"\ed20"}.bxs-carousel:before{content:"\ed21"}.bxs-cart:before{content:"\ed22"}.bxs-cart-add:before{content:"\ed23"}.bxs-cart-alt:before{content:"\ed24"}.bxs-cart-download:before{content:"\ed25"}.bxs-car-wash:before{content:"\ed26"}.bxs-category:before{content:"\ed27"}.bxs-category-alt:before{content:"\ed28"}.bxs-cctv:before{content:"\ed29"}.bxs-certification:before{content:"\ed2a"}.bxs-chalkboard:before{content:"\ed2b"}.bxs-chart:before{content:"\ed2c"}.bxs-chat:before{content:"\ed2d"}.bxs-checkbox:before{content:"\ed2e"}.bxs-checkbox-checked:before{content:"\ed2f"}.bxs-checkbox-minus:before{content:"\ed30"}.bxs-check-circle:before{content:"\ed31"}.bxs-check-shield:before{content:"\ed32"}.bxs-check-square:before{content:"\ed33"}.bxs-chess:before{content:"\ed34"}.bxs-chevron-down:before{content:"\ed35"}.bxs-chevron-down-circle:before{content:"\ed36"}.bxs-chevron-down-square:before{content:"\ed37"}.bxs-chevron-left:before{content:"\ed38"}.bxs-chevron-left-circle:before{content:"\ed39"}.bxs-chevron-left-square:before{content:"\ed3a"}.bxs-chevron-right:before{content:"\ed3b"}.bxs-chevron-right-circle:before{content:"\ed3c"}.bxs-chevron-right-square:before{content:"\ed3d"}.bxs-chevrons-down:before{content:"\ed3e"}.bxs-chevrons-left:before{content:"\ed3f"}.bxs-chevrons-right:before{content:"\ed40"}.bxs-chevrons-up:before{content:"\ed41"}.bxs-chevron-up:before{content:"\ed42"}.bxs-chevron-up-circle:before{content:"\ed43"}.bxs-chevron-up-square:before{content:"\ed44"}.bxs-chip:before{content:"\ed45"}.bxs-church:before{content:"\ed46"}.bxs-circle:before{content:"\ed47"}.bxs-city:before{content:"\ed48"}.bxs-clinic:before{content:"\ed49"}.bxs-cloud:before{content:"\ed4a"}.bxs-cloud-download:before{content:"\ed4b"}.bxs-cloud-lightning:before{content:"\ed4c"}.bxs-cloud-rain:before{content:"\ed4d"}.bxs-cloud-upload:before{content:"\ed4e"}.bxs-coffee:before{content:"\ed4f"}.bxs-coffee-alt:before{content:"\ed50"}.bxs-coffee-togo:before{content:"\ed51"}.bxs-cog:before{content:"\ed52"}.bxs-coin:before{content:"\ed53"}.bxs-coin-stack:before{content:"\ed54"}.bxs-collection:before{content:"\ed55"}.bxs-color-fill:before{content:"\ed56"}.bxs-comment:before{content:"\ed57"}.bxs-comment-add:before{content:"\ed58"}.bxs-comment-check:before{content:"\ed59"}.bxs-comment-detail:before{content:"\ed5a"}.bxs-comment-dots:before{content:"\ed5b"}.bxs-comment-edit:before{content:"\ed5c"}.bxs-comment-error:before{content:"\ed5d"}.bxs-comment-minus:before{content:"\ed5e"}.bxs-comment-x:before{content:"\ed5f"}.bxs-compass:before{content:"\ed60"}.bxs-component:before{content:"\ed61"}.bxs-confused:before{content:"\ed62"}.bxs-contact:before{content:"\ed63"}.bxs-conversation:before{content:"\ed64"}.bxs-cookie:before{content:"\ed65"}.bxs-cool:before{content:"\ed66"}.bxs-copy:before{content:"\ed67"}.bxs-copy-alt:before{content:"\ed68"}.bxs-copyright:before{content:"\ed69"}.bxs-coupon:before{content:"\ed6a"}.bxs-credit-card:before{content:"\ed6b"}.bxs-credit-card-alt:before{content:"\ed6c"}.bxs-credit-card-front:before{content:"\ed6d"}.bxs-crop:before{content:"\ed6e"}.bxs-crown:before{content:"\ed6f"}.bxs-cube:before{content:"\ed70"}.bxs-cube-alt:before{content:"\ed71"}.bxs-cuboid:before{content:"\ed72"}.bxs-customize:before{content:"\ed73"}.bxs-cylinder:before{content:"\ed74"}.bxs-dashboard:before{content:"\ed75"}.bxs-data:before{content:"\ed76"}.bxs-detail:before{content:"\ed77"}.bxs-devices:before{content:"\ed78"}.bxs-diamond:before{content:"\ed79"}.bxs-dice-1:before{content:"\ed7a"}.bxs-dice-2:before{content:"\ed7b"}.bxs-dice-3:before{content:"\ed7c"}.bxs-dice-4:before{content:"\ed7d"}.bxs-dice-5:before{content:"\ed7e"}.bxs-dice-6:before{content:"\ed7f"}.bxs-direction-left:before{content:"\ed80"}.bxs-direction-right:before{content:"\ed81"}.bxs-directions:before{content:"\ed82"}.bxs-disc:before{content:"\ed83"}.bxs-discount:before{content:"\ed84"}.bxs-dish:before{content:"\ed85"}.bxs-dislike:before{content:"\ed86"}.bxs-dizzy:before{content:"\ed87"}.bxs-dock-bottom:before{content:"\ed88"}.bxs-dock-left:before{content:"\ed89"}.bxs-dock-right:before{content:"\ed8a"}.bxs-dock-top:before{content:"\ed8b"}.bxs-dollar-circle:before{content:"\ed8c"}.bxs-donate-blood:before{content:"\ed8d"}.bxs-donate-heart:before{content:"\ed8e"}.bxs-door-open:before{content:"\ed8f"}.bxs-doughnut-chart:before{content:"\ed90"}.bxs-down-arrow:before{content:"\ed91"}.bxs-down-arrow-alt:before{content:"\ed92"}.bxs-down-arrow-circle:before{content:"\ed93"}.bxs-down-arrow-square:before{content:"\ed94"}.bxs-download:before{content:"\ed95"}.bxs-downvote:before{content:"\ed96"}.bxs-drink:before{content:"\ed97"}.bxs-droplet-half:before{content:"\ed98"}.bxs-dryer:before{content:"\ed99"}.bxs-duplicate:before{content:"\ed9a"}.bxs-edit:before{content:"\ed9b"}.bxs-edit-alt:before{content:"\ed9c"}.bxs-edit-location:before{content:"\ed9d"}.bxs-eject:before{content:"\ed9e"}.bxs-envelope:before{content:"\ed9f"}.bxs-envelope-open:before{content:"\eda0"}.bxs-eraser:before{content:"\eda1"}.bxs-error:before{content:"\eda2"}.bxs-error-alt:before{content:"\eda3"}.bxs-error-circle:before{content:"\eda4"}.bxs-ev-station:before{content:"\eda5"}.bxs-exit:before{content:"\eda6"}.bxs-extension:before{content:"\eda7"}.bxs-eyedropper:before{content:"\eda8"}.bxs-face:before{content:"\eda9"}.bxs-face-mask:before{content:"\edaa"}.bxs-factory:before{content:"\edab"}.bxs-fast-forward-circle:before{content:"\edac"}.bxs-file:before{content:"\edad"}.bxs-file-archive:before{content:"\edae"}.bxs-file-blank:before{content:"\edaf"}.bxs-file-css:before{content:"\edb0"}.bxs-file-doc:before{content:"\edb1"}.bxs-file-export:before{content:"\edb2"}.bxs-file-find:before{content:"\edb3"}.bxs-file-gif:before{content:"\edb4"}.bxs-file-html:before{content:"\edb5"}.bxs-file-image:before{content:"\edb6"}.bxs-file-import:before{content:"\edb7"}.bxs-file-jpg:before{content:"\edb8"}.bxs-file-js:before{content:"\edb9"}.bxs-file-json:before{content:"\edba"}.bxs-file-md:before{content:"\edbb"}.bxs-file-pdf:before{content:"\edbc"}.bxs-file-plus:before{content:"\edbd"}.bxs-file-png:before{content:"\edbe"}.bxs-file-txt:before{content:"\edbf"}.bxs-film:before{content:"\edc0"}.bxs-filter-alt:before{content:"\edc1"}.bxs-first-aid:before{content:"\edc2"}.bxs-flag:before{content:"\edc3"}.bxs-flag-alt:before{content:"\edc4"}.bxs-flag-checkered:before{content:"\edc5"}.bxs-flame:before{content:"\edc6"}.bxs-flask:before{content:"\edc7"}.bxs-florist:before{content:"\edc8"}.bxs-folder:before{content:"\edc9"}.bxs-folder-minus:before{content:"\edca"}.bxs-folder-open:before{content:"\edcb"}.bxs-folder-plus:before{content:"\edcc"}.bxs-food-menu:before{content:"\edcd"}.bxs-fridge:before{content:"\edce"}.bxs-game:before{content:"\edcf"}.bxs-gas-pump:before{content:"\edd0"}.bxs-ghost:before{content:"\edd1"}.bxs-gift:before{content:"\edd2"}.bxs-graduation:before{content:"\edd3"}.bxs-grid:before{content:"\edd4"}.bxs-grid-alt:before{content:"\edd5"}.bxs-group:before{content:"\edd6"}.bxs-guitar-amp:before{content:"\edd7"}.bxs-hand:before{content:"\edd8"}.bxs-hand-down:before{content:"\edd9"}.bxs-hand-left:before{content:"\edda"}.bxs-hand-right:before{content:"\eddb"}.bxs-hand-up:before{content:"\eddc"}.bxs-happy:before{content:"\eddd"}.bxs-happy-alt:before{content:"\edde"}.bxs-happy-beaming:before{content:"\eddf"}.bxs-happy-heart-eyes:before{content:"\ede0"}.bxs-hdd:before{content:"\ede1"}.bxs-heart:before{content:"\ede2"}.bxs-heart-circle:before{content:"\ede3"}.bxs-heart-square:before{content:"\ede4"}.bxs-help-circle:before{content:"\ede5"}.bxs-hide:before{content:"\ede6"}.bxs-home:before{content:"\ede7"}.bxs-home-circle:before{content:"\ede8"}.bxs-home-heart:before{content:"\ede9"}.bxs-home-smile:before{content:"\edea"}.bxs-hotel:before{content:"\edeb"}.bxs-hourglass:before{content:"\edec"}.bxs-hourglass-bottom:before{content:"\eded"}.bxs-hourglass-top:before{content:"\edee"}.bxs-id-card:before{content:"\edef"}.bxs-image:before{content:"\edf0"}.bxs-image-add:before{content:"\edf1"}.bxs-image-alt:before{content:"\edf2"}.bxs-inbox:before{content:"\edf3"}.bxs-info-circle:before{content:"\edf4"}.bxs-info-square:before{content:"\edf5"}.bxs-institution:before{content:"\edf6"}.bxs-joystick:before{content:"\edf7"}.bxs-joystick-alt:before{content:"\edf8"}.bxs-joystick-button:before{content:"\edf9"}.bxs-key:before{content:"\edfa"}.bxs-keyboard:before{content:"\edfb"}.bxs-label:before{content:"\edfc"}.bxs-landmark:before{content:"\edfd"}.bxs-landscape:before{content:"\edfe"}.bxs-laugh:before{content:"\edff"}.bxs-layer:before{content:"\ee00"}.bxs-layer-minus:before{content:"\ee01"}.bxs-layer-plus:before{content:"\ee02"}.bxs-layout:before{content:"\ee03"}.bxs-left-arrow:before{content:"\ee04"}.bxs-left-arrow-alt:before{content:"\ee05"}.bxs-left-arrow-circle:before{content:"\ee06"}.bxs-left-arrow-square:before{content:"\ee07"}.bxs-left-down-arrow-circle:before{content:"\ee08"}.bxs-left-top-arrow-circle:before{content:"\ee09"}.bxs-like:before{content:"\ee0a"}.bxs-location-plus:before{content:"\ee0b"}.bxs-lock:before{content:"\ee0c"}.bxs-lock-alt:before{content:"\ee0d"}.bxs-lock-open:before{content:"\ee0e"}.bxs-lock-open-alt:before{content:"\ee0f"}.bxs-log-in:before{content:"\ee10"}.bxs-log-in-circle:before{content:"\ee11"}.bxs-log-out:before{content:"\ee12"}.bxs-log-out-circle:before{content:"\ee13"}.bxs-low-vision:before{content:"\ee14"}.bxs-magic-wand:before{content:"\ee15"}.bxs-magnet:before{content:"\ee16"}.bxs-map:before{content:"\ee17"}.bxs-map-alt:before{content:"\ee18"}.bxs-map-pin:before{content:"\ee19"}.bxs-mask:before{content:"\ee1a"}.bxs-medal:before{content:"\ee1b"}.bxs-megaphone:before{content:"\ee1c"}.bxs-meh:before{content:"\ee1d"}.bxs-meh-alt:before{content:"\ee1e"}.bxs-meh-blank:before{content:"\ee1f"}.bxs-memory-card:before{content:"\ee20"}.bxs-message:before{content:"\ee21"}.bxs-message-add:before{content:"\ee22"}.bxs-message-alt:before{content:"\ee23"}.bxs-message-alt-add:before{content:"\ee24"}.bxs-message-alt-check:before{content:"\ee25"}.bxs-message-alt-detail:before{content:"\ee26"}.bxs-message-alt-dots:before{content:"\ee27"}.bxs-message-alt-edit:before{content:"\ee28"}.bxs-message-alt-error:before{content:"\ee29"}.bxs-message-alt-minus:before{content:"\ee2a"}.bxs-message-alt-x:before{content:"\ee2b"}.bxs-message-check:before{content:"\ee2c"}.bxs-message-detail:before{content:"\ee2d"}.bxs-message-dots:before{content:"\ee2e"}.bxs-message-edit:before{content:"\ee2f"}.bxs-message-error:before{content:"\ee30"}.bxs-message-minus:before{content:"\ee31"}.bxs-message-rounded:before{content:"\ee32"}.bxs-message-rounded-add:before{content:"\ee33"}.bxs-message-rounded-check:before{content:"\ee34"}.bxs-message-rounded-detail:before{content:"\ee35"}.bxs-message-rounded-dots:before{content:"\ee36"}.bxs-message-rounded-edit:before{content:"\ee37"}.bxs-message-rounded-error:before{content:"\ee38"}.bxs-message-rounded-minus:before{content:"\ee39"}.bxs-message-rounded-x:before{content:"\ee3a"}.bxs-message-square:before{content:"\ee3b"}.bxs-message-square-add:before{content:"\ee3c"}.bxs-message-square-check:before{content:"\ee3d"}.bxs-message-square-detail:before{content:"\ee3e"}.bxs-message-square-dots:before{content:"\ee3f"}.bxs-message-square-edit:before{content:"\ee40"}.bxs-message-square-error:before{content:"\ee41"}.bxs-message-square-minus:before{content:"\ee42"}.bxs-message-square-x:before{content:"\ee43"}.bxs-message-x:before{content:"\ee44"}.bxs-meteor:before{content:"\ee45"}.bxs-microchip:before{content:"\ee46"}.bxs-microphone:before{content:"\ee47"}.bxs-microphone-alt:before{content:"\ee48"}.bxs-microphone-off:before{content:"\ee49"}.bxs-minus-circle:before{content:"\ee4a"}.bxs-minus-square:before{content:"\ee4b"}.bxs-mobile:before{content:"\ee4c"}.bxs-mobile-vibration:before{content:"\ee4d"}.bxs-moon:before{content:"\ee4e"}.bxs-mouse:before{content:"\ee4f"}.bxs-mouse-alt:before{content:"\ee50"}.bxs-movie:before{content:"\ee51"}.bxs-movie-play:before{content:"\ee52"}.bxs-music:before{content:"\ee53"}.bxs-navigation:before{content:"\ee54"}.bxs-network-chart:before{content:"\ee55"}.bxs-news:before{content:"\ee56"}.bxs-no-entry:before{content:"\ee57"}.bxs-note:before{content:"\ee58"}.bxs-notepad:before{content:"\ee59"}.bxs-notification:before{content:"\ee5a"}.bxs-notification-off:before{content:"\ee5b"}.bxs-offer:before{content:"\ee5c"}.bxs-package:before{content:"\ee5d"}.bxs-paint:before{content:"\ee5e"}.bxs-paint-roll:before{content:"\ee5f"}.bxs-palette:before{content:"\ee60"}.bxs-paper-plane:before{content:"\ee61"}.bxs-parking:before{content:"\ee62"}.bxs-paste:before{content:"\ee63"}.bxs-pen:before{content:"\ee64"}.bxs-pencil:before{content:"\ee65"}.bxs-phone:before{content:"\ee66"}.bxs-phone-call:before{content:"\ee67"}.bxs-phone-incoming:before{content:"\ee68"}.bxs-phone-off:before{content:"\ee69"}.bxs-phone-outgoing:before{content:"\ee6a"}.bxs-photo-album:before{content:"\ee6b"}.bxs-piano:before{content:"\ee6c"}.bxs-pie-chart:before{content:"\ee6d"}.bxs-pie-chart-alt:before{content:"\ee6e"}.bxs-pie-chart-alt-2:before{content:"\ee6f"}.bxs-pin:before{content:"\ee70"}.bxs-pizza:before{content:"\ee71"}.bxs-plane:before{content:"\ee72"}.bxs-plane-alt:before{content:"\ee73"}.bxs-plane-land:before{content:"\ee74"}.bxs-planet:before{content:"\ee75"}.bxs-plane-take-off:before{content:"\ee76"}.bxs-playlist:before{content:"\ee77"}.bxs-plug:before{content:"\ee78"}.bxs-plus-circle:before{content:"\ee79"}.bxs-plus-square:before{content:"\ee7a"}.bxs-pointer:before{content:"\ee7b"}.bxs-polygon:before{content:"\ee7c"}.bxs-printer:before{content:"\ee7d"}.bxs-purchase-tag:before{content:"\ee7e"}.bxs-purchase-tag-alt:before{content:"\ee7f"}.bxs-pyramid:before{content:"\ee80"}.bxs-quote-alt-left:before{content:"\ee81"}.bxs-quote-alt-right:before{content:"\ee82"}.bxs-quote-left:before{content:"\ee83"}.bxs-quote-right:before{content:"\ee84"}.bxs-quote-single-left:before{content:"\ee85"}.bxs-quote-single-right:before{content:"\ee86"}.bxs-radiation:before{content:"\ee87"}.bxs-radio:before{content:"\ee88"}.bxs-receipt:before{content:"\ee89"}.bxs-rectangle:before{content:"\ee8a"}.bxs-registered:before{content:"\ee8b"}.bxs-rename:before{content:"\ee8c"}.bxs-report:before{content:"\ee8d"}.bxs-rewind-circle:before{content:"\ee8e"}.bxs-right-arrow:before{content:"\ee8f"}.bxs-right-arrow-alt:before{content:"\ee90"}.bxs-right-arrow-circle:before{content:"\ee91"}.bxs-right-arrow-square:before{content:"\ee92"}.bxs-right-down-arrow-circle:before{content:"\ee93"}.bxs-right-top-arrow-circle:before{content:"\ee94"}.bxs-rocket:before{content:"\ee95"}.bxs-ruler:before{content:"\ee96"}.bxs-sad:before{content:"\ee97"}.bxs-save:before{content:"\ee98"}.bxs-school:before{content:"\ee99"}.bxs-search:before{content:"\ee9a"}.bxs-search-alt-2:before{content:"\ee9b"}.bxs-select-multiple:before{content:"\ee9c"}.bxs-send:before{content:"\ee9d"}.bxs-server:before{content:"\ee9e"}.bxs-shapes:before{content:"\ee9f"}.bxs-share:before{content:"\eea0"}.bxs-share-alt:before{content:"\eea1"}.bxs-shield:before{content:"\eea2"}.bxs-shield-alt-2:before{content:"\eea3"}.bxs-shield-x:before{content:"\eea4"}.bxs-ship:before{content:"\eea5"}.bxs-shocked:before{content:"\eea6"}.bxs-shopping-bag:before{content:"\eea7"}.bxs-shopping-bag-alt:before{content:"\eea8"}.bxs-shopping-bags:before{content:"\eea9"}.bxs-show:before{content:"\eeaa"}.bxs-skip-next-circle:before{content:"\eeab"}.bxs-skip-previous-circle:before{content:"\eeac"}.bxs-skull:before{content:"\eead"}.bxs-sleepy:before{content:"\eeae"}.bxs-slideshow:before{content:"\eeaf"}.bxs-smile:before{content:"\eeb0"}.bxs-sort-alt:before{content:"\eeb1"}.bxs-spa:before{content:"\eeb2"}.bxs-speaker:before{content:"\eeb3"}.bxs-spray-can:before{content:"\eeb4"}.bxs-spreadsheet:before{content:"\eeb5"}.bxs-square:before{content:"\eeb6"}.bxs-square-rounded:before{content:"\eeb7"}.bxs-star:before{content:"\eeb8"}.bxs-star-half:before{content:"\eeb9"}.bxs-sticker:before{content:"\eeba"}.bxs-stopwatch:before{content:"\eebb"}.bxs-store:before{content:"\eebc"}.bxs-store-alt:before{content:"\eebd"}.bxs-sun:before{content:"\eebe"}.bxs-tachometer:before{content:"\eebf"}.bxs-tag:before{content:"\eec0"}.bxs-tag-alt:before{content:"\eec1"}.bxs-tag-x:before{content:"\eec2"}.bxs-taxi:before{content:"\eec3"}.bxs-tennis-ball:before{content:"\eec4"}.bxs-terminal:before{content:"\eec5"}.bxs-thermometer:before{content:"\eec6"}.bxs-time:before{content:"\eec7"}.bxs-time-five:before{content:"\eec8"}.bxs-timer:before{content:"\eec9"}.bxs-tired:before{content:"\eeca"}.bxs-toggle-left:before{content:"\eecb"}.bxs-toggle-right:before{content:"\eecc"}.bxs-tone:before{content:"\eecd"}.bxs-torch:before{content:"\eece"}.bxs-to-top:before{content:"\eecf"}.bxs-traffic:before{content:"\eed0"}.bxs-traffic-barrier:before{content:"\eed1"}.bxs-traffic-cone:before{content:"\eed2"}.bxs-train:before{content:"\eed3"}.bxs-trash:before{content:"\eed4"}.bxs-trash-alt:before{content:"\eed5"}.bxs-tree:before{content:"\eed6"}.bxs-trophy:before{content:"\eed7"}.bxs-truck:before{content:"\eed8"}.bxs-t-shirt:before{content:"\eed9"}.bxs-tv:before{content:"\eeda"}.bxs-up-arrow:before{content:"\eedb"}.bxs-up-arrow-alt:before{content:"\eedc"}.bxs-up-arrow-circle:before{content:"\eedd"}.bxs-up-arrow-square:before{content:"\eede"}.bxs-upside-down:before{content:"\eedf"}.bxs-upvote:before{content:"\eee0"}.bxs-user:before{content:"\eee1"}.bxs-user-account:before{content:"\eee2"}.bxs-user-badge:before{content:"\eee3"}.bxs-user-check:before{content:"\eee4"}.bxs-user-circle:before{content:"\eee5"}.bxs-user-detail:before{content:"\eee6"}.bxs-user-minus:before{content:"\eee7"}.bxs-user-pin:before{content:"\eee8"}.bxs-user-plus:before{content:"\eee9"}.bxs-user-rectangle:before{content:"\eeea"}.bxs-user-voice:before{content:"\eeeb"}.bxs-user-x:before{content:"\eeec"}.bxs-vector:before{content:"\eeed"}.bxs-vial:before{content:"\eeee"}.bxs-video:before{content:"\eeef"}.bxs-video-off:before{content:"\eef0"}.bxs-video-plus:before{content:"\eef1"}.bxs-video-recording:before{content:"\eef2"}.bxs-videos:before{content:"\eef3"}.bxs-virus:before{content:"\eef4"}.bxs-virus-block:before{content:"\eef5"}.bxs-volume:before{content:"\eef6"}.bxs-volume-full:before{content:"\eef7"}.bxs-volume-low:before{content:"\eef8"}.bxs-volume-mute:before{content:"\eef9"}.bxs-wallet:before{content:"\eefa"}.bxs-wallet-alt:before{content:"\eefb"}.bxs-washer:before{content:"\eefc"}.bxs-watch:before{content:"\eefd"}.bxs-watch-alt:before{content:"\eefe"}.bxs-webcam:before{content:"\eeff"}.bxs-widget:before{content:"\ef00"}.bxs-window-alt:before{content:"\ef01"}.bxs-wine:before{content:"\ef02"}.bxs-wink-smile:before{content:"\ef03"}.bxs-wink-tongue:before{content:"\ef04"}.bxs-wrench:before{content:"\ef05"}.bxs-x-circle:before{content:"\ef06"}.bxs-x-square:before{content:"\ef07"}.bxs-yin-yang:before{content:"\ef08"}.bxs-zap:before{content:"\ef09"}.bxs-zoom-in:before{content:"\ef0a"}.bxs-zoom-out:before{content:"\ef0b"}
\ No newline at end of file
diff --git a/Moonlight/wwwroot/fonts/boxicons.eot b/Moonlight/wwwroot/fonts/boxicons.eot
new file mode 100644
index 00000000..c81a1dea
Binary files /dev/null and b/Moonlight/wwwroot/fonts/boxicons.eot differ
diff --git a/Moonlight/wwwroot/fonts/boxicons.svg b/Moonlight/wwwroot/fonts/boxicons.svg
new file mode 100644
index 00000000..edce3834
--- /dev/null
+++ b/Moonlight/wwwroot/fonts/boxicons.svg
@@ -0,0 +1,1653 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Moonlight/wwwroot/fonts/boxicons.ttf b/Moonlight/wwwroot/fonts/boxicons.ttf
new file mode 100644
index 00000000..998f0598
Binary files /dev/null and b/Moonlight/wwwroot/fonts/boxicons.ttf differ
diff --git a/Moonlight/wwwroot/fonts/boxicons.woff b/Moonlight/wwwroot/fonts/boxicons.woff
new file mode 100644
index 00000000..3345c5ce
Binary files /dev/null and b/Moonlight/wwwroot/fonts/boxicons.woff differ
diff --git a/Moonlight/wwwroot/fonts/boxicons.woff2 b/Moonlight/wwwroot/fonts/boxicons.woff2
new file mode 100644
index 00000000..07d26184
Binary files /dev/null and b/Moonlight/wwwroot/fonts/boxicons.woff2 differ
diff --git a/Moonlight/wwwroot/js/bootstrap.bundle.min.js b/Moonlight/wwwroot/js/bootstrap.bundle.min.js
new file mode 100644
index 00000000..b1999d9a
--- /dev/null
+++ b/Moonlight/wwwroot/js/bootstrap.bundle.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v5.3.2 (https://getbootstrap.com/)
+ * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?n(i.trim()):null}return e},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=".dropdown-toggle",zs=`:not(${Bs})`,Rs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',qs=`.nav-link${zs}, .list-group-item${zs}, [role="tab"]${zs}, ${Rs}`,Vs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Ks extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Ks.getOrCreateInstance(i).show())}_getChildren(){return z.find(qs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Bs,Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(qs)?t:z.findOne(qs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Ks.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,Rs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Ks.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(Vs))Ks.getOrCreateInstance(t)})),m(Ks);const Qs=".bs.toast",Xs=`mouseover${Qs}`,Ys=`mouseout${Qs}`,Us=`focusin${Qs}`,Gs=`focusout${Qs}`,Js=`hide${Qs}`,Zs=`hidden${Qs}`,to=`show${Qs}`,eo=`shown${Qs}`,io="hide",no="show",so="showing",oo={animation:"boolean",autohide:"boolean",delay:"number"},ro={animation:!0,autohide:!0,delay:5e3};class ao extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return ro}static get DefaultType(){return oo}static get NAME(){return"toast"}show(){N.trigger(this._element,to).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(io),d(this._element),this._element.classList.add(no,so),this._queueCallback((()=>{this._element.classList.remove(so),N.trigger(this._element,eo),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Js).defaultPrevented||(this._element.classList.add(so),this._queueCallback((()=>{this._element.classList.add(io),this._element.classList.remove(so,no),N.trigger(this._element,Zs)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(no),super.dispose()}isShown(){return this._element.classList.contains(no)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Xs,(t=>this._onInteraction(t,!0))),N.on(this._element,Ys,(t=>this._onInteraction(t,!1))),N.on(this._element,Us,(t=>this._onInteraction(t,!0))),N.on(this._element,Gs,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ao.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ao),m(ao),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Ks,Toast:ao,Tooltip:cs}}));
+//# sourceMappingURL=bootstrap.bundle.min.js.map
\ No newline at end of file